I want to check if tolerations
is available in global
then use that for all the pods (a parent chart with subcharts) and if each submodule/subchart has its own tolerations
then use that instead of the global one. So this is how I defined it:
{{/* Set tolerations from global if available and if not set it from each module */}}
{{- define "helper.tolerations" }}
{{- if .globalTolerations.tolerations }}
tolerations:
{{toYaml .globalTolerations.tolerations | indent 2}}
{{- else if (.localTolerations.tolerations) }}
tolerations:
{{toYaml .localTolerations.tolerations | indent 2}}
{{- end }}
{{- end }}
and in each sub-chart, I have this:
spec:
template:
spec:
containers:
- name: my-container-name
{{toYaml (include "helper.tolerations" (dict "globalTolerations" .Values.global "localTolerations" (index .Values "ui-log-collector"))) | indent 6}}
The default values in values.yaml
are defined as below:
global:
tolerations: []
ui-log-collector:
image: a.b.c
tolerations: []
some-other-sub-charts:
image: x.y.z
tolerations: []
Now when I want to deploy the stack using helm, I pass a values.yaml
to override tolerations
as below:
global:
tolerations:
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoSchedule"
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoExecute"
ui-log-collector:
tolerations:
- key: "key2"
operator: "Equal"
value: "value2"
effect: "NoSchedule"
- key: "key2"
operator: "Equal"
value: "value2"
effect: "NoExecute"
With this set up I currently get this error:
error converting YAML to JSON: yaml: line 34: could not find expected ':'
I tried different things but I without toYaml
I get:
Error: UPGRADE FAILED: error validating "": error validating data: ValidationError(Deployment.spec.template.spec.tolerations): invalid type for io.k8s.api.core.v1.PodSpec.tolerations: got "string", expected "array"
I see two issues in the code as written. Go templates produce text output, so you don't need to call toYaml
on them. Also, when you call indent
, it doesn't know about the indentation of the current line, so if you're going to indent
something the {{ ... }}
template expression usually needs to be on an unindented line.
The call itself, for example, should look like:
spec:
template:
spec:
containers:
- name: my-container-name
{{ include "helper.tolerations" (dict "globalTolerations" .Values.global "localTolerations" .Values.ui-log-collector) | indent 6}}
{{-/* at the first column; without toYaml */}}
Within the helper function, using toYaml
is appropriate (.Values
is a composite object and not a string) but the indent
line again needs to begin at the first column.
tolerations:
{{toYaml .globalTolerations.tolerations | indent 2}}
You may find it useful to use helm template
to debug issues like this; it will write out the generated YAML file instead of sending it to the cluster. The toYaml
form in the question will probably convert the tolerations:
block into a YAML string, and that would be pretty visible in the output.