I'm using the text/template
package to dynamically construct my k8s manifest and I was almost successful in creating it the required output.
Since the target type is YAML, I want to ensure, the generated type of .ownerReferences
and .secrets
are created as list types in YAML, i.e. with a leading -
on each entry.
The output I'm expecting to achieve is
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: Foobar
labels:
app: Foobar
ownerReferences:
- uid: 123456789
kind: FoobarOrchestrator
secrets:
- name: thisisasecret1
- name: thisisasecret2
But with the attempt I have below
package main
import (
"os"
"text/template"
)
const serviceAccountTemplate = `---
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{.Name}}
{{- if .Labels}}
labels:
{{- end }}
{{- range $key, $value := .Labels }}
{{ $key }}: {{ $value }}
{{- end }}
{{- if .OwnerRef}}
ownerReferences:
{{- end }}
{{- range .OwnerRef }}
uid: {{ .UID }}
kind: {{ .Kind }}
{{- end }}
{{- if .Secrets}}
secrets:
{{- end }}
{{- range $value := .Secrets }}
name: {{ $value }}
{{- end }}
`
func main() {
type OwnerRef struct {
UID string
Kind string
}
data := struct {
Name string
Secrets []string
Labels map[string]string
OwnerRef []OwnerRef
}{
"dude",
[]string{"thisisasecret1", "thisisasecret2"},
map[string]string{"app": "Foobar"},
[]OwnerRef{OwnerRef{UID: "123456789", Kind: "Foobar"}},
}
t := template.New("t")
t, err := t.Parse(serviceAccountTemplate)
if err != nil {
panic(err)
}
err = t.Execute(os.Stdout, data)
if err != nil {
panic(err)
}
}
I was able to produce below
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: dude
labels:
app: Foobar
ownerReferences:
uid: 123456789
kind: Foobar
secrets:
name: thisisasecret1
name: thisisasecret2
but I want to be sure, if the types are accurate to be accepted by a proper YAML decoder.
Also would appreciate any enhancements to my existing template definition.
Playground link - https://go.dev/play/p/EbxcvGcYr9r
CodePudding user response:
To make the example template output YAML sequences for the desired nodes you can simply prepend -
in front of the child nodes. E.g.
const serviceAccountTemplate = `
...
{{- if .OwnerRef}}
ownerReferences:
{{- end }}
{{- range .OwnerRef }}
- uid: {{ .UID }}
kind: {{ .Kind }}
{{- end }}
{{- if .Secrets}}
secrets:
{{- end }}
{{- range $value := .Secrets }}
- name: {{ $value }}
{{- end }}
`
https://go.dev/play/p/R86Feu5VZOK
There's however no support in text/template
to check for proper YAML syntax. If you need guarantee that the generated text is valid YAML you'll have to write the tests for that.
But, just like when you want to generate JSON in Go you'd normally use structs and encoding/json
, so too with YAML you can use structs and gopkg.in/yaml.v3
to generate consistently valid YAML.