diff --git a/charts/library/common-test/tests/volsync/replication_dest_spec_test.yaml b/charts/library/common-test/tests/volsync/replication_dest_spec_test.yaml index 3391e3c7184..787cfafa755 100644 --- a/charts/library/common-test/tests/volsync/replication_dest_spec_test.yaml +++ b/charts/library/common-test/tests/volsync/replication_dest_spec_test.yaml @@ -425,3 +425,85 @@ tests: fsGroup: 568 runAsUser: 568 runAsGroup: 568 + + - it: should generate correct spec with customCASecretRef + set: + secret: + mys3-ca-secret: + enabled: true + data: + ca.crt: |- + -----BEGIN CERTIFICATE----- + ... + -----END CERTIFICATE----- + persistence: + destbackup: + enabled: true + type: pvc + mountPath: /backedup + volsync: + - name: mybackup1 + type: restic + credentials: mys3 + dest: + enabled: true + src: + enabled: false + credentials: + mys3: + type: s3 + url: https://s3.some-url + bucket: some-bucket + encrKey: some-key + accessKey: some-access-key + secretKey: some-secret-key + customCASecretRef: + name: mys3-ca-secret + key: ca.crt + asserts: + - documentIndex: *secretDoc + isKind: + of: Secret + - documentIndex: *secretDoc + isAPIVersion: + of: v1 + - documentIndex: *secretDoc + equal: + path: metadata.name + value: test-release-name-common-test-mys3-ca-secret + - documentIndex: *secretDoc + equal: + path: stringData + value: + ca.crt: |- + -----BEGIN CERTIFICATE----- + ... + -----END CERTIFICATE----- + - documentIndex: *replicationCaDestDoc + isKind: + of: ReplicationDestination + - documentIndex: *replicationCaDestDoc + isAPIVersion: + of: volsync.backube/v1alpha1 + - documentIndex: *replicationCaDestDoc + equal: + path: spec + value: + trigger: + manual: restore-once + restic: + repository: test-release-name-common-test-destbackup-volsync-mybackup1 + customCA: + secretName: test-release-name-common-test-mys3-ca-secret + key: ca.crt + copyMethod: Snapshot + cleanupTempPVC: false + cleanupCachePVC: false + cacheCapacity: 10Gi + capacity: 100Gi + accessModes: + - ReadWriteOnce + moverSecurityContext: + fsGroup: 568 + runAsUser: 568 + runAsGroup: 568 diff --git a/charts/library/common-test/tests/volsync/replication_src_spec_test.yaml b/charts/library/common-test/tests/volsync/replication_src_spec_test.yaml index 63b2a185b29..7d2f8452853 100644 --- a/charts/library/common-test/tests/volsync/replication_src_spec_test.yaml +++ b/charts/library/common-test/tests/volsync/replication_src_spec_test.yaml @@ -425,3 +425,96 @@ tests: matchRegex: path: spec.restic.unlock pattern: "^[0-9]{14}$" + + - it: should generate correct spec with customCASecretRef + set: + secret: + mys3-ca-secret: + enabled: true + data: + ca.crt: |- + -----BEGIN CERTIFICATE----- + ... + -----END CERTIFICATE----- + persistence: + srcbackup: + enabled: true + type: pvc + mountPath: /backedup + volsync: + - name: mybackup1 + type: restic + credentials: mys3 + dest: + enabled: false + src: + enabled: true + credentials: + mys3: + type: s3 + url: http://some-url + bucket: some-bucket + encrKey: some-key + accessKey: some-access-key + secretKey: some-secret-key + customCASecretRef: + name: mys3-ca-secret + key: ca.crt + asserts: + - documentIndex: *secretDoc + isKind: + of: Secret + - documentIndex: *secretDoc + isAPIVersion: + of: v1 + - documentIndex: *secretDoc + equal: + path: metadata.name + value: test-release-name-common-test-mys3-ca-secret + - documentIndex: *secretDoc + equal: + path: stringData + value: + ca.crt: |- + -----BEGIN CERTIFICATE----- + ... + -----END CERTIFICATE----- + - documentIndex: *replicationCaDestDoc + isKind: + of: ReplicationSource + - documentIndex: *replicationCaDestDoc + isAPIVersion: + of: volsync.backube/v1alpha1 + - documentIndex: *replicationCaDestDoc + isSubset: + path: spec + content: + sourcePVC: test-release-name-common-test-srcbackup + trigger: + schedule: "0 0 * * *" + - documentIndex: *replicationCaDestDoc + isSubset: + path: spec.restic + content: + repository: test-release-name-common-test-srcbackup-volsync-mybackup1 + customCA: + secretName: test-release-name-common-test-mys3-ca-secret + key: ca.crt + copyMethod: Snapshot + pruneIntervalDays: 7 + retain: + hourly: 6 + daily: 5 + weekly: 4 + monthly: 3 + yearly: 1 + accessModes: + - ReadWriteOnce + moverSecurityContext: + fsGroup: 568 + runAsUser: 568 + runAsGroup: 568 + - documentIndex: *replicationCaDestDoc + matchRegex: + path: spec.restic.unlock + pattern: "^[0-9]{14}$" diff --git a/charts/library/common/Chart.yaml b/charts/library/common/Chart.yaml index f4b8d952055..0d339cffa14 100644 --- a/charts/library/common/Chart.yaml +++ b/charts/library/common/Chart.yaml @@ -50,4 +50,4 @@ sources: - https://hub.docker.com/_/ - https://hub.docker.com/r/mikefarah/yq type: library -version: 28.22.0 +version: 28.23.0 diff --git a/charts/library/common/templates/class/volsync/_replicationDestination.tpl b/charts/library/common/templates/class/volsync/_replicationDestination.tpl index 70ffd895a4c..831c4b00d88 100644 --- a/charts/library/common/templates/class/volsync/_replicationDestination.tpl +++ b/charts/library/common/templates/class/volsync/_replicationDestination.tpl @@ -57,8 +57,8 @@ spec: repository: {{ $volsyncData.repository }} {{- if $volsyncData.customCA }} customCA: - secretName: {{ $volsyncData.customCA }} - key: ca.crt + secretName: {{ $volsyncData.customCA.name }} + key: {{ $volsyncData.customCA.key }} {{- end }} copyMethod: {{ $copyMethod }} capacity: {{ $capacity }} diff --git a/charts/library/common/templates/class/volsync/_replicationSource.tpl b/charts/library/common/templates/class/volsync/_replicationSource.tpl index 0403d21f21b..dd98fcb8392 100644 --- a/charts/library/common/templates/class/volsync/_replicationSource.tpl +++ b/charts/library/common/templates/class/volsync/_replicationSource.tpl @@ -55,8 +55,8 @@ spec: repository: {{ $volsyncData.repository }} {{- if $volsyncData.customCA }} customCA: - secretName: {{ $volsyncData.customCA }} - key: ca.crt + secretName: {{ $volsyncData.customCA.name }} + key: {{ $volsyncData.customCA.key }} {{- end }} copyMethod: {{ $volsyncData.copyMethod | default "Snapshot" }} pruneIntervalDays: {{ $volsyncData.src.pruneIntervalDays | default 7 }} diff --git a/charts/library/common/templates/lib/credentials/_validation.tpl b/charts/library/common/templates/lib/credentials/_validation.tpl index 18ae90335a6..7b3a6787ba8 100644 --- a/charts/library/common/templates/lib/credentials/_validation.tpl +++ b/charts/library/common/templates/lib/credentials/_validation.tpl @@ -28,4 +28,45 @@ {{- fail (printf "%s - Expected [url] in [credentials.%s] to start with [http://] or [https://]. It was observed that sometimes can cause issues if it does not. Got [%s]" $caller $credName $url) -}} {{- end -}} + {{- $customCA := get $credentials "customCA" -}} + {{- $customCASecretRef := get $credentials "customCASecretRef" -}} + + {{- if and $customCA $customCASecretRef -}} + {{- fail (printf "%s - Both [customCA] and [customCASecretRef] defined in [credentials.%s]. Choose one" $caller $credName) -}} + {{- end -}} + + {{- if and $customCA (not (kindIs "string" $customCA )) -}} + {{- fail (printf "%s - Expected [customCA] in [credentials.%s] to be a string. Got [%s]" $caller $credName (kindOf $customCA)) -}} + {{- end -}} + + {{- if $customCASecretRef -}} + {{- if not (kindIs "map" $customCASecretRef) -}} + {{- fail (printf "%s - Expected [credentials.%s.customCASecretRef] to be a dictionary. Got [%s]" $caller $credName (kindOf $customCASecretRef)) -}} + {{- end -}} + {{- if not $customCASecretRef.name -}} + {{- fail (printf "%s - Expected [name] key in [credentials.%s.customCASecretRef] to exist" $caller $credName) -}} + {{- else if not (kindIs "string" $customCASecretRef.name) -}} + {{- fail (printf "%s - Expected [name] in [credentials.%s.customCASecretRef] to be a string. Got [%s]" $caller $credName (kindOf $customCASecretRef.name)) -}} + {{- end -}} + {{- if not $customCASecretRef.key -}} + {{- fail (printf "%s - Expected [key] key in [credentials.%s.customCASecretRef] to exist" $caller $credName) -}} + {{- else if not (kindIs "string" $customCASecretRef.key) -}} + {{- fail (printf "%s - Expected [key] in [credentials.%s.customCASecretRef] to be a string. Got [%s]" $caller $credName (kindOf $customCASecretRef.key)) -}} + {{- end -}} + + {{- $expandName := (include "tc.v1.common.lib.util.expandName" (dict + "rootCtx" $rootCtx "objectData" $customCASecretRef + "name" $customCASecretRef.name "caller" $caller + "key" (printf "credentials.%s.customCASecretRef.name" $credName))) -}} + {{- if eq $expandName "true" -}} + {{- $object := (get $rootCtx.Values.secret $customCASecretRef.name) | default dict -}} + {{- if not $object -}} + {{- fail (printf "%s - Expected Secret [%s] referenced in [credentials.%s.customCASecretRef.name] to exist" $caller $customCASecretRef.name $credName) -}} + {{- end -}} + {{- if not (hasKey $object.data $customCASecretRef.key) -}} + {{- fail (printf "%s - Expected Secret [%s] referenced in [credentials.%s.customCASecretRef.name] to contain key [%s]" $caller $customCASecretRef.name $credName $customCASecretRef.key) -}} + {{- end -}} + {{- end -}} + {{- end -}} + {{- end -}} diff --git a/charts/library/common/templates/spawner/_pvc.tpl b/charts/library/common/templates/spawner/_pvc.tpl index a0a67b113cc..17854b3ccc4 100644 --- a/charts/library/common/templates/spawner/_pvc.tpl +++ b/charts/library/common/templates/spawner/_pvc.tpl @@ -129,9 +129,27 @@ {{- include "tc.v1.common.class.secret" (dict "rootCtx" $ "objectData" $volsyncSecretData) -}} - {{/* Create Custom CA Secret for VolSync */}} - {{- if $credentials.customCA -}} + {{- if $credentials.customCASecretRef -}} + {{/* Get the customCA secret name */}} + + {{- $customCASecretRef := $credentials.customCASecretRef -}} + {{- $expandName := (include "tc.v1.common.lib.util.expandName" (dict + "rootCtx" $ "objectData" $customCASecretRef + "name" $customCASecretRef.name "caller" "PVC - VolSync" + "key" (printf "credentials.%s.customCASecretRef.name" $volsyncData.credentials))) -}} + + {{- $CAsecretName := tpl $customCASecretRef.name $ -}} + {{- if eq $expandName "true" -}} + {{- $fullname := include "tc.v1.common.lib.chart.names.fullname" $ -}} + {{- $CAsecretName = (printf "%s-%s" $fullname $CAsecretName) -}} + {{- end -}} + + {{- $_ := set $volsyncData "customCA" (dict "name" $CAsecretName "key" $customCASecretRef.key) -}} + {{- else if $credentials.customCA -}} + {{/* Create Custom CA Secret for VolSync */}} + {{- $volsyncCASecretName := printf "%s-volsync-ca-%s" (include "tc.v1.common.lib.chart.names.fullname" $ ) $volsync.credentials -}} + {{- $volsyncCAKey := "ca.crt" -}} {{- $_ := set $volsyncData "customCA" $volsyncCASecretName -}} @@ -140,14 +158,15 @@ "labels" ($volsync.labels | default dict) "annotations" ($volsync.annotations | default dict) "data" (dict - "ca.crt" $credentials.customCA + $volsyncCAKey $credentials.customCA ) ) -}} {{- include "tc.v1.common.class.secret" (dict "rootCtx" $ "objectData" $volsyncCASecretData) -}} + {{- $_ := set $volsyncData "customCA" (dict "name" $volsyncCASecretName "key" $volsyncCAKey) -}} {{- end -}} - {{/* Create VolSync resources*/}} + {{/* Create VolSync resources*/}} {{- if $srcEnabled -}} {{- include "tc.v1.common.class.replicationsource" (dict "rootCtx" $ "objectData" $objectData "volsyncData" $volsyncData) -}} {{- end -}} diff --git a/charts/library/common/values.yaml b/charts/library/common/values.yaml index 66eb81002a7..81e5de8998f 100644 --- a/charts/library/common/values.yaml +++ b/charts/library/common/values.yaml @@ -297,7 +297,12 @@ credentials: # url: "" # ## Provide a custom certificate authority in cases where the URL endpoint # ## uses a self-signed certificate + # ## NOTE: DEPRECATED, use customCASecretRef instead # customCA: "" + # customCASecretRef: + # name: my-secret + # key: ca.crt + # # expandObjectName: false # default true # path: "" # bucket: "" # accessKey: "" diff --git a/website/src/content/docs/common/credentials.md b/website/src/content/docs/common/credentials.md index df0ac644c87..a363092ab4d 100644 --- a/website/src/content/docs/common/credentials.md +++ b/website/src/content/docs/common/credentials.md @@ -106,11 +106,116 @@ credentials: --- +#### `customCASecretRef` + +Reference a secret containing a custom CA to be used when connecting to the +endpoint defined by `url` over HTTPS. + +:::note + +Defining both this and [customCA](/common/credentials#customca) is invalid and +will result in an error. + +::: + +| | | +| ---------- | ------------------------------------------------------------- | +| Key | `credentials.$name.customCASecretRef` | +| Type | `map` | +| Required | ❌ | +| Helm `tpl` | ❌ | +| Example | `{}` | + +```yaml +credentials: + credentials-name: + customCASecretRef: {} +``` + +--- + +##### `customCASecretRef.name` + +Define the secret name + +:::note + +This will be automatically expanded to `fullname-secret-name`. +You can opt out of this by setting [`expandObjectName`](/common/credentials#customcasecretrefexpandobjectname) to `false` + +::: + +| | | +| ---------- | ------------------------------------------ | +| Key | `credentials.$name.customCASecretRef.name` | +| Type | `string` | +| Required | ✅ | +| Helm `tpl` | ✅ | +| Example | `""` | + +```yaml +credentials: + credentials-name: + customCASecretRef: + name: secret-name +``` + +--- + +##### `customCASecretRef.key` + +Define the key in the secret data containing the CA + +| | | +| ---------- | ------------------------------------------ | +| Key | `credentials.$name.customCASecretRef.key` | +| Type | `string` | +| Required | ✅ | +| Helm `tpl` | ❌ | +| Example | `""` | + +```yaml +credentials: + credentials-name: + customCASecretRef: + key: ca.crt +``` + +--- + +##### `customCASecretRef.expandObjectName` + +Whether to expand (adding the fullname as prefix) the secret name + +| | | +| ---------- | ------------------------------------------------------ | +| Key | `credentials.$name.customCASecretRef.expandObjectName` | +| Type | `bool` | +| Required | ❌ | +| Helm `tpl` | ❌ | +| Example | `true` | + +```yaml +credentials: + credentials-name: + customCASecretRef: + expandObjectName: false +``` + +--- + #### `customCA` Define a custom CA certificate to be used when connecting to the endpoint defined by `url` over HTTPS. +:::note + +Defining both this and [customCASecretRef](/common/credentials#customcasecretref) +is invalid and will result in an error. + +::: + | | | | ---------- | ------------------------------------------------------------- | | Key | `credentials.$name.customCA` |