helm escape ` in template yaml file - kubernetes-helm

Does anyone know how to espace ` in helm template?
I try to add \ in front doesn't seem to work
original:
{{- if not .Values.istio_cni.chained }}
k8s.v1.cni.cncf.io/networks: '{{ appendMultusNetwork (index .ObjectMeta.Annotations `k8s.v1.cni.cncf.io/networks`) `istio-cni` }}',
{{- end }}
Tried:
{{- if not .Values.istio_cni.chained }}
k8s.v1.cni.cncf.io/networks: '{{`{{ appendMultusNetwork (index .ObjectMeta.Annotations \`k8s.v1.cni.cncf.io/networks\`) `istio-cni` }}`}}',
{{- end }}
Error:
Error: parse error at (test/templates/istio-sidecar-injector-istio-system-ConfigMap.yaml:29): unexpected "k8s" in operand

In the Go text/template language backticks delimit "raw string constants"; in standard Go, there is no escaping at all inside raw string literals and they cannot contain backticks.
In your example, it looks like you're trying to emit a Go template block into the output. You can make this work if you use double quotes around the variable names inside the template, and then backticks around the whole thing:
# double quotes around string literal
# v v
k8s.v1.cni.cncf.io/networks: '{{`{{ appendMultusNetwork ... "istio-cni" }}`}}'
# ^ ^
# backticks around whole expression

Related

Include a helm template in yaml file, removing quotes

This is a snippet from helpers.tpl of my helm chart:
{{/*
Pod-specific labels - added to pod template only
Adding a revision label to the pod will cause it to restart every time the chart is deployed.
*/}}
{{- define "app.podLabels" -}}
helm-revision: {{ .Release.Revision | quote }}
{{- end }}
Including it in pod labels like this:
labels:
{{- include "app.podLabels" . | nindent 8 }}
The result would be as shown below. The quotes around 1 is required because Kubernetes accepts string labels only.
labels:
helm-revision: "1"
I need to use the same template for an init container, replacing the : with = like this:
args:
- "pod"
- "-l {{ include "app.podLabels" . | replace ": " "=" }}"
But the output would be an incorrect yaml:
args:
- "pod"
- "-l helm-revision="1""
with error:
error converting YAML to JSON: yaml: line 34: did not find expected '-' indicator
What I actually want is something like this, that doesn't contain quotes around 1:
args:
- "pod"
- "-l helm-revision=1"
How can I achieve this?
This can be achieved by replacing " with nothing ( In effect, removes "). Escaping the quotes using \ character would be needed.
Also adding a replace function to remove newlines and add , as a separator between labels. This would be helpful if more than one pod-specific label is present. But make sure this will work in your case when rendering the template.
args:
- "pod"
- "-l {{ include "app.podLabels" . | replace ": " "=" | replace "\n" ", " | replace "\"" "" }}"

Helm 'if' condition in one line

I was trying to put the if condition in a single line of the helm template:
- name: ENV_VARIABLE
value: {{- if .Values.condition }}"Value1"{{- else }}"Value2"{{- end }}
However, I'm getting error:
Error: YAML parse error on chart/templates/deployment.yaml: error
converting YAML to JSON: yaml: line NN: could not find expected ':'
So I've ended up with multi-line condition:
- name: ENV_VARIABLE
{{- if .Values.condition }}
value: "Value1"
{{- else }}
value: "Value2"
{{- end }}
which is working fine, but is very uncompact.
Is there a way to use one-liner if condition in helm?
What you do works, but you use the leading hyphen, which removes all preceding whitespace.
The below will render as value:foo due to the hyphen.
value: {{- "foo" }}
If you remove the hyphen, it should work.
That said, there is also the ternary function which could fit here.
ternary
The ternary function takes two values, and a test value. If the test value is true, the first value will be returned. If the test value is empty, the second value will be returned. This is similar to the c ternary operator.
true test value
ternary "foo" "bar" true
or
true | ternary "foo" "bar"
- name: ENV_VARIABLE
value: {{ .Values.condition | ternary "value1" "value2" | quote }}

How to use printf in this Helm template function?

