diff --git a/library/common-test/tests/lists/veleroVolumeSnapshotLocationList_test.yaml b/library/common-test/tests/lists/veleroVolumeSnapshotLocationList_test.yaml index 2c005a19..7181978e 100644 --- a/library/common-test/tests/lists/veleroVolumeSnapshotLocationList_test.yaml +++ b/library/common-test/tests/lists/veleroVolumeSnapshotLocationList_test.yaml @@ -10,7 +10,9 @@ tests: volumeSnapshotLocationList: - name: my-snap1 enabled: true - provider: aws + provider: my-snapshot-plugin + config: + provider: aws credential: aws: id: my-id @@ -40,7 +42,9 @@ tests: equal: path: spec value: - provider: velero.io/aws + provider: my-snapshot-plugin + config: + provider: aws credential: name: vsl-test-release-name-common-test-my-snap1 key: cloud diff --git a/library/common-test/tests/lists/volumeScheduleList_test.yaml b/library/common-test/tests/lists/volumeScheduleList_test.yaml new file mode 100644 index 00000000..8c1c314c --- /dev/null +++ b/library/common-test/tests/lists/volumeScheduleList_test.yaml @@ -0,0 +1,65 @@ +suite: volumeSnapshotList spec test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should generate correct spec + set: + schedulesList: + - name: example1 + enabled: true + schedule: "0 2 * * *" + - name: example2 + enabled: true + schedule: "0 2 * * *" + useOwnerReferencesInBackup: true + asserts: + - documentIndex: &scheduleDoc 0 + isKind: + of: Schedule + - documentIndex: *scheduleDoc + isAPIVersion: + of: velero.io/v1 + - documentIndex: *scheduleDoc + equal: + path: spec + value: + schedule: 0 2 * * * + template: + includeClusterResources: true + includedNamespaces: + - test-release-namespace + orLabelSelectors: + - matchLabels: + app.kubernetes.io/instance: test-release-name + - matchLabels: + release: test-release-name + - matchLabels: + name: test-release-name + owner: helm + - documentIndex: &scheduleDoc 1 + isKind: + of: Schedule + - documentIndex: *scheduleDoc + isAPIVersion: + of: velero.io/v1 + - documentIndex: *scheduleDoc + equal: + path: spec + value: + schedule: "0 2 * * *" + useOwnerReferencesInBackup: true + template: + includeClusterResources: true + includedNamespaces: + - test-release-namespace + orLabelSelectors: + - matchLabels: + app.kubernetes.io/instance: test-release-name + - matchLabels: + release: test-release-name + - matchLabels: + name: test-release-name + owner: helm diff --git a/library/common-test/tests/secret/data_test.yaml b/library/common-test/tests/secret/data_test.yaml index 434f12a3..5e5b8768 100644 --- a/library/common-test/tests/secret/data_test.yaml +++ b/library/common-test/tests/secret/data_test.yaml @@ -112,3 +112,15 @@ tests: foo: | Some other text some_text + + - it: should pass with empty data on kubernetes.io/service-account-token type + set: + secret: + my-secret: + enabled: true + type: kubernetes.io/service-account-token + asserts: + - documentIndex: *secretDoc + equal: + path: stringData + value: null diff --git a/library/common-test/tests/secret/validation_test.yaml b/library/common-test/tests/secret/validation_test.yaml index 969a6c2c..87585c72 100644 --- a/library/common-test/tests/secret/validation_test.yaml +++ b/library/common-test/tests/secret/validation_test.yaml @@ -96,7 +96,7 @@ tests: data: {} asserts: - failedTemplate: - errorMessage: Secret - Expected non-empty [data] or [stringData] + errorMessage: Secret - Expected non-empty [data] - it: should fail with empty type key set: @@ -108,7 +108,7 @@ tests: foo: bar asserts: - failedTemplate: - errorMessage: Secret - Found [type] key, but it's empty + errorMessage: Secret - Expected non-empty [type] key - it: should fail with empty enabled set: @@ -120,3 +120,14 @@ tests: asserts: - failedTemplate: errorMessage: Secret - Expected the defined key [enabled] in [secret.my-secret] to not be empty + + - it: should fail with stringData usage + set: + secret: + my-secret: + enabled: true + stringData: + foo: bar + asserts: + - failedTemplate: + errorMessage: Secret - Key [stringData] is not supported diff --git a/library/common-test/tests/veleroSchedule/names_test.yaml b/library/common-test/tests/veleroSchedule/names_test.yaml index 0671bbd1..c21137cb 100644 --- a/library/common-test/tests/veleroSchedule/names_test.yaml +++ b/library/common-test/tests/veleroSchedule/names_test.yaml @@ -14,6 +14,7 @@ tests: my-sched2: enabled: true schedule: "0 0 * * *" + expandObjectName: true asserts: - documentIndex: &scheduleDoc 0 isKind: @@ -24,7 +25,7 @@ tests: - documentIndex: *scheduleDoc equal: path: metadata.name - value: test-release-name-common-test-my-sched1 + value: my-sched1 - documentIndex: &otherScheduleDoc 1 isKind: of: Schedule diff --git a/library/common-test/tests/veleroSchedule/spec_test.yaml b/library/common-test/tests/veleroSchedule/spec_test.yaml index 835a8812..30dfa9b3 100644 --- a/library/common-test/tests/veleroSchedule/spec_test.yaml +++ b/library/common-test/tests/veleroSchedule/spec_test.yaml @@ -24,8 +24,18 @@ tests: value: schedule: 0 2 * * * template: + includeClusterResources: true includedNamespaces: - test-release-namespace + orLabelSelectors: + - matchLabels: + app.kubernetes.io/instance: test-release-name + - matchLabels: + release: test-release-name + - matchLabels: + name: test-release-name + owner: helm + - it: should generate correct spec with useOwnerReferencesInBackup set: schedules: @@ -47,10 +57,19 @@ tests: schedule: "0 2 * * *" useOwnerReferencesInBackup: true template: + includeClusterResources: true includedNamespaces: - test-release-namespace + orLabelSelectors: + - matchLabels: + app.kubernetes.io/instance: test-release-name + - matchLabels: + release: test-release-name + - matchLabels: + name: test-release-name + owner: helm - - it: should generate correct spec with template + - it: should generate correct spec with template and override on includedNamespaces set: schedules: my-sched: @@ -60,6 +79,8 @@ tests: ttl: 720h includeClusterResources: true snapshotVolumes: true + includedNamespaces: + - some-namespace asserts: - documentIndex: &scheduleDoc 0 isKind: @@ -77,7 +98,15 @@ tests: includeClusterResources: true snapshotVolumes: true includedNamespaces: - - test-release-namespace + - some-namespace + orLabelSelectors: + - matchLabels: + app.kubernetes.io/instance: test-release-name + - matchLabels: + release: test-release-name + - matchLabels: + name: test-release-name + owner: helm # Failures - it: should fail without schedule diff --git a/library/common-test/tests/veleroVolumeSnapshotLocation/metadata_test.yaml b/library/common-test/tests/veleroVolumeSnapshotLocation/metadata_test.yaml index 366e43d2..4227a8a0 100644 --- a/library/common-test/tests/veleroVolumeSnapshotLocation/metadata_test.yaml +++ b/library/common-test/tests/veleroVolumeSnapshotLocation/metadata_test.yaml @@ -35,7 +35,9 @@ tests: labelsList: - name: some-label value: some-value - provider: aws + provider: some-snapshot-plugin + config: + provider: aws credential: aws: id: my-id diff --git a/library/common-test/tests/veleroVolumeSnapshotLocation/names_test.yaml b/library/common-test/tests/veleroVolumeSnapshotLocation/names_test.yaml index e52d5051..4f906ca4 100644 --- a/library/common-test/tests/veleroVolumeSnapshotLocation/names_test.yaml +++ b/library/common-test/tests/veleroVolumeSnapshotLocation/names_test.yaml @@ -10,14 +10,18 @@ tests: volumeSnapshotLocation: my-snap1: enabled: true - provider: aws + provider: some-snapshot-plugin + config: + provider: aws credential: aws: id: my-id key: my-key my-snap2: enabled: true - provider: aws + provider: some-snapshot-plugin + config: + provider: aws credential: aws: id: my-id diff --git a/library/common-test/tests/veleroVolumeSnapshotLocation/spec_test.yaml b/library/common-test/tests/veleroVolumeSnapshotLocation/spec_test.yaml index e18ad5f5..c270fbca 100644 --- a/library/common-test/tests/veleroVolumeSnapshotLocation/spec_test.yaml +++ b/library/common-test/tests/veleroVolumeSnapshotLocation/spec_test.yaml @@ -10,7 +10,9 @@ tests: volumeSnapshotLocation: my-snap1: enabled: true - provider: aws + provider: some-snapshot-plugin + config: + provider: aws credential: aws: id: my-id @@ -40,7 +42,9 @@ tests: equal: path: spec value: - provider: velero.io/aws + provider: some-snapshot-plugin + config: + provider: aws credential: name: vsl-test-release-name-common-test-my-snap1 key: cloud @@ -50,7 +54,9 @@ tests: volumeSnapshotLocation: my-snap1: enabled: true - provider: s3 + provider: my-snapshot-plugin + config: + provider: s3 credential: s3: id: my-id @@ -80,7 +86,9 @@ tests: equal: path: spec value: - provider: velero.io/aws + provider: my-snapshot-plugin + config: + provider: aws credential: name: vsl-test-release-name-common-test-my-snap1 key: cloud @@ -90,7 +98,9 @@ tests: volumeSnapshotLocation: my-snap1: enabled: true - provider: my-provider + provider: my-snap-provider + config: + provider: my-provider credential: name: my-credential key: my-key @@ -105,7 +115,9 @@ tests: equal: path: spec value: - provider: my-provider + provider: my-snap-provider + config: + provider: my-provider credential: name: my-credential key: my-key @@ -117,12 +129,13 @@ tests: volumeSnapshotLocation: my-snap1: enabled: true - provider: aws + provider: my-snap-provider credential: aws: id: my-id key: my-key config: + provider: aws region: "{{ .Values.region }}" s3ForcePathStyle: "{{ .Values.useS3PathStyle }}" bool: false @@ -139,11 +152,12 @@ tests: equal: path: spec value: - provider: velero.io/aws + provider: my-snap-provider credential: name: vsl-test-release-name-common-test-my-snap1 key: cloud config: + provider: aws region: us-east-1 s3ForcePathStyle: "true" bool: "false" @@ -162,12 +176,44 @@ tests: - failedTemplate: errorMessage: Volume Snapshot Location - Expected non-empty [provider] + - it: should fail without config + set: + volumeSnapshotLocation: + my-snap1: + enabled: true + provider: some-snapshot-plugin + credential: + aws: + id: my-id + key: my-key + asserts: + - failedTemplate: + errorMessage: Volume Snapshot Location - Expected non-empty [config] + + - it: should fail without config provider + set: + volumeSnapshotLocation: + my-snap1: + enabled: true + provider: some-snapshot-plugin + config: + some-key: some-value + credential: + aws: + id: my-id + key: my-key + asserts: + - failedTemplate: + errorMessage: Volume Snapshot Location - Expected non-empty [config.provider] + - it: should fail without credential set: volumeSnapshotLocation: my-snap1: enabled: true - provider: my-provider + provider: my-snap-provider + config: + provider: my-provider asserts: - failedTemplate: errorMessage: Volume Snapshot Location - Expected non-empty [credential] @@ -177,7 +223,9 @@ tests: volumeSnapshotLocation: my-snap1: enabled: true - provider: my-provider + provider: my-snap-provider + config: + provider: my-provider credential: key: my-key asserts: @@ -189,7 +237,9 @@ tests: volumeSnapshotLocation: my-snap1: enabled: true - provider: my-provider + provider: my-snap-provider + config: + provider: my-provider credential: name: my-name asserts: @@ -201,7 +251,9 @@ tests: volumeSnapshotLocation: my-snap1: enabled: true - provider: aws + provider: my-snap-provider + config: + provider: aws credential: aws: key: my-key @@ -214,7 +266,9 @@ tests: volumeSnapshotLocation: my-snap1: enabled: true - provider: aws + provider: my-snap-provider + config: + provider: aws credential: aws: id: my-id diff --git a/library/common/Chart.yaml b/library/common/Chart.yaml index 5fff2507..1414947e 100644 --- a/library/common/Chart.yaml +++ b/library/common/Chart.yaml @@ -15,4 +15,4 @@ maintainers: name: common sources: null type: library -version: 17.3.9 +version: 17.3.10 diff --git a/library/common/templates/class/velero/_schedule.tpl b/library/common/templates/class/velero/_schedule.tpl index 2c4fb0fe..2080fa9a 100644 --- a/library/common/templates/class/velero/_schedule.tpl +++ b/library/common/templates/class/velero/_schedule.tpl @@ -14,13 +14,16 @@ objectData: {{- $rootCtx := .rootCtx -}} {{- $objectData := .objectData }} - {{- $namespace := (include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "Schedule")) -}} + {{- $namespace := (include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "Velero Schedule")) -}} + + {{/* Get existing BSLs */}} {{- $lookupBSL := (lookup "velero.io/v1" "BackupStorageLocation" "" "") -}} - {{- if and $lookupBSL $lookupBSL.items -}} - {{- $lookupBSL = $lookupBSL.items -}} - {{- end -}} - {{- range $BSL := $lookupBSL -}} - {{- $namespace = $BSL.metadata.namespace -}} + {{- if $lookupBSL.items -}} + {{/* + Find the velero namespace (this is where BSLs are created) + And use it as the namespace for the schedule too. + */}} + {{- $namespace = ($lookupBSL.items | first).metadata.namespace -}} {{- end }} --- apiVersion: velero.io/v1 @@ -44,10 +47,10 @@ spec: useOwnerReferencesInBackup: {{ $objectData.useOwnerReferencesInBackup }} {{- end }} template: - {{- if not $objectData.template }} + {{- if not $objectData.template }} includeClusterResources: true includedNamespaces: - - {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "Schedule") }} + - {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "Velero Schedule") }} orLabelSelectors: - matchLabels: app.kubernetes.io/instance: {{ $rootCtx.Release.Name }} @@ -56,10 +59,18 @@ spec: - matchLabels: owner: helm name: {{ $rootCtx.Release.Name }} - {{- end -}} - - {{- with $objectData.template }} + {{- end -}} + {{- with $objectData.template }} + {{/* + TODO: This toYaml should **not** be here if any of the checks + below renders when a key is present. Currently, checks below + only render when a key is not present, which is mostly safe + to use along with the toYaml. + */}} {{- toYaml . | nindent 4 }} + {{- if not (hasKey . "includeClusterResources") }} + includeClusterResources: true + {{- end -}} {{- if not .orLabelSelectors }} orLabelSelectors: - matchLabels: @@ -72,10 +83,7 @@ spec: {{- end -}} {{- if not .includedNamespaces }} includedNamespaces: - - {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "Schedule") }} - {{- end -}} - {{- if not (hasKey . "includeClusterResources") }} - includeClusterResources: true - {{- end -}} + - {{ include "tc.v1.common.lib.metadata.namespace" (dict "rootCtx" $rootCtx "objectData" $objectData "caller" "Velero Schedule") }} {{- end -}} + {{- end -}} {{- end -}} diff --git a/library/common/templates/class/velero/_volumeSnapshotLocation.tpl b/library/common/templates/class/velero/_volumeSnapshotLocation.tpl index 8a7d9eb5..037e9013 100644 --- a/library/common/templates/class/velero/_volumeSnapshotLocation.tpl +++ b/library/common/templates/class/velero/_volumeSnapshotLocation.tpl @@ -30,7 +30,7 @@ metadata: annotations: {{- . | nindent 4 }} {{- end }} -spec: +spec: {{/* This is the volume snapshot provider */}} provider: {{ $objectData.provider }} {{- with $objectData.credential }} credential: diff --git a/library/common/templates/lib/secret/_validation.tpl b/library/common/templates/lib/secret/_validation.tpl index d7039f9f..109093cc 100644 --- a/library/common/templates/lib/secret/_validation.tpl +++ b/library/common/templates/lib/secret/_validation.tpl @@ -10,16 +10,22 @@ objectData: {{- define "tc.v1.common.lib.secret.validation" -}} {{- $objectData := .objectData -}} - {{- if and ( not $objectData.data ) ( not $objectData.stringData ) -}} - {{- fail "Secret - Expected non-empty [data] or [stringData]" -}} + {{- if $objectData.stringData -}} + {{- fail "Secret - Key [stringData] is not supported" -}} {{- end -}} - {{- if and $objectData.data (not (kindIs "map" $objectData.data)) -}} - {{- fail (printf "Secret - Expected [data] to be a dictionary, but got [%v]" (kindOf $objectData.data)) -}} - {{- end -}} + {{- if ne $objectData.type "kubernetes.io/service-account-token" -}} + {{- if and (not $objectData.data) -}} + {{- fail "Secret - Expected non-empty [data]" -}} + {{- end -}} - {{- if and (hasKey $objectData "type") (not $objectData.type) -}} - {{- fail (printf "Secret - Found [type] key, but it's empty") -}} + {{- if and $objectData.data (not (kindIs "map" $objectData.data)) -}} + {{- fail (printf "Secret - Expected [data] to be a dictionary, but got [%v]" (kindOf $objectData.data)) -}} + {{- end -}} + + {{- if and (hasKey $objectData "type") (not $objectData.type) -}} + {{- fail (printf "Secret - Expected non-empty [type] key") -}} + {{- end -}} {{- end -}} {{- end -}} diff --git a/library/common/templates/lib/util/_expandName.tpl b/library/common/templates/lib/util/_expandName.tpl index 2ab16daa..44e23f8e 100644 --- a/library/common/templates/lib/util/_expandName.tpl +++ b/library/common/templates/lib/util/_expandName.tpl @@ -18,7 +18,7 @@ {{- $expandName = tpl $expandName $rootCtx -}} {{/* After tpl it becomes a string, not a bool */}} - {{- if eq $expandName "true" -}} + {{- if eq $expandName "true" -}} {{- $expandName = true -}} {{- else if eq $expandName "false" -}} {{- $expandName = false -}} diff --git a/library/common/templates/lib/velero/_providerSecret.tpl b/library/common/templates/lib/velero/_providerSecret.tpl index 626e1d3c..e00f59c8 100644 --- a/library/common/templates/lib/velero/_providerSecret.tpl +++ b/library/common/templates/lib/velero/_providerSecret.tpl @@ -4,23 +4,26 @@ {{- $prefix := .prefix -}} {{- $creds := "" -}} - {{- $provider := "" -}} - - {{/* Use credential provider when creating secret for VSL */}} {{/* Make sure provider is a string */}} - {{- if eq $prefix "vsl" -}} - {{- $provider = $objectData.credential.provider | toString -}} - {{- else -}} - {{- $provider = $objectData.provider | toString -}} + {{- $provider := $objectData.provider | toString -}} + + {{/* Use config.provider when creating secret for VSL */}} + {{- if and (eq $prefix "vsl") $objectData.config -}} + {{- $provider = $objectData.config.provider | toString -}} {{- end -}} - {{- if and (eq $provider "aws") $objectData.credential.aws -}} {{- $creds = (include "tc.v1.common.lib.velero.provider.aws.secret" (dict "creds" $objectData.credential.aws) | fromYaml).data -}} - {{- $_ := set $objectData "provider" "velero.io/aws" -}} + {{- if ne $prefix "vsl" -}} {{/* If its not VSL, update the provider with a prefix */}} + {{- $_ := set $objectData "provider" "velero.io/aws" -}} + {{- end -}} {{- else if and (eq $provider "s3") $objectData.credential.s3 -}} {{- $creds = (include "tc.v1.common.lib.velero.provider.aws.secret" (dict "creds" $objectData.credential.s3) | fromYaml).data -}} - {{- $_ := set $objectData "provider" "velero.io/aws" -}} + {{- if eq $prefix "vsl" -}} {{/* Convert s3 to aws for vsl under config.provider */}} + {{- $_ := set $objectData.config "provider" "aws" -}} + {{- else -}} {{/* If its not VSL, update the provider with a prefix */}} + {{- $_ := set $objectData "provider" "velero.io/aws" -}} + {{- end -}} {{- end -}} {{/* If we matched a provider, create the secret */}} diff --git a/library/common/templates/lib/velero/_volumeSnapshotLocationValidation.tpl b/library/common/templates/lib/velero/_volumeSnapshotLocationValidation.tpl index 8f549658..502bcad6 100644 --- a/library/common/templates/lib/velero/_volumeSnapshotLocationValidation.tpl +++ b/library/common/templates/lib/velero/_volumeSnapshotLocationValidation.tpl @@ -14,6 +14,14 @@ objectData: {{- fail "Volume Snapshot Location - Expected non-empty [provider]" -}} {{- end -}} + {{- if not $objectData.config -}} + {{- fail "Volume Snapshot Location - Expected non-empty [config]" -}} + {{- end -}} + + {{- if not $objectData.config.provider -}} + {{- fail "Volume Snapshot Location - Expected non-empty [config.provider]" -}} + {{- end -}} + {{- if not $objectData.credential -}} {{- fail "Volume Snapshot Location - Expected non-empty [credential]" -}} {{- end -}} diff --git a/library/common/templates/spawner/velero/_schedule.tpl b/library/common/templates/spawner/velero/_schedule.tpl index 2981b59d..1d6dc74f 100644 --- a/library/common/templates/spawner/velero/_schedule.tpl +++ b/library/common/templates/spawner/velero/_schedule.tpl @@ -19,6 +19,25 @@ {{- $objectName := $name -}} + {{/* + Default to false for schedule objects. + This is because those objects are usualy used + from the velero cli and having the object expanded + would make it harder to use the cli. + */}} + {{- if not (hasKey $objectData "expandObjectName") -}} + {{- $_ := set $objectData "expandObjectName" "false" -}} + {{- end -}} + + {{- $expandName := (include "tc.v1.common.lib.util.expandName" (dict + "rootCtx" $ "objectData" $objectData + "name" $name "caller" "Velero Schedule" + "key" "schedules")) -}} + + {{- if eq $expandName "true" -}} + {{- $objectName = (printf "%s-%s" $fullname $name) -}} + {{- end -}} + {{- include "tc.v1.common.lib.util.metaListToDict" (dict "objectData" $objectData) -}} {{/* Perform validations */}} {{/* schedules have a max name length of 253 */}}