diff --git a/controllers/rabbitmqcluster_controller_test.go b/controllers/rabbitmqcluster_controller_test.go index 3eaac22af..3072c589d 100644 --- a/controllers/rabbitmqcluster_controller_test.go +++ b/controllers/rabbitmqcluster_controller_test.go @@ -493,7 +493,7 @@ var _ = Describe("RabbitmqClusterController", func() { Eventually(func() []corev1.LocalObjectReference { sts := statefulSet(ctx, cluster) return sts.Spec.Template.Spec.ImagePullSecrets - }, 3).Should(ConsistOf(corev1.LocalObjectReference{Name: "my-new-secret"})) + }, 3).Should(ConsistOf(corev1.LocalObjectReference{Name: "image-secret-3"}, corev1.LocalObjectReference{Name: "image-secret-2"}, corev1.LocalObjectReference{Name: "image-secret-1"})) }) It("labels are updated", func() { diff --git a/controllers/reconcile_operator_defaults.go b/controllers/reconcile_operator_defaults.go index 608b080be..df020eb8a 100644 --- a/controllers/reconcile_operator_defaults.go +++ b/controllers/reconcile_operator_defaults.go @@ -6,11 +6,60 @@ import ( rabbitmqv1beta1 "github.com/rabbitmq/cluster-operator/api/v1beta1" corev1 "k8s.io/api/core/v1" k8serrors "k8s.io/apimachinery/pkg/api/errors" + "reflect" ctrl "sigs.k8s.io/controller-runtime" + "sort" "strings" "time" ) +// mergeImagePullSecrets merge ImagePullSecrets and update +func (r *RabbitmqClusterReconciler) mergeImagePullSecrets(ctx context.Context, rabbitmqCluster *rabbitmqv1beta1.RabbitmqCluster) (time.Duration, bool, error) { + checkUniqueName := map[string]struct{}{} + names := []string{} + for _, s := range rabbitmqCluster.Spec.ImagePullSecrets { + if strings.TrimSpace(s.Name) == "" { + continue + } + _, ok := checkUniqueName[s.Name] + if !ok { + checkUniqueName[s.Name] = struct{}{} + names = append(names, s.Name) + } + } + // split the comma separated list of default image pull secrets from + // the 'DEFAULT_IMAGE_PULL_SECRETS' env var, but ignore empty strings. + for _, nam := range strings.Split(r.DefaultImagePullSecrets, ",") { + if strings.TrimSpace(nam) == "" { + continue + } + _, ok := checkUniqueName[nam] + if !ok { + checkUniqueName[nam] = struct{}{} + names = append(names, nam) + } + } + sort.Slice(names, func(i, j int) bool { + return names[i] > names[j] + }) + mergedImagePullSecrets := []corev1.LocalObjectReference{} + for _, nam := range names { + mergedImagePullSecrets = append(mergedImagePullSecrets, corev1.LocalObjectReference{Name: nam}) + } + isMerged := false + if len(mergedImagePullSecrets) != len(rabbitmqCluster.Spec.ImagePullSecrets) { + isMerged = true + } else { + isMerged = !reflect.DeepEqual(mergedImagePullSecrets, rabbitmqCluster.Spec.ImagePullSecrets) + } + if isMerged { + rabbitmqCluster.Spec.ImagePullSecrets = mergedImagePullSecrets + requeue, err := r.updateRabbitmqCluster(ctx, rabbitmqCluster, "image pull secrets") + return requeue, isMerged, err + } + return 0, isMerged, nil +} + // reconcileOperatorDefaults updates current rabbitmqCluster with operator defaults from the Reconciler // it handles RabbitMQ image, imagePullSecrets, and user updater image func (r *RabbitmqClusterReconciler) reconcileOperatorDefaults(ctx context.Context, rabbitmqCluster *rabbitmqv1beta1.RabbitmqCluster) (time.Duration, error) { @@ -20,20 +69,10 @@ func (r *RabbitmqClusterReconciler) reconcileOperatorDefaults(ctx context.Contex return requeue, err } } - - if rabbitmqCluster.Spec.ImagePullSecrets == nil { - // split the comma separated list of default image pull secrets from - // the 'DEFAULT_IMAGE_PULL_SECRETS' env var, but ignore empty strings. - for _, reference := range strings.Split(r.DefaultImagePullSecrets, ",") { - if len(reference) > 0 { - rabbitmqCluster.Spec.ImagePullSecrets = append(rabbitmqCluster.Spec.ImagePullSecrets, corev1.LocalObjectReference{Name: reference}) - } - } - if requeue, err := r.updateRabbitmqCluster(ctx, rabbitmqCluster, "image pull secrets"); err != nil { - return requeue, err - } + requeue, isMerged, err := r.mergeImagePullSecrets(ctx, rabbitmqCluster) + if isMerged && err != nil { + return requeue, err } - if rabbitmqCluster.UsesDefaultUserUpdaterImage() { rabbitmqCluster.Spec.SecretBackend.Vault.DefaultUserUpdaterImage = &r.DefaultUserUpdaterImage if requeue, err := r.updateRabbitmqCluster(ctx, rabbitmqCluster, "default user image"); err != nil {