I created this Helm template function in my templates/_helpers.yaml file. It simply gets the gets the value of an array element (the index .Values... part), based on the passed-in environment. It works fine.
{{/*
Function to get min CPU units
*/}}
{{- define "microserviceChart.minCpuUnits" -}}
{{ index .Values.valuesPerEnvironment.cpuUnits ((pluck .Values.environment .Values.environments | first | default .Values.environments.sandbox) | int) | quote }}
{{- end }}
For example, in my values.yaml file
environments:
sandbox: 0
staging: 1
production: 2
valuesPerEnvironment:
cpuUnits: [512, 512, 1024]
so my template function returns "512", "512", "1024" based on my passed-in environment. However, can I use printf to it adds m to these values? In other words, I want it to return "1024m" for production. I tried the following but I get a syntax error
{{/*
Function to get min CPU units
*/}}
{{- define "microserviceChart.minCpuUnits" -}}
{{- printf "%dm" index .Values.valuesPerEnvironment.cpuUnits ((pluck .Values.environment .Values.environments | first | default .Values.environments.sandbox) | int) | quote }}
{{- end }}
Instead of trying to get the arguments in the right order for printf, you could include the m in the template body. You'll also need to make the "..." explicit, instead of using the quote function, to get the m inside the quotes.
Expanded out (note that {{- and -}} will delete whitespace before and after, including newlines):
{{- define "microserviceChart.minCpuUnits" -}}
"
{{- index .Values.valuesPerEnvironment.cpuUnits ((pluck .Values.environment .Values.environments | first | default .Values.environments.sandbox) | int) -}}
m"
{{- end }}
The heck with it. I just made my values.yaml like this, and I get the same result.
environments:
sandbox: 0
staging: 1
production: 2
valuesPerEnvironment:
cpuUnits: [512m, 512m, 1024m]
It'd still be cool to know if I can do this in the function, so if someone answers the actual question, I'll accept that as the answer.

trying to remove first and last square brackets from json injecting data into configmap using helm

I have data in a JSON file and am adding each line as key value into a ConfigMap using Helm, but i need to remove first and last curly brackets.
Below is the JSON file content:
{
"type": "PurposeResourcesDefinition",
"version": "1.0",
"purposeId": "p#####",
"description": "Artifactory container registry",
"resources": [{
"type": "artifactory.containerregistry",
"name": "<repository name prefixed with the purpose>"
]
}
I am using the below Helm syntax:
data:
{{ range .Files.Lines "foo/app.json" }}
{{ . }}{{ end }}
How can I remove the surrounding curly brackets using Helm templating?
If you know that { and } will be on lines by themselves, you can just skip them. This isn't especially robust, but it will work for the example you show.
data:
{{- range .Files.Lines "foo/app.json" }}
{{- if and (ne . "{") (ne . "}") }}
{{ . }}
{{- end }}
At a higher level, it looks like you're trying to read in a JSON file and then write these values out as the contents of a ConfigMap. Stripping the leading and trailing braces will work because of the syntactic similarities between YAML and JSON, but it might be better to actively convert from one format to the other. Helm has several undocumented conversion functions including fromJson and toYaml. So you can also write this as:
data: {{- .Files.Get "foo/app.json" | fromJson | toYaml | nindent 2 }}

Helm - comma-separated list of dynamic strings

Is it possible, within a helm chart to create a single string which is a comma-separated representation (similar to using the ",".join() command in Python) of strings with a common prefix and a variable suffix?
For example, I have a CLI application that requires an argument like so via the extraArgs parameter in a kubernetes pod definition:
extraArgs: >-
-M {{ $.Values.global.hostname }}/100
I now have to modify this value to be over a range (i.e. from {{$.Values.global.minval}} to {{$.Values.global.maxval}}, inclusive). So, for a minval=100 and maxval=105, my chart needs to now become (note the lack of a trailing comma, and no spaces other than the space after -M):
extraArgs: >-
-M {{ $.Values.global.hostname }}/100,{{ $.Values.global.hostname }}/101,{{ $.Values.global.hostname }}/102,{{ $.Values.global.hostname }}/103,{{ $.Values.global.hostname }}/104,{{ $.Values.global.hostname }}/105
Is there some way I can execute this in a range/loop in my chart? I have several instances of this chart that will use different min/max values, and I'd like to automate this tedious task as much as I can (additionally, I do not have access to the app's source, so I can't change the CLI interface to the application).
In Python, I could accomplish this roughly by:
minval = 100
minval = 105
s = "-M "
L = []
for i in range(minval, maxval+1):
L.append("{{{{ $.Values.global.hostname }}}}/{}".format(i))
s = s + ",".join(L)
# print(s)
I'm not sure where to begin doing this in a Helm template beyond starting with the range() function.
Helm includes the sprig library of template functions which contains untilStep and join.
There is no concept of a map or each operator in sprig yet so you can construct the list in a range loop to be joined later (from here)
{{- $minval := int .Values.minval -}}
{{- $maxval := int .Values.maxval | add1 | int -}}
{{- $args := list -}}
{{- range untilStep $minval $maxval 1 -}}
{{- $args = printf "%s/%d" $hostname . | append $args -}}
{{- end }}
extraArgs: '-M {{ $args | join "," }}'