Detect if variable is dict / array / list

5.7k views Asked by At

I've the following values.yaml:

env:
  NODES:
    value:
      - 192.168.178.1:1234
      - 192.168.178.2:1234
      - 192.168.178.3:1234
      - 192.168.178.4:1234
  PASSWORD:
    valueFrom:
      secretKeyRef:
        name: foo
        key: bar

Now, in the deployment I've the following lines to specify the environment:

          env:
            {{- range $name, $item := .Values.env }}
            - name: {{ $name }}
              {{- $item | toYaml | nindent 14 }}
            {{- end }}

This works as long as "NODES" is no list because they are not allowed as env variable, but I would like to specify them as list in the values.yaml. So the question is, how I can test if $item.value is a dict or a simple string.

I tried using typeOf, but it tells me that NODES is "[]interface {}". So I wonder what's the correct way to test?!

My goal is, if I see an array in the env of my deployment to join them using ";", e.g. value: {{ join ";" .env.NODES.value | quote }}.

1

There are 1 answers

0
David Maze On

Helm has some template functions to inspect object types (from the Sprig support library) but these quickly get into the underlying Go type system.

For the specific thing you're asking, you might try the Helm/Sprig kindIs function. This passes through to the underlying Go reflect package but in particular it does distinguish slice (list) and map (dict) as specific kinds.

{{- if and $item.value (kindIs "slice" $item.value) }}
value: {{ join ";" $item.value }}
{{- end }}

Rather than trying to have your Helm values directly reflect the Kubernetes object structure, you might consider having configuration values like this list of nodes as top-level configuration values.

# values.yaml
# not inside an `env:` block, at the top level
nodes:
  - 192.168.178.1:1234
  - 192.168.178.2:1234

Then you can construct these from a known format in your template. This will be much more straightforward than trying to use the reflection functions.

env:
  - name: NODES
    value: {{ join ";" .Values.nodes }}