Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- prevent cluster scale down from happening by checking current number of replicas vs desired number of replicas after running statefulSetBuilder.Update() - return errors, logs, publish events and set ReconcileSuccess to false if scale down request detected
- Loading branch information
Showing
6 changed files
with
151 additions
and
33 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package controllers | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"github.com/go-logr/logr" | ||
"github.com/rabbitmq/cluster-operator/api/v1beta1" | ||
"github.com/rabbitmq/cluster-operator/internal/status" | ||
appsv1 "k8s.io/api/apps/v1" | ||
corev1 "k8s.io/api/core/v1" | ||
) | ||
|
||
// cluster scale down not supported | ||
// log error, publish warning event, and set ReconcileSuccess to false when scale down request detected | ||
func (r *RabbitmqClusterReconciler) scaleDown(ctx context.Context, cluster *v1beta1.RabbitmqCluster, current, sts *appsv1.StatefulSet) bool { | ||
logger := logr.FromContext(ctx) | ||
|
||
currentReplicas := *current.Spec.Replicas | ||
desiredReplicas := *sts.Spec.Replicas | ||
if currentReplicas > desiredReplicas { | ||
msg := "Cluster Scale down not supported" | ||
reason := "UnsupportedOperation" | ||
logger.Error(errors.New(reason), msg) | ||
r.Recorder.Event(cluster, corev1.EventTypeWarning, reason, msg) | ||
cluster.Status.SetCondition(status.ReconcileSuccess, corev1.ConditionFalse, reason, msg) | ||
if statusErr := r.Status().Update(ctx, cluster); statusErr != nil { | ||
logger.Error(statusErr, "Failed to update ReconcileSuccess condition state") | ||
} | ||
return true | ||
} | ||
return false | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
package controllers_test | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
. "github.com/onsi/ginkgo" | ||
. "github.com/onsi/gomega" | ||
rabbitmqv1beta1 "github.com/rabbitmq/cluster-operator/api/v1beta1" | ||
"github.com/rabbitmq/cluster-operator/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/pointer" | ||
runtimeClient "sigs.k8s.io/controller-runtime/pkg/client" | ||
) | ||
|
||
var _ = Describe("Cluster scale down", func() { | ||
var ( | ||
cluster *rabbitmqv1beta1.RabbitmqCluster | ||
defaultNamespace = "default" | ||
ctx = context.Background() | ||
) | ||
|
||
AfterEach(func() { | ||
Expect(client.Delete(ctx, cluster)).To(Succeed()) | ||
Eventually(func() bool { | ||
rmq := &rabbitmqv1beta1.RabbitmqCluster{} | ||
err := client.Get(ctx, types.NamespacedName{Name: cluster.Name, Namespace: cluster.Namespace}, rmq) | ||
return apierrors.IsNotFound(err) | ||
}, 5).Should(BeTrue()) | ||
}) | ||
|
||
It("does not allow cluster scale down", func() { | ||
By("not updating statefulSet replicas", func() { | ||
cluster = &rabbitmqv1beta1.RabbitmqCluster{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: "rabbitmq-shrink", | ||
Namespace: defaultNamespace, | ||
}, | ||
Spec: rabbitmqv1beta1.RabbitmqClusterSpec{ | ||
Replicas: pointer.Int32Ptr(5), | ||
}, | ||
} | ||
Expect(client.Create(ctx, cluster)).To(Succeed()) | ||
waitForClusterCreation(ctx, cluster, client) | ||
|
||
Expect(updateWithRetry(cluster, func(r *rabbitmqv1beta1.RabbitmqCluster) { | ||
r.Spec.Replicas = pointer.Int32Ptr(3) | ||
})).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(5))) | ||
}) | ||
|
||
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" | ||
}, 5).Should(Equal("ReconcileSuccess status: False, " + | ||
"with reason: UnsupportedOperation " + | ||
"and message: Cluster Scale down not supported")) | ||
}) | ||
}) | ||
}) |