From 377b68f13ba87e3c4e1f03bf7eaa3d9ab5f34dec Mon Sep 17 00:00:00 2001 From: Arend Lapere Date: Fri, 25 Aug 2023 00:14:19 +0200 Subject: [PATCH] Add support for dual stack clusters (#833) --- CHANGELOG.md | 3 ++ templates/server-ha-active-service.yaml | 8 +++++ templates/server-ha-standby-service.yaml | 8 +++++ templates/server-headless-service.yaml | 8 +++++ templates/server-service.yaml | 8 +++++ templates/ui-service.yaml | 8 +++++ test/unit/server-headless-service.bats | 42 ++++++++++++++++++++++ test/unit/server-service.bats | 42 ++++++++++++++++++++++ test/unit/ui-service.bats | 45 ++++++++++++++++++++++++ values.schema.json | 18 ++++++++++ values.yaml | 30 ++++++++++++++++ 11 files changed, 220 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e59adea4..6ddd8bcac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ ## Unreleased +Features: +* server: Add support for dual stack clusters [GH-833](https://github.com/hashicorp/vault-helm/pull/833) + Bugs: * csi: Add namespace field to `csi-role` and `csi-rolebindings`. [GH-909](https://github.com/hashicorp/vault-helm/pull/909) diff --git a/templates/server-ha-active-service.yaml b/templates/server-ha-active-service.yaml index 2a3375a63..32201585b 100644 --- a/templates/server-ha-active-service.yaml +++ b/templates/server-ha-active-service.yaml @@ -27,6 +27,14 @@ spec: {{- if .Values.server.service.type}} type: {{ .Values.server.service.type }} {{- end}} + {{- if (semverCompare ">= 1.23-0" .Capabilities.KubeVersion.Version) }} + {{- if .Values.server.service.ipFamilyPolicy }} + ipFamilyPolicy: {{ .Values.server.service.ipFamilyPolicy }} + {{- end }} + {{- if .Values.server.service.ipFamilies }} + ipFamilies: {{ .Values.server.service.ipFamilies | toYaml | nindent 2 }} + {{- end }} + {{- end }} {{- if .Values.server.service.clusterIP }} clusterIP: {{ .Values.server.service.clusterIP }} {{- end }} diff --git a/templates/server-ha-standby-service.yaml b/templates/server-ha-standby-service.yaml index 27fdfce8b..e5d662b32 100644 --- a/templates/server-ha-standby-service.yaml +++ b/templates/server-ha-standby-service.yaml @@ -26,6 +26,14 @@ spec: {{- if .Values.server.service.type}} type: {{ .Values.server.service.type }} {{- end}} + {{- if (semverCompare ">= 1.23-0" .Capabilities.KubeVersion.Version) }} + {{- if .Values.server.service.ipFamilyPolicy }} + ipFamilyPolicy: {{ .Values.server.service.ipFamilyPolicy }} + {{- end }} + {{- if .Values.server.service.ipFamilies }} + ipFamilies: {{ .Values.server.service.ipFamilies | toYaml | nindent 2 }} + {{- end }} + {{- end }} {{- if .Values.server.service.clusterIP }} clusterIP: {{ .Values.server.service.clusterIP }} {{- end }} diff --git a/templates/server-headless-service.yaml b/templates/server-headless-service.yaml index 4df81e219..c0f4d3460 100644 --- a/templates/server-headless-service.yaml +++ b/templates/server-headless-service.yaml @@ -22,6 +22,14 @@ metadata: annotations: {{ template "vault.service.annotations" .}} spec: + {{- if (semverCompare ">= 1.23-0" .Capabilities.KubeVersion.Version) }} + {{- if .Values.server.service.ipFamilyPolicy }} + ipFamilyPolicy: {{ .Values.server.service.ipFamilyPolicy }} + {{- end }} + {{- if .Values.server.service.ipFamilies }} + ipFamilies: {{ .Values.server.service.ipFamilies | toYaml | nindent 2 }} + {{- end }} + {{- end }} clusterIP: None publishNotReadyAddresses: true ports: diff --git a/templates/server-service.yaml b/templates/server-service.yaml index 444b15e60..c12e190cb 100644 --- a/templates/server-service.yaml +++ b/templates/server-service.yaml @@ -24,6 +24,14 @@ spec: {{- if .Values.server.service.type}} type: {{ .Values.server.service.type }} {{- end}} + {{- if (semverCompare ">= 1.23-0" .Capabilities.KubeVersion.Version) }} + {{- if .Values.server.service.ipFamilyPolicy }} + ipFamilyPolicy: {{ .Values.server.service.ipFamilyPolicy }} + {{- end }} + {{- if .Values.server.service.ipFamilies }} + ipFamilies: {{ .Values.server.service.ipFamilies | toYaml | nindent 2 }} + {{- end }} + {{- end }} {{- if .Values.server.service.clusterIP }} clusterIP: {{ .Values.server.service.clusterIP }} {{- end }} diff --git a/templates/ui-service.yaml b/templates/ui-service.yaml index 261732ba1..95370842e 100644 --- a/templates/ui-service.yaml +++ b/templates/ui-service.yaml @@ -20,6 +20,14 @@ metadata: app.kubernetes.io/managed-by: {{ .Release.Service }} {{- template "vault.ui.annotations" . }} spec: + {{- if (semverCompare ">= 1.23-0" .Capabilities.KubeVersion.Version) }} + {{- if .Values.ui.serviceIPFamilyPolicy }} + ipFamilyPolicy: {{ .Values.ui.serviceIPFamilyPolicy }} + {{- end }} + {{- if .Values.ui.serviceIPFamilies }} + ipFamilies: {{ .Values.ui.serviceIPFamilies | toYaml | nindent 2 }} + {{- end }} + {{- end }} selector: app.kubernetes.io/name: {{ include "vault.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} diff --git a/test/unit/server-headless-service.bats b/test/unit/server-headless-service.bats index 8a1f52fe8..df649bebc 100644 --- a/test/unit/server-headless-service.bats +++ b/test/unit/server-headless-service.bats @@ -53,4 +53,46 @@ load _helpers . | tee /dev/stderr | yq -r '.metadata.namespace' | tee /dev/stderr) [ "${actual}" = "bar" ] +} + +@test "server/headless-Service: Assert ipFamilyPolicy set" { + cd `chart_dir` + local actual=$(helm template \ + --show-only templates/server-headless-service.yaml \ + --set 'server.service.ipFamilyPolicy=PreferDualStack' \ + . | tee /dev/stderr | + yq -r '.spec.ipFamilyPolicy' | tee /dev/stderr) + [ "${actual}" = "PreferDualStack" ] +} + +@test "server/headless-Service: Assert ipFamilies set" { + cd `chart_dir` + local actual=$(helm template \ + --show-only templates/server-headless-service.yaml \ + --set 'server.service.ipFamilies={IPv4,IPv6}' \ + . | tee /dev/stderr | + yq '.spec.ipFamilies' -c | tee /dev/stderr) + [ "${actual}" = '["IPv4","IPv6"]' ] +} + +@test "server/headless-Service: Assert ipFamilyPolicy is not set if version below 1.23" { + cd `chart_dir` + local actual=$(helm template \ + --show-only templates/server-headless-service.yaml \ + --kube-version 1.22.0 \ + --set 'server.service.ipFamilyPolicy=PreferDualStack' \ + . | tee /dev/stderr | + yq -r '.spec.ipFamilyPolicy' | tee /dev/stderr) + [ "${actual}" = "null" ] +} + +@test "server/headless-Service: Assert ipFamilies is not set if version below 1.23" { + cd `chart_dir` + local actual=$(helm template \ + --show-only templates/server-headless-service.yaml \ + --kube-version 1.22.0 \ + --set 'server.service.ipFamilies={IPv4,IPv6}' \ + . | tee /dev/stderr | + yq -r '.spec.ipFamilies' | tee /dev/stderr) + [ "${actual}" = "null" ] } \ No newline at end of file diff --git a/test/unit/server-service.bats b/test/unit/server-service.bats index b84e5b1d0..040e9fadf 100755 --- a/test/unit/server-service.bats +++ b/test/unit/server-service.bats @@ -467,3 +467,45 @@ load _helpers yq -r '.spec.selector["app.kubernetes.io/instance"]' | tee /dev/stderr) [ "${actual}" = "null" ] } + +@test "server/Service: Assert ipFamilyPolicy set" { + cd `chart_dir` + local actual=$(helm template \ + --show-only templates/server-service.yaml \ + --set 'server.service.ipFamilyPolicy=PreferDualStack' \ + . | tee /dev/stderr | + yq -r '.spec.ipFamilyPolicy' | tee /dev/stderr) + [ "${actual}" = "PreferDualStack" ] +} + +@test "server/Service: Assert ipFamilies set" { + cd `chart_dir` + local actual=$(helm template \ + --show-only templates/server-service.yaml \ + --set 'server.service.ipFamilies={IPv4,IPv6}' \ + . | tee /dev/stderr | + yq '.spec.ipFamilies' -c | tee /dev/stderr) + [ "${actual}" = '["IPv4","IPv6"]' ] +} + +@test "server/Service: Assert ipFamilyPolicy is not set if version below 1.23" { + cd `chart_dir` + local actual=$(helm template \ + --show-only templates/server-service.yaml \ + --kube-version 1.22.0 \ + --set 'server.service.ipFamilyPolicy=PreferDualStack' \ + . | tee /dev/stderr | + yq -r '.spec.ipFamilyPolicy' | tee /dev/stderr) + [ "${actual}" = "null" ] +} + +@test "server/Service: Assert ipFamilies is not set if version below 1.23" { + cd `chart_dir` + local actual=$(helm template \ + --show-only templates/server-service.yaml \ + --kube-version 1.22.0 \ + --set 'server.service.ipFamilies={IPv4,IPv6}' \ + . | tee /dev/stderr | + yq -r '.spec.ipFamilies' | tee /dev/stderr) + [ "${actual}" = "null" ] +} \ No newline at end of file diff --git a/test/unit/ui-service.bats b/test/unit/ui-service.bats index 384098f89..dce0e5e7c 100755 --- a/test/unit/ui-service.bats +++ b/test/unit/ui-service.bats @@ -383,5 +383,50 @@ load _helpers . | tee /dev/stderr | yq '.spec.externalTrafficPolicy' | tee /dev/stderr) [ "${actual}" = "null" ] +} + +@test "ui/Service: Assert ipFamilies set" { + cd `chart_dir` + local actual=$(helm template \ + --show-only templates/ui-service.yaml \ + --set 'ui.enabled=true' \ + --set 'ui.serviceIPFamilies={IPv4,IPv6}' \ + . | tee /dev/stderr | + yq '.spec.ipFamilies' -c | tee /dev/stderr) + [ "${actual}" = '["IPv4","IPv6"]' ] +} + +@test "ui/Service: Assert ipFamilyPolicy set" { + cd `chart_dir` + local actual=$(helm template \ + --show-only templates/ui-service.yaml \ + --set 'ui.enabled=true' \ + --set 'ui.serviceIPFamilyPolicy=PreferDualStack' \ + . | tee /dev/stderr | + yq -r '.spec.ipFamilyPolicy' | tee /dev/stderr) + [ "${actual}" = "PreferDualStack" ] +} +@test "server/Service: Assert ipFamilyPolicy is not set if version below 1.23" { + cd `chart_dir` + local actual=$(helm template \ + --show-only templates/ui-service.yaml \ + --kube-version 1.22.0 \ + --set 'ui.enabled=true' \ + --set 'ui.serviceIPFamilyPolicy=PreferDualStack' \ + . | tee /dev/stderr | + yq -r '.spec.ipFamilyPolicy' | tee /dev/stderr) + [ "${actual}" = "null" ] } + +@test "server/Service: Assert ipFamilies is not set if version below 1.23" { + cd `chart_dir` + local actual=$(helm template \ + --show-only templates/ui-service.yaml \ + --kube-version 1.22.0 \ + --set 'ui.enabled=true' \ + --set 'ui.serviceIPFamilies={IPv4,IPv6}' \ + . | tee /dev/stderr | + yq -r '.spec.ipFamilies' | tee /dev/stderr) + [ "${actual}" = "null" ] +} \ No newline at end of file diff --git a/values.schema.json b/values.schema.json index f08a98e16..39f0e0274 100644 --- a/values.schema.json +++ b/values.schema.json @@ -967,6 +967,14 @@ }, "standbyNodePort": { "type": "integer" + }, + "ipFamilyPolicy": { + "type": "string" + }, + "ipFamilies": { + "type": [ + "array" + ] } } }, @@ -1143,6 +1151,16 @@ }, "targetPort": { "type": "integer" + }, + "serviceIPFamilyPolicy": { + "type": [ + "string" + ] + }, + "serviceIPFamilies": { + "type": [ + "array" + ] } } } diff --git a/values.yaml b/values.yaml index b10b3f125..c100c17ea 100644 --- a/values.yaml +++ b/values.yaml @@ -676,6 +676,21 @@ server: # or NodePort. #type: ClusterIP + # The IP family and IP families options are to set the behaviour in a dual-stack environment. + # Omitting these values will let the service fall back to whatever the CNI dictates the defaults + # should be. + # These are only supported for kubernetes versions >=1.23.0 + # + # Configures the service's supported IP family policy, can be either: + # SingleStack: Single-stack service. The control plane allocates a cluster IP for the Service, using the first configured service cluster IP range. + # PreferDualStack: Allocates IPv4 and IPv6 cluster IPs for the Service. + # RequireDualStack: Allocates Service .spec.ClusterIPs from both IPv4 and IPv6 address ranges. + ipFamilyPolicy: "" + + # Sets the families that should be supported and the order in which they should be applied to ClusterIP as well. + # Can be IPv4 and/or IPv6. + ipFamilies: [] + # Do not wait for pods to be ready before including them in the services' # targets. Does not apply to the headless service, which is used for # cluster-internal communication. @@ -979,6 +994,21 @@ ui: externalPort: 8200 targetPort: 8200 + # The IP family and IP families options are to set the behaviour in a dual-stack environment. + # Omitting these values will let the service fall back to whatever the CNI dictates the defaults + # should be. + # These are only supported for kubernetes versions >=1.23.0 + # + # Configures the service's supported IP family, can be either: + # SingleStack: Single-stack service. The control plane allocates a cluster IP for the Service, using the first configured service cluster IP range. + # PreferDualStack: Allocates IPv4 and IPv6 cluster IPs for the Service. + # RequireDualStack: Allocates Service .spec.ClusterIPs from both IPv4 and IPv6 address ranges. + serviceIPFamilyPolicy: "" + + # Sets the families that should be supported and the order in which they should be applied to ClusterIP as well + # Can be IPv4 and/or IPv6. + serviceIPFamilies: [] + # The externalTrafficPolicy can be set to either Cluster or Local # and is only valid for LoadBalancer and NodePort service types. # The default value is Cluster.