diff --git a/README.md b/README.md index 4cf069e..c99a0cf 100644 --- a/README.md +++ b/README.md @@ -145,6 +145,10 @@ The chart supports both internal and external PostgreSQL databases: | `affinity` | Affinity rules | `{}` | | `volumes` | Additional volumes | `[]` | | `volumeMounts` | Additional volume mounts | `[]` | +| `extraEnv` | Environment variables (EnvVar entries) for API pods only, rendered before the chart's own | `[]` | +| `extraVolumes` | Volumes for API pods only, rendered before the chart's own | `[]` | +| `extraVolumeMounts` | Volume mounts for the API container only, rendered before the chart's own | `[]` | +| `commonAnnotations` | Annotations added to every rendered object; an object's own annotation with the same key wins | `{}` | ### Graceful rollouts @@ -356,6 +360,8 @@ The fusillade daemon handles background batch processing tasks. By default, it r | `fusillade.nodeSelector` | Node selector for fusillade pods | `{}` | | `fusillade.tolerations` | Tolerations for fusillade pods | `[]` | | `fusillade.affinity` | Affinity rules for fusillade pods | `{}` | +| `fusillade.strategy` | Deployment strategy for fusillade daemons (per daemon under `fusillade.split..strategy`) | Kubernetes default | +| `fusillade.terminationGracePeriodSeconds` | Pod termination grace period for fusillade daemons (per daemon under `fusillade.split.`) | Kubernetes default | | `fusillade.env` | Additional environment variables | `{}` | When `fusillade.enabled: true`: diff --git a/templates/_helpers.tpl b/templates/_helpers.tpl index 6b14d0c..4774c77 100644 --- a/templates/_helpers.tpl +++ b/templates/_helpers.tpl @@ -310,10 +310,10 @@ options renders byte-for-byte the same template as before this helper existed. {{ " " }}template: metadata: annotations: - checksum/secret: {{ include (print $root.Template.BasePath "/secret.yaml") $root | sha256sum }} - checksum/config: {{ include (print $root.Template.BasePath "/configmap.yaml") $root | sha256sum }} + checksum/secret: {{ include "control-layer.checksum" (dict "root" $root "path" "secret.yaml") }} + checksum/config: {{ include "control-layer.checksum" (dict "root" $root "path" "configmap.yaml") }} {{- if $root.Values.modelProvisioning.enabled }} - checksum/model-provisioning: {{ include (print $root.Template.BasePath "/model-provisioning-configmap.yaml") $root | sha256sum }} + checksum/model-provisioning: {{ include "control-layer.checksum" (dict "root" $root "path" "model-provisioning-configmap.yaml") }} {{- end }} {{- with $root.Values.podAnnotations }} {{- toYaml . | nindent 8 }} @@ -376,6 +376,9 @@ options renders byte-for-byte the same template as before this helper existed. name: {{ . | quote }} {{- end }} env: + {{- with $root.Values.extraEnv }} + {{- toYaml . | nindent 12 }} + {{- end }} {{- if $root.Values.modelProvisioning.enabled }} - name: DWCTL_MODEL_PROVISIONING__ENABLED value: "true" @@ -430,6 +433,9 @@ options renders byte-for-byte the same template as before this helper existed. {{- toYaml . | nindent 12 }} {{- end }} volumeMounts: + {{- with $root.Values.extraVolumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} - name: config mountPath: /app/config.yaml subPath: control-layer-config.yaml @@ -448,6 +454,9 @@ options renders byte-for-byte the same template as before this helper existed. {{- toYaml . | nindent 12 }} {{- end }} volumes: + {{- with $root.Values.extraVolumes }} + {{- toYaml . | nindent 8 }} + {{- end }} - name: config configMap: name: {{ include "control-layer.fullname" $root }}-config @@ -478,3 +487,42 @@ options renders byte-for-byte the same template as before this helper existed. {{- end }} {{- end }} + +{{/* +`commonAnnotations` as the object's `annotations:` key and map, or nothing when +none are set. For templates whose objects carry no annotations of their own; +templates that do use control-layer.commonAnnotationEntries. +*/}} +{{- define "control-layer.commonAnnotations" -}} +{{- with .Values.commonAnnotations }} +annotations: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} + +{{/* +The `commonAnnotations` entries an object does not set itself, as map entries +(no `annotations:` key): an object's own annotations win. Takes a dict: root +(the chart context), own (the object's own annotations, as a map). +*/}} +{{- define "control-layer.commonAnnotationEntries" -}} +{{- $own := .own | default dict -}} +{{- $entries := dict -}} +{{- range $key, $value := .root.Values.commonAnnotations | default dict }} +{{- if not (hasKey $own $key) }}{{ $_ := set $entries $key $value }}{{ end }} +{{- end }} +{{- with $entries }}{{ toYaml . }}{{ end }} +{{- end }} + +{{/* +sha256 of a rendered template, computed without `commonAnnotations`: annotations +on a ConfigMap or Secret do not change what a pod mounts, so they must not roll +the pods. Takes a dict: root (the chart context), path (the template's path +under templates/). +*/}} +{{- define "control-layer.checksum" -}} +{{- $context := omit .root "Values" -}} +{{- $_ := set $context "Values" (omit .root.Values "commonAnnotations") -}} +{{- include (print .root.Template.BasePath "/" .path) $context | sha256sum -}} +{{- end }} + diff --git a/templates/configmap.yaml b/templates/configmap.yaml index 14d8be8..f493ae8 100644 --- a/templates/configmap.yaml +++ b/templates/configmap.yaml @@ -4,6 +4,9 @@ metadata: name: {{ include "control-layer.fullname" . }}-config labels: {{- include "control-layer.labels" . | nindent 4 }} + {{- with include "control-layer.commonAnnotations" . }} + {{- . | nindent 2 }} + {{- end }} data: control-layer-config.yaml: | {{- .Values.config | nindent 4 }} @@ -15,6 +18,9 @@ metadata: name: {{ include "control-layer.fullname" . }}-bootstrap labels: {{- include "control-layer.labels" . | nindent 4 }} + {{- with include "control-layer.commonAnnotations" . }} + {{- . | nindent 2 }} + {{- end }} data: bootstrap.js: | {{- .Values.bootstrap.content | nindent 4 }} @@ -27,6 +33,9 @@ metadata: name: {{ include "control-layer.fullname" . }}-email-templates labels: {{- include "control-layer.labels" . | nindent 4 }} + {{- with include "control-layer.commonAnnotations" . }} + {{- . | nindent 2 }} + {{- end }} data: {{- range $name, $content := .Values.emailTemplates.files }} {{ $name }}: | diff --git a/templates/deployment.yaml b/templates/deployment.yaml index 3937560..cd7322e 100644 --- a/templates/deployment.yaml +++ b/templates/deployment.yaml @@ -27,6 +27,9 @@ metadata: name: {{ include "control-layer.fullname" . }} labels: {{- include "control-layer.labels" . | nindent 4 }} + {{- with include "control-layer.commonAnnotations" . }} + {{- . | nindent 2 }} + {{- end }} spec: replicas: {{ .Values.replicaCount }} {{- if .Values.rollout.enabled }} diff --git a/templates/fusillade/deployment.yaml b/templates/fusillade/deployment.yaml index 7b5ed04..15e760b 100644 --- a/templates/fusillade/deployment.yaml +++ b/templates/fusillade/deployment.yaml @@ -10,22 +10,32 @@ {{- $database := mergeOverwrite (deepCopy ($fusillade.database | default dict)) (get $config "database" | default dict) -}} {{- $podAnnotations := mergeOverwrite (deepCopy ($fusillade.podAnnotations | default dict)) (get $config "podAnnotations" | default dict) -}} {{- $podLabels := mergeOverwrite (deepCopy ($fusillade.podLabels | default dict)) (get $config "podLabels" | default dict) -}} +{{- $strategy := get $config "strategy" | default $fusillade.strategy -}} +{{- $terminationGracePeriodSeconds := $fusillade.terminationGracePeriodSeconds -}} +{{- if and (hasKey $config "terminationGracePeriodSeconds") (not (kindIs "invalid" (index $config "terminationGracePeriodSeconds"))) }}{{ $terminationGracePeriodSeconds = index $config "terminationGracePeriodSeconds" }}{{ end -}} apiVersion: apps/v1 kind: Deployment metadata: name: {{ include "control-layer.fullname" $root }}{{ $suffix }} labels: {{- include "control-layer.fusillade.labelsFor" (dict "root" $root "component" $component) | nindent 4 }} + {{- with include "control-layer.commonAnnotations" $root }} + {{- . | nindent 2 }} + {{- end }} spec: replicas: {{- if hasKey $config "replicaCount" }} {{ get $config "replicaCount" }}{{- else }} {{ $fusillade.replicaCount }}{{- end }} selector: matchLabels: {{- include "control-layer.fusillade.selectorLabelsFor" (dict "root" $root "component" $component) | nindent 6 }} + {{- with $strategy }} + strategy: + {{- toYaml . | nindent 4 }} + {{- end }} template: metadata: annotations: - checksum/secret: {{ include (print $root.Template.BasePath "/secret.yaml") $root | sha256sum }} - checksum/config: {{ include (print $root.Template.BasePath "/configmap.yaml") $root | sha256sum }} + checksum/secret: {{ include "control-layer.checksum" (dict "root" $root "path" "secret.yaml") }} + checksum/config: {{ include "control-layer.checksum" (dict "root" $root "path" "configmap.yaml") }} {{- with $podAnnotations }} {{- toYaml . | nindent 8 }} {{- end }} @@ -40,6 +50,9 @@ spec: {{- toYaml . | nindent 8 }} {{- end }} serviceAccountName: {{ include "control-layer.serviceAccountName" $root }} + {{- if not (kindIs "invalid" $terminationGracePeriodSeconds) }} + terminationGracePeriodSeconds: {{ $terminationGracePeriodSeconds }} + {{- end }} {{- with (get $config "podSecurityContext" | default $fusillade.podSecurityContext | default $root.Values.podSecurityContext) }} securityContext: {{- toYaml . | nindent 8 }} diff --git a/templates/fusillade/service.yaml b/templates/fusillade/service.yaml index 81038d4..3bbd2af 100644 --- a/templates/fusillade/service.yaml +++ b/templates/fusillade/service.yaml @@ -8,6 +8,9 @@ metadata: name: {{ include "control-layer.fullname" $root }}{{ $suffix }} labels: {{- include "control-layer.fusillade.labelsFor" (dict "root" $root "component" $component) | nindent 4 }} + {{- with include "control-layer.commonAnnotations" $root }} + {{- . | nindent 2 }} + {{- end }} spec: type: ClusterIP ports: diff --git a/templates/fusillade/servicemonitor.yaml b/templates/fusillade/servicemonitor.yaml index 9c3c458..385c6ae 100644 --- a/templates/fusillade/servicemonitor.yaml +++ b/templates/fusillade/servicemonitor.yaml @@ -11,6 +11,9 @@ metadata: {{- with $root.Values.serviceMonitor.labels }} {{- toYaml . | nindent 4 }} {{- end }} + {{- with include "control-layer.commonAnnotations" $root }} + {{- . | nindent 2 }} + {{- end }} spec: selector: matchLabels: diff --git a/templates/heap-profiling-networkpolicy.yaml b/templates/heap-profiling-networkpolicy.yaml index 5a4f99a..ae692d4 100644 --- a/templates/heap-profiling-networkpolicy.yaml +++ b/templates/heap-profiling-networkpolicy.yaml @@ -5,6 +5,9 @@ metadata: name: {{ include "control-layer.fullname" . }}-heap-profiling labels: {{- include "control-layer.labels" . | nindent 4 }} + {{- with include "control-layer.commonAnnotations" . }} + {{- . | nindent 2 }} + {{- end }} spec: podSelector: matchLabels: diff --git a/templates/keystore/service.yaml b/templates/keystore/service.yaml index aa7fb75..89a377c 100644 --- a/templates/keystore/service.yaml +++ b/templates/keystore/service.yaml @@ -6,6 +6,9 @@ metadata: name: {{ include "control-layer.fullname" . }}-keystore labels: {{- include "control-layer.keystore.labels" . | nindent 4 }} + {{- with include "control-layer.commonAnnotations" . }} + {{- . | nindent 2 }} + {{- end }} spec: type: ClusterIP ports: diff --git a/templates/keystore/statefulset.yaml b/templates/keystore/statefulset.yaml index 187de93..ef5243a 100644 --- a/templates/keystore/statefulset.yaml +++ b/templates/keystore/statefulset.yaml @@ -6,6 +6,9 @@ metadata: name: {{ include "control-layer.fullname" . }}-keystore labels: {{- include "control-layer.keystore.labels" . | nindent 4 }} + {{- with include "control-layer.commonAnnotations" . }} + {{- . | nindent 2 }} + {{- end }} spec: serviceName: {{ include "control-layer.fullname" . }}-keystore # Single instance by design: the keystore is a strongly-consistent custody diff --git a/templates/keystore/storageclass.yaml b/templates/keystore/storageclass.yaml index ffe01cf..4a13eed 100644 --- a/templates/keystore/storageclass.yaml +++ b/templates/keystore/storageclass.yaml @@ -6,9 +6,15 @@ metadata: name: {{ include "control-layer.keystore.storageClassName" . }} labels: {{- include "control-layer.keystore.labels" . | nindent 4 }} - {{- with .Values.keystore.persistence.managedStorageClass.annotations }} + {{- $commonAnnotations := include "control-layer.commonAnnotationEntries" (dict "root" . "own" .Values.keystore.persistence.managedStorageClass.annotations) }} + {{- if or .Values.keystore.persistence.managedStorageClass.annotations $commonAnnotations }} annotations: + {{- with .Values.keystore.persistence.managedStorageClass.annotations }} {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $commonAnnotations }} + {{- . | nindent 4 }} + {{- end }} {{- end }} provisioner: {{ .Values.keystore.persistence.managedStorageClass.provisioner | quote }} reclaimPolicy: {{ .Values.keystore.persistence.managedStorageClass.reclaimPolicy | quote }} diff --git a/templates/migrations/config.yaml b/templates/migrations/config.yaml index 81a0b9a..95e33e2 100644 --- a/templates/migrations/config.yaml +++ b/templates/migrations/config.yaml @@ -15,6 +15,9 @@ metadata: {{- include "control-layer.migrations.labels" . | nindent 4 }} annotations: {{- include "control-layer.migrations.hookAnnotations" (dict "root" . "weight" "-5" "wave" .Values.migrations.job.prerequisiteSyncWave) | nindent 4 }} + {{- with include "control-layer.commonAnnotationEntries" (dict "root" . "own" (include "control-layer.migrations.hookAnnotations" (dict "root" . "weight" "-5" "wave" .Values.migrations.job.prerequisiteSyncWave) | fromYaml)) }} + {{- . | nindent 4 }} + {{- end }} data: control-layer-config.yaml: | {{- .Values.config | nindent 4 }} diff --git a/templates/migrations/job.yaml b/templates/migrations/job.yaml index ad3d3b6..6f1886e 100644 --- a/templates/migrations/job.yaml +++ b/templates/migrations/job.yaml @@ -52,6 +52,10 @@ metadata: {{- with .Values.migrations.job.annotations }} {{- toYaml . | nindent 4 }} {{- end }} + {{- $own := merge (include "control-layer.migrations.hookAnnotations" (dict "root" . "weight" "0" "wave" .Values.migrations.job.syncWave) | fromYaml) (.Values.migrations.job.annotations | default dict) }} + {{- with include "control-layer.commonAnnotationEntries" (dict "root" . "own" $own) }} + {{- . | nindent 4 }} + {{- end }} spec: backoffLimit: {{ .Values.migrations.job.backoffLimit }} activeDeadlineSeconds: {{ .Values.migrations.job.activeDeadlineSeconds }} @@ -66,8 +70,8 @@ spec: {{- toYaml . | nindent 8 }} {{- end }} annotations: - checksum/config: {{ include (print $.Template.BasePath "/migrations/config.yaml") . | sha256sum }} - checksum/secret: {{ include (print $.Template.BasePath "/migrations/secret.yaml") . | sha256sum }} + checksum/config: {{ include "control-layer.checksum" (dict "root" . "path" "migrations/config.yaml") }} + checksum/secret: {{ include "control-layer.checksum" (dict "root" . "path" "migrations/secret.yaml") }} {{- with .Values.migrations.job.podAnnotations }} {{- toYaml . | nindent 8 }} {{- end }} diff --git a/templates/migrations/secret.yaml b/templates/migrations/secret.yaml index 66f5085..12747ab 100644 --- a/templates/migrations/secret.yaml +++ b/templates/migrations/secret.yaml @@ -24,6 +24,9 @@ metadata: {{- include "control-layer.migrations.labels" . | nindent 4 }} annotations: {{- include "control-layer.migrations.hookAnnotations" (dict "root" . "weight" "-5" "wave" .Values.migrations.job.prerequisiteSyncWave) | nindent 4 }} + {{- with include "control-layer.commonAnnotationEntries" (dict "root" . "own" (include "control-layer.migrations.hookAnnotations" (dict "root" . "weight" "-5" "wave" .Values.migrations.job.prerequisiteSyncWave) | fromYaml)) }} + {{- . | nindent 4 }} + {{- end }} type: Opaque data: {{- range $key, $value := include "control-layer.migrations.secretData" . | fromYaml }} diff --git a/templates/model-provisioning-configmap.yaml b/templates/model-provisioning-configmap.yaml index ac3588d..aeda00c 100644 --- a/templates/model-provisioning-configmap.yaml +++ b/templates/model-provisioning-configmap.yaml @@ -5,6 +5,9 @@ metadata: name: {{ include "control-layer.fullname" . }}-model-provisioning labels: {{- include "control-layer.labels" . | nindent 4 }} + {{- with include "control-layer.commonAnnotations" . }} + {{- . | nindent 2 }} + {{- end }} {{- if .Values.modelProvisioning.files }} data: {{- range $name := keys .Values.modelProvisioning.files | sortAlpha }} diff --git a/templates/postgres/secret.yaml b/templates/postgres/secret.yaml index 7b26117..68e3dcf 100644 --- a/templates/postgres/secret.yaml +++ b/templates/postgres/secret.yaml @@ -4,6 +4,9 @@ metadata: name: {{ include "control-layer.fullname" . }}-postgres-secret labels: {{- include "control-layer.postgres.labels" . | nindent 4 }} + {{- with include "control-layer.commonAnnotations" . }} + {{- . | nindent 2 }} + {{- end }} type: Opaque stringData: {{- with .Values.secrets.postgres.data }} diff --git a/templates/postgres/service.yaml b/templates/postgres/service.yaml index 0645b73..30fbfbb 100644 --- a/templates/postgres/service.yaml +++ b/templates/postgres/service.yaml @@ -5,6 +5,9 @@ metadata: name: {{ include "control-layer.fullname" . }}-postgres labels: {{- include "control-layer.postgres.labels" . | nindent 4 }} + {{- with include "control-layer.commonAnnotations" . }} + {{- . | nindent 2 }} + {{- end }} spec: type: ClusterIP ports: diff --git a/templates/postgres/statefulset.yaml b/templates/postgres/statefulset.yaml index 6f221c8..48f5af4 100644 --- a/templates/postgres/statefulset.yaml +++ b/templates/postgres/statefulset.yaml @@ -5,6 +5,9 @@ metadata: name: {{ include "control-layer.fullname" . }}-postgres labels: {{- include "control-layer.postgres.labels" . | nindent 4 }} + {{- with include "control-layer.commonAnnotations" . }} + {{- . | nindent 2 }} + {{- end }} spec: serviceName: {{ include "control-layer.fullname" . }}-postgres replicas: {{ .Values.postgresql.replicaCount }} @@ -14,7 +17,7 @@ spec: template: metadata: annotations: - checksum/secret: {{ include (print $.Template.BasePath "/postgres/secret.yaml") . | sha256sum }} + checksum/secret: {{ include "control-layer.checksum" (dict "root" . "path" "postgres/secret.yaml") }} {{- with .Values.postgresql.podAnnotations }} {{- toYaml . | nindent 8 }} {{- end }} diff --git a/templates/secret.yaml b/templates/secret.yaml index b553828..c66954a 100644 --- a/templates/secret.yaml +++ b/templates/secret.yaml @@ -5,6 +5,9 @@ metadata: name: {{ include "control-layer.secretName" . }} labels: {{- include "control-layer.labels" . | nindent 4 }} + {{- with include "control-layer.commonAnnotations" . }} + {{- . | nindent 2 }} + {{- end }} type: Opaque stringData: {{- $secrets := .Values.secrets.controlLayer.data }} diff --git a/templates/service.yaml b/templates/service.yaml index 48ae652..a32d431 100644 --- a/templates/service.yaml +++ b/templates/service.yaml @@ -4,6 +4,9 @@ metadata: name: {{ include "control-layer.fullname" . }} labels: {{- include "control-layer.labels" . | nindent 4 }} + {{- with include "control-layer.commonAnnotations" . }} + {{- . | nindent 2 }} + {{- end }} spec: type: {{ .Values.service.type }} ports: diff --git a/templates/serviceaccount.yaml b/templates/serviceaccount.yaml index 05e0ab0..0f2becc 100644 --- a/templates/serviceaccount.yaml +++ b/templates/serviceaccount.yaml @@ -5,9 +5,15 @@ metadata: name: {{ include "control-layer.serviceAccountName" . }} labels: {{- include "control-layer.labels" . | nindent 4 }} - {{- with .Values.serviceAccount.annotations }} + {{- $commonAnnotations := include "control-layer.commonAnnotationEntries" (dict "root" . "own" .Values.serviceAccount.annotations) }} + {{- if or .Values.serviceAccount.annotations $commonAnnotations }} annotations: + {{- with .Values.serviceAccount.annotations }} {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $commonAnnotations }} + {{- . | nindent 4 }} + {{- end }} {{- end }} automountServiceAccountToken: {{ .Values.serviceAccount.automount }} {{- end }} diff --git a/templates/servicemonitor.yaml b/templates/servicemonitor.yaml index f591acc..cf1b669 100644 --- a/templates/servicemonitor.yaml +++ b/templates/servicemonitor.yaml @@ -8,6 +8,9 @@ metadata: {{- with .Values.serviceMonitor.labels }} {{- toYaml . | nindent 4 }} {{- end }} + {{- with include "control-layer.commonAnnotations" . }} + {{- . | nindent 2 }} + {{- end }} spec: selector: matchLabels: diff --git a/tests/common_annotations_test.yaml b/tests/common_annotations_test.yaml new file mode 100644 index 0000000..bd9ff6f --- /dev/null +++ b/tests/common_annotations_test.yaml @@ -0,0 +1,81 @@ +suite: test common annotations +templates: + - deployment.yaml + - service.yaml + - configmap.yaml + - secret.yaml + - serviceaccount.yaml + - migrations/job.yaml + - migrations/config.yaml + - migrations/secret.yaml +tests: + - it: annotates every object with commonAnnotations + set: + commonAnnotations: + argocd.argoproj.io/sync-wave: "-20" + asserts: + - equal: + path: metadata.annotations["argocd.argoproj.io/sync-wave"] + value: "-20" + template: deployment.yaml + - equal: + path: metadata.annotations["argocd.argoproj.io/sync-wave"] + value: "-20" + template: service.yaml + - equal: + path: metadata.annotations["argocd.argoproj.io/sync-wave"] + value: "-20" + template: secret.yaml + - equal: + path: metadata.annotations["argocd.argoproj.io/sync-wave"] + value: "-20" + template: serviceaccount.yaml + + - it: leaves objects unannotated by default + asserts: + - notExists: + path: metadata.annotations + template: deployment.yaml + - notExists: + path: metadata.annotations + template: service.yaml + + - it: keeps an object's own annotations and adds the common ones + set: + serviceAccount.annotations: + eks.amazonaws.com/role-arn: arn:aws:iam::123:role/control-layer + commonAnnotations: + argocd.argoproj.io/sync-wave: "-20" + template: serviceaccount.yaml + asserts: + - equal: + path: metadata.annotations + value: + eks.amazonaws.com/role-arn: arn:aws:iam::123:role/control-layer + argocd.argoproj.io/sync-wave: "-20" + + - it: lets a migration hook keep its own sync wave + set: + postgresql.enabled: false + secrets.controlLayer.data.DATABASE_URL: postgres://user:pass@host:5432/db + migrations.job.enabled: true + commonAnnotations: + argocd.argoproj.io/sync-wave: "-20" + example.com/owner: platform + asserts: + - equal: + path: metadata.annotations["argocd.argoproj.io/sync-wave"] + value: "-5" + template: migrations/job.yaml + - equal: + path: metadata.annotations["example.com/owner"] + value: platform + template: migrations/job.yaml + - equal: + path: metadata.annotations["argocd.argoproj.io/sync-wave"] + value: "-10" + template: migrations/config.yaml + - equal: + path: metadata.annotations["example.com/owner"] + value: platform + template: migrations/config.yaml diff --git a/tests/control_layer_deployment_test.yaml b/tests/control_layer_deployment_test.yaml index 2d2760d..9bb2b2b 100644 --- a/tests/control_layer_deployment_test.yaml +++ b/tests/control_layer_deployment_test.yaml @@ -220,3 +220,36 @@ tests: asserts: - failedTemplate: errorMessage: rollout.connectionDrainTimeoutSeconds must be 3600 to match the control-layer request timeout + + - it: renders the extra env, volumes and mounts before the chart's own + template: deployment.yaml + set: + extraEnv: + - name: EXTRA_DIRECTORY + value: /app/extra.d + extraVolumes: + - name: extra + configMap: + name: extra + extraVolumeMounts: + - name: extra + mountPath: /app/extra.d + readOnly: true + asserts: + - equal: + path: spec.template.spec.containers[0].env[0] + value: + name: EXTRA_DIRECTORY + value: /app/extra.d + - equal: + path: spec.template.spec.volumes[0] + value: + name: extra + configMap: + name: extra + - equal: + path: spec.template.spec.containers[0].volumeMounts[0] + value: + name: extra + mountPath: /app/extra.d + readOnly: true diff --git a/tests/fusillade_deployment_test.yaml b/tests/fusillade_deployment_test.yaml index a806384..6659029 100644 --- a/tests/fusillade_deployment_test.yaml +++ b/tests/fusillade_deployment_test.yaml @@ -371,3 +371,78 @@ tests: content: name: DWCTL_BACKGROUND_SERVICES__BATCH_DAEMON__MODE value: "request_only" + + - it: sets the rollout strategy and grace period on both split daemons + template: fusillade/deployment.yaml + set: + fusillade.enabled: true + fusillade.split.enabled: true + fusillade.strategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 0 + maxSurge: 1 + fusillade.terminationGracePeriodSeconds: 3700 + asserts: + - hasDocuments: + count: 2 + - equal: + path: spec.strategy + value: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 0 + maxSurge: 1 + - equal: + path: spec.template.spec.terminationGracePeriodSeconds + value: 3700 + + - it: lets a split daemon override the grace period + template: fusillade/deployment.yaml + set: + fusillade.enabled: true + fusillade.split.enabled: true + fusillade.terminationGracePeriodSeconds: 3700 + fusillade.split.request.terminationGracePeriodSeconds: 60 + asserts: + - equal: + path: spec.template.spec.terminationGracePeriodSeconds + value: 60 + documentIndex: 0 + - equal: + path: spec.template.spec.terminationGracePeriodSeconds + value: 3700 + documentIndex: 1 + + - it: leaves strategy and grace period to Kubernetes by default + template: fusillade/deployment.yaml + set: + fusillade.enabled: true + fusillade.split.enabled: true + asserts: + - notExists: + path: spec.strategy + - notExists: + path: spec.template.spec.terminationGracePeriodSeconds + + - it: does not give the daemons the API pods' extra env and volumes + template: fusillade/deployment.yaml + set: + fusillade.enabled: true + extraEnv: + - name: API_ONLY + value: "1" + extraVolumes: + - name: api-only + emptyDir: {} + asserts: + - notContains: + path: spec.template.spec.containers[0].env + content: + name: API_ONLY + value: "1" + - notContains: + path: spec.template.spec.volumes + content: + name: api-only + emptyDir: {} diff --git a/values.yaml b/values.yaml index ed9405e..3c612e3 100644 --- a/values.yaml +++ b/values.yaml @@ -6,6 +6,10 @@ nameOverride: "" fullnameOverride: "" +# Annotations added to every object the chart renders (for example an Argo CD +# sync wave). An object's own annotation with the same key wins. +commonAnnotations: {} + # This is for the secrets for pulling an image from a private repository imagePullSecrets: [] @@ -276,6 +280,15 @@ volumeMounts: [] # mountPath: "/etc/foo" # readOnly: true +# API pods only (not Fusillade): environment variables (Kubernetes EnvVar +# entries), volumes and volume mounts rendered before the chart's own, so the +# chart's own entries win on a duplicate name. +extraEnv: [] +# - name: FOO +# value: bar +extraVolumes: [] +extraVolumeMounts: [] + # Declarative model catalog loaded transactionally by dwctl during startup. # Each map entry becomes one YAML file in the mounted directory. An enabled # catalog with no files mounts an empty directory and is a startup no-op. @@ -431,6 +444,12 @@ fusillade: tolerations: [] affinity: {} + # Deployment rollout strategy and pod termination grace period. Unset leaves + # Kubernetes' defaults. A split daemon may set its own under split.request or + # split.batch. + strategy: {} + terminationGracePeriodSeconds: null + # Liveness probe for fusillade daemon # Defaults to HTTP healthcheck on the same port as the control layer livenessProbe: