Is there a way to store arithmetic results into a helm variable? - kubernetes-helm

I have a variable say :
{{- $var := 7 -}}
I need to perform an arithmetic operation involving this variable and store the result back into the same i.e for example
var = var + 2
I tried doing :
{{- $var := add ( {{ $var }} 2 ) -}}
but doesn't seem to work, throws this error
unexpected "{" in parenthesized pipeline

It should be (see add & documentation):
{{- $var := add $var 2 -}}
For example
apiVersion: v1
kind: ConfigMap
metadata:
name: myconfigmap
data:
{{ $var := 5 }}
prevVal: {{ $var }}
{{ $var = add $var 2 }}
newVal: {{ $var }}
Rendered:
apiVersion: v1
kind: ConfigMap
metadata:
name: myconfigmap
data:
prevVal: 5
newVal: 7
= is to assign a variable and := is define and assign a variable.

Related

In helmcharts, how to combine a list with multiple fields per element into a string?

I have a list that has multiple fields per element, and I would need to concatenate it into a comma separated string that has fields foo and bar separated with a semicolon.
myList:
- foo: "asdf"
bar: "hnng"
- foo: "meh"
bar: "dunno"
For example, the above would need to be concatenated into "asdf;hnng,meh;dunno".
You could iterate through the list with range, but how would you then pass on that list to join? For example, the following should produce a list of strings, but how would I then pass it into join function?
{{- range .Values.myList }}
- {{.foo}};{{.bar}}
{{- end}
=>
- asdf;hnng
- meh;dunno
values.yaml
myList:
- foo: "asdf"
bar: "hnng"
- foo: "meh"
bar: "dunno"
template
apiVersion: v1
kind: ConfigMap
metadata:
name: test
data:
data: |-
{{- $str := "" }}
{{- range $i, $e := .Values.myList }}
{{- if $i }}
{{- $str = print $str "," }}
{{- end }}
{{- $str = print $str $e.foo ";" $e.bar }}
{{- end }}
{{- $str | nindent 4 }}
output
apiVersion: v1
kind: ConfigMap
metadata:
name: test
data:
data: |-
asdf;hnng,meh;dunno
The Go text/template language doesn't have a generic map function or anything else that would make it possible to transform a list into another list. You need to rewrite this to emit the whole string in one block, it's probably not going to be possible to construct an input to join.
When you iterate through the outer list, you can get the current index and then use that to decide whether to set a separator:
{{- $index, $item := range .Values.myList -}}
{{- if ne $index 0 -}},{{- end -}}
{{- $item.foo -}};{{- $item.bar -}}
{{- end -}}
It's possible to make this a lot more complicated - split out the individual item into its own template, change the loop to a recursive template call - but fundamentally you need to emit the list-item separators yourself.

what is the manifest yaml file equivalent of the create configmap --from-env-file command

I need to create a manifest configmap yaml file (configmap template helm) that execute the same operation that we get when we run the command
kubectl create configmap config-env-file --from-env-file=config.properties
Please note that I must retrieve the parameters from 'properties' file (and not from configmap file)
config.properties file
# dummy param
node=2
pod=3
when i run the command that create the the configmap from the config.properties file, I get:
apiVersion: v1
data:
node: "2"
pod: "3"
kind: ConfigMap
metadata:
name: config-env-file
namespace: default
I need to reproduce this result by building a configmap helm chart
thanks
I am by far not an expert on templating, but this works (I took your example literally):
apiVersion: v1
kind: ConfigMap
metadata:
name: config-env-file
namespace: default
data:
{{- $content := .Files.Get "resources/config.properties" }}
{{- range $line := splitList "\n" $content }}
{{ $parts := split "=" $line }}
{{- $key := printf "%s" $parts._0 }}
{{- $value := printf "%s" $parts._1 }}
{{- printf "%s:" $key }} {{ quote $value }}
{{- end }}

How to render list (slice) of string as list in yaml file by Helm Chart

I have a list or (slice) of string data for example [string1, string2, string3].
I want to render it in list fashion in yaml file as
- string1
- string2
- string3
How can I do that?
I have tried
{{- range $val := $list }}
- {{ $val }}
{{- end }}
but it renders following as multiple line of strings
- |-
- string1
- string2
- string2
any idea? thank you in advance
You may use formatted string output to solve the problem.
eg.
values.yaml
arr:
- string1
- string2
- string3
_helpers.tpl
{{/*
Print string from list split by ,
*/}}
{{- define "print.list" -}}
{{- range $idx, $val := $.Values.arr -}}
{{- if $idx }}
{{- print ", " -}}
{{- end -}}
{{- $val -}}
{{- end -}}
{{- end -}}
The template you want to render, for example comfigmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "test.fullname" . }}
data:
test: [{{- include "print.list" .}}]
output
piVersion: v1
kind: ConfigMap
metadata:
name: test
data:
test: [string1, string2, string3]
---↓ 2022-01-05 update ↓---
values.yaml
arr:
- string1
- string2
- string3
The template you want to render, for example comfigmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "test.fullname" . }}
data:
test: |
{{- toYaml $.Values.arr | nindent 4 }}
output
piVersion: v1
kind: ConfigMap
metadata:
name: test
data:
test: |
- string1
- string2
- string3
no pipe
helm --dry-run --debug template test .
The template you want to render, for example comfigmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "test.fullname" . }}
data:
test:
{{- toYaml $.Values.arr | nindent 4 }}
output
piVersion: v1
kind: ConfigMap
metadata:
name: test
data:
test:
- string1
- string2
- string3
range
{{- range $i, $v := $.Values.arr }}
- {{ $v }}
{{- end }}
output
- string1
- string2
- string3

