diff --git a/cmd/main.go b/cmd/main.go index 069cd78..25e4d2c 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -56,7 +56,7 @@ type config struct { TeamsFolderNumber string `env:"TEAMS_FOLDER_NUMBER,required,notEmpty"` Stage string `env:"STAGE,required,notEmpty"` IamProbeImage string `env:"IAM_PROBE_IMAGE"` - PrecreatorImage string `env:"PRECREATOR_IMAGE"` + PrecreatorImage *string `env:"PRECREATOR_IMAGE"` ADCGroupEnvName string `env:"ADC_GROUP_ENV_NAME"` GroupConfigs []controller.AccessGroupConfig `env:"GROUP_CONFIG,required,notEmpty"` AuditSinks []auditSink `env:"AUDIT_SINKS"` diff --git a/internal/controller/precreator.go b/internal/controller/precreator.go new file mode 100644 index 0000000..fb81b1a --- /dev/null +++ b/internal/controller/precreator.go @@ -0,0 +1,52 @@ +package controller + +import ( + "fmt" + "slices" + + corev1 "k8s.io/api/core/v1" +) + +func addOrUpdatePrecreator(podspec *corev1.PodSpec, bucketMounts map[string]string, precreatorImage string) (modified bool) { + precreator := corev1.Container{ + Image: precreatorImage, + Name: precreatorContainerName, + } + volumeMounts := make(map[string]corev1.VolumeMount, len(bucketMounts)) + for mountPoint, bucket := range bucketMounts { + volumeName := maxLengthVolumeName(mountPoint) + volumeMounts[volumeName] = corev1.VolumeMount{ + Name: volumeName, + MountPath: fmt.Sprintf("/buckets/%s", bucket), + } + } + for _, mount := range volumeMounts { + precreator.VolumeMounts = append(precreator.VolumeMounts, mount) + } + for i, c := range podspec.Containers { + if c.Name == precreator.Name { + if c.Image != precreatorImage || + !slices.EqualFunc(precreator.VolumeMounts, c.VolumeMounts, func(a, b corev1.VolumeMount) bool { + return a.Name == b.Name + }) { + podspec.Containers[i] = precreator + return true + } + return false + } + } + + podspec.Containers = append(podspec.Containers, precreator) + return true +} + +func removePrecreator(podspec *corev1.PodSpec) (modified bool) { + podspec.Containers = slices.DeleteFunc(podspec.Containers, func(c corev1.Container) bool { + if c.Name == precreatorContainerName { + modified = true + return true + } + return false + }) + return false +} diff --git a/internal/controller/statefulset_webhook.go b/internal/controller/statefulset_webhook.go index 8039362..b42e3b4 100644 --- a/internal/controller/statefulset_webhook.go +++ b/internal/controller/statefulset_webhook.go @@ -50,7 +50,7 @@ type StatefulsetMutator struct { TeamsFolderNumber string Stage string IamProbeImage string - PrecreatorImage string + PrecreatorImage *string ADCGroupEnvName string GroupConfigs AccessGroupConfigs @@ -142,6 +142,7 @@ func (m *StatefulsetMutator) Handle(ctx context.Context, req admission.Request) if accessExpired { removeBucketsFromPodSpec(&sfs.Spec.Template.Spec, serviceContainer) + removePrecreator(&sfs.Spec.Template.Spec) } else { bucketMounts := getExtraBucketMounts(sfs.Annotations) @@ -158,7 +159,12 @@ func (m *StatefulsetMutator) Handle(ctx context.Context, req admission.Request) } } - addBucketsToPodSpec(&sfs.Spec.Template.Spec, serviceContainer, bucketMounts, m.PrecreatorImage) + addBucketsToPodSpec(&sfs.Spec.Template.Spec, serviceContainer, bucketMounts) + if m.PrecreatorImage != nil { + addOrUpdatePrecreator(&sfs.Spec.Template.Spec, bucketMounts, *m.PrecreatorImage) + } else { + removePrecreator(&sfs.Spec.Template.Spec) + } } if m.IamProbeImage != "" && sfs.Annotations[iamProbeStatus] != iamProbeDone { diff --git a/internal/controller/volumes.go b/internal/controller/volumes.go index 0663bca..9503bdb 100644 --- a/internal/controller/volumes.go +++ b/internal/controller/volumes.go @@ -38,7 +38,7 @@ func maxLengthVolumeName(mountPoint string) string { return volumeName } -func addBucketsToPodSpec(podspec *corev1.PodSpec, container *corev1.Container, bucketMounts map[string]string, precreatorImage string) (shouldUpdate bool) { +func addBucketsToPodSpec(podspec *corev1.PodSpec, container *corev1.Container, bucketMounts map[string]string) (shouldUpdate bool) { volumes := make([]corev1.Volume, 0, len(bucketMounts)) volumeMounts := make([]corev1.VolumeMount, 0, len(bucketMounts)) for mountPoint, bucket := range bucketMounts { @@ -78,42 +78,7 @@ func addBucketsToPodSpec(podspec *corev1.PodSpec, container *corev1.Container, b container.VolumeMounts = append(container.VolumeMounts, volumeMounts...) } - precreatorModified := addOrUpdatePrecreator(podspec, bucketMounts, precreatorImage) - - return precreatorModified || len(volumes) > 0 || len(volumeMounts) > 0 -} - -func addOrUpdatePrecreator(podspec *corev1.PodSpec, bucketMounts map[string]string, precreatorImage string) (modified bool) { - precreator := corev1.Container{ - Image: precreatorImage, - Name: precreatorContainerName, - } - volumeMounts := make(map[string]corev1.VolumeMount, len(bucketMounts)) - for mountPoint, bucket := range bucketMounts { - volumeName := maxLengthVolumeName(mountPoint) - volumeMounts[volumeName] = corev1.VolumeMount{ - Name: volumeName, - MountPath: fmt.Sprintf("/buckets/%s", bucket), - } - } - for _, mount := range volumeMounts { - precreator.VolumeMounts = append(precreator.VolumeMounts, mount) - } - for i, c := range podspec.Containers { - if c.Name == precreator.Name { - if c.Image != precreatorImage || - !slices.EqualFunc(precreator.VolumeMounts, c.VolumeMounts, func(a, b corev1.VolumeMount) bool { - return a.Name == b.Name - }) { - podspec.Containers[i] = precreator - return true - } - return false - } - } - - podspec.Containers = append(podspec.Containers, precreator) - return true + return len(volumes) > 0 || len(volumeMounts) > 0 } func removeBucketsFromPodSpec(podspec *corev1.PodSpec, container *corev1.Container) (shouldUpdate bool) { @@ -135,13 +100,5 @@ func removeBucketsFromPodSpec(podspec *corev1.PodSpec, container *corev1.Contain return false }) - podspec.Containers = slices.DeleteFunc(podspec.Containers, func(c corev1.Container) bool { - if c.Name == precreatorContainerName { - modified = true - return true - } - return false - }) - return modified }