Search code examples
kubernetes-helmgo-templates

Return a list variable from a helm helper function


I would like to save some boilerplate template code in helm. In my values.yaml I have to fields: schema, schemas which define the same object, once singular and once as list.

In my template I would like to not care about this. Thats why I combine this field as a single list:

{{- $schemas := list -}}
{{- if .Values.schema -}}
{{- $schemas = list .Values.schema -}}
{{- end -}}
{{- if .Values.schemas -}}
{{- $schemas = .Values.schemas -}}
{{- end -}}

then I can simply loop over $schemas

Now I do not want to copy past this whole bulk into every template. I would love to handle this as a helper function.

so I tried this:

{{- define "helper.schemas" -}}
{{- $schemas := list -}}
{{- if .Values.postgres.database.schema -}}
{{- $schemas = list .Values.postgres.database.schema -}}
{{- end -}}
{{- if .Values.postgres.database.schemas -}}
{{- $schemas = .Values.postgres.database.schemas -}}
{{- end -}}
{{- $schemas }}
{{- end -}}

.....
mytemplate.yaml

{{- range $indx, $schema := include "helper.schemas" .  }}
...

this results in range can't iterate over [map[.. ..]]

How can I pass as helm list from a helper function to a template variable?


Solution

  • In the Go text/template language, defined helper functions only ever produce strings. In the core language, the template action writes the string to the template's output; Helm has an include extension that returns a string, but it always returns only a string and nothing else.

    In principle you could use some other syntax, like transforming the list result to and from JSON

    {{- define "helper.schemas -}}
    {{/* ... */}}
    {{- toJson $schemas -}}
    {{- end -}}
    
    {{ $schemas := include "helper.schemas" . | fromJson }}
    

    Perhaps writing this as a one-liner might make it easier to copy-and-paste, but maybe not

    {{ $schemas := .Values.schema | list | compact | default .Values.schemas }}
    

    (Take schema; package it into a singleton list; remove falsey [null] values from the list; and if the result is falsey [empty] then use schemas instead.)

    In practice I'd probably avoid having two different settings for the same thing and just use the list-typed schemas setting, with the YAML syntax for a single-valued list being pretty straightforward.