Skip to content

Commit 90bc43f

Browse files
authored
feat: enable provider webhooks (#195)
* enable webhooks * grant provider init jobs cluster-admin privileges * remove webhook from provider config and check for TLS secret instead
1 parent 52a8830 commit 90bc43f

File tree

7 files changed

+70
-46
lines changed

7 files changed

+70
-46
lines changed

api/provider/v1alpha1/deployment_types.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,12 @@ type DeploymentSpec struct {
9696
TopologySpreadConstraints []corev1.TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty" patchStrategy:"merge" patchMergeKey:"topologyKey"`
9797
}
9898

99+
type WebhookConfiguration struct {
100+
// Enabled indicates whether the webhook is enabled.
101+
// +kubebuilder:default=false
102+
Enabled bool `json:"enabled"`
103+
}
104+
99105
// DeploymentStatus defines the observed state of a provider.
100106
type DeploymentStatus struct {
101107
// +optional

api/provider/v1alpha1/zz_generated.deepcopy.go

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/controllers/provider/install/deployment.go

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,24 @@ func (m *deploymentMutator) Mutate(d *appsv1.Deployment) error {
5757
return err
5858
}
5959

60+
volumes := m.values.deploymentSpec.ExtraVolumes
61+
volumeMounts := m.values.deploymentSpec.ExtraVolumeMounts
62+
if m.values.webhookTLSSecretName != "" {
63+
volumes = append(volumes, corev1.Volume{
64+
Name: "webhook-tls",
65+
VolumeSource: corev1.VolumeSource{
66+
Secret: &corev1.SecretVolumeSource{
67+
SecretName: m.values.webhookTLSSecretName,
68+
},
69+
},
70+
})
71+
volumeMounts = append(volumeMounts, corev1.VolumeMount{
72+
Name: "webhook-tls",
73+
MountPath: "/tmp/k8s-webhook-server/serving-certs",
74+
ReadOnly: true,
75+
})
76+
}
77+
6078
runCmd := slices.Clone(m.values.deploymentSpec.RunCommand)
6179
if len(runCmd) == 0 {
6280
runCmd = []string{"run"}
@@ -86,12 +104,12 @@ func (m *deploymentMutator) Mutate(d *appsv1.Deployment) error {
86104
ImagePullPolicy: corev1.PullIfNotPresent,
87105
Args: runCmd,
88106
Env: env,
89-
VolumeMounts: m.values.deploymentSpec.ExtraVolumeMounts,
107+
VolumeMounts: volumeMounts,
90108
},
91109
},
92110
ImagePullSecrets: m.values.ImagePullSecrets(),
93111
ServiceAccountName: m.values.NamespacedDefaultResourceName(),
94-
Volumes: m.values.deploymentSpec.ExtraVolumes,
112+
Volumes: volumes,
95113
TopologySpreadConstraints: m.values.deploymentSpec.TopologySpreadConstraints,
96114
},
97115
},

internal/controllers/provider/install/installer.go

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"sigs.k8s.io/controller-runtime/pkg/client"
1717

1818
"github.com/openmcp-project/openmcp-operator/api/provider/v1alpha1"
19+
libutils "github.com/openmcp-project/openmcp-operator/lib/utils"
1920
)
2021

