Search code examples
kuberneteskubernetes-helmgo-templates

How to add counter to helm range


Here is my values.yaml file:

options:
  collection: "myCollection"
  ttl: 100800
  autoReconnect: true
  reconnectTries: 3
  reconnectInterval: 5

Now I'm trying to convert it into JSON in my configMap like this:

options: {
  {{- range $key, $val := .Values.options }}
  {{ $key }}: {{ $val | quote }},
  {{- end }}
}

But I need to eliminate last comma in JSON so I'm trying to add a counter:

options: {
  {{ $c := 0 | int }}
  {{- range $key, $val := .Values.options }}
  {{ if ne $c 0 }},{{ end }}
  {{- $key }}: {{ $val | quote }}
  {{ $c := $c add 1 }}
  {{- end }}
}

But I'm getting following error for helm template ... command:

at <$c>: can't give argument to non-function $c

So what am I doing wrong?


Solution

  • Helm has an undocumented toJson template function, so if you can get your data in the right format you can just ask it to serialize it.

    Managing the quoting for the embedded JSON file will be tricky. The two good options are to use a YAML block scalar, where indentation at the start of a line delimits the content, or treat it as binary data.

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: x
    data:
      optionsAsBlockScalar: >-
    {{ .Values.options | toJson | indent 4 }}
    binaryData:
      optionsAsBase64: {{ .Values.options | toJson | b64enc }}
    

    Note that this approach will preserve the native types of the objects in the JSON content; your example forces everything to strings. If you need everything to be a string then the Sprig support library contains functions to convert arbitrary objects to strings and to mutate a dictionary-type object in place, though this starts to get into the unfortunate land of writing real code in your templating language.