Helm Go Template to Combine Files

5/23/2018

Given as set of JSON files, that contain this simplified data: file1.json:

{ "name" : "file1" }

file2.json:

{ "name" : "file2" }

And so on. I want to create a config map that ends up with the content of these files combined into a JSON map that looks like this:

apiVersion: v1
kind: ConfigMap
metadata:
  name: jsondata
data:
  jsondata: |-
    {
      "file1":  { "name" : "file1" },
      "file2":  { "name" : "file2" }
    }

Note that the last item should not be followed by a comma. If I create template yaml that looks like this:

apiVersion: v1
kind: ConfigMap
metadata:
  name: jsondata
data:
  jsondata: |-
    {
{{- $root := . }}
{{- range $path, $bytes := .Files.Glob "data/json/*.json" }}
  {{ base $path | replace ".json" "" | quote | indent 4 }}:
  {{ $root.Files.Get $path | indent 6 }}
  {{- "," }}
{{- end }}
    }

I end up with an extra comma after the file2 element, which breaks the json syntax.

How can I iterate over the files and know where I am (on the first or the last) so I can control whether to insert the comma or not? I've tried to figure out how to get the keys of the glob result into a list so I could use first and rest, but can't figure out what that syntax would be in the go template.

This is not a duplicate of detect last item inside an array using range inside go-templates unless you can show how to get the glob results into an array that has an index. The glob result doesn't have an index, it is a dictionary of file name / bytes.

Update: Hmm, I guess this question is dead because it was incorrectly flagged as a "duplicate." It is a shame this system has this way of shutting something down when it isn't really a duplicate.

For the interest of those who really need to solve a problem like this and are not helped by the substantially unrelated link to the "duplicate" that works on a simple list, here is a solution:

data:
  appdata: |-
    {
      {{- $candidates := .Files.Glob "data/json/*.json" -}}
      {{- $valuesJson := toJson $candidates -}}
      {{- $filesMap := fromJson $valuesJson -}}
      {{- $outputMap := dict -}}
      {{- range $index, $filename := keys $filesMap -}}
        {{- $fileContents := $.Files.Get $filename -}}
        {{- $fileContentMap := fromJson $fileContents -}}
        {{- $contentName := pluck "name" $fileContentMap | first -}}
        {{- $_ := set $outputMap $filename $contentName -}}
      {{- end -}}
      {{- range $index, $filename := keys $outputMap -}}
        {{- if ne $index 0 -}}
          ,
        {{- end -}}
        {{- pluck $filename $outputMap | first | printf "%q:" | nindent 6 -}}
        {{- $.Files.Get $filename | nindent 8 -}}
      {{- end }}
    }
-- Matt Gerrans
go
kubernetes
kubernetes-helm
templates

0 Answers