2122
const (
@@ -48,10 +49,6 @@ func (a *Installer) InstallInitJob(ctx context.Context) (completed bool, err err
4849
return false, err
4950
}
5051

51-
if err = resources.CreateOrUpdateResource(ctx, a.PlatformClient, newInitClusterRoleMutator(values)); err != nil {
52-
return false, err
53-
}
54-
5552
if err = resources.CreateOrUpdateResource(ctx, a.PlatformClient, newInitClusterRoleBindingMutator(values)); err != nil {
5653
return false, err
5754
}
@@ -116,6 +113,17 @@ func (a *Installer) InstallProvider(ctx context.Context) error {
116113
return err
117114
}
118115

116+
// check if webhook TLS secret exists
117+
whSecretName, err := libutils.WebhookSecretName(values.provider.GetName())
118+
if err != nil {
119+
return err
120+
}
121+
if err := a.PlatformClient.Get(ctx, client.ObjectKey{Name: whSecretName, Namespace: values.Namespace()}, &core.Secret{}); err == nil {
122+
values.webhookTLSSecretName = whSecretName
123+
} else if !apierrors.IsNotFound(err) {
124+
return fmt.Errorf("unable to check for webhook TLS secret existence: %w", err)
125+
}
126+
119127
if err := resources.CreateOrUpdateResource(ctx, a.PlatformClient, NewDeploymentMutator(values)); err != nil {
120128
return err
121129
}
@@ -159,10 +167,6 @@ func (a *Installer) UninstallProvider(ctx context.Context) (deleted bool, err er
159167
return false, err
160168
}
161169

162-
if err := resources.DeleteResource(ctx, a.PlatformClient, newInitClusterRoleMutator(values)); err != nil {
163-
return false, err
164-
}
165-
166170
if err := resources.DeleteResource(ctx, a.PlatformClient, newInitServiceAccountMutator(values)); err != nil {
167171
return false, err
168172
}

internal/controllers/provider/install/rbac_init.go

Lines changed: 1 addition & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -23,37 +23,7 @@ func newInitClusterRoleBindingMutator(values *Values) resources.Mutator[*rbac.Cl
2323
Namespace: values.Namespace(),
2424
},
2525
},
26-
resources.NewClusterRoleRef(clusterRoleName),
27-
)
28-
res.MetadataMutator().WithLabels(values.LabelsInitJob())
29-
return res
30-
}
31-
32-
func newInitClusterRoleMutator(values *Values) resources.Mutator[*rbac.ClusterRole] {
33-
res := resources.NewClusterRoleMutator(
34-
values.ClusterScopedResourceName(initPrefix),
35-
[]rbac.PolicyRule{
36-
{
37-
APIGroups: []string{"apiextensions.k8s.io"},
38-
Resources: []string{"customresourcedefinitions"},
39-
Verbs: []string{"get", "list", "watch", "create", "update", "patch", "delete"},
40-
},
41-
{
42-
APIGroups: []string{""},
43-
Resources: []string{"secrets"},
44-
Verbs: []string{"get", "list", "watch"},
45-
},
46-
{
47-
APIGroups: []string{""},
48-
Resources: []string{"configmaps"},
49-
Verbs: []string{"get", "list", "watch"},
50-
},
51-
{
52-
APIGroups: []string{"clusters.openmcp.cloud"},
53-
Resources: []string{"accessrequests", "clusterrequests", "clusterprofiles"},
54-
Verbs: []string{"get", "list", "watch", "create", "update", "patch", "delete"},
55-
},
56-
},
26+
resources.NewClusterRoleRef("cluster-admin"),
5727
)
5828
res.MetadataMutator().WithLabels(values.LabelsInitJob())
5929
return res

internal/controllers/provider/install/values.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,12 @@ func NewValues(provider *unstructured.Unstructured, deploymentSpec *v1alpha1.Dep
2727
}
2828

2929
type Values struct {
30-
provider *unstructured.Unstructured
31-
deploymentSpec *v1alpha1.DeploymentSpec
32-
environment string
33-
namespace string
34-
providerPrefix string
30+
provider *unstructured.Unstructured
31+
deploymentSpec *v1alpha1.DeploymentSpec
32+
environment string
33+
namespace string
34+
providerPrefix string
35+
webhookTLSSecretName string
3536
}
3637

3738
func (v *Values) Environment() string {

lib/utils/utils.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,13 @@ func StableMCPIdentifier(onboardingName, onboardingNamespace string) (string, er
7070
}
7171
return res, nil
7272
}
73+
74+
// WebhookSecretName computes the name the secret containing the webhook TLS certificate is expected to have, based on the provider's name.
75+
func WebhookSecretName(providerName string) (string, error) {
76+
suffix := "-webhook-tls"
77+
base, err := controller.ShortenToXCharacters(providerName, controller.K8sMaxNameLength-len(suffix))
78+
if err != nil {
79+
return "", fmt.Errorf("error computing webhook secret name: %w", err)
80+
}
81+
return base + suffix, nil
82+
}

0 commit comments

Comments
 (0)