From 2b2b0dd2fa9e871d7525e35c7eff5a518bbf9c22 Mon Sep 17 00:00:00 2001 From: Theron Voran Date: Fri, 21 Feb 2020 08:16:33 -0800 Subject: [PATCH] Added support for external vault (#207) Uses Values.injector.externalVaultAddr to control the vault address env variable and server yaml rendering. If injector.externalVaultAddr is empty, both the injector and vault are deployed, with the injector using the local vault. If injector.externalVaultAddr is not empty, only the injector is deployed, and it uses the vault at the address specified in injector.externalVaultAddr. --- templates/_helpers.tpl | 4 +- templates/injector-deployment.yaml | 4 ++ templates/server-clusterrolebinding.yaml | 2 + templates/server-config-configmap.yaml | 2 + templates/server-disruptionbudget.yaml | 2 + templates/server-ingress.yaml | 3 ++ templates/server-service.yaml | 3 ++ templates/server-serviceaccount.yaml | 2 + templates/server-statefulset.yaml | 2 + templates/ui-service.yaml | 2 + test/unit/injector-deployment.bats | 34 ++++++++++++++ test/unit/server-clusterrolebinding.bats | 10 +++++ test/unit/server-configmap.bats | 10 +++++ test/unit/server-dev-statefulset.bats | 11 +++++ test/unit/server-ha-disruptionbudget.bats | 10 +++++ test/unit/server-ha-statefulset.bats | 11 +++++ test/unit/server-ingress.bats | 11 +++++ test/unit/server-service.bats | 30 +++++++++++++ test/unit/server-serviceaccount.bats | 54 +++++++++++++++++++++++ test/unit/server-statefulset.bats | 11 +++++ test/unit/ui-service.bats | 27 ++++++++++++ values.yaml | 4 ++ 22 files changed, 248 insertions(+), 1 deletion(-) diff --git a/templates/_helpers.tpl b/templates/_helpers.tpl index 0098ab1..f985a8c 100644 --- a/templates/_helpers.tpl +++ b/templates/_helpers.tpl @@ -51,7 +51,9 @@ Set the variable 'mode' to the server mode requested by the user to simplify template logic. */}} {{- define "vault.mode" -}} - {{- if eq (.Values.server.dev.enabled | toString) "true" -}} + {{- if .Values.injector.externalVaultAddr -}} + {{- $_ := set . "mode" "external" -}} + {{- else if eq (.Values.server.dev.enabled | toString) "true" -}} {{- $_ := set . "mode" "dev" -}} {{- else if eq (.Values.server.ha.enabled | toString) "true" -}} {{- $_ := set . "mode" "ha" -}} diff --git a/templates/injector-deployment.yaml b/templates/injector-deployment.yaml index 86c54ff..2362915 100644 --- a/templates/injector-deployment.yaml +++ b/templates/injector-deployment.yaml @@ -40,7 +40,11 @@ spec: - name: AGENT_INJECT_LOG_LEVEL value: {{ .Values.injector.logLevel | default "info" }} - name: AGENT_INJECT_VAULT_ADDR + {{- if .Values.injector.externalVaultAddr }} + value: "{{ .Values.injector.externalVaultAddr }}" + {{- else }} value: {{ include "vault.scheme" . }}://{{ template "vault.fullname" . }}.{{ .Release.Namespace }}.svc:{{ .Values.server.service.port }} + {{- end }} - name: AGENT_INJECT_VAULT_IMAGE value: "{{ .Values.injector.agentImage.repository }}:{{ .Values.injector.agentImage.tag }}" {{- if .Values.injector.certs.secretName }} diff --git a/templates/server-clusterrolebinding.yaml b/templates/server-clusterrolebinding.yaml index ac60cd7..733764f 100644 --- a/templates/server-clusterrolebinding.yaml +++ b/templates/server-clusterrolebinding.yaml @@ -1,4 +1,5 @@ {{ template "vault.mode" . }} +{{- if ne .mode "external" }} {{- if and (ne .mode "") (and (eq (.Values.global.enabled | toString) "true") (eq (.Values.server.authDelegator.enabled | toString) "true")) }} apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding @@ -19,3 +20,4 @@ subjects: name: {{ template "vault.fullname" . }} namespace: {{ .Release.Namespace }} {{ end }} +{{ end }} diff --git a/templates/server-config-configmap.yaml b/templates/server-config-configmap.yaml index 811500b..6748d0f 100644 --- a/templates/server-config-configmap.yaml +++ b/templates/server-config-configmap.yaml @@ -1,4 +1,5 @@ {{ template "vault.mode" . }} +{{- if ne .mode "external" }} {{- if and (eq (.Values.global.enabled | toString) "true") (ne .mode "dev") -}} {{ if or (ne .Values.server.standalone.config "") (ne .Values.server.ha.config "") -}} apiVersion: v1 @@ -21,3 +22,4 @@ data: {{ end }} {{- end }} {{- end }} +{{- end }} diff --git a/templates/server-disruptionbudget.yaml b/templates/server-disruptionbudget.yaml index 40ba8b4..6d7f824 100644 --- a/templates/server-disruptionbudget.yaml +++ b/templates/server-disruptionbudget.yaml @@ -1,4 +1,5 @@ {{ template "vault.mode" . }} +{{- if ne .mode "external" -}} {{- if and (and (eq (.Values.global.enabled | toString) "true") (eq .mode "ha")) (eq (.Values.server.ha.disruptionBudget.enabled | toString) "true") -}} # PodDisruptionBudget to prevent degrading the server cluster through # voluntary cluster changes. @@ -20,3 +21,4 @@ spec: app.kubernetes.io/instance: {{ .Release.Name }} component: server {{- end -}} +{{- end -}} diff --git a/templates/server-ingress.yaml b/templates/server-ingress.yaml index 0402eab..8786d97 100644 --- a/templates/server-ingress.yaml +++ b/templates/server-ingress.yaml @@ -1,3 +1,5 @@ +{{ template "vault.mode" . }} +{{- if ne .mode "external" }} {{- if .Values.server.ingress.enabled -}} {{- $serviceName := include "vault.fullname" . -}} {{- $servicePort := .Values.server.service.port -}} @@ -42,3 +44,4 @@ spec: {{- end }} {{- end }} {{- end }} +{{- end }} diff --git a/templates/server-service.yaml b/templates/server-service.yaml index 4ea2363..dc633c6 100644 --- a/templates/server-service.yaml +++ b/templates/server-service.yaml @@ -1,3 +1,5 @@ +{{ template "vault.mode" . }} +{{- if ne .mode "external" }} {{- if and (eq (.Values.server.service.enabled | toString) "true" ) (eq (.Values.global.enabled | toString) "true") }} # Service for Vault cluster apiVersion: v1 @@ -43,3 +45,4 @@ spec: app.kubernetes.io/instance: {{ .Release.Name }} component: server {{- end }} +{{- end }} diff --git a/templates/server-serviceaccount.yaml b/templates/server-serviceaccount.yaml index 557ee1a..b375182 100644 --- a/templates/server-serviceaccount.yaml +++ b/templates/server-serviceaccount.yaml @@ -1,4 +1,5 @@ {{ template "vault.mode" . }} +{{- if ne .mode "external" }} {{- if and (ne .mode "") (eq (.Values.global.enabled | toString) "true") }} apiVersion: v1 kind: ServiceAccount @@ -12,3 +13,4 @@ metadata: app.kubernetes.io/managed-by: {{ .Release.Service }} {{ template "vault.serviceAccount.annotations" . }} {{ end }} +{{ end }} diff --git a/templates/server-statefulset.yaml b/templates/server-statefulset.yaml index 8a51e6d..18e0d6b 100644 --- a/templates/server-statefulset.yaml +++ b/templates/server-statefulset.yaml @@ -1,4 +1,5 @@ {{ template "vault.mode" . }} +{{- if ne .mode "external" }} {{- if and (ne .mode "") (eq (.Values.global.enabled | toString) "true") }} # StatefulSet to run the actual vault server cluster. apiVersion: apps/v1 @@ -143,3 +144,4 @@ spec: {{- end }} {{ template "vault.volumeclaims" . }} {{ end }} +{{ end }} diff --git a/templates/ui-service.yaml b/templates/ui-service.yaml index cfc53e5..6d89264 100644 --- a/templates/ui-service.yaml +++ b/templates/ui-service.yaml @@ -1,4 +1,5 @@ {{ template "vault.mode" . }} +{{- if ne .mode "external" }} {{- if and (ne .mode "") (eq (.Values.global.enabled | toString) "true") }} {{- if eq (.Values.ui.enabled | toString) "true" }} # Headless service for Vault server DNS entries. This service should only @@ -43,3 +44,4 @@ spec: {{- end -}} {{ end }} +{{ end }} diff --git a/test/unit/injector-deployment.bats b/test/unit/injector-deployment.bats index 1f6caaa..7018ea9 100755 --- a/test/unit/injector-deployment.bats +++ b/test/unit/injector-deployment.bats @@ -154,3 +154,37 @@ load _helpers yq -r '.[5].name' | tee /dev/stderr) [ "${actual}" = "AGENT_INJECT_TLS_AUTO_HOSTS" ] } + +@test "injector/deployment: with externalVaultAddr" { + cd `chart_dir` + local object=$(helm template \ + --show-only templates/injector-deployment.yaml \ + --set 'injector.externalVaultAddr=http://vault-outside' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].env' | tee /dev/stderr) + + local actual=$(echo $object | + yq -r '.[2].name' | tee /dev/stderr) + [ "${actual}" = "AGENT_INJECT_VAULT_ADDR" ] + + local actual=$(echo $object | + yq -r '.[2].value' | tee /dev/stderr) + [ "${actual}" = "http://vault-outside" ] +} + +@test "injector/deployment: without externalVaultAddr" { + cd `chart_dir` + local object=$(helm template \ + --show-only templates/injector-deployment.yaml \ + --release-name not-external-test \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].env' | tee /dev/stderr) + + local actual=$(echo $object | + yq -r '.[2].name' | tee /dev/stderr) + [ "${actual}" = "AGENT_INJECT_VAULT_ADDR" ] + + local actual=$(echo $object | + yq -r '.[2].value' | tee /dev/stderr) + [ "${actual}" = "http://not-external-test-vault.default.svc:8200" ] +} diff --git a/test/unit/server-clusterrolebinding.bats b/test/unit/server-clusterrolebinding.bats index d1245c4..d0d2acf 100755 --- a/test/unit/server-clusterrolebinding.bats +++ b/test/unit/server-clusterrolebinding.bats @@ -60,3 +60,13 @@ load _helpers yq 'length > 0' | tee /dev/stderr) [ "${actual}" = "false" ] } + +@test "server/ClusterRoleBinding: disable with injector.externalVaultAddr" { + cd `chart_dir` + local actual=$( (helm template \ + --show-only templates/server-clusterrolebinding.yaml \ + --set 'injector.externalVaultAddr=http://vault-outside' \ + . || echo "---") | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} diff --git a/test/unit/server-configmap.bats b/test/unit/server-configmap.bats index 679a76f..2aa8856 100755 --- a/test/unit/server-configmap.bats +++ b/test/unit/server-configmap.bats @@ -82,3 +82,13 @@ load _helpers yq '.data["extraconfig-from-values.hcl"] | match("bar") | length' | tee /dev/stderr) [ ! -z "${actual}" ] } + +@test "server/ConfigMap: disabled by injector.externalVaultAddr" { + cd `chart_dir` + local actual=$( (helm template \ + --show-only templates/server-config-configmap.yaml \ + --set 'injector.externalVaultAddr=http://vault-outside' \ + . || echo "---") | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} diff --git a/test/unit/server-dev-statefulset.bats b/test/unit/server-dev-statefulset.bats index 57acd20..10a9da6 100755 --- a/test/unit/server-dev-statefulset.bats +++ b/test/unit/server-dev-statefulset.bats @@ -23,6 +23,17 @@ load _helpers [ "${actual}" = "false" ] } +@test "server/dev-StatefulSet: disable with injector.externalVaultAddr" { + cd `chart_dir` + local actual=$( (helm template \ + --show-only templates/server-statefulset.yaml \ + --set 'injector.externalVaultAddr=http://vault-outside' \ + --set 'server.dev.enabled=true' \ + . || echo "---") | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + @test "server/dev-StatefulSet: image defaults to server.image.repository:tag" { cd `chart_dir` local actual=$(helm template \ diff --git a/test/unit/server-ha-disruptionbudget.bats b/test/unit/server-ha-disruptionbudget.bats index 2c0174a..f3c329e 100755 --- a/test/unit/server-ha-disruptionbudget.bats +++ b/test/unit/server-ha-disruptionbudget.bats @@ -43,6 +43,16 @@ load _helpers [ "${actual}" = "false" ] } +@test "server/DisruptionBudget: disable with injector.exernalVaultAddr" { + cd `chart_dir` + local actual=$( (helm template \ + --show-only templates/server-disruptionbudget.yaml \ + --set 'injector.externalVaultAddr=http://vault-outside' \ + . || echo "---") | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + @test "server/DisruptionBudget: correct maxUnavailable with n=1" { cd `chart_dir` local actual=$(helm template \ diff --git a/test/unit/server-ha-statefulset.bats b/test/unit/server-ha-statefulset.bats index a40e92f..11c4e93 100755 --- a/test/unit/server-ha-statefulset.bats +++ b/test/unit/server-ha-statefulset.bats @@ -23,6 +23,17 @@ load _helpers [ "${actual}" = "false" ] } +@test "server/ha-StatefulSet: disable with injector.externalVaultAddr" { + cd `chart_dir` + local actual=$( (helm template \ + --show-only templates/server-statefulset.yaml \ + --set 'injector.externalVaultAddr=http://vault-outside' \ + --set 'server.ha.enabled=true' \ + . || echo "---") | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + @test "server/ha-StatefulSet: image defaults to server.image.repository:tag" { cd `chart_dir` local actual=$(helm template \ diff --git a/test/unit/server-ingress.bats b/test/unit/server-ingress.bats index 1cf1576..850ad4c 100755 --- a/test/unit/server-ingress.bats +++ b/test/unit/server-ingress.bats @@ -11,6 +11,17 @@ load _helpers [ "${actual}" = "false" ] } +@test "server/ingress: disable by injector.externalVaultAddr" { + cd `chart_dir` + local actual=$( (helm template \ + --show-only templates/server-ingress.yaml \ + --set 'server.ingress.enabled=true' \ + --set 'injector.externalVaultAddr=http://vault-outside' \ + . || echo "---") | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + @test "server/ingress: checking host entry gets added and path is /" { cd `chart_dir` local actual=$(helm template \ diff --git a/test/unit/server-service.bats b/test/unit/server-service.bats index adcf95f..059a1d3 100755 --- a/test/unit/server-service.bats +++ b/test/unit/server-service.bats @@ -113,6 +113,36 @@ load _helpers [ "${actual}" = "false" ] } +@test "server/Service: disable with injector.externalVaultAddr" { + cd `chart_dir` + local actual=$( (helm template \ + --show-only templates/server-service.yaml \ + --set 'server.dev.enabled=true' \ + --set 'injector.externalVaultAddr=http://vault-outside' \ + --set 'server.service.enabled=true' \ + . || echo "---") | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$( (helm template \ + --show-only templates/server-service.yaml \ + --set 'server.ha.enabled=true' \ + --set 'injector.externalVaultAddr=http://vault-outside' \ + --set 'server.service.enabled=true' \ + . || echo "---") | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$( (helm template \ + --show-only templates/server-service.yaml \ + --set 'server.standalone.enabled=true' \ + --set 'injector.externalVaultAddr=http://vault-outside' \ + --set 'server.service.enabled=true' \ + . || echo "---") | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + # This can be seen as testing just what we put into the YAML raw, but # this is such an important part of making everything work we verify it here. @test "server/Service: tolerates unready endpoints" { diff --git a/test/unit/server-serviceaccount.bats b/test/unit/server-serviceaccount.bats index 66fd84b..d72de5d 100755 --- a/test/unit/server-serviceaccount.bats +++ b/test/unit/server-serviceaccount.bats @@ -27,3 +27,57 @@ load _helpers yq -r '.metadata.annotations["foo"]' | tee /dev/stderr) [ "${actual}" = "null" ] } + +@test "server/ServiceAccount: disable with global.enabled false" { + cd `chart_dir` + local actual=$( (helm template \ + --show-only templates/server-service.yaml \ + --set 'server.dev.enabled=true' \ + --set 'global.enabled=false' \ + . || echo "---") | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$( (helm template \ + --show-only templates/server-service.yaml \ + --set 'server.ha.enabled=true' \ + --set 'global.enabled=false' \ + . || echo "---") | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$( (helm template \ + --show-only templates/server-service.yaml \ + --set 'server.standalone.enabled=true' \ + --set 'global.enabled=false' \ + . || echo "---") | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + +@test "server/ServiceAccount: disable by injector.externalVaultAddr" { + cd `chart_dir` + local actual=$( (helm template \ + --show-only templates/server-service.yaml \ + --set 'server.dev.enabled=true' \ + --set 'injector.externalVaultAddr=http://vault-outside' \ + . || echo "---") | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$( (helm template \ + --show-only templates/server-service.yaml \ + --set 'server.ha.enabled=true' \ + --set 'injector.externalVaultAddr=http://vault-outside' \ + . || echo "---") | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$( (helm template \ + --show-only templates/server-service.yaml \ + --set 'server.standalone.enabled=true' \ + --set 'injector.externalVaultAddr=http://vault-outside' \ + . || echo "---") | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} diff --git a/test/unit/server-statefulset.bats b/test/unit/server-statefulset.bats index 059e1c4..1db272a 100755 --- a/test/unit/server-statefulset.bats +++ b/test/unit/server-statefulset.bats @@ -32,6 +32,17 @@ load _helpers [ "${actual}" = "false" ] } +@test "server/standalone-StatefulSet: disable with injector.externalVaultAddr" { + cd `chart_dir` + local actual=$( (helm template \ + --show-only templates/server-statefulset.yaml \ + --set 'injector.externalVaultAddr=http://vault-outside' \ + --set 'server.standalone.enabled=true' \ + . || echo "---") | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + @test "server/standalone-StatefulSet: image defaults to server.image.repository:tag" { cd `chart_dir` local actual=$(helm template \ diff --git a/test/unit/ui-service.bats b/test/unit/ui-service.bats index b0da7bf..59f1818 100755 --- a/test/unit/ui-service.bats +++ b/test/unit/ui-service.bats @@ -53,6 +53,33 @@ load _helpers [ "${actual}" = "false" ] } +@test "ui/Service: disable with injector.externalVaultAddr" { + cd `chart_dir` + local actual=$( (helm template \ + --show-only templates/ui-service.yaml \ + --set 'server.dev.enabled=true' \ + --set 'injector.externalVaultAddr=http://vault-outside' \ + . || echo "---") | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$( (helm template \ + --show-only templates/ui-service.yaml \ + --set 'server.ha.enabled=true' \ + --set 'injector.externalVaultAddr=http://vault-outside' \ + . || echo "---") | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$( (helm template \ + --show-only templates/ui-service.yaml \ + --set 'server.standalone.enabled=true' \ + --set 'injector.externalVaultAddr=http://vault-outside' \ + . || echo "---") | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] +} + @test "ui/Service: ClusterIP type by default" { cd `chart_dir` local actual=$(helm template \ diff --git a/values.yaml b/values.yaml index 5433026..a5437bf 100644 --- a/values.yaml +++ b/values.yaml @@ -15,6 +15,10 @@ injector: # True if you want to enable vault agent injection. enabled: true + # External vault server address for the injector to use. Setting this will + # disable deployment of a vault server along with the injector. + externalVaultAddr: "" + # image sets the repo and tag of the vault-k8s image to use for the injector. image: repository: "hashicorp/vault-k8s"