From 2a2465d24079c5d2111c04f03e239f53f3252962 Mon Sep 17 00:00:00 2001 From: jonathancri Date: Thu, 26 Jun 2025 14:48:53 +0200 Subject: [PATCH 1/4] Support scale to zero rabbitMQ --- controllers/rabbitmqcluster_controller.go | 20 +- controllers/reconcile_scale_zero.go | 98 +++++++++ controllers/reconcile_scale_zero_test.go | 231 ++++++++++++++++++++++ go.mod | 4 +- 4 files changed, 347 insertions(+), 6 deletions(-) create mode 100644 controllers/reconcile_scale_zero.go create mode 100644 controllers/reconcile_scale_zero_test.go diff --git a/controllers/rabbitmqcluster_controller.go b/controllers/rabbitmqcluster_controller.go index a896463fb..a05bc9ac4 100644 --- a/controllers/rabbitmqcluster_controller.go +++ b/controllers/rabbitmqcluster_controller.go @@ -201,9 +201,23 @@ func (r *RabbitmqClusterReconciler) Reconcile(ctx context.Context, req ctrl.Requ if err := builder.Update(sts); err != nil { return ctrl.Result{}, err } - if r.scaleDown(ctx, rabbitmqCluster, current, sts) { - // return when cluster scale down detected; unsupported operation - return ctrl.Result{}, nil + if r.scaleToZero(current, sts) { + err := r.saveReplicasBeforeZero(ctx, rabbitmqCluster, current) + if err != nil { + return ctrl.Result{}, err + } + } else { + if r.scaleDown(ctx, rabbitmqCluster, current, sts) { + // return when cluster scale down detected; unsupported operation + return ctrl.Result{}, nil + } + } + if r.scaleFromZero(current, sts) { + if r.scaleDownFromZero(ctx, rabbitmqCluster, sts) { + // return when cluster scale down from zero detected; unsupported operation + return ctrl.Result{}, nil + } + r.removeReplicasBeforeZeroAnnotationIfExists(ctx, rabbitmqCluster) } } diff --git a/controllers/reconcile_scale_zero.go b/controllers/reconcile_scale_zero.go new file mode 100644 index 000000000..296dcf8de --- /dev/null +++ b/controllers/reconcile_scale_zero.go @@ -0,0 +1,98 @@ +package controllers + +import ( + "context" + "errors" + "fmt" + "strconv" + + ctrl "sigs.k8s.io/controller-runtime" + + "github.com/rabbitmq/cluster-operator/v2/api/v1beta1" + "github.com/rabbitmq/cluster-operator/v2/internal/status" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" +) + +const beforeZeroReplicasConfigured = "rabbitmq.com/before-zero-replicas-configured" + +// scaleToZero checks if the desired replicas is zero and the current replicas is not zero. +func (r *RabbitmqClusterReconciler) scaleToZero(current, sts *appsv1.StatefulSet) bool { + currentReplicas := *current.Spec.Replicas + desiredReplicas := *sts.Spec.Replicas + return desiredReplicas == 0 && currentReplicas > 0 +} + +// scaleFromZero checks if the current replicas is zero and the desired replicas is greater than zero. +func (r *RabbitmqClusterReconciler) scaleFromZero(current, sts *appsv1.StatefulSet) bool { + currentReplicas := *current.Spec.Replicas + desiredReplicas := *sts.Spec.Replicas + return currentReplicas == 0 && desiredReplicas > 0 +} + +// scaleDownFromZero checks if the current replicas is desired replicas would be greatter than replicas configured before zero state. +func (r *RabbitmqClusterReconciler) scaleDownFromZero(ctx context.Context, cluster *v1beta1.RabbitmqCluster, sts *appsv1.StatefulSet) bool { + var err error + var beforeZeroReplicas int64 + desiredReplicas := *sts.Spec.Replicas + annotationValue, ok := cluster.Annotations[beforeZeroReplicasConfigured] + if !ok { + return false + } + + beforeZeroReplicas, err = strconv.ParseInt(annotationValue, 10, 32) + if err != nil { + msg := "Failed to convert string to integer for before-zero-replicas-configuration annotation" + reason := "TransformErrorOperation" + err = r.recordEventsAndSetCondition(ctx, cluster, status.ReconcileSuccess, corev1.ConditionFalse, corev1.EventTypeWarning, reason, msg) + if err != nil { + return true + } + return true + } + + if desiredReplicas < int32(beforeZeroReplicas) { + msg := fmt.Sprintf("Cluster Scale down not supported; tried to scale cluster from %d nodes to %d nodes", int32(beforeZeroReplicas), desiredReplicas) + reason := "UnsupportedOperation" + err = r.recordEventsAndSetCondition(ctx, cluster, status.ReconcileSuccess, corev1.ConditionFalse, corev1.EventTypeWarning, reason, msg) + if err != nil { + return true + } + return true + } + return false +} + +// saveReplicasBeforeZero saves the current replicas count in an annotation before scaling down to zero. +// This is used to prevent scaling down when the cluster change from zero replicas to a number less than the saved replicas count. +func (r *RabbitmqClusterReconciler) saveReplicasBeforeZero(ctx context.Context, cluster *v1beta1.RabbitmqCluster, current *appsv1.StatefulSet) error { + var err error + currentReplicas := *current.Spec.Replicas + logger := ctrl.LoggerFrom(ctx) + msg := "Cluster Scale down to 0 replicas." + reason := "ScaleDownToZero" + logger.Info(msg) + err = r.updateAnnotation(ctx, cluster, cluster.Namespace, cluster.Name, beforeZeroReplicasConfigured, fmt.Sprint(currentReplicas)) + r.Recorder.Event(cluster, corev1.EventTypeNormal, reason, msg) + return err +} + +// If the annotation rabbitmq.com/before-zero-replicas-configured exists it will be deleted. +func (r *RabbitmqClusterReconciler) removeReplicasBeforeZeroAnnotationIfExists(ctx context.Context, cluster *v1beta1.RabbitmqCluster) { + if _, ok := cluster.Annotations[beforeZeroReplicasConfigured]; ok { + r.deleteAnnotation(ctx, cluster, beforeZeroReplicasConfigured) + } +} + +func (r *RabbitmqClusterReconciler) recordEventsAndSetCondition(ctx context.Context, cluster *v1beta1.RabbitmqCluster, condType status.RabbitmqClusterConditionType, condStatus corev1.ConditionStatus, eventType, reason, msg string) error { + logger := ctrl.LoggerFrom(ctx) + var statusErr error + logger.Error(errors.New(reason), msg) + r.Recorder.Event(cluster, eventType, reason, msg) + cluster.Status.SetCondition(condType, condStatus, reason, msg) + if statusErr := r.Status().Update(ctx, cluster); statusErr != nil { + logger.Error(statusErr, "Failed to update ReconcileSuccess condition state") + } + return statusErr + +} diff --git a/controllers/reconcile_scale_zero_test.go b/controllers/reconcile_scale_zero_test.go new file mode 100644 index 000000000..114b8a104 --- /dev/null +++ b/controllers/reconcile_scale_zero_test.go @@ -0,0 +1,231 @@ +package controllers_test + +import ( + "context" + "fmt" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + rabbitmqv1beta1 "github.com/rabbitmq/cluster-operator/v2/api/v1beta1" + "github.com/rabbitmq/cluster-operator/v2/internal/status" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/utils/ptr" + runtimeClient "sigs.k8s.io/controller-runtime/pkg/client" +) + +var _ = Describe("Cluster scale to zero", func() { + var ( + cluster *rabbitmqv1beta1.RabbitmqCluster + defaultNamespace = "default" + ctx = context.Background() + ) + + AfterEach(func() { + Expect(client.Delete(ctx, cluster)).To(Succeed()) + waitForClusterDeletion(ctx, cluster, client) + Eventually(func() bool { + rmq := &rabbitmqv1beta1.RabbitmqCluster{} + err := client.Get(ctx, types.NamespacedName{Name: cluster.Name, Namespace: cluster.Namespace}, rmq) + return apierrors.IsNotFound(err) + }).Should(BeTrue()) + }) + + It("scale to zero", func() { + By("update statefulSet replicas to zero", func() { + cluster = &rabbitmqv1beta1.RabbitmqCluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "rabbitmq-to-zero", + Namespace: defaultNamespace, + }, + Spec: rabbitmqv1beta1.RabbitmqClusterSpec{ + Replicas: ptr.To(int32(2)), + }, + } + Expect(client.Create(ctx, cluster)).To(Succeed()) + waitForClusterCreation(ctx, cluster, client) + + Expect(updateWithRetry(cluster, func(r *rabbitmqv1beta1.RabbitmqCluster) { + r.Spec.Replicas = ptr.To(int32(0)) + })).To(Succeed()) + + Eventually(func() int32 { + sts, err := clientSet.AppsV1().StatefulSets(defaultNamespace).Get(ctx, cluster.ChildResourceName("server"), metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + return *sts.Spec.Replicas + }, 10, 1).Should(Equal(int32(0))) + + }) + + By("setting ReconcileSuccess to 'true'", func() { + Eventually(func() string { + rabbit := &rabbitmqv1beta1.RabbitmqCluster{} + Expect(client.Get(ctx, runtimeClient.ObjectKey{ + Name: cluster.Name, + Namespace: defaultNamespace, + }, rabbit)).To(Succeed()) + + for i := range rabbit.Status.Conditions { + if rabbit.Status.Conditions[i].Type == status.ReconcileSuccess { + return fmt.Sprintf( + "ReconcileSuccess status: %s, with reason: %s and message: %s", + rabbit.Status.Conditions[i].Status, + rabbit.Status.Conditions[i].Reason, + rabbit.Status.Conditions[i].Message) + } + } + return "ReconcileSuccess status: condition not present" + }, 0).Should(Equal("ReconcileSuccess status: True, " + + "with reason: Success " + + "and message: Finish reconciling")) + }) + }) +}) + +var _ = Describe("Cluster scale from zero", func() { + var ( + cluster *rabbitmqv1beta1.RabbitmqCluster + defaultNamespace = "default" + ctx = context.Background() + ) + + AfterEach(func() { + Expect(client.Delete(ctx, cluster)).To(Succeed()) + waitForClusterDeletion(ctx, cluster, client) + Eventually(func() bool { + rmq := &rabbitmqv1beta1.RabbitmqCluster{} + err := client.Get(ctx, types.NamespacedName{Name: cluster.Name, Namespace: cluster.Namespace}, rmq) + return apierrors.IsNotFound(err) + }).Should(BeTrue()) + }) + + It("scale from zero", func() { + By("update statefulSet replicas from zero", func() { + cluster = &rabbitmqv1beta1.RabbitmqCluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "rabbitmq-from-zero", + Namespace: defaultNamespace, + Annotations: map[string]string{ + "rabbitmq.com/before-zero-replicas-configured": "2", + }, + }, + Spec: rabbitmqv1beta1.RabbitmqClusterSpec{ + Replicas: ptr.To(int32(0)), + }, + } + Expect(client.Create(ctx, cluster)).To(Succeed()) + waitForClusterCreation(ctx, cluster, client) + + Expect(updateWithRetry(cluster, func(r *rabbitmqv1beta1.RabbitmqCluster) { + r.Spec.Replicas = ptr.To(int32(2)) + })).To(Succeed()) + + Eventually(func() int32 { + sts, err := clientSet.AppsV1().StatefulSets(defaultNamespace).Get(ctx, cluster.ChildResourceName("server"), metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + return *sts.Spec.Replicas + }, 10, 1).Should(Equal(int32(2))) + + }) + + By("setting ReconcileSuccess to 'true'", func() { + Eventually(func() string { + rabbit := &rabbitmqv1beta1.RabbitmqCluster{} + Expect(client.Get(ctx, runtimeClient.ObjectKey{ + Name: cluster.Name, + Namespace: defaultNamespace, + }, rabbit)).To(Succeed()) + + for i := range rabbit.Status.Conditions { + if rabbit.Status.Conditions[i].Type == status.ReconcileSuccess { + return fmt.Sprintf( + "ReconcileSuccess status: %s, with reason: %s and message: %s", + rabbit.Status.Conditions[i].Status, + rabbit.Status.Conditions[i].Reason, + rabbit.Status.Conditions[i].Message) + } + } + return "ReconcileSuccess status: condition not present" + }, 0).Should(Equal("ReconcileSuccess status: True, " + + "with reason: Success " + + "and message: Finish reconciling")) + }) + }) +}) + +var _ = Describe("Cluster scale from zero to less replicas configured", Ordered, func() { + var ( + cluster *rabbitmqv1beta1.RabbitmqCluster + defaultNamespace = "default" + ctx = context.Background() + ) + + AfterEach(func() { + Expect(client.Delete(ctx, cluster)).To(Succeed()) + waitForClusterDeletion(ctx, cluster, client) + Eventually(func() bool { + rmq := &rabbitmqv1beta1.RabbitmqCluster{} + err := client.Get(ctx, types.NamespacedName{Name: cluster.Name, Namespace: cluster.Namespace}, rmq) + return apierrors.IsNotFound(err) + }).Should(BeTrue()) + }) + + It("scale from zero to less replicas", func() { + By("update statefulSet replicas from zero", func() { + cluster = &rabbitmqv1beta1.RabbitmqCluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "rabbitmq-from-zero-to-less", + Namespace: defaultNamespace, + Annotations: map[string]string{ + "rabbitmq.com/before-zero-replicas-configured": "2", + }, + }, + Spec: rabbitmqv1beta1.RabbitmqClusterSpec{ + Replicas: ptr.To(int32(0)), + }, + } + Expect(client.Create(ctx, cluster)).To(Succeed()) + waitForClusterCreation(ctx, cluster, client) + + Expect(updateWithRetry(cluster, func(r *rabbitmqv1beta1.RabbitmqCluster) { + r.Spec.Replicas = ptr.To(int32(1)) + })).To(Succeed()) + + Consistently(func() int32 { + sts, err := clientSet.AppsV1().StatefulSets(defaultNamespace).Get(ctx, cluster.ChildResourceName("server"), metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + return *sts.Spec.Replicas + }, 10, 1).Should(Equal(int32(0))) + + }) + + By("setting 'Warning' events", func() { + Expect(aggregateEventMsgs(ctx, cluster, "UnsupportedOperation")).To( + ContainSubstring("Cluster Scale down not supported")) + }) + + By("setting ReconcileSuccess to 'false'", func() { + Eventually(func() string { + rabbit := &rabbitmqv1beta1.RabbitmqCluster{} + Expect(client.Get(ctx, runtimeClient.ObjectKey{ + Name: cluster.Name, + Namespace: defaultNamespace, + }, rabbit)).To(Succeed()) + + for i := range rabbit.Status.Conditions { + if rabbit.Status.Conditions[i].Type == status.ReconcileSuccess { + return fmt.Sprintf( + "ReconcileSuccess status: %s, with reason: %s and message: %s", + rabbit.Status.Conditions[i].Status, + rabbit.Status.Conditions[i].Reason, + rabbit.Status.Conditions[i].Message) + } + } + return "ReconcileSuccess status: condition not present" + }, 0).Should(Equal("ReconcileSuccess status: False, " + + "with reason: UnsupportedOperation " + + "and message: Cluster Scale down not supported; tried to scale cluster from 2 nodes to 1 nodes")) + }) + }) +}) diff --git a/go.mod b/go.mod index 9fe9bcf2e..eb3eb4bc2 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,6 @@ module github.com/rabbitmq/cluster-operator/v2 -go 1.24.2 - -toolchain go1.24.3 +go 1.24.4 require ( github.com/cloudflare/cfssl v1.6.5 From cc9cc6a76acb64ff018399f2b7fc527fedd0d6d4 Mon Sep 17 00:00:00 2001 From: jonathancri Date: Mon, 14 Jul 2025 12:05:40 +0200 Subject: [PATCH 2/4] feat: update code to align with pr comments --- controllers/rabbitmqcluster_controller.go | 5 ++--- controllers/reconcile_scale_zero.go | 13 +++++-------- controllers/reconcile_scale_zero_test.go | 4 ++-- internal/status/all_replicas_ready.go | 7 +++++++ 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/controllers/rabbitmqcluster_controller.go b/controllers/rabbitmqcluster_controller.go index a05bc9ac4..e4b399686 100644 --- a/controllers/rabbitmqcluster_controller.go +++ b/controllers/rabbitmqcluster_controller.go @@ -213,7 +213,7 @@ func (r *RabbitmqClusterReconciler) Reconcile(ctx context.Context, req ctrl.Requ } } if r.scaleFromZero(current, sts) { - if r.scaleDownFromZero(ctx, rabbitmqCluster, sts) { + if r.scaleFromZeroToBeforeReplicasConfigured(ctx, rabbitmqCluster, sts) { // return when cluster scale down from zero detected; unsupported operation return ctrl.Result{}, nil } @@ -227,7 +227,6 @@ func (r *RabbitmqClusterReconciler) Reconcile(ctx context.Context, req ctrl.Requ return ctrl.Result{}, err } } - var operationResult controllerutil.OperationResult err = clientretry.RetryOnConflict(clientretry.DefaultRetry, func() error { var apiError error @@ -263,9 +262,9 @@ func (r *RabbitmqClusterReconciler) Reconcile(ctx context.Context, req ctrl.Requ } return ctrl.Result{RequeueAfter: requeueAfter}, err } - // Set ReconcileSuccess to true and update observedGeneration after all reconciliation steps have finished with no error rabbitmqCluster.Status.ObservedGeneration = rabbitmqCluster.GetGeneration() + r.setReconcileSuccess(ctx, rabbitmqCluster, corev1.ConditionTrue, "Success", "Finish reconciling") logger.Info("Finished reconciling") diff --git a/controllers/reconcile_scale_zero.go b/controllers/reconcile_scale_zero.go index 296dcf8de..f5836ccc8 100644 --- a/controllers/reconcile_scale_zero.go +++ b/controllers/reconcile_scale_zero.go @@ -31,7 +31,7 @@ func (r *RabbitmqClusterReconciler) scaleFromZero(current, sts *appsv1.StatefulS } // scaleDownFromZero checks if the current replicas is desired replicas would be greatter than replicas configured before zero state. -func (r *RabbitmqClusterReconciler) scaleDownFromZero(ctx context.Context, cluster *v1beta1.RabbitmqCluster, sts *appsv1.StatefulSet) bool { +func (r *RabbitmqClusterReconciler) scaleFromZeroToBeforeReplicasConfigured(ctx context.Context, cluster *v1beta1.RabbitmqCluster, sts *appsv1.StatefulSet) bool { var err error var beforeZeroReplicas int64 desiredReplicas := *sts.Spec.Replicas @@ -50,9 +50,8 @@ func (r *RabbitmqClusterReconciler) scaleDownFromZero(ctx context.Context, clust } return true } - - if desiredReplicas < int32(beforeZeroReplicas) { - msg := fmt.Sprintf("Cluster Scale down not supported; tried to scale cluster from %d nodes to %d nodes", int32(beforeZeroReplicas), desiredReplicas) + if desiredReplicas != int32(beforeZeroReplicas) { + msg := fmt.Sprintf("Cluster Scale from zero to other replicas than before configured not supported; tried to scale cluster from %d nodes to %d nodes", int32(beforeZeroReplicas), desiredReplicas) reason := "UnsupportedOperation" err = r.recordEventsAndSetCondition(ctx, cluster, status.ReconcileSuccess, corev1.ConditionFalse, corev1.EventTypeWarning, reason, msg) if err != nil { @@ -61,6 +60,7 @@ func (r *RabbitmqClusterReconciler) scaleDownFromZero(ctx context.Context, clust return true } return false + } // saveReplicasBeforeZero saves the current replicas count in an annotation before scaling down to zero. @@ -90,9 +90,6 @@ func (r *RabbitmqClusterReconciler) recordEventsAndSetCondition(ctx context.Cont logger.Error(errors.New(reason), msg) r.Recorder.Event(cluster, eventType, reason, msg) cluster.Status.SetCondition(condType, condStatus, reason, msg) - if statusErr := r.Status().Update(ctx, cluster); statusErr != nil { - logger.Error(statusErr, "Failed to update ReconcileSuccess condition state") - } + statusErr = r.Status().Update(ctx, cluster) return statusErr - } diff --git a/controllers/reconcile_scale_zero_test.go b/controllers/reconcile_scale_zero_test.go index 114b8a104..da6137a60 100644 --- a/controllers/reconcile_scale_zero_test.go +++ b/controllers/reconcile_scale_zero_test.go @@ -202,7 +202,7 @@ var _ = Describe("Cluster scale from zero to less replicas configured", Ordered, By("setting 'Warning' events", func() { Expect(aggregateEventMsgs(ctx, cluster, "UnsupportedOperation")).To( - ContainSubstring("Cluster Scale down not supported")) + ContainSubstring("Cluster Scale from zero to other replicas than before configured not supported")) }) By("setting ReconcileSuccess to 'false'", func() { @@ -225,7 +225,7 @@ var _ = Describe("Cluster scale from zero to less replicas configured", Ordered, return "ReconcileSuccess status: condition not present" }, 0).Should(Equal("ReconcileSuccess status: False, " + "with reason: UnsupportedOperation " + - "and message: Cluster Scale down not supported; tried to scale cluster from 2 nodes to 1 nodes")) + "and message: Cluster Scale from zero to other replicas than before configured not supported; tried to scale cluster from 2 nodes to 1 nodes")) }) }) }) diff --git a/internal/status/all_replicas_ready.go b/internal/status/all_replicas_ready.go index 6a9589791..00215031f 100644 --- a/internal/status/all_replicas_ready.go +++ b/internal/status/all_replicas_ready.go @@ -41,6 +41,13 @@ func AllReplicasReadyCondition(resources []runtime.Object, if resource.Spec.Replicas != nil { desiredReplicas = *resource.Spec.Replicas } + + if desiredReplicas == 0 { + condition.Status = corev1.ConditionFalse + condition.Reason = "ScaledToZero" + goto assignLastTransitionTime + } + if desiredReplicas == resource.Status.ReadyReplicas { condition.Status = corev1.ConditionTrue condition.Reason = "AllPodsAreReady" From 535851e066fc87a1a5b1f32d4eebcf80c57364e1 Mon Sep 17 00:00:00 2001 From: jonathancri Date: Fri, 18 Jul 2025 12:02:25 +0200 Subject: [PATCH 3/4] feat: change logger --- controllers/reconcile_scale_zero.go | 2 +- controllers/reconcile_scale_zero_test.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/controllers/reconcile_scale_zero.go b/controllers/reconcile_scale_zero.go index f5836ccc8..33b386b65 100644 --- a/controllers/reconcile_scale_zero.go +++ b/controllers/reconcile_scale_zero.go @@ -51,7 +51,7 @@ func (r *RabbitmqClusterReconciler) scaleFromZeroToBeforeReplicasConfigured(ctx return true } if desiredReplicas != int32(beforeZeroReplicas) { - msg := fmt.Sprintf("Cluster Scale from zero to other replicas than before configured not supported; tried to scale cluster from %d nodes to %d nodes", int32(beforeZeroReplicas), desiredReplicas) + msg := fmt.Sprintf("Unsupported operation; when scaling from zero, you can only restore the previous number of replicas (%d)", int32(beforeZeroReplicas)) reason := "UnsupportedOperation" err = r.recordEventsAndSetCondition(ctx, cluster, status.ReconcileSuccess, corev1.ConditionFalse, corev1.EventTypeWarning, reason, msg) if err != nil { diff --git a/controllers/reconcile_scale_zero_test.go b/controllers/reconcile_scale_zero_test.go index da6137a60..1295c0361 100644 --- a/controllers/reconcile_scale_zero_test.go +++ b/controllers/reconcile_scale_zero_test.go @@ -202,7 +202,7 @@ var _ = Describe("Cluster scale from zero to less replicas configured", Ordered, By("setting 'Warning' events", func() { Expect(aggregateEventMsgs(ctx, cluster, "UnsupportedOperation")).To( - ContainSubstring("Cluster Scale from zero to other replicas than before configured not supported")) + ContainSubstring("Unsupported operation")) }) By("setting ReconcileSuccess to 'false'", func() { @@ -225,7 +225,7 @@ var _ = Describe("Cluster scale from zero to less replicas configured", Ordered, return "ReconcileSuccess status: condition not present" }, 0).Should(Equal("ReconcileSuccess status: False, " + "with reason: UnsupportedOperation " + - "and message: Cluster Scale from zero to other replicas than before configured not supported; tried to scale cluster from 2 nodes to 1 nodes")) + "and message: Unsupported operation; when scaling from zero, you can only restore the previous number of replicas (1)")) }) }) }) From 71e14c4333c06088cbb5c57e061bd26f32da9c69 Mon Sep 17 00:00:00 2001 From: jonathancri Date: Fri, 18 Jul 2025 12:19:21 +0200 Subject: [PATCH 4/4] fix: fix error on test --- controllers/reconcile_scale_zero_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/controllers/reconcile_scale_zero_test.go b/controllers/reconcile_scale_zero_test.go index 1295c0361..6bed247a0 100644 --- a/controllers/reconcile_scale_zero_test.go +++ b/controllers/reconcile_scale_zero_test.go @@ -225,7 +225,7 @@ var _ = Describe("Cluster scale from zero to less replicas configured", Ordered, return "ReconcileSuccess status: condition not present" }, 0).Should(Equal("ReconcileSuccess status: False, " + "with reason: UnsupportedOperation " + - "and message: Unsupported operation; when scaling from zero, you can only restore the previous number of replicas (1)")) + "and message: Unsupported operation; when scaling from zero, you can only restore the previous number of replicas (2)")) }) }) })