diff --git a/charts/library/common-test/Chart.yaml b/charts/library/common-test/Chart.yaml index dc852063acd..0c72d74cb6a 100644 --- a/charts/library/common-test/Chart.yaml +++ b/charts/library/common-test/Chart.yaml @@ -35,4 +35,3 @@ sources: - https://github.com/truecharts/charts/tree/master/charts/library/common-test type: application version: 1.0.0 - diff --git a/charts/library/common-test/tests/persistence/pvc_stategy_type_test.yaml b/charts/library/common-test/tests/persistence/pvc_stategy_type_test.yaml new file mode 100644 index 00000000000..c53fd1f645f --- /dev/null +++ b/charts/library/common-test/tests/persistence/pvc_stategy_type_test.yaml @@ -0,0 +1,153 @@ +suite: pvc strategy type test +templates: + - common.yaml +release: + name: test-release-name + namespace: test-release-namespace +tests: + - it: should leave strategy as defined with non RWO accessModes and single replica + set: + workload: + some-workload: + enabled: true + primary: true + type: Deployment + strategy: RollingUpdate + podSpec: {} + persistence: + my-volume1: + enabled: true + type: pvc + accessModes: + - ReadWriteMany + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + equal: + path: spec.strategy.type + value: RollingUpdate + - documentIndex: &pvcDoc 1 + isKind: + of: PersistentVolumeClaim + - documentIndex: *pvcDoc + equal: + path: metadata.name + value: test-release-name-common-test-my-volume1 + - documentIndex: *pvcDoc + equal: + path: spec.accessModes + value: + - ReadWriteMany + - it: should set strategy to Recreate with RWO accessModes and single replica + set: + workload: + some-workload: + enabled: true + primary: true + type: Deployment + strategy: RollingUpdate + podSpec: {} + persistence: + my-volume1: + enabled: true + type: pvc + accessModes: + - ReadWriteMany + - ReadWriteOnce + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + equal: + path: spec.strategy.type + value: Recreate + - documentIndex: &pvcDoc 1 + isKind: + of: PersistentVolumeClaim + - documentIndex: *pvcDoc + equal: + path: metadata.name + value: test-release-name-common-test-my-volume1 + - documentIndex: *pvcDoc + equal: + path: spec.accessModes + value: + - ReadWriteMany + - ReadWriteOnce + - it: should leave strategy as defined with non RWO accessModes and multiple replica + set: + workload: + some-workload: + enabled: true + primary: true + type: Deployment + replicas: 2 + strategy: RollingUpdate + podSpec: {} + persistence: + my-volume1: + enabled: true + type: pvc + accessModes: + - ReadWriteMany + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + equal: + path: spec.strategy.type + value: RollingUpdate + - documentIndex: &pvcDoc 1 + isKind: + of: PersistentVolumeClaim + - documentIndex: *pvcDoc + equal: + path: metadata.name + value: test-release-name-common-test-my-volume1 + - documentIndex: *pvcDoc + equal: + path: spec.accessModes + value: + - ReadWriteMany + - it: should leave strategy as defined with RWO accessModes and multiple replica + set: + workload: + some-workload: + enabled: true + primary: true + type: Deployment + replicas: 2 + strategy: RollingUpdate + podSpec: {} + persistence: + my-volume1: + enabled: true + type: pvc + accessModes: + - ReadWriteMany + - ReadWriteOnce + asserts: + - documentIndex: &deploymentDoc 0 + isKind: + of: Deployment + - documentIndex: *deploymentDoc + equal: + path: spec.strategy.type + value: RollingUpdate + - documentIndex: &pvcDoc 1 + isKind: + of: PersistentVolumeClaim + - documentIndex: *pvcDoc + equal: + path: metadata.name + value: test-release-name-common-test-my-volume1 + - documentIndex: *pvcDoc + equal: + path: spec.accessModes + value: + - ReadWriteMany + - ReadWriteOnce diff --git a/charts/library/common/templates/lib/pod/_volumes.tpl b/charts/library/common/templates/lib/pod/_volumes.tpl index db9b40e700d..12d872c8a6e 100644 --- a/charts/library/common/templates/lib/pod/_volumes.tpl +++ b/charts/library/common/templates/lib/pod/_volumes.tpl @@ -96,15 +96,9 @@ objectData: The object data to be used to render the Pod. "objectData" $persistence "caller" "Volumes") | fromYamlArray -}} - {{- $hasRWO := false -}} - {{- range $m := $modes -}} - {{- if eq $m "ReadWriteOnce" -}} - {{- $hasRWO = true -}} - {{- break -}} - {{- end -}} - {{- end -}} + {{- $hasRWO := include "tc.v1.common.lib.pod.volumes.hasRWO" (dict "modes" $modes) -}} - {{- if $hasRWO -}} + {{- if eq $hasRWO "true" -}} {{- if eq $objectData.type "DaemonSet" -}} {{- fail "Expected [accessMode] to not be [ReadWriteOnce] when used on a [DaemonSet]" -}} @@ -117,3 +111,15 @@ objectData: The object data to be used to render the Pod. {{- end -}} {{- end -}} + +{{- define "tc.v1.common.lib.pod.volumes.hasRWO" -}} + {{- $modes := .modes -}} + {{- $hasRWO := false -}} + {{- range $m := $modes -}} + {{- if eq $m "ReadWriteOnce" -}} + {{- $hasRWO = true -}} + {{- break -}} + {{- end -}} + {{- end -}} + {{- $hasRWO -}} +{{- end -}} diff --git a/charts/library/common/templates/lib/workload/_daemonsetSpec.tpl b/charts/library/common/templates/lib/workload/_daemonsetSpec.tpl index 82e5abae92a..c17771994d4 100644 --- a/charts/library/common/templates/lib/workload/_daemonsetSpec.tpl +++ b/charts/library/common/templates/lib/workload/_daemonsetSpec.tpl @@ -9,10 +9,13 @@ objectData: {{- define "tc.v1.common.lib.workload.daemonsetSpec" -}} {{- $objectData := .objectData -}} {{- $rootCtx := .rootCtx -}} - {{- $strategy := $objectData.strategy | default "RollingUpdate" }} + {{- include "tc.v1.common.lib.workload.components.strategyType" (dict + "rootCtx" $rootCtx "objectData" $objectData + "defaultStrategy" "RollingUpdate" "resource" "DaemonSet" + ) }} revisionHistoryLimit: {{ $objectData.revisionHistoryLimit | default 3 }} updateStrategy: - type: {{ $strategy }} + type: {{ $objectData.strategy }} {{- if and (eq $objectData.strategy "RollingUpdate") $objectData.rollingUpdate -}} {{ if (or (hasKey $objectData.rollingUpdate "maxUnavailable") (hasKey $objectData.rollingUpdate "maxSurge")) }} rollingUpdate: diff --git a/charts/library/common/templates/lib/workload/_deploymentSpec.tpl b/charts/library/common/templates/lib/workload/_deploymentSpec.tpl index bae179099b1..067238198fd 100644 --- a/charts/library/common/templates/lib/workload/_deploymentSpec.tpl +++ b/charts/library/common/templates/lib/workload/_deploymentSpec.tpl @@ -10,7 +10,10 @@ objectData: {{- define "tc.v1.common.lib.workload.deploymentSpec" -}} {{- $objectData := .objectData -}} {{- $rootCtx := .rootCtx -}} - {{- $strategy := $objectData.strategy | default "Recreate" -}} + {{- include "tc.v1.common.lib.workload.components.strategyType" (dict + "rootCtx" $rootCtx "objectData" $objectData + "defaultStrategy" "Recreate" "resource" "Deployment" + ) -}} {{- $replicas := 1 -}} {{- if hasKey $objectData "replicas" -}} {{- $replicas = $objectData.replicas -}} @@ -21,7 +24,7 @@ objectData: replicas: {{ $replicas }} revisionHistoryLimit: {{ $objectData.revisionHistoryLimit | default 3 }} strategy: - type: {{ $strategy }} + type: {{ $objectData.strategy }} {{- if and (eq $objectData.strategy "RollingUpdate") $objectData.rollingUpdate -}} {{ if (or (hasKey $objectData.rollingUpdate "maxUnavailable") (hasKey $objectData.rollingUpdate "maxSurge")) }} rollingUpdate: diff --git a/charts/library/common/templates/lib/workload/_statefulsetSpec.tpl b/charts/library/common/templates/lib/workload/_statefulsetSpec.tpl index 364376d038e..bd26f339294 100644 --- a/charts/library/common/templates/lib/workload/_statefulsetSpec.tpl +++ b/charts/library/common/templates/lib/workload/_statefulsetSpec.tpl @@ -10,7 +10,10 @@ objectData: {{- define "tc.v1.common.lib.workload.statefulsetSpec" -}} {{- $objectData := .objectData -}} {{- $rootCtx := .rootCtx -}} - {{- $strategy := $objectData.strategy | default "RollingUpdate" -}} + {{- include "tc.v1.common.lib.workload.components.strategyType" (dict + "rootCtx" $rootCtx "objectData" $objectData + "defaultStrategy" "RollingUpdate" "resource" "StatefulSet" + ) -}} {{- $replicas := 1 -}} {{- if hasKey $objectData "replicas" -}} {{- $replicas = $objectData.replicas -}} @@ -22,7 +25,7 @@ replicas: {{ $replicas }} revisionHistoryLimit: {{ $objectData.revisionHistoryLimit | default 3 }} serviceName: {{ $objectData.name }} updateStrategy: - type: {{ $strategy }} + type: {{ $objectData.strategy }} {{- if and (eq $objectData.strategy "RollingUpdate") $objectData.rollingUpdate -}} {{- if (or (hasKey $objectData.rollingUpdate "maxUnavailable") (hasKey $objectData.rollingUpdate "partition")) }} rollingUpdate: diff --git a/charts/library/common/templates/lib/workload/components/_strategyType.tpl b/charts/library/common/templates/lib/workload/components/_strategyType.tpl new file mode 100644 index 00000000000..99fdceaa96b --- /dev/null +++ b/charts/library/common/templates/lib/workload/components/_strategyType.tpl @@ -0,0 +1,71 @@ +{{/* Call this template: +{{ include "tc.v1.common.lib.workload.components.strategyType" (dict "rootCtx" $rootCtx "objectData" $objectData) -}} +rootCtx: The root context of the chart. +objectData: + replicas: The number of replicas. + strategy: The deployment strategy to use to replace existing pods with new ones. +*/}} +{{- define "tc.v1.common.lib.workload.components.strategyType" -}} + {{- $objectData := .objectData -}} + {{- $rootCtx := .rootCtx -}} + {{- $defaultStrategy := .defaultStrategy -}} + {{- $resource := .resource -}} + {{- $strategy := $objectData.strategy | default $defaultStrategy -}} + + {{- $replicas := 1 -}} + {{- if hasKey $objectData "replicas" -}} + {{- $replicas = $objectData.replicas -}} + {{- end -}} + {{- $replicas = $replicas | int -}} + + {{- $volsRWO := list -}} + {{- range $name, $persistence := $rootCtx.Values.persistence }} + {{- $enabled := (include "tc.v1.common.lib.util.enabled" (dict + "rootCtx" $rootCtx "objectData" $persistence + "name" $name "caller" "Volumes" + "key" "persistence")) -}} + + {{- if (ne $enabled "true") -}}{{- continue -}}{{- end -}} + + {{- $type := ($persistence.type | default $rootCtx.Values.global.fallbackDefaults.persistenceType) -}} + {{- $typesWithAccessMode := (list "pvc") -}} + + {{- if (mustHas $type $typesWithAccessMode) -}} + {{- $modes := include "tc.v1.common.lib.pvc.accessModes" (dict "rootCtx" $rootCtx + "objectData" $persistence "caller" "Volumes") | fromYamlArray + -}} + + {{- $hasRWO := include "tc.v1.common.lib.pod.volumes.hasRWO" (dict "modes" $modes) -}} + {{- if ne $hasRWO "true" -}}{{- continue -}}{{- end -}} + {{- $volsRWO = mustAppend $volsRWO $name -}} + {{- end -}} + {{- end -}} + + {{/* If there are any RWO vols, do some checks and add warnings */}} + {{- if gt (len $volsRWO) 0 -}} + {{/* RWO + replicas > 1 is a no-no */}} + {{- if gt $replicas 1 -}} + {{- include "add.warning" (dict "rootCtx" $rootCtx "warn" (printf + "WARNING: The [accessModes] on volume(s) [%s] is set to [ReadWriteOnce] with a more than 1 replica. This is not stables" (join "," $volsRWO) + )) -}} + {{- else -}} + {{/* DaemonSets and StatefulSets can have RWO with 1 replica under their supported strategies (OnDelete, RollingUpdate) */}} + + {{- if eq $resource "Deployment" -}} + + {{/* On Deployments with single replicas, warn if strategy is not recreate */}} + {{- if eq $strategy "Recreate" -}} + {{- include "add.warning" (dict "rootCtx" $rootCtx "warn" (printf + "WARNING: The [accessModes] on volume(s) [%s] is set to [ReadWriteOnce] with a single replica and an strategy of [%s]. %s" + (join "," $volsRWO) $strategy "This is not stable, defaulting to [Recreate] strategy" + )) -}} + {{- end -}} + {{- $strategy = "Recreate" -}} + + {{- end -}} + {{- end -}} + {{- end -}} + + {{/* Update strategy */}} + {{- $_ := set $objectData "strategy" $strategy -}} +{{- end -}}