From 4005767e87c29ca676103c24f44d20f4d8a54117 Mon Sep 17 00:00:00 2001 From: Eric Miller Date: Thu, 28 Apr 2022 12:47:40 -0500 Subject: [PATCH] Implement support for Topology Spread Constraints (#652) * Implemented support for topology spread constraints * Update values.yaml Co-authored-by: Ben Ash <32777270+benashz@users.noreply.github.com> * Update values.yaml Co-authored-by: Ben Ash <32777270+benashz@users.noreply.github.com> * Add topologySpreadConstraints to values schema * Implement injector deployment topology spread UTs * also remove string from the relevant schema types * Implement injector statefulset topology spread UTs * Implement injector HA statefulset topology UTs * Allow topologySpreadConstraints to be a string Co-authored-by: Ellis Tarn Co-authored-by: Ben Ash <32777270+benashz@users.noreply.github.com> Co-authored-by: Christopher Swenson --- templates/_helpers.tpl | 31 ++++++++++++++++++++++++++++ templates/injector-deployment.yaml | 1 + templates/server-statefulset.yaml | 1 + test/unit/injector-deployment.bats | 21 +++++++++++++++++++ test/unit/server-ha-statefulset.bats | 26 +++++++++++++++++++++++ test/unit/server-statefulset.bats | 23 +++++++++++++++++++++ values.schema.json | 7 +++++++ values.yaml | 12 +++++++++++ 8 files changed, 122 insertions(+) diff --git a/templates/_helpers.tpl b/templates/_helpers.tpl index 144008e..846bfc3 100644 --- a/templates/_helpers.tpl +++ b/templates/_helpers.tpl @@ -293,6 +293,37 @@ Sets the injector affinity for pod placement {{ end }} {{- end -}} +{{/* +Sets the topologySpreadConstraints when running in standalone and HA modes. +*/}} +{{- define "vault.topologySpreadConstraints" -}} + {{- if and (ne .mode "dev") .Values.server.topologySpreadConstraints }} + topologySpreadConstraints: + {{ $tp := typeOf .Values.server.topologySpreadConstraints }} + {{- if eq $tp "string" }} + {{- tpl .Values.server.topologySpreadConstraints . | nindent 8 | trim }} + {{- else }} + {{- toYaml .Values.server.topologySpreadConstraints | nindent 8 }} + {{- end }} + {{ end }} +{{- end -}} + + +{{/* +Sets the injector topologySpreadConstraints for pod placement +*/}} +{{- define "injector.topologySpreadConstraints" -}} + {{- if .Values.injector.topologySpreadConstraints }} + topologySpreadConstraints: + {{ $tp := typeOf .Values.injector.topologySpreadConstraints }} + {{- if eq $tp "string" }} + {{- tpl .Values.injector.topologySpreadConstraints . | nindent 8 | trim }} + {{- else }} + {{- toYaml .Values.injector.topologySpreadConstraints | nindent 8 }} + {{- end }} + {{ end }} +{{- end -}} + {{/* Sets the toleration for pod placement when running in standalone and HA modes. */}} diff --git a/templates/injector-deployment.yaml b/templates/injector-deployment.yaml index 9a50c7d..d46cefc 100644 --- a/templates/injector-deployment.yaml +++ b/templates/injector-deployment.yaml @@ -31,6 +31,7 @@ spec: {{ template "injector.annotations" . }} spec: {{ template "injector.affinity" . }} + {{ template "injector.topologySpreadConstraints" . }} {{ template "injector.tolerations" . }} {{ template "injector.nodeselector" . }} {{- if .Values.injector.priorityClassName }} diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index 2cae84f..518a193 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -37,6 +37,7 @@ spec: {{ template "vault.annotations" . }} spec: {{ template "vault.affinity" . }} + {{ template "vault.topologySpreadConstraints" . }} {{ template "vault.tolerations" . }} {{ template "vault.nodeselector" . }} {{- if .Values.server.priorityClassName }} diff --git a/test/unit/injector-deployment.bats b/test/unit/injector-deployment.bats index bfbd3eb..94d01cd 100755 --- a/test/unit/injector-deployment.bats +++ b/test/unit/injector-deployment.bats @@ -462,6 +462,27 @@ load _helpers [ "${actual}" = "true" ] } +#-------------------------------------------------------------------- +# topologySpreadConstraints + +@test "injector/deployment: topologySpreadConstraints is null by default" { + cd `chart_dir` + local actual=$(helm template \ + --show-only templates/injector-deployment.yaml \ + . | tee /dev/stderr | + yq '.spec.template.spec | .topologySpreadConstraints? == null' | tee /dev/stderr) +} + +@test "injector/deployment: topologySpreadConstraints can be set as YAML" { + cd `chart_dir` + local actual=$(helm template \ + --show-only templates/injector-deployment.yaml \ + --set "injector.topologySpreadConstraints[0].foo=bar,injector.topologySpreadConstraints[1].baz=qux" \ + . | tee /dev/stderr | + yq '.spec.template.spec.topologySpreadConstraints == [{"foo": "bar"}, {"baz": "qux"}]' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + #-------------------------------------------------------------------- # tolerations diff --git a/test/unit/server-ha-statefulset.bats b/test/unit/server-ha-statefulset.bats index 0722c26..342fa43 100755 --- a/test/unit/server-ha-statefulset.bats +++ b/test/unit/server-ha-statefulset.bats @@ -585,6 +585,32 @@ load _helpers [ "${actual}" = "1" ] } +#-------------------------------------------------------------------- +# topologySpreadConstraints + +@test "server/ha-StatefulSet: topologySpreadConstraints is null by default" { + cd `chart_dir` + local actual=$(helm template \ + --show-only templates/server-statefulset.yaml \ + --set 'server.ha.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec | .topologySpreadConstraints? == null' | tee /dev/stderr) +} + +@test "server/ha-StatefulSet: topologySpreadConstraints can be set as YAML" { + cd `chart_dir` + local actual=$(helm template \ + --show-only templates/server-statefulset.yaml \ + --set 'server.ha.enabled=true' \ + --set "server.topologySpreadConstraints[0].foo=bar,server.topologySpreadConstraints[1].baz=qux" \ + . | tee /dev/stderr | + yq '.spec.template.spec.topologySpreadConstraints == [{"foo": "bar"}, {"baz": "qux"}]' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +#-------------------------------------------------------------------- +# tolerations + @test "server/ha-StatefulSet: tolerations not set by default" { cd `chart_dir` local actual=$(helm template \ diff --git a/test/unit/server-statefulset.bats b/test/unit/server-statefulset.bats index 6a8d451..a240e3d 100755 --- a/test/unit/server-statefulset.bats +++ b/test/unit/server-statefulset.bats @@ -784,6 +784,29 @@ load _helpers [ "${actual}" = "true" ] } +#-------------------------------------------------------------------- +# topologySpreadConstraints + +@test "server/standalone-StatefulSet: topologySpreadConstraints is null by default" { + cd `chart_dir` + local actual=$(helm template \ + --show-only templates/server-statefulset.yaml \ + . | tee /dev/stderr | + yq '.spec.template.spec | .topologySpreadConstraints? == null' | tee /dev/stderr) +} + +@test "server/standalone-StatefulSet: topologySpreadConstraints can be set as YAML" { + cd `chart_dir` + local actual=$(helm template \ + --show-only templates/server-statefulset.yaml \ + --set "server.topologySpreadConstraints[0].foo=bar,server.topologySpreadConstraints[1].baz=qux" \ + . | tee /dev/stderr | + yq '.spec.template.spec.topologySpreadConstraints == [{"foo": "bar"}, {"baz": "qux"}]' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +#-------------------------------------------------------------------- +# tolerations @test "server/standalone-StatefulSet: tolerations not set by default" { cd `chart_dir` diff --git a/values.schema.json b/values.schema.json index 39d0765..87a02f8 100644 --- a/values.schema.json +++ b/values.schema.json @@ -380,6 +380,13 @@ "string" ] }, + "topologySpreadConstraints": { + "type": [ + "null", + "array", + "string" + ] + }, "webhook": { "type": "object", "properties": { diff --git a/values.yaml b/values.yaml index 891129e..a693ee0 100644 --- a/values.yaml +++ b/values.yaml @@ -218,6 +218,12 @@ injector: component: webhook topologyKey: kubernetes.io/hostname + # Topology settings for injector pods + # ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ + # This should be either a multi-line string or YAML matching the topologySpreadConstraints array + # in a PodSpec. + topologySpreadConstraints: [] + # Toleration Settings for injector pods # This should be either a multi-line string or YAML matching the Toleration array # in a PodSpec. @@ -508,6 +514,12 @@ server: component: server topologyKey: kubernetes.io/hostname + # Topology settings for server pods + # ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ + # This should be either a multi-line string or YAML matching the topologySpreadConstraints array + # in a PodSpec. + topologySpreadConstraints: [] + # Toleration Settings for server pods # This should be either a multi-line string or YAML matching the Toleration array # in a PodSpec.