Skip to content

Commit 82415be

Browse files
committed
Add rabbitmq.com/disable-default-topology-spread-constraints annotation
When the annotation rabbitmq.com/disable-default-topology-spread-constraints is set to "true" the default topologySpreadConstraints based on label topology.kubernetes.io/zone is ommited.
1 parent fd080de commit 82415be

File tree

3 files changed

+113
-13
lines changed

3 files changed

+113
-13
lines changed

Diff for: api/v1beta1/rabbitmqcluster_types.go

+10
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ import (
2121
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2222
)
2323

24+
const DisableDefaultTopologySpreadAnnotation = "rabbitmq.com/disable-default-topology-spread-constraints"
25+
2426
// +kubebuilder:object:root=true
2527
// +kubebuilder:subresource:status
2628
// +kubebuilder:printcolumn:name="AllReplicasReady",type="string",JSONPath=".status.conditions[?(@.type == 'AllReplicasReady')].status"
@@ -506,6 +508,14 @@ func (cluster RabbitmqCluster) PVCName(i int) string {
506508
return strings.Join([]string{"persistence", cluster.Name, "server", strconv.Itoa(i)}, "-")
507509
}
508510

511+
func (cluster RabbitmqCluster) DisableDefaultTopologySpreadConstraints() bool {
512+
value, ok := cluster.Annotations[DisableDefaultTopologySpreadAnnotation]
513+
if ok && strings.TrimSpace(value) == "true" {
514+
return true
515+
}
516+
return false
517+
}
518+
509519
func init() {
510520
SchemeBuilder.Register(&RabbitmqCluster{}, &RabbitmqClusterList{})
511521
}

Diff for: internal/resource/statefulset.go

