diff --git a/examples/app/templates/deployment.yaml b/examples/app/templates/deployment.yaml index 67d6f29..9a28ce9 100644 --- a/examples/app/templates/deployment.yaml +++ b/examples/app/templates/deployment.yaml @@ -87,8 +87,7 @@ spec: name: init-container resources: {} nodeSelector: {{- toYaml .Values.myapp.nodeSelector | nindent 8 }} - securityContext: - runAsNonRoot: true + securityContext: {{- toYaml .Values.myapp.podSecurityContext | nindent 8 }} terminationGracePeriodSeconds: 10 volumes: - configMap: diff --git a/examples/app/values.yaml b/examples/app/values.yaml index 6f23e91..8a19b2c 100644 --- a/examples/app/values.yaml +++ b/examples/app/values.yaml @@ -76,6 +76,10 @@ myapp: nodeSelector: region: east type: user-node + podSecurityContext: + fsGroup: 20000 + runAsNonRoot: true + runAsUser: 65532 proxySidecar: args: - --secure-listen-address=0.0.0.0:8443 diff --git a/examples/operator/templates/deployment.yaml b/examples/operator/templates/deployment.yaml index 7281fc3..a32a57b 100644 --- a/examples/operator/templates/deployment.yaml +++ b/examples/operator/templates/deployment.yaml @@ -87,8 +87,8 @@ spec: imagePullSecrets: - name: {{ include "operator.fullname" . }}-secret-registry-credentials nodeSelector: {{- toYaml .Values.controllerManager.nodeSelector | nindent 8 }} - securityContext: - runAsNonRoot: true + securityContext: {{- toYaml .Values.controllerManager.podSecurityContext | nindent + 8 }} serviceAccountName: {{ include "operator.fullname" . }}-controller-manager terminationGracePeriodSeconds: 10 topologySpreadConstraints: diff --git a/examples/operator/values.yaml b/examples/operator/values.yaml index ece5796..399c6e5 100644 --- a/examples/operator/values.yaml +++ b/examples/operator/values.yaml @@ -43,6 +43,8 @@ controllerManager: nodeSelector: region: east type: user-node + podSecurityContext: + runAsNonRoot: true replicas: 1 serviceAccount: annotations: diff --git a/pkg/processor/pod/pod.go b/pkg/processor/pod/pod.go index 09979ab..88adb82 100644 --- a/pkg/processor/pod/pod.go +++ b/pkg/processor/pod/pod.go @@ -60,6 +60,23 @@ func ProcessSpec(objName string, appMeta helmify.AppMetadata, spec corev1.PodSpe if err != nil { return nil, nil, err } + if spec.SecurityContext != nil { + securityContextMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&spec.SecurityContext) + if err != nil { + return nil, nil, err + } + if len(securityContextMap) > 0 { + err = unstructured.SetNestedField(specMap, fmt.Sprintf(`{{- toYaml .Values.%[1]s.podSecurityContext | nindent 8 }}`, objName), "securityContext") + if err != nil { + return nil, nil, err + } + + err = unstructured.SetNestedField(values, securityContextMap, objName, "podSecurityContext") + if err != nil { + return nil, nil, fmt.Errorf("%w: unable to set deployment value field", err) + } + } + } // process nodeSelector if presented: if spec.NodeSelector != nil { diff --git a/pkg/processor/pod/pod_test.go b/pkg/processor/pod/pod_test.go index c55b4fc..5a2fd72 100644 --- a/pkg/processor/pod/pod_test.go +++ b/pkg/processor/pod/pod_test.go @@ -110,6 +110,33 @@ spec: image: localhost:6001/my_project:latest ports: - containerPort: 80 +` + strDeploymentWithPodSecurityContext = ` +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nginx-deployment + labels: + app: nginx +spec: + replicas: 3 + selector: + matchLabels: + app: nginx + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginx + image: localhost:6001/my_project:latest + securityContext: + fsGroup: 20000 + runAsGroup: 30000 + runAsNonRoot: true + runAsUser: 65532 + ` ) @@ -274,5 +301,45 @@ func Test_pod_Process(t *testing.T) { }, }, tmpl) }) + t.Run("deployment with securityContext", func(t *testing.T) { + var deploy appsv1.Deployment + obj := internal.GenerateObj(strDeploymentWithPodSecurityContext) + err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &deploy) + specMap, tmpl, err := ProcessSpec("nginx", &metadata.Service{}, deploy.Spec.Template.Spec) + assert.NoError(t, err) + assert.Equal(t, map[string]interface{}{ + "containers": []interface{}{ + map[string]interface{}{ + "env": []interface{}{ + map[string]interface{}{ + "name": "KUBERNETES_CLUSTER_DOMAIN", + "value": "{{ quote .Values.kubernetesClusterDomain }}", + }, + }, + "image": "{{ .Values.nginx.nginx.image.repository }}:{{ .Values.nginx.nginx.image.tag | default .Chart.AppVersion }}", + "name": "nginx", + "resources": map[string]interface{}{}, + }, + }, + "securityContext": "{{- toYaml .Values.nginx.podSecurityContext | nindent 8 }}", + }, specMap) + + assert.Equal(t, helmify.Values{ + "nginx": map[string]interface{}{ + "podSecurityContext": map[string]interface{}{ + "fsGroup": int64(20000), + "runAsGroup": int64(30000), + "runAsNonRoot": true, + "runAsUser": int64(65532), + }, + "nginx": map[string]interface{}{ + "image": map[string]interface{}{ + "repository": "localhost:6001/my_project", + "tag": "latest", + }, + }, + }, + }, tmpl) + }) } diff --git a/test_data/sample-app.yaml b/test_data/sample-app.yaml index a80e04e..030c8a7 100644 --- a/test_data/sample-app.yaml +++ b/test_data/sample-app.yaml @@ -81,6 +81,8 @@ spec: name: https securityContext: runAsNonRoot: true + fsGroup: 20000 + runAsUser: 65532 nodeSelector: region: east type: user-node