Skip to content

Commit a2576bc

Browse files
committed
fix(redis, valkey, harbor): default null topology spread selectors
A null selector matches no pods, so the configured policy cannot spread siblings. Treat it as unset while preserving explicit selectors. Assisted-by: LLM Signed-off-by: Yan Bondarenko <[email protected]>
1 parent 0d389f4 commit a2576bc

6 files changed

Lines changed: 117 additions & 6 deletions

File tree

‎packages/apps/redis/templates/redisfailover.yaml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ spec:
9090
{{- if $spreadConstraints }}
9191
topologySpreadConstraints:
9292
{{- range $spreadConstraints }}
93-
- {{- toYaml (ternary . (merge (deepCopy .) (dict "labelSelector" (dict "matchLabels" (dict "app.kubernetes.io/name" $.Release.Name "app.kubernetes.io/component" "sentinel")))) (hasKey . "labelSelector")) | nindent 6 }}
93+
- {{- toYaml (ternary . (merge (deepCopy .) (dict "labelSelector" (dict "matchLabels" (dict "app.kubernetes.io/name" $.Release.Name "app.kubernetes.io/component" "sentinel")))) (not (kindIs "invalid" .labelSelector))) | nindent 6 }}
9494
{{- end }}
9595
{{- else }}
9696
topologySpreadConstraints:
@@ -113,7 +113,7 @@ spec:
113113
{{- if $spreadConstraints }}
114114
topologySpreadConstraints:
115115
{{- range $spreadConstraints }}
116-
- {{- toYaml (ternary . (merge (deepCopy .) (dict "labelSelector" (dict "matchLabels" (dict "app.kubernetes.io/name" $.Release.Name "app.kubernetes.io/component" "redis")))) (hasKey . "labelSelector")) | nindent 6 }}
116+
- {{- toYaml (ternary . (merge (deepCopy .) (dict "labelSelector" (dict "matchLabels" (dict "app.kubernetes.io/name" $.Release.Name "app.kubernetes.io/component" "redis")))) (not (kindIs "invalid" .labelSelector))) | nindent 6 }}
117117
{{- end }}
118118
{{- else }}
119119
topologySpreadConstraints:

‎packages/apps/redis/tests/topology_spread_test.yaml‎

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,3 +247,40 @@ tests:
247247
asserts:
248248
- failedTemplate:
249249
errorMessage: "redis: _cluster.scheduling.globalAppTopologySpreadConstraints must be YAML with a non-empty topologySpreadConstraints list."
250+
251+
- it: fills null selectors and preserves explicit empty selectors
252+
set:
253+
_cluster:
254+
scheduling:
255+
globalAppTopologySpreadConstraints: |
256+
topologySpreadConstraints:
257+
- maxSkew: 1
258+
topologyKey: kubernetes.io/hostname
259+
whenUnsatisfiable: DoNotSchedule
260+
labelSelector: null
261+
- maxSkew: 1
262+
topologyKey: topology.kubernetes.io/zone
263+
whenUnsatisfiable: ScheduleAnyway
264+
labelSelector: {}
265+
documentSelector:
266+
path: kind
267+
value: RedisFailover
268+
asserts:
269+
- equal:
270+
path: spec.sentinel.topologySpreadConstraints[0].labelSelector
271+
value:
272+
matchLabels:
273+
app.kubernetes.io/name: my-redis
274+
app.kubernetes.io/component: sentinel
275+
- equal:
276+
path: spec.sentinel.topologySpreadConstraints[1].labelSelector
277+
value: {}
278+
- equal:
279+
path: spec.redis.topologySpreadConstraints[0].labelSelector
280+
value:
281+
matchLabels:
282+
app.kubernetes.io/name: my-redis
283+
app.kubernetes.io/component: redis
284+
- equal:
285+
path: spec.redis.topologySpreadConstraints[1].labelSelector
286+
value: {}

‎packages/apps/valkey/templates/valkeyfailover.yaml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ spec:
4242
{{- if $spreadConstraints }}
4343
topologySpreadConstraints:
4444
{{- range $spreadConstraints }}
45-
- {{- toYaml (ternary . (merge (deepCopy .) (dict "labelSelector" (dict "matchLabels" (dict "app.kubernetes.io/name" $.Release.Name "app.kubernetes.io/component" "sentinel")))) (hasKey . "labelSelector")) | nindent 6 }}
45+
- {{- toYaml (ternary . (merge (deepCopy .) (dict "labelSelector" (dict "matchLabels" (dict "app.kubernetes.io/name" $.Release.Name "app.kubernetes.io/component" "sentinel")))) (not (kindIs "invalid" .labelSelector))) | nindent 6 }}
4646
{{- end }}
4747
{{- else }}
4848
topologySpreadConstraints:
@@ -65,7 +65,7 @@ spec:
6565
{{- if $spreadConstraints }}
6666
topologySpreadConstraints:
6767
{{- range $spreadConstraints }}
68-
- {{- toYaml (ternary . (merge (deepCopy .) (dict "labelSelector" (dict "matchLabels" (dict "app.kubernetes.io/name" $.Release.Name "app.kubernetes.io/component" "redis")))) (hasKey . "labelSelector")) | nindent 6 }}
68+
- {{- toYaml (ternary . (merge (deepCopy .) (dict "labelSelector" (dict "matchLabels" (dict "app.kubernetes.io/name" $.Release.Name "app.kubernetes.io/component" "redis")))) (not (kindIs "invalid" .labelSelector))) | nindent 6 }}
6969
{{- end }}
7070
{{- else }}
7171
topologySpreadConstraints:

‎packages/apps/valkey/tests/topology_spread_test.yaml‎

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,3 +191,40 @@ tests:
191191
asserts:
192192
- failedTemplate:
193193
errorMessage: "valkey: _cluster.scheduling.globalAppTopologySpreadConstraints must be YAML with a non-empty topologySpreadConstraints list."
194+
195+
- it: fills null selectors and preserves explicit empty selectors
196+
set:
197+
_cluster:
198+
scheduling:
199+
globalAppTopologySpreadConstraints: |
200+
topologySpreadConstraints:
201+
- maxSkew: 1
202+
topologyKey: kubernetes.io/hostname
203+
whenUnsatisfiable: DoNotSchedule
204+
labelSelector: null
205+
- maxSkew: 1
206+
topologyKey: topology.kubernetes.io/zone
207+
whenUnsatisfiable: ScheduleAnyway
208+
labelSelector: {}
209+
documentSelector:
210+
path: kind
211+
value: RedisFailover
212+
asserts:
213+
- equal:
214+
path: spec.sentinel.topologySpreadConstraints[0].labelSelector
215+
value:
216+
matchLabels:
217+
app.kubernetes.io/name: my-valkey
218+
app.kubernetes.io/component: sentinel
219+
- equal:
220+
path: spec.sentinel.topologySpreadConstraints[1].labelSelector
221+
value: {}
222+
- equal:
223+
path: spec.redis.topologySpreadConstraints[0].labelSelector
224+
value:
225+
matchLabels:
226+
app.kubernetes.io/name: my-valkey
227+
app.kubernetes.io/component: redis
228+
- equal:
229+
path: spec.redis.topologySpreadConstraints[1].labelSelector
230+
value: {}

‎packages/system/harbor/templates/redis.yaml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ spec:
3838
{{- if $spreadConstraints }}
3939
topologySpreadConstraints:
4040
{{- range $spreadConstraints }}
41-
- {{- toYaml (ternary . (merge (deepCopy .) (dict "labelSelector" (dict "matchLabels" (dict "app.kubernetes.io/name" (printf "%s-redis" $.Values.harbor.fullnameOverride) "app.kubernetes.io/component" "sentinel")))) (hasKey . "labelSelector")) | nindent 6 }}
41+
- {{- toYaml (ternary . (merge (deepCopy .) (dict "labelSelector" (dict "matchLabels" (dict "app.kubernetes.io/name" (printf "%s-redis" $.Values.harbor.fullnameOverride) "app.kubernetes.io/component" "sentinel")))) (not (kindIs "invalid" .labelSelector))) | nindent 6 }}
4242
{{- end }}
4343
{{- else }}
4444
topologySpreadConstraints:
@@ -68,7 +68,7 @@ spec:
6868
{{- if $spreadConstraints }}
6969
topologySpreadConstraints:
7070
{{- range $spreadConstraints }}
71-
- {{- toYaml (ternary . (merge (deepCopy .) (dict "labelSelector" (dict "matchLabels" (dict "app.kubernetes.io/name" (printf "%s-redis" $.Values.harbor.fullnameOverride) "app.kubernetes.io/component" "redis")))) (hasKey . "labelSelector")) | nindent 6 }}
71+
- {{- toYaml (ternary . (merge (deepCopy .) (dict "labelSelector" (dict "matchLabels" (dict "app.kubernetes.io/name" (printf "%s-redis" $.Values.harbor.fullnameOverride) "app.kubernetes.io/component" "redis")))) (not (kindIs "invalid" .labelSelector))) | nindent 6 }}
7272
{{- end }}
7373
{{- else }}
7474
topologySpreadConstraints:

‎packages/system/harbor/tests/redis_spread_test.yaml‎

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,3 +192,40 @@ tests:
192192
asserts:
193193
- failedTemplate:
194194
errorMessage: "harbor: _cluster.scheduling.globalAppTopologySpreadConstraints must be YAML with a non-empty topologySpreadConstraints list."
195+
196+
- it: fills null selectors and preserves explicit empty selectors
197+
set:
198+
_cluster:
199+
scheduling:
200+
globalAppTopologySpreadConstraints: |
201+
topologySpreadConstraints:
202+
- maxSkew: 1
203+
topologyKey: kubernetes.io/hostname
204+
whenUnsatisfiable: DoNotSchedule
205+
labelSelector: null
206+
- maxSkew: 1
207+
topologyKey: topology.kubernetes.io/zone
208+
whenUnsatisfiable: ScheduleAnyway
209+
labelSelector: {}
210+
documentSelector:
211+
path: kind
212+
value: RedisFailover
213+
asserts:
214+
- equal:
215+
path: spec.sentinel.topologySpreadConstraints[0].labelSelector
216+
value:
217+
matchLabels:
218+
app.kubernetes.io/name: harbor-test-redis
219+
app.kubernetes.io/component: sentinel
220+
- equal:
221+
path: spec.sentinel.topologySpreadConstraints[1].labelSelector
222+
value: {}
223+
- equal:
224+
path: spec.redis.topologySpreadConstraints[0].labelSelector
225+
value:
226+
matchLabels:
227+
app.kubernetes.io/name: harbor-test-redis
228+
app.kubernetes.io/component: redis
229+
- equal:
230+
path: spec.redis.topologySpreadConstraints[1].labelSelector
231+
value: {}

0 commit comments

Comments
 (0)