Skip to content

Commit

Permalink
csi/server.statefulset: custom security context (hashicorp#767)
Browse files Browse the repository at this point in the history
csi/server.statefulset: custom security context

This adds flexibility to have custom pod template and container
`securityContext` and preserves current default values and behavior.

Fixes hashicorp#663.

This also is a way to address hashicorp#599
so that people can specify, for example, the CSI to run in a privileged
container for OpenShift.

This is a follow-up to hashicorp#750
and builds on the same principles.

Side note: I am not able to run `helm schema-gen` since it is
unmaintained and does not work with M1 Macs.
  • Loading branch information
swenson authored Aug 8, 2022
1 parent 8bc1604 commit 9efd98a
Show file tree
Hide file tree
Showing 10 changed files with 341 additions and 37 deletions.
5 changes: 3 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ CHANGES:
* Start testing against Kubernetes 1.24. [GH-744](https://github.com/hashicorp/vault-helm/pull/744)
* Deprecated `injector.externalVaultAddr`. Added `global.externalVaultAddr`, which applies to both the Injector and the CSI Provider. [GH-745](https://github.com/hashicorp/vault-helm/pull/745)
* CSI Provider pods now set the `VAULT_ADDR` environment variable to either the internal Vault service or the configured external address. [GH-745](https://github.com/hashicorp/vault-helm/pull/745)
* Deprecated `injector.uid` and `injector.gid`. Replaced with `injector.securityContext.pod`. [GH-750](https://github.com/hashicorp/vault-helm/pull/750)

Features:
* server: Add `server.statefulSet.securityContext` to override pod and container `securityContext`. [GH-767](https://github.com/hashicorp/vault-helm/pull/767)
* csi: Add `csi.daemonSet.securityContext` to override pod and container `securityContext`. [GH-767](https://github.com/hashicorp/vault-helm/pull/767)
* injector: Add `injector.securityContext` to override pod and container `securityContext`. [GH-750](https://github.com/hashicorp/vault-helm/pull/750) and [GH-767](https://github.com/hashicorp/vault-helm/pull/767)
* Add `server.service.activeNodePort` and `server.service.standbyNodePort` to specify the `nodePort` for active and standby services. [GH-610](https://github.com/hashicorp/vault-helm/pull/610)
* Support for setting annotations on the injector's serviceAccount [GH-753](https://github.com/hashicorp/vault-helm/pull/753)
* injector: Support setting both pod and container securityContext [GH-750](https://github.com/hashicorp/vault-helm/pull/750)

## 0.20.1 (May 25th, 2022)
CHANGES:
Expand Down
100 changes: 94 additions & 6 deletions templates/_helpers.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -474,14 +474,20 @@ Sets extra injector service annotations
securityContext for the injector pod level.
*/}}
{{- define "injector.securityContext.pod" -}}
{{- if or (.Values.injector.uid) (.Values.injector.gid) }}
{{- if .Values.injector.securityContext.pod }}
securityContext:
{{- $tp := typeOf .Values.injector.securityContext.pod }}
{{- if eq $tp "string" }}
{{- tpl .Values.injector.securityContext.pod . | nindent 8 }}
{{- else }}
{{- toYaml .Values.injector.securityContext.pod | nindent 8 }}
{{- end }}
{{- else if not .Values.global.openshift }}
securityContext:
runAsNonRoot: true
runAsGroup: {{ .Values.injector.gid | default 1000 }}
runAsUser: {{ .Values.injector.uid | default 100 }}
{{- else if .Values.injector.securityContext.pod }}
securityContext:
{{- toYaml .Values.injector.securityContext.pod | nindent 8 }}
fsGroup: {{ .Values.injector.gid | default 1000 }}
{{- end }}
{{- end -}}

Expand All @@ -491,9 +497,60 @@ securityContext for the injector container level.
{{- define "injector.securityContext.container" -}}
{{- if .Values.injector.securityContext.container}}
securityContext:
{{- toYaml .Values.injector.securityContext.container | nindent 12 }}
{{- $tp := typeOf .Values.injector.securityContext.container }}
{{- if eq $tp "string" }}
{{- tpl .Values.injector.securityContext.container . | nindent 12 }}
{{- else }}
{{- toYaml .Values.injector.securityContext.container | nindent 12 }}
{{- end }}
{{- else if not .Values.global.openshift }}
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
{{- end }}
{{- end -}}
{{- end -}}

{{/*
securityContext for the statefulset pod template.
*/}}
{{- define "server.statefulSet.securityContext.pod" -}}
{{- if .Values.server.statefulSet.securityContext.pod }}
securityContext:
{{- $tp := typeOf .Values.server.statefulSet.securityContext.pod }}
{{- if eq $tp "string" }}
{{- tpl .Values.server.statefulSet.securityContext.pod . | nindent 8 }}
{{- else }}
{{- toYaml .Values.server.statefulSet.securityContext.pod | nindent 8 }}
{{- end }}
{{- else if not .Values.global.openshift }}
securityContext:
runAsNonRoot: true
runAsGroup: {{ .Values.server.gid | default 1000 }}
runAsUser: {{ .Values.server.uid | default 100 }}
fsGroup: {{ .Values.server.gid | default 1000 }}
{{- end }}
{{- end -}}

{{/*
securityContext for the statefulset vault container
*/}}
{{- define "server.statefulSet.securityContext.container" -}}
{{- if .Values.server.statefulSet.securityContext.container }}
securityContext:
{{- $tp := typeOf .Values.server.statefulSet.securityContext.container }}
{{- if eq $tp "string" }}
{{- tpl .Values.server.statefulSet.securityContext.container . | nindent 12 }}
{{- else }}
{{- toYaml .Values.server.statefulSet.securityContext.container | nindent 12 }}
{{- end }}
{{- else if not .Values.global.openshift }}
securityContext:
allowPrivilegeEscalation: false
{{- end }}
{{- end -}}


{{/*
Sets extra injector service account annotations
Expand Down Expand Up @@ -731,6 +788,37 @@ Sets extra CSI daemonset annotations
{{- end }}
{{- end -}}

{{/*
Sets CSI daemonset securityContext for pod template
*/}}
{{- define "csi.daemonSet.securityContext.pod" -}}
{{- if .Values.csi.daemonSet.securityContext.pod }}
securityContext:
{{- $tp := typeOf .Values.csi.daemonSet.securityContext.pod }}
{{- if eq $tp "string" }}
{{- tpl .Values.csi.daemonSet.securityContext.pod . | nindent 8 }}
{{- else }}
{{- toYaml .Values.csi.daemonSet.securityContext.pod | nindent 8 }}
{{- end }}
{{- end }}
{{- end -}}

{{/*
Sets CSI daemonset securityContext for container
*/}}
{{- define "csi.daemonSet.securityContext.container" -}}
{{- if .Values.csi.daemonSet.securityContext.container }}
securityContext:
{{- $tp := typeOf .Values.csi.daemonSet.securityContext.container }}
{{- if eq $tp "string" }}
{{- tpl .Values.csi.daemonSet.securityContext.container . | nindent 12 }}
{{- else }}
{{- toYaml .Values.csi.daemonSet.securityContext.container | nindent 12 }}
{{- end }}
{{- end }}
{{- end -}}


{{/*
Sets the injector toleration for pod placement
*/}}
Expand Down
2 changes: 2 additions & 0 deletions templates/csi-daemonset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ spec:
{{- end -}}
{{ template "csi.pod.annotations" . }}
spec:
{{ template "csi.daemonSet.securityContext.pod" . }}
{{- if .Values.csi.priorityClassName }}
priorityClassName: {{ .Values.csi.priorityClassName }}
{{- end }}
Expand All @@ -42,6 +43,7 @@ spec:
containers:
- name: {{ include "vault.name" . }}-csi-provider
{{ template "csi.resources" . }}
{{ template "csi.daemonSet.securityContext.container" . }}
image: "{{ .Values.csi.image.repository }}:{{ .Values.csi.image.tag }}"
imagePullPolicy: {{ .Values.csi.image.pullPolicy }}
args:
Expand Down
6 changes: 2 additions & 4 deletions templates/injector-deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,16 @@ spec:
priorityClassName: {{ .Values.injector.priorityClassName }}
{{- end }}
serviceAccountName: "{{ template "vault.fullname" . }}-agent-injector"
{{ template "injector.securityContext.pod" . -}}
{{- if not .Values.global.openshift }}
hostNetwork: {{ .Values.injector.hostNetwork }}
{{ template "injector.securityContext.pod" . -}}
{{- end }}
containers:
- name: sidecar-injector
{{ template "injector.resources" . }}
image: "{{ .Values.injector.image.repository }}:{{ .Values.injector.image.tag }}"
imagePullPolicy: "{{ .Values.injector.image.pullPolicy }}"
{{- if not .Values.global.openshift }}
{{ template "injector.securityContext.container" . -}}
{{- end }}
{{- template "injector.securityContext.container" . }}
env:
- name: AGENT_INJECT_LISTEN
value: {{ printf ":%v" .Values.injector.port }}
Expand Down
13 changes: 2 additions & 11 deletions templates/server-statefulset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,7 @@ spec:
{{ if .Values.server.shareProcessNamespace }}
shareProcessNamespace: true
{{ end }}
{{- if not .Values.global.openshift }}
securityContext:
runAsNonRoot: true
runAsGroup: {{ .Values.server.gid | default 1000 }}
runAsUser: {{ .Values.server.uid | default 100 }}
fsGroup: {{ .Values.server.gid | default 1000 }}
{{- end }}
{{- template "server.statefulSet.securityContext.pod" . }}
volumes:
{{ template "vault.volumes" . }}
- name: home
Expand All @@ -72,10 +66,7 @@ spec:
- "/bin/sh"
- "-ec"
args: {{ template "vault.args" . }}
{{- if not .Values.global.openshift }}
securityContext:
allowPrivilegeEscalation: false
{{- end }}
{{- template "server.statefulSet.securityContext.container" . }}
env:
- name: HOST_IP
valueFrom:
Expand Down
56 changes: 56 additions & 0 deletions test/unit/csi-daemonset.bats
Original file line number Diff line number Diff line change
Expand Up @@ -592,3 +592,59 @@ load _helpers
yq -r 'map(select(.name=="VAULT_ADDR")) | .[] .value' | tee /dev/stderr)
[ "${value}" = "http://vault-outside" ]
}

#--------------------------------------------------------------------
# securityContext

@test "csi/daemonset: default csi.daemonSet.securityContext.pod" {
cd `chart_dir`
local actual=$(helm template \
--show-only templates/csi-daemonset.yaml \
--set 'csi.enabled=true' \
. | tee /dev/stderr |
yq -r '.spec.template.spec.securityContext' | tee /dev/stderr)
[ "${actual}" = "null" ]
}

@test "csi/daemonset: default csi.daemonSet.securityContext.container" {
cd `chart_dir`
local actual=$(helm template \
--show-only templates/csi-daemonset.yaml \
--set 'csi.enabled=true' \
. | tee /dev/stderr |
yq -r '.spec.template.spec.containers[0].securityContext' | tee /dev/stderr)
[ "${actual}" = "null" ]
}

@test "csi/daemonset: specify csi.daemonSet.securityContext.pod yaml" {
cd `chart_dir`
local actual=$(helm template \
--show-only templates/csi-daemonset.yaml \
--set 'csi.enabled=true' \
--set 'csi.daemonSet.securityContext.pod.foo=bar' \
. | tee /dev/stderr |
yq -r '.spec.template.spec.securityContext.foo' | tee /dev/stderr)
[ "${actual}" = "bar" ]
}

@test "csi/daemonset: specify csi.daemonSet.securityContext.container yaml" {
cd `chart_dir`
local actual=$(helm template \
--show-only templates/csi-daemonset.yaml \
--set 'csi.enabled=true' \
--set 'csi.daemonSet.securityContext.container.foo=bar' \
. | tee /dev/stderr |
yq -r '.spec.template.spec.containers[0].securityContext.foo' | tee /dev/stderr)
[ "${actual}" = "bar" ]
}

@test "csi/daemonset: specify csi.daemonSet.securityContext.container yaml string" {
cd `chart_dir`
local actual=$(helm template \
--show-only templates/csi-daemonset.yaml \
--set 'csi.enabled=true' \
--set 'csi.daemonSet.securityContext.container=foo: bar' \
. | tee /dev/stderr |
yq -r '.spec.template.spec.containers[0].securityContext.foo' | tee /dev/stderr)
[ "${actual}" = "bar" ]
}
45 changes: 44 additions & 1 deletion test/unit/injector-deployment.bats
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ load _helpers
}

#--------------------------------------------------------------------
# securityContext or pod and container
# securityContext for pod and container

# for backward compatibility
@test "injector/deployment: backward pod securityContext" {
Expand Down Expand Up @@ -445,6 +445,49 @@ load _helpers
[ "${actual}" = "1001" ]
}

@test "injector/deployment: custom pod securityContext from string" {
cd `chart_dir`
local multi=$(cat <<EOF
foo: bar
bar: foo
EOF
)
local actual=$(helm template \
--show-only templates/injector-deployment.yaml \
--set 'injector.enabled=true' \
--set "injector.securityContext.pod=$multi" \
. | tee /dev/stderr |
yq -r '.spec.template.spec.securityContext.bar' | tee /dev/stderr)
[ "${actual}" = "foo" ]
}

@test "injector/deployment: custom container securityContext" {
cd `chart_dir`
local actual=$(helm template \
--show-only templates/injector-deployment.yaml \
--set 'injector.enabled=true' \
--set "injector.securityContext.container.bar=foo" \
. | tee /dev/stderr |
yq -r '.spec.template.spec.containers[0].securityContext.bar' | tee /dev/stderr)
[ "${actual}" = "foo" ]
}

@test "injector/deployment: custom container securityContext from string" {
cd `chart_dir`
local multi=$(cat <<EOF
foo: bar
bar: foo
EOF
)
local actual=$(helm template \
--show-only templates/injector-deployment.yaml \
--set 'injector.enabled=true' \
--set "injector.securityContext.container=$multi" \
. | tee /dev/stderr |
yq -r '.spec.template.spec.containers[0].securityContext.bar' | tee /dev/stderr)
[ "${actual}" = "foo" ]
}

@test "injector/deployment: default container securityContext sidecar-injector" {
cd `chart_dir`
local actual=$(helm template \
Expand Down
61 changes: 61 additions & 0 deletions test/unit/server-statefulset.bats
Original file line number Diff line number Diff line change
Expand Up @@ -1723,3 +1723,64 @@ load _helpers
yq -r -c '.spec.template.spec.containers[0].env[] | select(.name == "VAULT_LICENSE_PATH")' | tee /dev/stderr)
[ "${actual}" = '' ]
}

#--------------------------------------------------------------------
# securityContext

@test "server/standalone-StatefulSet: default statefulSet.securityContext.pod" {
cd `chart_dir`
local actual=$(helm template \
--show-only templates/server-statefulset.yaml \
. | tee /dev/stderr |
yq -r '.spec.template.spec.securityContext' | tee /dev/stderr)
[ ! "${actual}" = "null" ]
}

@test "server/standalone-StatefulSet: default statefulSet.securityContext.container" {
cd `chart_dir`
local actual=$(helm template \
--show-only templates/server-statefulset.yaml \
. | tee /dev/stderr |
yq -r '.spec.template.spec.containers[0].securityContext' | tee /dev/stderr)
[ ! "${actual}" = "null" ]
}

@test "server/standalone-StatefulSet: specify statefulSet.securityContext.pod yaml" {
cd `chart_dir`
local actual=$(helm template \
--show-only templates/server-statefulset.yaml \
--set 'server.statefulSet.securityContext.pod.foo=bar' \
. | tee /dev/stderr |
yq -r '.spec.template.spec.securityContext.foo' | tee /dev/stderr)
[ "${actual}" = "bar" ]
}

@test "server/standalone-StatefulSet: specify statefulSet.securityContext.container yaml" {
cd `chart_dir`
local actual=$(helm template \
--show-only templates/server-statefulset.yaml \
--set 'server.statefulSet.securityContext.container.foo=bar' \
. | tee /dev/stderr |
yq -r '.spec.template.spec.containers[0].securityContext.foo' | tee /dev/stderr)
[ "${actual}" = "bar" ]
}

@test "server/standalone-StatefulSet: specify statefulSet.securityContext.pod yaml string" {
cd `chart_dir`
local actual=$(helm template \
--show-only templates/server-statefulset.yaml \
--set 'server.statefulSet.securityContext.pod=foo: bar' \
. | tee /dev/stderr |
yq -r '.spec.template.spec.securityContext.foo' | tee /dev/stderr)
[ "${actual}" = "bar" ]
}

@test "server/standalone-StatefulSet: specify statefulSet.securityContext.container yaml string" {
cd `chart_dir`
local actual=$(helm template \
--show-only templates/server-statefulset.yaml \
--set 'server.statefulSet.securityContext.container=foo: bar' \
. | tee /dev/stderr |
yq -r '.spec.template.spec.containers[0].securityContext.foo' | tee /dev/stderr)
[ "${actual}" = "bar" ]
}
Loading

0 comments on commit 9efd98a

Please sign in to comment.