kuberneteskubernetes-helm

Helm set default for a dict


I have a following template,

{{- if .Values.rollout.nodeSelector | default dict "batch" "true" }}
nodeSelector:
{{- range $nodeSelectorKey, $nodeSelectorValue  := .Values.rollout.nodeSelector }}
  {{- if $nodeSelectorValue }}
  {{ $nodeSelectorKey }}: {{ $nodeSelectorValue | quote }}
  {{- end }}
{{- end }}
{{- end }}

Which basically renders,

nodeSelector:

i.e. the default dict is being set as empty, when explicitly a value is given for nodeSelector, it works, however the default flow does not render anything, can someone point what is wrong with the template/logic,

Thanks!


Solution

  • You need to assign some temporary variables with the defaulted value. I might write

    {{- $rollout := .Values.rollout | default dict }}
    {{- $nodeSelector := $rollout.nodeSelector | default (dict "batch" "true") }}
    nodeSelector:
    {{- range $nodeSelectorKey, $nodeSelectorValue  := $nodeSelector }}
      {{- with $nodeSelectorValue }}
      {{ $nodeSelectorKey }}: {{ toJson . }}
      {{- end }}
    {{- end }}
    

    As you've written it, if $someValue | default ... will always be evaluated – if the condition is falsey, the default will replace it with something else, and then the if will be true. But that expression doesn't change the value of the thing you defaulted. In the range statement, then, you're checking the value of the original value, without the default being applied.

    {{- if .Values.rollout.nodeSelector | default dict "batch" "true" }}
    {{/*^^ always true                    ^^^^^^^ because this replaces a falsey value */}}
    nodeSelector:
    {{- range $nodeSelectorKey, $nodeSelectorValue  := .Values.rollout.nodeSelector }}
    {{/*             but this tests the original value ^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/}}