I can't seem to find a simple and effective solution for what I imagine comes up a lot in Go templates / Helm. Basically, given a values.yaml like this:
ingress:
hosts:
- host: busy-a.local
paths:
- backend:
serviceName:busy-a
servicePort: 80
path: /busy/[A-Z0-9]{1}
and a templates/ingress.yaml like this:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: {{.Values.project}}-ingress
annotations:
nginx.ingress.kubernetes.io/use-regex: "true"
spec:
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
backend:
serviceName: {{ .backend.serviceName }} # this works
servicePort: {{ .backend.servicePort }} # but can we shorthand backend?
{{- end }}
{{- end }}
But, wouldn't it be easier to "unpack" the backend
map in the .paths range
, like backend: {{.backend}}
? However, it doesn't seem to work like that.
...
paths:
- path: /busy/[A-Z0-9]{3}
backend: map[serviceName:busy-a servicePort:80]
What's the preferred way to unpack or assign a whole object like this in Go Templates or with Sprig extensions?
Helm has a couple of barely-documented functions and one of those is a toYaml
. This accepts an arbitrary object and writes it out in YAML format, unindented.
In your case you can achieve what you're trying for by combining toYaml
and indent
:
spec:
...
backend:
{{ .backend | trim | indent 14 }}
{{/* above line intentionally at left margin */}}
Since toYaml
can handle nested objects just fine, given your input and output, I might apply it higher up:
spec:
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths: {{- .paths | toYaml | trim | nindent 10 }}
{{- end }}
toYaml
will always emit a trailing newline, so I tend to trim
it off so I get a little more control over it. In the last example I use nindent
to insert a leading newline to make the template a little bit more compact.