+22-13
Original file line numberDiff line numberDiff line change
@@ -551,19 +551,7 @@ func (builder *StatefulSetBuilder) podTemplateSpec(previousPodAnnotations map[st
551551
Labels: metadata.Label(builder.Instance.Name),
552552
},
553553
Spec: corev1.PodSpec{
554-
TopologySpreadConstraints: []corev1.TopologySpreadConstraint{
555-
{
556-
MaxSkew: 1,
557-
// "topology.kubernetes.io/zone" is a well-known label.
558-
// It is automatically set by kubelet if the cloud provider provides the zone information.
559-
// See: https://kubernetes.io/docs/reference/kubernetes-api/labels-annotations-taints/#topologykubernetesiozone
560-
TopologyKey: "topology.kubernetes.io/zone",
561-
WhenUnsatisfiable: corev1.ScheduleAnyway,
562-
LabelSelector: &metav1.LabelSelector{
563-
MatchLabels: metadata.LabelSelector(builder.Instance.Name),
564-
},
565-
},
566-
},
554+
TopologySpreadConstraints: builder.defaultTopologySpreadConstraints(),
567555
SecurityContext: &corev1.PodSecurityContext{
568556
FSGroup: ptr.To(int64(0)),
569557
RunAsUser: &rabbitmqUID,
@@ -1088,6 +1076,27 @@ func (builder *StatefulSetBuilder) updateContainerPortsOnlyTLSListeners() []core
10881076
return ports
10891077
}
10901078

1079+
func (builder *StatefulSetBuilder) defaultTopologySpreadConstraints() []corev1.TopologySpreadConstraint {
1080+
1081+
if builder.Instance.DisableDefaultTopologySpreadConstraints() {
1082+
return []corev1.TopologySpreadConstraint{}
1083+
}
1084+
1085+
return []corev1.TopologySpreadConstraint{
1086+
{
1087+
MaxSkew: 1,
1088+
// "topology.kubernetes.io/zone" is a well-known label.
1089+
// It is automatically set by kubelet if the cloud provider provides the zone information.
1090+
// See: https://kubernetes.io/docs/reference/kubernetes-api/labels-annotations-taints/#topologykubernetesiozone
1091+
TopologyKey: "topology.kubernetes.io/zone",
1092+
WhenUnsatisfiable: corev1.ScheduleAnyway,
1093+
LabelSelector: &metav1.LabelSelector{
1094+
MatchLabels: metadata.LabelSelector(builder.Instance.Name),
1095+
},
1096+
},
1097+
}
1098+
}
1099+
10911100
func copyLabelsAnnotations(base *metav1.ObjectMeta, override rabbitmqv1beta1.EmbeddedLabelsAnnotations) {
10921101
if override.Labels != nil {
10931102
base.Labels = mergeMap(base.Labels, override.Labels)

Diff for: internal/resource/statefulset_test.go

+81
Original file line numberDiff line numberDiff line change
@@ -2138,6 +2138,87 @@ default_pass = {{ .Data.data.password }}
21382138

21392139
})
21402140

2141+
Context("TopologySpreadConstraints composition", func() {
2142+
BeforeEach(func() {
2143+
instance.Spec.Override.StatefulSet = &rabbitmqv1beta1.StatefulSet{
2144+
Spec: &rabbitmqv1beta1.StatefulSetSpec{
2145+
Template: &rabbitmqv1beta1.PodTemplateSpec{
2146+
Spec: &corev1.PodSpec{},
2147+
},
2148+
},
2149+
}
2150+
builder = &resource.RabbitmqResourceBuilder{
2151+
Instance: &instance,
2152+
Scheme: scheme,
2153+
}
2154+
})
2155+
When("Default TopologySpreadConstraints", func() {
2156+
It("uses the default", func() {
2157+
stsBuilder := builder.StatefulSet()
2158+
Expect(stsBuilder.Update(statefulSet)).To(Succeed())
2159+
Expect(statefulSet.Spec.Template.Spec.TopologySpreadConstraints).To(ConsistOf(
2160+
corev1.TopologySpreadConstraint{
2161+
MaxSkew: 1,
2162+
TopologyKey: "topology.kubernetes.io/zone",
2163+
WhenUnsatisfiable: corev1.ScheduleAnyway,
2164+
LabelSelector: &metav1.LabelSelector{
2165+
MatchLabels: map[string]string{
2166+
"app.kubernetes.io/name": instance.Name,
2167+
},
2168+
},
2169+
},
2170+
))
2171+
})
2172+
})
2173+
When("Disable Default TopologySpreadConstraints", func() {
2174+
It("does not have any constraint", func() {
2175+
instance.Annotations = map[string]string{rabbitmqv1beta1.DisableDefaultTopologySpreadAnnotation: "true"}
2176+
stsBuilder := builder.StatefulSet()
2177+
Expect(stsBuilder.Update(statefulSet)).To(Succeed())
2178+
Expect(statefulSet.Spec.Template.Spec.TopologySpreadConstraints).To(BeEmpty())
2179+
})
2180+
})
2181+
When("Disable Default TopologySpreadConstraints and override has a value", func() {
2182+
It("overrides the default", func() {
2183+
instance.Annotations = map[string]string{rabbitmqv1beta1.DisableDefaultTopologySpreadAnnotation: "true"}
2184+
instance.Spec.Override.StatefulSet = &rabbitmqv1beta1.StatefulSet{
2185+
Spec: &rabbitmqv1beta1.StatefulSetSpec{
2186+
Template: &rabbitmqv1beta1.PodTemplateSpec{
2187+
Spec: &corev1.PodSpec{
2188+
TopologySpreadConstraints: []corev1.TopologySpreadConstraint{
2189+
{
2190+
MaxSkew: 1,
2191+
TopologyKey: "my-topology",
2192+
WhenUnsatisfiable: corev1.DoNotSchedule,
2193+
LabelSelector: &metav1.LabelSelector{
2194+
MatchLabels: map[string]string{
2195+
"key": "value",
2196+
},
2197+
},
2198+
},
2199+
},
2200+
},
2201+
},
2202+
},
2203+
}
2204+
stsBuilder := builder.StatefulSet()
2205+
Expect(stsBuilder.Update(statefulSet)).To(Succeed())
2206+
Expect(statefulSet.Spec.Template.Spec.TopologySpreadConstraints).To(ConsistOf(
2207+
corev1.TopologySpreadConstraint{
2208+
MaxSkew: 1,
2209+
TopologyKey: "my-topology",
2210+
WhenUnsatisfiable: corev1.DoNotSchedule,
2211+
LabelSelector: &metav1.LabelSelector{
2212+
MatchLabels: map[string]string{
2213+
"key": "value",
2214+
},
2215+
},
2216+
},
2217+
))
2218+
})
2219+
})
2220+
})
2221+
21412222
Context("Rabbitmq Container volume mounts", func() {
21422223
It("Overrides the volume mounts list while making sure that '/var/lib/rabbitmq/' mounts before '/var/lib/rabbitmq/mnesia/' ", func() {
21432224
instance.Spec.Override.StatefulSet = &rabbitmqv1beta1.StatefulSet{

0 commit comments

Comments
 (0)