Pass JSON config variable to helm using --set [duplicate]

This question already has answers here:
How to pass entire JSON string to Helm chart value?
(5 answers)
Closed 1 year ago.
apiVersion: v1
kind: ConfigMap
metadata:
name: app-configmap
data:
{{- range $key, $value := .Values.envVars }}
{{ $key }}: {{ $value | quote }}
{{- end }}
Running
helm upgrade my-app --install --set envVars.CREDS='{"key":"val"}'
with the above configmap results in a configmap as follows:
CREDS = ["key":"val"]
So instead of a JSON, it's an array.
What do I need to configure to pass it as a JSON?
That looks fine, based on this answer regarding json objects representation in yamls: https://stackoverflow.com/a/33989696/11874278
If you want to achieve another thing - this key as json string you could do:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-configmap
data:
{{- range $key, $value := .Values.envVars }}
{{ $key }}: >
{{ $value }}
{{- end }}

Helm range without leaving global scope

I need to loop through a list of instances and create 1 stateful set for every instance. However, inside range I then limit myself to the scope of that loop. I need to access some global values in my statefulset.
I've solved it by just putting all global objects I need in an env variable but... this very seems hacky.
What is the correct way to loop through ranges while still being able to reference global objects?
Example of my loop
{{- $values := .Values -}}
{{- $release := .Release -}}
{{- range .Values.nodes }}
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: {{ $release.Name }} <-- Global Scope
labels:
.
.
.
env:
- name: IP_ADDRESS
value: {{ .ip_address }} <-- From range scope
.
.
.
{{- end }}
Example of values
# Global
image:
repository: ..ecr.....
# Instances
nodes:
- node1:
name: node-1
iP: 1.1.1.1
- node2:
name: node-2
iP: 1.1.1.1
When entering a loop block you lose your global context when using .. You can access the global context by using $. instead.
As written in the Helm docs -
there is one variable that is always global - $ - this variable will always point to the root context. This can be very useful when you are looping in a range and need to know the chart's release name.
In your example, using this would look something like:
{{- range .Values.nodes }}
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: {{ $.Release.Name }}
labels:
.
.
.
env:
- name: IP_ADDRESS
value: {{ .ip_address }}
.
.
.
{{- end }}
The question is about the global scope, but it is possible to keep access to any outer scope by storing it, like this:
{{- $outer := . -}}
Then, if you use named variables for the range, like this:
{{- range $idx, $node := .Values.nodes }}
You don't need ., so you can restore the outer scope, like this:
{{- with $outer -}}
In your example, using this would look something like:
{{- $outer := . -}}
{{- range $idx, $node := .Values.nodes }}
{{- with $outer -}}
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: {{ .Release.Name }}
labels:
.
.
.
env:
- name: IP_ADDRESS
value: {{ $node.ip_address }}
.
.
.
{{- end }}
If you need to access the global scope only, simply add {{- with $ -}} will do.
{{- range $idx, $node := .Values.nodes }}
{{- with $ -}}
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: {{ .Release.Name }}
labels:
.
.
.
env:
- name: IP_ADDRESS
value: {{ $node.ip_address }}
.
.
.
{{- end }}
{{- end }}
The best way is not to call many external objects inside the loop.
you can declare release name at the top in a variable to overcome this issue:
{{- $release_name := .Release.Name -}}