diff --git a/internal/templating/services/templates_cronjob.go b/internal/templating/services/templates_cronjob.go index 2f5a9827..4f941b8f 100644 --- a/internal/templating/services/templates_cronjob.go +++ b/internal/templating/services/templates_cronjob.go @@ -205,6 +205,16 @@ func GenerateCronjobTemplate( FSGroup: helpers.Int64Ptr(buildValues.PodSecurityContext.FsGroup), } } + if buildValues.PodSecurityContext.OnRootMismatch { + fsGroupChangePolicy := corev1.FSGroupChangeOnRootMismatch + if cronjob.Spec.JobTemplate.Spec.Template.Spec.SecurityContext != nil { + cronjob.Spec.JobTemplate.Spec.Template.Spec.SecurityContext.FSGroupChangePolicy = &fsGroupChangePolicy + } else { + cronjob.Spec.JobTemplate.Spec.Template.Spec.SecurityContext = &corev1.PodSecurityContext{ + FSGroupChangePolicy: &fsGroupChangePolicy, + } + } + } // start set up any volumes this cronjob can use // first handle any dynamic secret volumes that come from kubernetes secrets that are labeled diff --git a/internal/templating/services/templates_cronjob_test.go b/internal/templating/services/templates_cronjob_test.go index 1abc686c..43ed203e 100644 --- a/internal/templating/services/templates_cronjob_test.go +++ b/internal/templating/services/templates_cronjob_test.go @@ -81,6 +81,72 @@ func TestGenerateCronjobTemplate(t *testing.T) { }, want: "test-resources/cronjob/result-cli-1.yaml", }, + { + name: "test2 - cli - security context", + args: args{ + buildValues: generator.BuildValues{ + Project: "example-project", + Environment: "environment-name", + EnvironmentType: "production", + Namespace: "myexample-project-environment-name", + BuildType: "branch", + LagoonVersion: "v2.x.x", + Kubernetes: "generator.local", + Branch: "environment-name", + ImageReferences: map[string]string{ + "myservice": "harbor.example.com/example-project/environment-name/myservice@latest", + "myservice-persist": "harbor.example.com/example-project/environment-name/myservice-persistent@latest", + }, + GitSHA: "0", + ConfigMapSha: "32bf1359ac92178c8909f0ef938257b477708aa0d78a5a15ad7c2d7919adf273", + PodSecurityContext: generator.PodSecurityContext{ + RunAsGroup: 0, + RunAsUser: 10000, + FsGroup: 10001, + OnRootMismatch: true, + }, + Services: []generator.ServiceValues{ + { + Name: "myservice", + OverrideName: "myservice", + Type: "cli", + DBaaSEnvironment: "production", + NativeCronjobs: []lagoon.Cronjob{ + { + Name: "cronjob-myservice-my-cronjobbb", + Service: "myservice", + Command: "sleep 300", + Schedule: "5 2 * * *", + }, + { + Name: "cronjob-myservice-my-other-cronjobbb", + Service: "myservice", + Command: "env", + Schedule: "25 6 * * *", + }, + }, + }, + { + Name: "myservice-persist", + OverrideName: "myservice-persist", + Type: "cli-persistent", + DBaaSEnvironment: "production", + PersistentVolumePath: "/storage/data", + PersistentVolumeName: "nginx-php", + NativeCronjobs: []lagoon.Cronjob{ + { + Name: "cronjob-myservice-my-cronjobbb", + Service: "myservice", + Command: "sleep 300", + Schedule: "5 2 * * *", + }, + }, + }, + }, + }, + }, + want: "test-resources/cronjob/result-cli-2.yaml", + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/internal/templating/services/test-resources/cronjob/result-cli-2.yaml b/internal/templating/services/test-resources/cronjob/result-cli-2.yaml new file mode 100644 index 00000000..92395636 --- /dev/null +++ b/internal/templating/services/test-resources/cronjob/result-cli-2.yaml @@ -0,0 +1,282 @@ +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + annotations: + lagoon.sh/branch: environment-name + lagoon.sh/version: v2.x.x + creationTimestamp: null + labels: + app.kubernetes.io/managed-by: build-deploy-tool + lagoon.sh/buildType: branch + lagoon.sh/environment: environment-name + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + lagoon.sh/service: myservice + lagoon.sh/service-type: cli + lagoon.sh/template: cli-0.1.0 + name: cronjob-myservice-my-cronjobbb +spec: + concurrencyPolicy: Forbid + failedJobsHistoryLimit: 1 + jobTemplate: + metadata: + creationTimestamp: null + spec: + template: + metadata: + annotations: + lagoon.sh/branch: environment-name + lagoon.sh/configMapSha: 32bf1359ac92178c8909f0ef938257b477708aa0d78a5a15ad7c2d7919adf273 + lagoon.sh/version: v2.x.x + creationTimestamp: null + labels: + app.kubernetes.io/managed-by: build-deploy-tool + lagoon.sh/buildType: branch + lagoon.sh/environment: environment-name + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + lagoon.sh/service: myservice + lagoon.sh/service-type: cli + lagoon.sh/template: cli-0.1.0 + spec: + containers: + - command: + - /lagoon/cronjob.sh + - sleep 300 + env: + - name: LAGOON_GIT_SHA + value: "0" + - name: SERVICE_NAME + value: myservice + envFrom: + - configMapRef: + name: lagoon-env + image: harbor.example.com/example-project/environment-name/myservice@latest + imagePullPolicy: Always + name: cronjob-myservice-my-cronjobbb + resources: + requests: + cpu: 10m + memory: 10Mi + securityContext: {} + volumeMounts: + - mountPath: /var/run/secrets/lagoon/sshkey/ + name: lagoon-sshkey + readOnly: true + dnsConfig: + options: + - name: timeout + value: "60" + - name: attempts + value: "10" + enableServiceLinks: false + imagePullSecrets: + - name: lagoon-internal-registry-secret + priorityClassName: lagoon-priority-production + restartPolicy: Never + securityContext: + fsGroup: 10001 + fsGroupChangePolicy: OnRootMismatch + runAsGroup: 0 + runAsUser: 10000 + volumes: + - name: lagoon-sshkey + secret: + defaultMode: 420 + secretName: lagoon-sshkey + schedule: 5 2 * * * + startingDeadlineSeconds: 240 + successfulJobsHistoryLimit: 0 +status: {} +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + annotations: + lagoon.sh/branch: environment-name + lagoon.sh/version: v2.x.x + creationTimestamp: null + labels: + app.kubernetes.io/managed-by: build-deploy-tool + lagoon.sh/buildType: branch + lagoon.sh/environment: environment-name + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + lagoon.sh/service: myservice + lagoon.sh/service-type: cli + lagoon.sh/template: cli-0.1.0 + name: cronjob-myservice-my-other-cronjobbb +spec: + concurrencyPolicy: Forbid + failedJobsHistoryLimit: 1 + jobTemplate: + metadata: + creationTimestamp: null + spec: + template: + metadata: + annotations: + lagoon.sh/branch: environment-name + lagoon.sh/configMapSha: 32bf1359ac92178c8909f0ef938257b477708aa0d78a5a15ad7c2d7919adf273 + lagoon.sh/version: v2.x.x + creationTimestamp: null + labels: + app.kubernetes.io/managed-by: build-deploy-tool + lagoon.sh/buildType: branch + lagoon.sh/environment: environment-name + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + lagoon.sh/service: myservice + lagoon.sh/service-type: cli + lagoon.sh/template: cli-0.1.0 + spec: + containers: + - command: + - /lagoon/cronjob.sh + - env + env: + - name: LAGOON_GIT_SHA + value: "0" + - name: SERVICE_NAME + value: myservice + envFrom: + - configMapRef: + name: lagoon-env + image: harbor.example.com/example-project/environment-name/myservice@latest + imagePullPolicy: Always + name: cronjob-myservice-my-other-cronjobbb + resources: + requests: + cpu: 10m + memory: 10Mi + securityContext: {} + volumeMounts: + - mountPath: /var/run/secrets/lagoon/sshkey/ + name: lagoon-sshkey + readOnly: true + dnsConfig: + options: + - name: timeout + value: "60" + - name: attempts + value: "10" + enableServiceLinks: false + imagePullSecrets: + - name: lagoon-internal-registry-secret + priorityClassName: lagoon-priority-production + restartPolicy: Never + securityContext: + fsGroup: 10001 + fsGroupChangePolicy: OnRootMismatch + runAsGroup: 0 + runAsUser: 10000 + volumes: + - name: lagoon-sshkey + secret: + defaultMode: 420 + secretName: lagoon-sshkey + schedule: 25 6 * * * + startingDeadlineSeconds: 240 + successfulJobsHistoryLimit: 0 +status: {} +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + annotations: + lagoon.sh/branch: environment-name + lagoon.sh/version: v2.x.x + creationTimestamp: null + labels: + app.kubernetes.io/managed-by: build-deploy-tool + lagoon.sh/buildType: branch + lagoon.sh/environment: environment-name + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + lagoon.sh/service: myservice-persist + lagoon.sh/service-type: cli-persistent + lagoon.sh/template: cli-persistent-0.1.0 + name: cronjob-myservice-my-cronjobbb +spec: + concurrencyPolicy: Forbid + failedJobsHistoryLimit: 1 + jobTemplate: + metadata: + creationTimestamp: null + spec: + template: + metadata: + annotations: + lagoon.sh/branch: environment-name + lagoon.sh/configMapSha: 32bf1359ac92178c8909f0ef938257b477708aa0d78a5a15ad7c2d7919adf273 + lagoon.sh/version: v2.x.x + creationTimestamp: null + labels: + app.kubernetes.io/managed-by: build-deploy-tool + lagoon.sh/buildType: branch + lagoon.sh/environment: environment-name + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + lagoon.sh/service: myservice-persist + lagoon.sh/service-type: cli-persistent + lagoon.sh/template: cli-persistent-0.1.0 + spec: + containers: + - command: + - /lagoon/cronjob.sh + - sleep 300 + env: + - name: LAGOON_GIT_SHA + value: "0" + - name: SERVICE_NAME + value: myservice-persist + envFrom: + - configMapRef: + name: lagoon-env + image: harbor.example.com/example-project/environment-name/myservice-persistent@latest + imagePullPolicy: Always + name: cronjob-myservice-my-cronjobbb + resources: + requests: + cpu: 10m + memory: 10Mi + securityContext: {} + volumeMounts: + - mountPath: /var/run/secrets/lagoon/sshkey/ + name: lagoon-sshkey + readOnly: true + - mountPath: /storage/data/php + name: nginx-php-twig + - mountPath: /storage/data + name: nginx-php + dnsConfig: + options: + - name: timeout + value: "60" + - name: attempts + value: "10" + enableServiceLinks: false + imagePullSecrets: + - name: lagoon-internal-registry-secret + priorityClassName: lagoon-priority-production + restartPolicy: Never + securityContext: + fsGroup: 10001 + fsGroupChangePolicy: OnRootMismatch + runAsGroup: 0 + runAsUser: 10000 + volumes: + - name: lagoon-sshkey + secret: + defaultMode: 420 + secretName: lagoon-sshkey + - emptyDir: {} + name: nginx-php-twig + - name: nginx-php + persistentVolumeClaim: + claimName: nginx-php + schedule: 5 2 * * * + startingDeadlineSeconds: 240 + successfulJobsHistoryLimit: 0 +status: {}