From 6dedefe207b4c70f00b4428710e89b01f53de0f6 Mon Sep 17 00:00:00 2001 From: Rahul Johny Date: Tue, 6 Oct 2026 14:04:59 +0530 Subject: [PATCH] feat: render imagePullSecrets, nodeSelector and tolerations through tpl Adds pgdog.tplvalues.render (the Bitnami tplvalues.render pattern) and uses it for imagePullSecrets, nodeSelector and tolerations on the PgDog Deployment and for prometheusCollector.nodeSelector / tolerations, so a parent chart can point them at its own global values. A string is rendered as a template producing the whole field; a map or list is rendered with toYaml first, so its leaves may be templated. Values without template markers render unchanged. Chart version v0.85. Co-Authored-By: Claude Opus 5.5 --- Chart.yaml | 2 +- templates/_helpers.tpl | 17 ++++++++++++++ templates/deployment.yaml | 6 ++--- .../prometheus-collector/deployment.yaml | 4 ++-- test/test.sh | 22 +++++++++++++++++++ test/values-tpl-placement.yaml | 16 ++++++++++++++ values.yaml | 16 ++++++++++++-- 7 files changed, 75 insertions(+), 8 deletions(-) create mode 100644 test/values-tpl-placement.yaml diff --git a/Chart.yaml b/Chart.yaml index bc67cf2..843905f 100644 --- a/Chart.yaml +++ b/Chart.yaml @@ -1,4 +1,4 @@ apiVersion: v1 name: pgdog -version: v0.84 +version: v0.85 appVersion: "v0.1.60" diff --git a/templates/_helpers.tpl b/templates/_helpers.tpl index 8a61a1c..c71b45c 100644 --- a/templates/_helpers.tpl +++ b/templates/_helpers.tpl @@ -141,3 +141,20 @@ resources: {{- end }} {{- end }} {{- end -}} + +{{/* +Render a value that may contain Helm template expressions, for fields a parent +chart may need to point at its own global values (pull secrets, placement). +A string is rendered as a template that produces YAML, so it can stand for the +whole field, e.g. '{{ toYaml .Values.global.tolerations }}'. A map or list is +converted to YAML first, so expressions in its leaves are rendered too. A value +with no template markers renders unchanged. Do not template untrusted input. +Usage: {{ include "pgdog.tplvalues.render" (dict "value" .Values.nodeSelector "context" $) }} +*/}} +{{- define "pgdog.tplvalues.render" -}} +{{- if typeIs "string" .value -}} +{{- tpl .value .context -}} +{{- else -}} +{{- tpl (.value | toYaml) .context -}} +{{- end -}} +{{- end -}} diff --git a/templates/deployment.yaml b/templates/deployment.yaml index 1131ae3..5b986df 100644 --- a/templates/deployment.yaml +++ b/templates/deployment.yaml @@ -79,7 +79,7 @@ spec: {{- end }} {{- with .Values.imagePullSecrets }} imagePullSecrets: - {{- toYaml . | nindent 8 }} + {{- include "pgdog.tplvalues.render" (dict "value" . "context" $) | nindent 8 }} {{- end }} {{- with .Values.podSecurityContext }} securityContext: @@ -276,11 +276,11 @@ spec: {{- end }} {{- with .Values.nodeSelector }} nodeSelector: - {{- toYaml . | nindent 8 }} + {{- include "pgdog.tplvalues.render" (dict "value" . "context" $) | nindent 8 }} {{- end }} {{- with .Values.tolerations }} tolerations: - {{- toYaml . | nindent 8 }} + {{- include "pgdog.tplvalues.render" (dict "value" . "context" $) | nindent 8 }} {{- end }} {{- if or .Values.affinity .Values.podAntiAffinity.enabled }} affinity: diff --git a/templates/prometheus-collector/deployment.yaml b/templates/prometheus-collector/deployment.yaml index 054402f..7049e22 100644 --- a/templates/prometheus-collector/deployment.yaml +++ b/templates/prometheus-collector/deployment.yaml @@ -109,11 +109,11 @@ spec: {{- end }} {{- with .Values.prometheusCollector.nodeSelector }} nodeSelector: - {{- toYaml . | nindent 8 }} + {{- include "pgdog.tplvalues.render" (dict "value" . "context" $) | nindent 8 }} {{- end }} {{- with .Values.prometheusCollector.tolerations }} tolerations: - {{- toYaml . | nindent 8 }} + {{- include "pgdog.tplvalues.render" (dict "value" . "context" $) | nindent 8 }} {{- end }} {{- with .Values.prometheusCollector.affinity }} affinity: diff --git a/test/test.sh b/test/test.sh index 5c9d3a4..be05ff7 100755 --- a/test/test.sh +++ b/test/test.sh @@ -99,5 +99,27 @@ else exit 1 fi +echo "" +echo "==> Validating templated pull secrets and placement..." +tpl_field() { + helm template test-release "$CHART_DIR" -f "$TEST_DIR/$1" \ + | yq -o=json -I=0 "select(.kind == \"Deployment\" and .metadata.name == \"test-release-pgdog\") | .spec.template.spec.$2" +} + +tpl_pull=$(tpl_field values-tpl-placement.yaml imagePullSecrets) +tpl_node=$(tpl_field values-tpl-placement.yaml nodeSelector) +tpl_tol=$(tpl_field values-tpl-placement.yaml tolerations) +plain_pull=$(tpl_field values-default.yaml imagePullSecrets) + +if [ "$tpl_pull" = '[{"name":"parent-regcred"}]' ] \ + && [ "$tpl_node" = '{"service":"pooler"}' ] \ + && [ "$tpl_tol" = '[{"effect":"NoSchedule","key":"dedicated","operator":"Equal","value":"pooler"}]' ] \ + && [ "$plain_pull" = "null" ]; then + echo " Templated pull secrets, nodeSelector and tolerations render from the given values" +else + echo " FAIL: unexpected templated fields (pull=$tpl_pull node=$tpl_node tolerations=$tpl_tol default pull=$plain_pull)" + exit 1 +fi + echo "" echo "==> All tests passed!" diff --git a/test/values-tpl-placement.yaml b/test/values-tpl-placement.yaml new file mode 100644 index 0000000..693d897 --- /dev/null +++ b/test/values-tpl-placement.yaml @@ -0,0 +1,16 @@ +# A parent chart pointing pull secrets and placement at its own globals: whole-field +# string templates and a leaf template, rendered through pgdog.tplvalues.render. +global: + imagePullSecrets: + - name: parent-regcred + nodeSelector: + service: pooler + tolerations: + - key: dedicated + operator: Equal + value: pooler + effect: NoSchedule +imagePullSecrets: '{{ toYaml .Values.global.imagePullSecrets }}' +nodeSelector: + service: '{{ .Values.global.nodeSelector.service }}' +tolerations: '{{ toYaml .Values.global.tolerations }}' diff --git a/values.yaml b/values.yaml index c9bee14..d743b73 100644 --- a/values.yaml +++ b/values.yaml @@ -37,6 +37,10 @@ podAnnotations: {} ## imagePullSecrets: ## - name: regcred ## +# Rendered through tpl (pgdog.tplvalues.render), so a parent chart can point it at +# its own globals: a string is a template producing the whole field, e.g. +# '{{ toYaml .Values.global.imagePullSecrets }}'; a map or list may template its leaves. +# Values without {{ }} render unchanged. imagePullSecrets: [] # image contains the Docker image properties. @@ -383,10 +387,18 @@ service: # Valid values: "internet-facing" or "internal" scheme: "internet-facing" -# nodeSelector allows scheduling pods on nodes with specific labels +# nodeSelector allows scheduling pods on nodes with specific labels. +# Rendered through tpl (pgdog.tplvalues.render), so a parent chart can point it at +# its own globals: a string is a template producing the whole field, e.g. +# '{{ toYaml .Values.global.nodeSelector }}'; a map or list may template its leaves. +# Values without {{ }} render unchanged. nodeSelector: {} -# tolerations allows pods to be scheduled on nodes with matching taints +# tolerations allows pods to be scheduled on nodes with matching taints. +# Rendered through tpl (pgdog.tplvalues.render), so a parent chart can point it at +# its own globals: a string is a template producing the whole field, e.g. +# '{{ toYaml .Values.global.tolerations }}'; a map or list may template its leaves. +# Values without {{ }} render unchanged. tolerations: [] # affinity and anti-affinity rules for pod scheduling