k8s/helm-charts/dashy/charts/common/templates/lib/container/_securityContext.tpl
root 1eaf295724
Some checks failed
continuous-integration/drone/push Build is failing
new way of doin
2023-11-16 19:42:02 +10:00

182 lines
7.7 KiB
Smarty

{{/* Returns Container Security Context */}}
{{/* Call this template:
{{ include "tc.v1.common.lib.container.securityContext" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the chart.
objectData: The object data to be used to render the container.
*/}}
{{- define "tc.v1.common.lib.container.securityContext" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{/* Initialize from the "global" options */}}
{{- $secContext := fromJson (include "tc.v1.common.lib.container.securityContext.calculate" (dict "rootCtx" $rootCtx "objectData" $objectData)) }}
runAsNonRoot: {{ $secContext.runAsNonRoot }}
runAsUser: {{ $secContext.runAsUser }}
runAsGroup: {{ $secContext.runAsGroup }}
readOnlyRootFilesystem: {{ $secContext.readOnlyRootFilesystem }}
allowPrivilegeEscalation: {{ $secContext.allowPrivilegeEscalation }}
privileged: {{ $secContext.privileged }}
seccompProfile:
type: {{ $secContext.seccompProfile.type }}
{{- if eq $secContext.seccompProfile.type "Localhost" }}
localhostProfile: {{ $secContext.seccompProfile.profile }}
{{- end }}
capabilities:
{{- if $secContext.capabilities.add }}
add:
{{- range $secContext.capabilities.add }}
- {{ . }}
{{- end -}}
{{- else }}
add: []
{{- end -}}
{{- if $secContext.capabilities.drop }}
drop:
{{- range $secContext.capabilities.drop }}
- {{ . }}
{{- end -}}
{{- else }}
drop: []
{{- end -}}
{{- end -}}
{{/* Calculates Container Security Context */}}
{{/* Call this template:
{{ include "tc.v1.common.lib.container.securityContext.calculate" (dict "rootCtx" $ "objectData" $objectData) }}
rootCtx: The root context of the chart.
objectData: The object data to be used to render the container.
*/}}
{{- define "tc.v1.common.lib.container.securityContext.calculate" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $mustPrivileged := false -}}
{{- range $persistenceName, $persistenceValues := $rootCtx.Values.persistence -}}
{{- if $persistenceValues.enabled -}}
{{- if eq $persistenceValues.type "device" -}}
{{- $volume := (fromJson (include "tc.v1.common.lib.container.volumeMount.isSelected" (dict "persistenceName" $persistenceName "persistenceValues" $persistenceValues "objectData" $objectData "key" "persistence"))) -}}
{{- if $volume -}} {{/* If a volume is returned, it means that the container has an assigned device */}}
{{- $mustPrivileged = true -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- if not $rootCtx.Values.securityContext.container -}}
{{- fail "Container - Expected non-empty <.Values.securityContext.container>" -}}
{{- end -}}
{{/* Initialize from the "global" options */}}
{{- $secContext := mustDeepCopy $rootCtx.Values.securityContext.container -}}
{{/* Override with containers options */}}
{{- with $objectData.securityContext -}}
{{- $secContext = mustMergeOverwrite $secContext . -}}
{{- end -}}
{{/* Validations, as we might endup with null values after merge */}}
{{- range $key := (list "runAsUser" "runAsGroup") -}}
{{- $value := (get $secContext $key) -}}
{{- if not (mustHas (kindOf $value) (list "float64" "int" "int64")) -}}
{{- fail (printf "Container - Expected <securityContext.%s> to be [int], but got [%v] of type [%s]" $key $value (kindOf $value)) -}}
{{- end -}}
{{- end -}}
{{- if or (eq (int $secContext.runAsUser) 0) (eq (int $secContext.runAsGroup) 0) -}}
{{- $_ := set $secContext "runAsNonRoot" false -}}
{{- else -}}
{{- $_ := set $secContext "runAsNonRoot" true -}}
{{- end -}}
{{- if $secContext.privileged -}} {{/* When privileged is true, allowPrivilegeEscalation is required */}}
{{- $_ := set $secContext "allowPrivilegeEscalation" true -}}
{{- end -}}
{{- if $mustPrivileged -}}
{{- $_ := set $secContext "privileged" true -}}
{{- $_ := set $secContext "allowPrivilegeEscalation" true -}}
{{- $_ := set $secContext "runAsNonRoot" false -}}
{{- $_ := set $secContext "runAsUser" 0 -}}
{{- $_ := set $secContext "runAsGroup" 0 -}}
{{- end -}}
{{- range $key := (list "privileged" "allowPrivilegeEscalation" "runAsNonRoot" "readOnlyRootFilesystem") -}}
{{- $value := (get $secContext $key) -}}
{{- if not (kindIs "bool" $value) -}}
{{- fail (printf "Container - Expected <securityContext.%s> to be [bool], but got [%s] of type [%s]" $key $value (kindOf $value)) -}}
{{- end -}}
{{- end -}}
{{- if not $secContext.seccompProfile -}}
{{- fail "Container - Expected <securityContext.seccompProfile> to be defined" -}}
{{- end -}}
{{- $profiles := (list "RuntimeDefault" "Localhost" "Unconfined") -}}
{{- if not (mustHas $secContext.seccompProfile.type $profiles) -}}
{{- fail (printf "Container - Expected <securityContext.seccompProfile> to be one of [%s], but got [%s]" (join ", " $profiles) $secContext.seccompProfile.type) -}}
{{- end -}}
{{- if eq $secContext.seccompProfile.type "Localhost" -}}
{{- if not $secContext.seccompProfile.profile -}}
{{- fail "Container - Expected <securityContext.seccompProfile.profile> to be defined on type [Localhost]" -}}
{{- end -}}
{{- end -}}
{{- if not $secContext.capabilities -}}
{{- fail "Container - Expected <securityContext.capabilities> to be defined" -}}
{{- end -}}
{{- $tempObjectData := (dict "shortName" $objectData.podShortName "primary" $objectData.podPrimary) -}}
{{- $portRange := fromJson (include "tc.v1.common.lib.helpers.securityContext.getPortRange" (dict "rootCtx" $rootCtx "objectData" $tempObjectData)) -}}
{{- if and $portRange.low (le (int $portRange.low) 1024) -}} {{/* If a container wants to bind a port <= 1024 add NET_BIND_SERVICE */}}
{{- $addCap := $secContext.capabilities.add -}}
{{- if not (mustHas "NET_BIND_SERIVCE" $addCap) -}}
{{- $addCap = mustAppend $addCap "NET_BIND_SERVICE" -}}
{{- end -}}
{{- $_ := set $secContext.capabilities "add" $addCap -}}
{{- end -}}
{{/*
Most containers that run as root, is because it has to chown
files before switching to another user.
Lets add automatically the CHOWN cap.
*/}}
{{- if eq (int $secContext.runAsUser) 0 -}}
{{- if not (kindIs "bool" $secContext.capabilities.disableS6Caps) -}}
{{- fail (printf "Container - Expected <securityContext.capabilities.disableS6Caps> to be [bool], but got [%s] of type [%s]" $secContext.capabilities.disableS6Caps (kindOf $secContext.capabilities.disableS6Caps)) -}}
{{- end -}}
{{- $addCap := $secContext.capabilities.add -}}
{{- if not $secContext.capabilities.disableS6Caps -}}
{{- $addCap = mustAppend $addCap "CHOWN" -}}
{{- $addCap = mustAppend $addCap "SETUID" -}}
{{- $addCap = mustAppend $addCap "SETGID" -}}
{{- $addCap = mustAppend $addCap "FOWNER" -}}
{{- $addCap = mustAppend $addCap "DAC_OVERRIDE" -}}
{{- end -}}
{{- $_ := set $secContext.capabilities "add" $addCap -}}
{{- end -}}
{{- range $key := (list "add" "drop") -}}
{{- $item := (get $secContext.capabilities $key) -}}
{{- if not (kindIs "slice" $item) -}}
{{- fail (printf "Container - Expected <securityContext.capabilities.%s> to be [list], but got [%s]" $key (kindOf $item)) -}}
{{- end -}}
{{- range $item -}}
{{- if not (kindIs "string" .) -}}
{{- fail (printf "Container - Expected items of <securityContext.capabilities.%s> to be [string], but got [%s]" $key (kindOf .)) -}}
{{- end -}}
{{- end -}}
{{- if not (deepEqual (uniq $item) $item) -}}
{{- fail (printf "Container - Expected items of <securityContext.capabilities.%s> to be unique, but got [%s]" $key (join ", " $item)) -}}
{{- end -}}
{{- end -}}
{{- $secContext | toJson -}}
{{- end -}}