Skip to content

Commit 8f81c23

Browse files
perdasilvaPer Goncalves da Silva
and
Per Goncalves da Silva
authored
🐛 Fix webhook cert duplicate volume mount path bug (#2002)
* Remove api-service certificate volume from operator deployment Signed-off-by: Per Goncalves da Silva <[email protected]> * Add tls.crt and tls.key constants Signed-off-by: Per Goncalves da Silva <[email protected]> * Ensure volumes with volume mounts referencing protected cert paths get replaced Signed-off-by: Per Goncalves da Silva <[email protected]> --------- Signed-off-by: Per Goncalves da Silva <[email protected]> Co-authored-by: Per Goncalves da Silva <[email protected]>
1 parent d41ddd0 commit 8f81c23

File tree

2 files changed

+46
-69
lines changed

2 files changed

+46
-69
lines changed

internal/operator-controller/rukpak/render/registryv1/generators/generators.go

Lines changed: 32 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,14 @@ import (
2626
"github.com/operator-framework/operator-controller/internal/operator-controller/rukpak/util"
2727
)
2828

29-
var certVolumeMounts = map[string]corev1.VolumeMount{
30-
"apiservice-cert": {
31-
Name: "apiservice-cert",
32-
MountPath: "/apiserver.local.config/certificates",
33-
},
34-
"webhook-cert": {
35-
Name: "webhook-cert",
36-
MountPath: "/tmp/k8s-webhook-server/serving-certs",
37-
},
29+
const (
30+
tlsCrtPath = "tls.crt"
31+
tlsKeyPath = "tls.key"
32+
)
33+
34+
// volume mount name -> mount path
35+
var certVolumeMounts = map[string]string{
36+
"webhook-cert": "/tmp/k8s-webhook-server/serving-certs",
3837
}
3938

4039
// BundleCSVDeploymentGenerator generates all deployments defined in rv1's cluster service version (CSV). The generated
@@ -480,43 +479,35 @@ func getWebhookServicePort(wh v1alpha1.WebhookDescription) corev1.ServicePort {
480479
}
481480

482481
func addCertVolumesToDeployment(dep *appsv1.Deployment, certSecretInfo render.CertSecretInfo) {
482+
volumeMountsToReplace := sets.New(slices.Collect(maps.Keys(certVolumeMounts))...)
483+
certVolumeMountPaths := sets.New(slices.Collect(maps.Values(certVolumeMounts))...)
484+
for _, c := range dep.Spec.Template.Spec.Containers {
485+
for _, containerVolumeMount := range c.VolumeMounts {
486+
if certVolumeMountPaths.Has(containerVolumeMount.MountPath) {
487+
volumeMountsToReplace.Insert(containerVolumeMount.Name)
488+
}
489+
}
490+
}
491+
483492
// update pod volumes
484493
dep.Spec.Template.Spec.Volumes = slices.Concat(
485494
slices.DeleteFunc(dep.Spec.Template.Spec.Volumes, func(v corev1.Volume) bool {
486-
_, ok := certVolumeMounts[v.Name]
487-
return ok
495+
return volumeMountsToReplace.Has(v.Name)
488496
}),
489497
[]corev1.Volume{
490498
{
491-
Name: "apiservice-cert",
492-
VolumeSource: corev1.VolumeSource{
493-
Secret: &corev1.SecretVolumeSource{
494-
SecretName: certSecretInfo.SecretName,
495-
Items: []corev1.KeyToPath{
496-
{
497-
Key: certSecretInfo.CertificateKey,
498-
Path: "apiserver.crt",
499-
},
500-
{
501-
Key: certSecretInfo.PrivateKeyKey,
502-
Path: "apiserver.key",
503-
},
504-
},
505-
},
506-
},
507-
}, {
508499
Name: "webhook-cert",
509500
VolumeSource: corev1.VolumeSource{
510501
Secret: &corev1.SecretVolumeSource{
511502
SecretName: certSecretInfo.SecretName,
512503
Items: []corev1.KeyToPath{
513504
{
514505
Key: certSecretInfo.CertificateKey,
515-
Path: "tls.crt",
506+
Path: tlsCrtPath,
516507
},
517508
{
518509
Key: certSecretInfo.PrivateKeyKey,
519-
Path: "tls.key",
510+
Path: tlsKeyPath,
520511
},
521512
},
522513
},
@@ -529,15 +520,18 @@ func addCertVolumesToDeployment(dep *appsv1.Deployment, certSecretInfo render.Ce
529520
for i := range dep.Spec.Template.Spec.Containers {
530521
dep.Spec.Template.Spec.Containers[i].VolumeMounts = slices.Concat(
531522
slices.DeleteFunc(dep.Spec.Template.Spec.Containers[i].VolumeMounts, func(v corev1.VolumeMount) bool {
532-
_, ok := certVolumeMounts[v.Name]
533-
return ok
523+
return volumeMountsToReplace.Has(v.Name)
534524
}),
535-
slices.SortedFunc(
536-
maps.Values(certVolumeMounts),
537-
func(a corev1.VolumeMount, b corev1.VolumeMount) int {
538-
return cmp.Compare(a.Name, b.Name)
539-
},
540-
),
525+
func() []corev1.VolumeMount {
526+
volumeMounts := make([]corev1.VolumeMount, 0, len(certVolumeMounts))
527+
for _, name := range slices.Sorted(maps.Keys(certVolumeMounts)) {
528+
volumeMounts = append(volumeMounts, corev1.VolumeMount{
529+
Name: name,
530+
MountPath: certVolumeMounts[name],
531+
})
532+
}
533+
return volumeMounts
534+
}(),
541535
)
542536
}
543537
}

internal/operator-controller/rukpak/render/registryv1/generators/generators_test.go

Lines changed: 14 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ func Test_BundleCSVDeploymentGenerator_WithCertWithCertProvider_Succeeds(t *test
173173
},
174174
}
175175

176-
bundle := &bundle.RegistryV1{
176+
b := &bundle.RegistryV1{
177177
CSV: MakeCSV(
178178
WithWebhookDefinitions(
179179
v1alpha1.WebhookDescription{
@@ -189,31 +189,39 @@ func Test_BundleCSVDeploymentGenerator_WithCertWithCertProvider_Succeeds(t *test
189189
Spec: corev1.PodSpec{
190190
Volumes: []corev1.Volume{
191191
{
192-
Name: "apiservice-cert",
192+
Name: "some-other-mount",
193193
VolumeSource: corev1.VolumeSource{
194194
EmptyDir: &corev1.EmptyDirVolumeSource{},
195195
},
196196
},
197+
// this volume should be replaced by the webhook-cert volume
198+
// because it has a volume mount targeting the protected path
199+
// /tmp/k8s-webhook-server/serving-certs
197200
{
198-
Name: "some-other-mount",
201+
Name: "some-webhook-cert-mount",
199202
VolumeSource: corev1.VolumeSource{
200203
EmptyDir: &corev1.EmptyDirVolumeSource{},
201204
},
202205
},
203-
// expect webhook-cert volume to be injected
204206
},
205207
Containers: []corev1.Container{
206208
{
207209
Name: "container-1",
208210
VolumeMounts: []corev1.VolumeMount{
209-
// expect apiservice-cert volume to be injected
211+
// the mount path for this volume mount will be replaced with
212+
// /tmp/k8s-webhook-server/serving-certs
210213
{
211214
Name: "webhook-cert",
212215
MountPath: "/webhook-cert-path",
213216
}, {
214217
Name: "some-other-mount",
215218
MountPath: "/some/other/mount/path",
216219
},
220+
// this volume mount will be removed
221+
{
222+
Name: "some-webhook-cert-mount",
223+
MountPath: "/tmp/k8s-webhook-server/serving-certs",
224+
},
217225
},
218226
},
219227
{
@@ -229,7 +237,7 @@ func Test_BundleCSVDeploymentGenerator_WithCertWithCertProvider_Succeeds(t *test
229237
),
230238
}
231239

232-
objs, err := generators.BundleCSVDeploymentGenerator(bundle, render.Options{
240+
objs, err := generators.BundleCSVDeploymentGenerator(b, render.Options{
233241
InstallNamespace: "install-namespace",
234242
CertificateProvider: fakeProvider,
235243
})
@@ -247,23 +255,6 @@ func Test_BundleCSVDeploymentGenerator_WithCertWithCertProvider_Succeeds(t *test
247255
},
248256
},
249257
{
250-
Name: "apiservice-cert",
251-
VolumeSource: corev1.VolumeSource{
252-
Secret: &corev1.SecretVolumeSource{
253-
SecretName: "some-secret",
254-
Items: []corev1.KeyToPath{
255-
{
256-
Key: "some-cert-key",
257-
Path: "apiserver.crt",
258-
},
259-
{
260-
Key: "some-private-key-key",
261-
Path: "apiserver.key",
262-
},
263-
},
264-
},
265-
},
266-
}, {
267258
Name: "webhook-cert",
268259
VolumeSource: corev1.VolumeSource{
269260
Secret: &corev1.SecretVolumeSource{
@@ -290,10 +281,6 @@ func Test_BundleCSVDeploymentGenerator_WithCertWithCertProvider_Succeeds(t *test
290281
Name: "some-other-mount",
291282
MountPath: "/some/other/mount/path",
292283
},
293-
{
294-
Name: "apiservice-cert",
295-
MountPath: "/apiserver.local.config/certificates",
296-
},
297284
{
298285
Name: "webhook-cert",
299286
MountPath: "/tmp/k8s-webhook-server/serving-certs",
@@ -303,10 +290,6 @@ func Test_BundleCSVDeploymentGenerator_WithCertWithCertProvider_Succeeds(t *test
303290
{
304291
Name: "container-2",
305292
VolumeMounts: []corev1.VolumeMount{
306-
{
307-
Name: "apiservice-cert",
308-
MountPath: "/apiserver.local.config/certificates",
309-
},
310293
{
311294
Name: "webhook-cert",
312295
MountPath: "/tmp/k8s-webhook-server/serving-certs",

0 commit comments

Comments
 (0)