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 }}
}