Skip to content

Commit 918823d

Browse files
mnenciaarmruNiccoloFei
authored
fix: do not add barman-certificates projection if not needed (#354)
Closes #347 #364 Signed-off-by: Marco Nenciarini <[email protected]> Signed-off-by: Armando Ruocco <[email protected]> Signed-off-by: Niccolò Fei <[email protected]> Co-authored-by: Armando Ruocco <[email protected]> Co-authored-by: Niccolò Fei <[email protected]>
1 parent 1097abb commit 918823d

File tree

2 files changed

+199
-34
lines changed

2 files changed

+199
-34
lines changed

internal/cnpgi/operator/lifecycle.go

Lines changed: 76 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,7 @@ func reconcilePodSpec(
333333
Drop: []corev1.Capability{"ALL"},
334334
},
335335
}
336+
sidecarTemplate.RestartPolicy = ptr.To(corev1.ContainerRestartPolicyAlways)
336337
sidecarTemplate.Resources = config.resources
337338

338339
// merge the main container envs if they aren't already set
@@ -368,20 +369,29 @@ func reconcilePodSpec(
368369
}
369370
}
370371

371-
if err := injectPluginSidecarPodSpec(spec, &sidecarTemplate, mainContainerName); err != nil {
372-
return err
373-
}
372+
if len(config.certificates) > 0 {
373+
sidecarTemplate.VolumeMounts = ensureVolumeMount(
374+
sidecarTemplate.VolumeMounts,
375+
corev1.VolumeMount{
376+
Name: barmanCertificatesVolumeName,
377+
MountPath: metadata.BarmanCertificatesPath,
378+
})
374379

375-
// inject the volume containing the certificates if needed
376-
if !volumeListHasVolume(spec.Volumes, barmanCertificatesVolumeName) {
377-
spec.Volumes = append(spec.Volumes, corev1.Volume{
380+
spec.Volumes = ensureVolume(spec.Volumes, corev1.Volume{
378381
Name: barmanCertificatesVolumeName,
379382
VolumeSource: corev1.VolumeSource{
380383
Projected: &corev1.ProjectedVolumeSource{
381384
Sources: config.certificates,
382385
},
383386
},
384387
})
388+
} else {
389+
sidecarTemplate.VolumeMounts = removeVolumeMount(sidecarTemplate.VolumeMounts, barmanCertificatesVolumeName)
390+
spec.Volumes = removeVolume(spec.Volumes, barmanCertificatesVolumeName)
391+
}
392+
393+
if err := injectPluginSidecarPodSpec(spec, &sidecarTemplate, mainContainerName); err != nil {
394+
return err
385395
}
386396

387397
return nil
@@ -407,7 +417,7 @@ func InjectPluginVolumePodSpec(spec *corev1.PodSpec, mainContainerName string) {
407417
return
408418
}
409419

410-
spec.Volumes = append(spec.Volumes, corev1.Volume{
420+
spec.Volumes = ensureVolume(spec.Volumes, corev1.Volume{
411421
Name: pluginVolumeName,
412422
VolumeSource: corev1.VolumeSource{
413423
EmptyDir: &corev1.EmptyDirVolumeSource{},
@@ -416,7 +426,7 @@ func InjectPluginVolumePodSpec(spec *corev1.PodSpec, mainContainerName string) {
416426

417427
for i := range spec.Containers {
418428
if spec.Containers[i].Name == mainContainerName {
419-
spec.Containers[i].VolumeMounts = append(
429+
spec.Containers[i].VolumeMounts = ensureVolumeMount(
420430
spec.Containers[i].VolumeMounts,
421431
corev1.VolumeMount{
422432
Name: pluginVolumeName,
@@ -428,10 +438,6 @@ func InjectPluginVolumePodSpec(spec *corev1.PodSpec, mainContainerName string) {
428438
}
429439

430440
// injectPluginSidecarPodSpec injects a plugin sidecar into a CNPG Pod spec.
431-
//
432-
// If the "injectMainContainerVolumes" flag is true, this will append all the volume
433-
// mounts that are used in the instance manager Pod to the passed sidecar
434-
// container, granting it superuser access to the PostgreSQL instance.
435441
func injectPluginSidecarPodSpec(
436442
spec *corev1.PodSpec,
437443
sidecar *corev1.Container,
@@ -440,12 +446,11 @@ func injectPluginSidecarPodSpec(
440446
sidecar = sidecar.DeepCopy()
441447
InjectPluginVolumePodSpec(spec, mainContainerName)
442448

443-
var volumeMounts []corev1.VolumeMount
444449
sidecarContainerFound := false
445450
mainContainerFound := false
446451
for i := range spec.Containers {
447452
if spec.Containers[i].Name == mainContainerName {
448-
volumeMounts = spec.Containers[i].VolumeMounts
453+
sidecar.VolumeMounts = ensureVolumeMount(sidecar.VolumeMounts, spec.Containers[i].VolumeMounts...)
449454
mainContainerFound = true
450455
}
451456
}
@@ -457,38 +462,75 @@ func injectPluginSidecarPodSpec(
457462
for i := range spec.InitContainers {
458463
if spec.InitContainers[i].Name == sidecar.Name {
459464
sidecarContainerFound = true
465+
spec.InitContainers[i] = *sidecar
460466
}
461467
}
462468

463-
if sidecarContainerFound {
464-
// The sidecar container was already added
465-
return nil
469+
if !sidecarContainerFound {
470+
spec.InitContainers = append(spec.InitContainers, *sidecar)
466471
}
467472

468-
// Do not modify the passed sidecar definition
469-
sidecar.VolumeMounts = append(
470-
sidecar.VolumeMounts,
471-
corev1.VolumeMount{
472-
Name: barmanCertificatesVolumeName,
473-
MountPath: metadata.BarmanCertificatesPath,
474-
})
475-
sidecar.VolumeMounts = append(sidecar.VolumeMounts, volumeMounts...)
476-
sidecar.RestartPolicy = ptr.To(corev1.ContainerRestartPolicyAlways)
477-
spec.InitContainers = append(spec.InitContainers, *sidecar)
478-
479473
return nil
480474
}
481475

482-
// volumeListHasVolume check if a volume with a known name exists
483-
// in the volume list
484-
func volumeListHasVolume(volumes []corev1.Volume, name string) bool {
476+
// ensureVolume makes sure the passed volume is present in the list of volumes.
477+
// If the volume is already present, it is updated.
478+
func ensureVolume(volumes []corev1.Volume, volume corev1.Volume) []corev1.Volume {
479+
volumeFound := false
485480
for i := range volumes {
486-
if volumes[i].Name == name {
487-
return true
481+
if volumes[i].Name == volume.Name {
482+
volumeFound = true
483+
volumes[i] = volume
488484
}
489485
}
490486

491-
return false
487+
if !volumeFound {
488+
volumes = append(volumes, volume)
489+
}
490+
491+
return volumes
492+
}
493+
494+
// ensureVolumeMount makes sure the passed volume mounts are present in the list of volume mounts.
495+
// If a volume mount is already present, it is updated.
496+
func ensureVolumeMount(mounts []corev1.VolumeMount, volumeMounts ...corev1.VolumeMount) []corev1.VolumeMount {
497+
for _, mount := range volumeMounts {
498+
mountFound := false
499+
for i := range mounts {
500+
if mounts[i].Name == mount.Name {
501+
mountFound = true
502+
mounts[i] = mount
503+
break
504+
}
505+
}
506+
507+
if !mountFound {
508+
mounts = append(mounts, mount)
509+
}
510+
}
511+
512+
return mounts
513+
}
514+
515+
// removeVolume removes a volume with a known name from a list of volumes.
516+
func removeVolume(volumes []corev1.Volume, name string) []corev1.Volume {
517+
var filteredVolumes []corev1.Volume
518+
for _, volume := range volumes {
519+
if volume.Name != name {
520+
filteredVolumes = append(filteredVolumes, volume)
521+
}
522+
}
523+
return filteredVolumes
524+
}
525+
526+
func removeVolumeMount(mounts []corev1.VolumeMount, name string) []corev1.VolumeMount {
527+
var filteredMounts []corev1.VolumeMount
528+
for _, mount := range mounts {
529+
if mount.Name != name {
530+
filteredMounts = append(filteredMounts, mount)
531+
}
532+
}
533+
return filteredMounts
492534
}
493535

494536
// getCNPGJobRole gets the role associated to a CNPG job

internal/cnpgi/operator/lifecycle_test.go

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,3 +209,126 @@ var _ = Describe("LifecycleImplementation", func() {
209209
})
210210
})
211211
})
212+
213+
var _ = Describe("Volume utilities", func() {
214+
Describe("ensureVolume", func() {
215+
It("adds a new volume if not present", func() {
216+
volumes := []corev1.Volume{{Name: "vol1"}}
217+
newVol := corev1.Volume{Name: "vol2"}
218+
result := ensureVolume(volumes, newVol)
219+
Expect(result).To(HaveLen(2))
220+
Expect(result[1]).To(Equal(newVol))
221+
})
222+
223+
It("updates an existing volume", func() {
224+
volumes := []corev1.Volume{{Name: "vol1"}}
225+
updatedVol := corev1.Volume{Name: "vol1", VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{}}}
226+
result := ensureVolume(volumes, updatedVol)
227+
Expect(result).To(HaveLen(1))
228+
Expect(result[0]).To(Equal(updatedVol))
229+
})
230+
})
231+
232+
Describe("removeVolume", func() {
233+
It("removes the specified volume", func() {
234+
volumes := []corev1.Volume{
235+
{Name: "vol1"},
236+
{Name: "vol2"},
237+
{Name: "vol3"},
238+
}
239+
result := removeVolume(volumes, "vol2")
240+
Expect(result).To(HaveLen(2))
241+
for _, v := range result {
242+
Expect(v.Name).NotTo(Equal("vol2"))
243+
}
244+
})
245+
246+
It("returns the same list if the volume is not present", func() {
247+
volumes := []corev1.Volume{{Name: "vol1"}, {Name: "vol2"}}
248+
result := removeVolume(volumes, "vol3")
249+
Expect(result).To(Equal(volumes))
250+
})
251+
})
252+
253+
Describe("removeVolumeMount", func() {
254+
It("removes the specified volume mount", func() {
255+
mounts := []corev1.VolumeMount{
256+
{Name: "mount1"},
257+
{Name: "mount2"},
258+
{Name: "mount3"},
259+
}
260+
result := removeVolumeMount(mounts, "mount2")
261+
Expect(result).To(HaveLen(2))
262+
for _, m := range result {
263+
Expect(m.Name).NotTo(Equal("mount2"))
264+
}
265+
})
266+
267+
It("returns the same list if the volume mount is not present", func() {
268+
mounts := []corev1.VolumeMount{{Name: "mount1"}, {Name: "mount2"}}
269+
result := removeVolumeMount(mounts, "mount3")
270+
Expect(result).To(HaveLen(2))
271+
Expect(result[0].Name).To(Equal("mount1"))
272+
Expect(result[1].Name).To(Equal("mount2"))
273+
})
274+
275+
It("handles empty input slice", func() {
276+
var mounts []corev1.VolumeMount
277+
result := removeVolumeMount(mounts, "mount1")
278+
Expect(result).To(BeEmpty())
279+
})
280+
})
281+
282+
Describe("ensureVolumeMount", func() {
283+
It("adds a new volume mount to an empty list", func() {
284+
var mounts []corev1.VolumeMount
285+
newMount := corev1.VolumeMount{Name: "mount1", MountPath: "/path1"}
286+
result := ensureVolumeMount(mounts, newMount)
287+
Expect(result).To(HaveLen(1))
288+
Expect(result[0]).To(Equal(newMount))
289+
})
290+
291+
It("adds a new volume mount to a non-empty list", func() {
292+
mounts := []corev1.VolumeMount{{Name: "mount1", MountPath: "/path1"}}
293+
newMount := corev1.VolumeMount{Name: "mount2", MountPath: "/path2"}
294+
result := ensureVolumeMount(mounts, newMount)
295+
Expect(result).To(HaveLen(2))
296+
Expect(result[0].Name).To(Equal("mount1"))
297+
Expect(result[1].Name).To(Equal("mount2"))
298+
})
299+
300+
It("updates an existing volume mount", func() {
301+
mounts := []corev1.VolumeMount{{Name: "mount1", MountPath: "/path1"}}
302+
updatedMount := corev1.VolumeMount{Name: "mount1", MountPath: "/new-path"}
303+
result := ensureVolumeMount(mounts, updatedMount)
304+
Expect(result).To(HaveLen(1))
305+
Expect(result[0].MountPath).To(Equal("/new-path"))
306+
})
307+
308+
It("adds multiple new volume mounts", func() {
309+
mounts := []corev1.VolumeMount{{Name: "mount1", MountPath: "/path1"}}
310+
newMount1 := corev1.VolumeMount{Name: "mount2", MountPath: "/path2"}
311+
newMount2 := corev1.VolumeMount{Name: "mount3", MountPath: "/path3"}
312+
result := ensureVolumeMount(mounts, newMount1, newMount2)
313+
Expect(result).To(HaveLen(3))
314+
Expect(result[0].Name).To(Equal("mount1"))
315+
Expect(result[1].Name).To(Equal("mount2"))
316+
Expect(result[2].Name).To(Equal("mount3"))
317+
})
318+
319+
It("handles a mix of new and existing volume mounts", func() {
320+
mounts := []corev1.VolumeMount{
321+
{Name: "mount1", MountPath: "/path1"},
322+
{Name: "mount2", MountPath: "/path2"},
323+
}
324+
updatedMount := corev1.VolumeMount{Name: "mount1", MountPath: "/new-path"}
325+
newMount := corev1.VolumeMount{Name: "mount3", MountPath: "/path3"}
326+
result := ensureVolumeMount(mounts, updatedMount, newMount)
327+
Expect(result).To(HaveLen(3))
328+
Expect(result[0].Name).To(Equal("mount1"))
329+
Expect(result[0].MountPath).To(Equal("/new-path"))
330+
Expect(result[1].Name).To(Equal("mount2"))
331+
Expect(result[2].Name).To(Equal("mount3"))
332+
})
333+
})
334+
})

0 commit comments

Comments
 (0)