I have a "YAML" file. And I want to validate it before I render the go-template variables in it. For example:
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Hello World"
drink: {{ .Values.favorite.drink | default "tea" | quote }}
food: {{ .Values.favorite.food | upper | quote }}
The typical YAML parser doesn't work here, as it will parse {
as the start of a map.
err := yaml.Unmarshal(data, &Content)
// Failed to parse the provided YAML: yaml: line 4: did not find expected key
I wonder if there is any package that can help me do this? I've searched online for a while but have no luck. Thanks for any help!
It's not just the YAML parser complaining: that actually is invalid YAML (because the {...}
is inline mapping syntax). That looks like it comes from the Kubernetes Helm deployment tool, and some routine-but-interesting uses really actually require rendering the YAML.
In practice what you probably want is to use the helm template
command to render a chart to multi-document YAML, and then run a YAML validator on that. It doesn't seem to be documented, but Helm version 3 will actually do this validation on its own (Helm 2 doesn't) so if your chart produces invalid YAML you'll get an error at that point.
The way Helm works, it interprets this "YAML" file as a plain text file and applies Go text/template
templating to it, and then reads it back as YAML. To some extent you could make this valid YAML by quoting strings yourself:
name: "{{ .Release.Name }}-configmap"
But there's some fairly common constructs where this will actually break the generated YAML. For example, the helm create
template generates
{{/* _helpers.tpl */}}
{{- define "<CHARTNAME>.labels" -}}
helm.sh/chart: {{ include "<CHARTNAME>.chart" . }}
{{- end -}}
metadata:
name: {{ include "<CHARTNAME>.fullname" . }}
labels:
{{- include "<CHARTNAME>.labels" . | nindent 4 }}
and no amount of quoting will make this valid YAML. It's very possible to put something into the "labels" helper template that's not valid in a YAML mapping context and you want to catch that in your validation stage.