diff --git a/cmd/template_backups_test.go b/cmd/template_backups_test.go index 0ae74a96..4f51789b 100644 --- a/cmd/template_backups_test.go +++ b/cmd/template_backups_test.go @@ -19,6 +19,7 @@ import ( func TestBackupTemplateGeneration(t *testing.T) { tests := []struct { name string + description string args testdata.TestData templatePath string want string @@ -262,6 +263,55 @@ func TestBackupTemplateGeneration(t *testing.T) { templatePath: "testoutput", want: "internal/testdata/node/backup-templates/backup-9", }, + { + name: "test-generic-backup-rootless-workloads", + description: "this will generate a podsecuritycontext if the environment is configured for rootless workloads against k8up/v1 crs", + args: testdata.GetSeedData( + testdata.TestData{ + ProjectName: "example-project", + EnvironmentName: "main", + Branch: "main", + EnvironmentType: "production", + LagoonYAML: "internal/testdata/node/lagoon.yml", + K8UPVersion: "v2", + ProjectVariables: []lagoon.EnvironmentVariable{ + { + Name: "LAGOON_FEATURE_FLAG_ROOTLESS_WORKLOAD", + Value: "enabled", + Scope: "global", + }, + }, + }, true), + templatePath: "testoutput", + want: "internal/testdata/node/backup-templates/test-generic-backup-rootless-workloads", + }, + { + name: "test-generic-backup-rootless-workloads-onrootmismatch", + description: "this will generate a podsecuritycontext if the environment is configured for rootless workloads k8up/v1 crs", + args: testdata.GetSeedData( + testdata.TestData{ + ProjectName: "example-project", + EnvironmentName: "main", + Branch: "main", + EnvironmentType: "production", + LagoonYAML: "internal/testdata/node/lagoon.yml", + K8UPVersion: "v2", + ProjectVariables: []lagoon.EnvironmentVariable{ + { + Name: "LAGOON_FEATURE_FLAG_ROOTLESS_WORKLOAD", + Value: "enabled", + Scope: "global", + }, + { + Name: "LAGOON_FEATURE_FLAG_FS_ON_ROOT_MISMATCH", + Value: "enabled", + Scope: "global", + }, + }, + }, true), + templatePath: "testoutput", + want: "internal/testdata/node/backup-templates/test-generic-backup-rootless-workloads-onrootmismatch", + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/internal/templating/template_schedule.go b/internal/templating/template_schedule.go index 4d0922ec..f4a14f30 100644 --- a/internal/templating/template_schedule.go +++ b/internal/templating/template_schedule.go @@ -217,6 +217,23 @@ func GenerateBackupSchedule( }, }, } + if lValues.PodSecurityContext.RunAsUser != 0 { + schedule.Spec.PodSecurityContext = &corev1.PodSecurityContext{ + RunAsUser: helpers.Int64Ptr(lValues.PodSecurityContext.RunAsUser), + RunAsGroup: helpers.Int64Ptr(lValues.PodSecurityContext.RunAsGroup), + FSGroup: helpers.Int64Ptr(lValues.PodSecurityContext.FsGroup), + } + if lValues.PodSecurityContext.OnRootMismatch { + fsGroupChangePolicy := corev1.FSGroupChangeOnRootMismatch + if schedule.Spec.PodSecurityContext != nil { + schedule.Spec.PodSecurityContext.FSGroupChangePolicy = &fsGroupChangePolicy + } else { + schedule.Spec.PodSecurityContext = &corev1.PodSecurityContext{ + FSGroupChangePolicy: &fsGroupChangePolicy, + } + } + } + } // add the default labels schedule.ObjectMeta.Labels = map[string]string{ "app.kubernetes.io/name": "k8up-schedule", diff --git a/internal/templating/template_schedule_test.go b/internal/templating/template_schedule_test.go index 14822a3b..b553ee99 100644 --- a/internal/templating/template_schedule_test.go +++ b/internal/templating/template_schedule_test.go @@ -16,10 +16,11 @@ func TestGenerateBackupSchedule(t *testing.T) { lValues generator.BuildValues } tests := []struct { - name string - args args - want string - wantErr bool + name string + description string + args args + want string + wantErr bool }{ { name: "test1 - k8up/v1alpha1", @@ -225,6 +226,89 @@ func TestGenerateBackupSchedule(t *testing.T) { }, want: "test-resources/backups/result-schedule6.yaml", }, + { + name: "test-k8up-v1-rootless", + description: "this will generate a podsecuritycontext if the environment is configured for rootless workloads against k8up/v1 crs", + args: args{ + lValues: generator.BuildValues{ + Project: "example-project", + Environment: "environment", + EnvironmentType: "production", + Namespace: "myexample-project-environment", + BuildType: "branch", + LagoonVersion: "v2.x.x", + Kubernetes: "generator.local", + Branch: "environment", + BackupsEnabled: true, + Backup: generator.BackupConfiguration{ + K8upVersion: "v2", + S3Endpoint: "https://minio.endpoint", + S3BucketName: "my-bucket", + S3SecretName: "my-s3-secret", + BackupSchedule: "50 5 * * 6", + CheckSchedule: "50 5 * * 6", + PruneSchedule: "50 5 * * 6", + PruneRetention: generator.PruneRetention{ + Hourly: 0, + Daily: 7, + Weekly: 6, + Monthly: 0, + }, + }, + FeatureFlags: map[string]bool{ + "rootlessworkloads": true, + }, + PodSecurityContext: generator.PodSecurityContext{ + RunAsGroup: 0, + RunAsUser: 10000, + FsGroup: 10001, + }, + }, + }, + want: "test-resources/backups/test-k8up-v1-rootless.yaml", + }, + { + name: "test-k8up-v1-rootless-onrootmismatch", + description: "this will generate a podsecuritycontext if the environment is configured for rootless workloads k8up/v1 crs", + args: args{ + lValues: generator.BuildValues{ + Project: "example-project", + Environment: "environment", + EnvironmentType: "production", + Namespace: "myexample-project-environment", + BuildType: "branch", + LagoonVersion: "v2.x.x", + Kubernetes: "generator.local", + Branch: "environment", + BackupsEnabled: true, + Backup: generator.BackupConfiguration{ + K8upVersion: "v2", + S3Endpoint: "https://minio.endpoint", + S3BucketName: "my-bucket", + S3SecretName: "my-s3-secret", + BackupSchedule: "50 5 * * 6", + CheckSchedule: "50 5 * * 6", + PruneSchedule: "50 5 * * 6", + PruneRetention: generator.PruneRetention{ + Hourly: 0, + Daily: 7, + Weekly: 6, + Monthly: 0, + }, + }, + FeatureFlags: map[string]bool{ + "rootlessworkloads": true, + }, + PodSecurityContext: generator.PodSecurityContext{ + RunAsGroup: 0, + RunAsUser: 10000, + FsGroup: 10001, + OnRootMismatch: true, + }, + }, + }, + want: "test-resources/backups/test-k8up-v1-rootless-onrootmismatch.yaml", + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/internal/templating/test-resources/backups/test-k8up-v1-rootless-onrootmismatch.yaml b/internal/templating/test-resources/backups/test-k8up-v1-rootless-onrootmismatch.yaml new file mode 100644 index 00000000..8705dae2 --- /dev/null +++ b/internal/templating/test-resources/backups/test-k8up-v1-rootless-onrootmismatch.yaml @@ -0,0 +1,53 @@ +--- +apiVersion: k8up.io/v1 +kind: Schedule +metadata: + annotations: + lagoon.sh/branch: environment + lagoon.sh/version: v2.x.x + creationTimestamp: null + labels: + app.kubernetes.io/instance: k8up-lagoon-backup-schedule + app.kubernetes.io/managed-by: build-deploy-tool + app.kubernetes.io/name: k8up-schedule + lagoon.sh/buildType: branch + lagoon.sh/environment: environment + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + lagoon.sh/service: k8up-lagoon-backup-schedule + lagoon.sh/service-type: k8up-schedule + lagoon.sh/template: k8up-schedule-0.1.0 + name: k8up-lagoon-backup-schedule +spec: + backend: + repoPasswordSecretRef: + key: repo-pw + name: baas-repo-pw + s3: + accessKeyIDSecretRef: + key: access-key + name: my-s3-secret + bucket: my-bucket + endpoint: https://minio.endpoint + secretAccessKeySecretRef: + key: secret-key + name: my-s3-secret + backup: + resources: {} + schedule: 50 5 * * 6 + check: + resources: {} + schedule: 50 5 * * 6 + podSecurityContext: + fsGroup: 10001 + fsGroupChangePolicy: OnRootMismatch + runAsGroup: 0 + runAsUser: 10000 + prune: + resources: {} + retention: + keepDaily: 7 + keepWeekly: 6 + schedule: 50 5 * * 6 + resourceRequirementsTemplate: {} +status: {} diff --git a/internal/templating/test-resources/backups/test-k8up-v1-rootless.yaml b/internal/templating/test-resources/backups/test-k8up-v1-rootless.yaml new file mode 100644 index 00000000..e2d26330 --- /dev/null +++ b/internal/templating/test-resources/backups/test-k8up-v1-rootless.yaml @@ -0,0 +1,52 @@ +--- +apiVersion: k8up.io/v1 +kind: Schedule +metadata: + annotations: + lagoon.sh/branch: environment + lagoon.sh/version: v2.x.x + creationTimestamp: null + labels: + app.kubernetes.io/instance: k8up-lagoon-backup-schedule + app.kubernetes.io/managed-by: build-deploy-tool + app.kubernetes.io/name: k8up-schedule + lagoon.sh/buildType: branch + lagoon.sh/environment: environment + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + lagoon.sh/service: k8up-lagoon-backup-schedule + lagoon.sh/service-type: k8up-schedule + lagoon.sh/template: k8up-schedule-0.1.0 + name: k8up-lagoon-backup-schedule +spec: + backend: + repoPasswordSecretRef: + key: repo-pw + name: baas-repo-pw + s3: + accessKeyIDSecretRef: + key: access-key + name: my-s3-secret + bucket: my-bucket + endpoint: https://minio.endpoint + secretAccessKeySecretRef: + key: secret-key + name: my-s3-secret + backup: + resources: {} + schedule: 50 5 * * 6 + check: + resources: {} + schedule: 50 5 * * 6 + podSecurityContext: + fsGroup: 10001 + runAsGroup: 0 + runAsUser: 10000 + prune: + resources: {} + retention: + keepDaily: 7 + keepWeekly: 6 + schedule: 50 5 * * 6 + resourceRequirementsTemplate: {} +status: {} diff --git a/internal/testdata/node/backup-templates/test-generic-backup-rootless-workloads-onrootmismatch/k8up-lagoon-backup-schedule.yaml b/internal/testdata/node/backup-templates/test-generic-backup-rootless-workloads-onrootmismatch/k8up-lagoon-backup-schedule.yaml new file mode 100644 index 00000000..db4d188c --- /dev/null +++ b/internal/testdata/node/backup-templates/test-generic-backup-rootless-workloads-onrootmismatch/k8up-lagoon-backup-schedule.yaml @@ -0,0 +1,46 @@ +--- +apiVersion: k8up.io/v1 +kind: Schedule +metadata: + annotations: + lagoon.sh/branch: main + lagoon.sh/version: v2.7.x + creationTimestamp: null + labels: + app.kubernetes.io/instance: k8up-lagoon-backup-schedule + app.kubernetes.io/managed-by: build-deploy-tool + app.kubernetes.io/name: k8up-schedule + lagoon.sh/buildType: branch + lagoon.sh/environment: main + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + lagoon.sh/service: k8up-lagoon-backup-schedule + lagoon.sh/service-type: k8up-schedule + lagoon.sh/template: k8up-schedule-0.1.0 + name: k8up-lagoon-backup-schedule +spec: + backend: + repoPasswordSecretRef: + key: repo-pw + name: baas-repo-pw + s3: + bucket: baas-example-project + backup: + resources: {} + schedule: 48 22 * * * + check: + resources: {} + schedule: 48 5 * * 1 + podSecurityContext: + fsGroup: 10001 + fsGroupChangePolicy: OnRootMismatch + runAsGroup: 0 + runAsUser: 10000 + prune: + resources: {} + retention: + keepDaily: 7 + keepWeekly: 6 + schedule: 48 3 * * 0 + resourceRequirementsTemplate: {} +status: {} diff --git a/internal/testdata/node/backup-templates/test-generic-backup-rootless-workloads/k8up-lagoon-backup-schedule.yaml b/internal/testdata/node/backup-templates/test-generic-backup-rootless-workloads/k8up-lagoon-backup-schedule.yaml new file mode 100644 index 00000000..2cb6e9c9 --- /dev/null +++ b/internal/testdata/node/backup-templates/test-generic-backup-rootless-workloads/k8up-lagoon-backup-schedule.yaml @@ -0,0 +1,45 @@ +--- +apiVersion: k8up.io/v1 +kind: Schedule +metadata: + annotations: + lagoon.sh/branch: main + lagoon.sh/version: v2.7.x + creationTimestamp: null + labels: + app.kubernetes.io/instance: k8up-lagoon-backup-schedule + app.kubernetes.io/managed-by: build-deploy-tool + app.kubernetes.io/name: k8up-schedule + lagoon.sh/buildType: branch + lagoon.sh/environment: main + lagoon.sh/environmentType: production + lagoon.sh/project: example-project + lagoon.sh/service: k8up-lagoon-backup-schedule + lagoon.sh/service-type: k8up-schedule + lagoon.sh/template: k8up-schedule-0.1.0 + name: k8up-lagoon-backup-schedule +spec: + backend: + repoPasswordSecretRef: + key: repo-pw + name: baas-repo-pw + s3: + bucket: baas-example-project + backup: + resources: {} + schedule: 48 22 * * * + check: + resources: {} + schedule: 48 5 * * 1 + podSecurityContext: + fsGroup: 10001 + runAsGroup: 0 + runAsUser: 10000 + prune: + resources: {} + retention: + keepDaily: 7 + keepWeekly: 6 + schedule: 48 3 * * 0 + resourceRequirementsTemplate: {} +status: {}