From c48f7444edb0795c045d259e03d9cff61a18fa67 Mon Sep 17 00:00:00 2001 From: Aakcht Date: Thu, 22 Jun 2023 19:45:58 +0300 Subject: [PATCH] Chart: Do not propagate global security context to statsd and redis (#31865) --- chart/templates/_helpers.yaml | 23 +++++++++++ chart/templates/redis/redis-statefulset.yaml | 2 +- chart/templates/statsd/statsd-deployment.yaml | 2 +- chart/values.schema.json | 6 +-- chart/values.yaml | 1 - .../charts/security/test_security_context.py | 40 +++++++++++++++++++ 6 files changed, 68 insertions(+), 6 deletions(-) diff --git a/chart/templates/_helpers.yaml b/chart/templates/_helpers.yaml index 0a707c4184a49..651dfa6914b57 100644 --- a/chart/templates/_helpers.yaml +++ b/chart/templates/_helpers.yaml @@ -864,6 +864,29 @@ capabilities: {{- end -}} {{- end -}} + {{/* + Set the default value for external container securityContext(redis and statsd). + If no value is passed for .securityContexts.container, defaults to deny privileges escallation and dropping all POSIX capabilities. + + +-----------------------------------+ +-----------------------------------------------------------+ + | .securityContexts.container | -> | allowPrivilegesEscalation: false, capabilities.drop: [ALL]| + +-----------------------------------+ +-----------------------------------------------------------+ + + + The template can be called like so: + include "externalContainerSecurityContext" .Values.statsd + */}} +{{- define "externalContainerSecurityContext" -}} + {{- if .securityContexts.container -}} + {{ toYaml .securityContexts.container | print }} + {{- else -}} +allowPrivilegeEscalation: false +capabilities: + drop: + - ALL + {{- end -}} +{{- end -}} + {{- define "container_extra_envs" -}} {{- $ := index . 0 -}} {{- $env := index . 1 -}} diff --git a/chart/templates/redis/redis-statefulset.yaml b/chart/templates/redis/redis-statefulset.yaml index 7b7866b8e386c..ec544cc6f23c8 100644 --- a/chart/templates/redis/redis-statefulset.yaml +++ b/chart/templates/redis/redis-statefulset.yaml @@ -26,7 +26,7 @@ {{- $tolerations := or .Values.redis.tolerations .Values.tolerations }} {{- $topologySpreadConstraints := or .Values.redis.topologySpreadConstraints .Values.topologySpreadConstraints }} {{- $securityContext := include "localPodSecurityContext" .Values.redis }} -{{- $containerSecurityContext := include "containerSecurityContext" (list . .Values.redis) }} +{{- $containerSecurityContext := include "externalContainerSecurityContext" .Values.redis }} apiVersion: apps/v1 kind: StatefulSet metadata: diff --git a/chart/templates/statsd/statsd-deployment.yaml b/chart/templates/statsd/statsd-deployment.yaml index 28c89e4caafc8..06f034506c4f6 100644 --- a/chart/templates/statsd/statsd-deployment.yaml +++ b/chart/templates/statsd/statsd-deployment.yaml @@ -27,7 +27,7 @@ {{- $topologySpreadConstraints := or .Values.statsd.topologySpreadConstraints .Values.topologySpreadConstraints }} {{- $revisionHistoryLimit := or .Values.statsd.revisionHistoryLimit .Values.revisionHistoryLimit }} {{- $securityContext := include "localPodSecurityContext" .Values.statsd }} -{{- $containerSecurityContext := include "containerSecurityContext" (list . .Values.statsd) }} +{{- $containerSecurityContext := include "externalContainerSecurityContext" .Values.statsd }} apiVersion: apps/v1 kind: Deployment metadata: diff --git a/chart/values.schema.json b/chart/values.schema.json index 65c0cc80cccc9..395506701bec0 100644 --- a/chart/values.schema.json +++ b/chart/values.schema.json @@ -4790,7 +4790,7 @@ "default": [] }, "securityContext": { - "description": "Security context for the StatsD pod (deprecated, use `securityContexts` instead). If not set, the values from `securityContext` will be used.", + "description": "Security context for the StatsD pod (deprecated, use `securityContexts` instead).", "type": "object", "$ref": "#/definitions/io.k8s.api.core.v1.PodSecurityContext", "default": {}, @@ -4803,7 +4803,7 @@ ] }, "securityContexts": { - "description": "Security context definition for the statsd. If not set, the values from global `securityContexts` will be used.", + "description": "Security context definition for the statsd.", "type": "object", "x-docsSection": "Kubernetes", "properties": { @@ -5517,7 +5517,7 @@ ] }, "securityContexts": { - "description": "Security context definition for the redis. If not set, the values from global `securityContexts` will be used.", + "description": "Security context definition for the redis.", "type": "object", "x-docsSection": "Kubernetes", "properties": { diff --git a/chart/values.yaml b/chart/values.yaml index c6ea8e637967d..b1879f0d44663 100644 --- a/chart/values.yaml +++ b/chart/values.yaml @@ -1629,7 +1629,6 @@ statsd: uid: 65534 # When not set, `statsd.uid` will be used - # When not set, the values defined in the global securityContext will be used # (deprecated, use `securityContexts` instead) securityContext: {} # runAsUser: 65534 diff --git a/tests/charts/security/test_security_context.py b/tests/charts/security/test_security_context.py index 4fa52ea34b03f..66c06023d22b9 100644 --- a/tests/charts/security/test_security_context.py +++ b/tests/charts/security/test_security_context.py @@ -210,6 +210,46 @@ def test_gitsync_sidecar_and_init_container(self): docs[index], ) + # Test securityContexts for main containers + def test_global_security_context(self): + ctx_value_pod = {"runAsUser": 7000} + ctx_value_container = {"allowPrivilegeEscalation": False} + docs = render_chart( + values={"securityContexts": {"containers": ctx_value_container, "pod": ctx_value_pod}}, + show_only=[ + "templates/flower/flower-deployment.yaml", + "templates/scheduler/scheduler-deployment.yaml", + "templates/webserver/webserver-deployment.yaml", + "templates/workers/worker-deployment.yaml", + "templates/jobs/create-user-job.yaml", + "templates/jobs/migrate-database-job.yaml", + "templates/triggerer/triggerer-deployment.yaml", + "templates/statsd/statsd-deployment.yaml", + "templates/redis/redis-statefulset.yaml", + ], + ) + + for index in range(len(docs) - 2): + assert ctx_value_container == jmespath.search( + "spec.template.spec.containers[0].securityContext", docs[index] + ) + assert ctx_value_pod == jmespath.search("spec.template.spec.securityContext", docs[index]) + + # Global security context is not propagated to redis and statsd, so we test default value + default_ctx_value_container = {"allowPrivilegeEscalation": False, "capabilities": {"drop": ["ALL"]}} + default_ctx_value_pod_statsd = {"runAsUser": 65534} + default_ctx_value_pod_redis = {"runAsUser": 0} + for index in range(len(docs) - 2, len(docs)): + assert default_ctx_value_container == jmespath.search( + "spec.template.spec.containers[0].securityContext", docs[index] + ) + assert default_ctx_value_pod_statsd == jmespath.search( + "spec.template.spec.securityContext", docs[len(docs) - 2] + ) + assert default_ctx_value_pod_redis == jmespath.search( + "spec.template.spec.securityContext", docs[len(docs) - 1] + ) + # Test securityContexts for main containers def test_main_container_setting(self): ctx_value = {"allowPrivilegeEscalation": False}