Consul Template variable assinging with condition - haproxy

I have to assign some variable depending on other variable and some conditions
I've tried to code this but with no luck
{{- $region_for_link := $region}}
{{- if eq $region "a"}} {{- $region_for_link := "AAA"}} {{- end}}
{{- if eq $region "b"}} {{- $region_for_link := "BBB"}} {{- end}}
I wanted to have value in $region_for_link AAA when $region is a, but after that $region_for_link is still a. How to code that properly, probably it is obvious case, but I can't get it.
Please help, I'm waiting for your answer
Best Regards

Consul-template uses a version of the Go Template engine. According to the documentation at https://golang.org/pkg/text/template/#hdr-Variables :
A pipeline inside an action may initialize a variable to capture the result. The initialization has syntax
$variable := pipeline
where $variable is the name of the variable. An action that declares a variable produces no output.
Variables previously declared can also be assigned, using the syntax
$variable = pipeline
The below code, resulted in printing of AAA:
{{ $region := "a" }}
{{- $region_for_link := $region}}
{{- if eq $region "a"}} {{- $region_for_link = "AAA"}} {{- end}}
{{- if eq $region "b"}} {{- $region_for_link = "BBB"}} {{- end}}
{{ $region_for_link }}

Related

helm function to transform yaml to property-like format

new to k8s, trying to remove stupid boilerplate and write better config-map.yaml generation. Expected format is:
...
data:
first.property: 1
second.property: 2
...
I don't want to refer there key by key to values.yaml, like:
...
data:
first.property: {{.Values.configuration.first.property}}
second.property: {{.Values.configuration.second.property}}
...
I want to include whole subtree into here, like:
{{ (toYaml .Values.configuration | indent 2) }}
That works, but (as expected) the yaml is inserted as is. I need to adapt it to property-like format. So the question is: is there a function/way in helm/go templates how to transform this yaml:
a:
b:
c: 1
d: 2
into following representation?
a.b.c: 1
a.b.d: 2
this based on answer How do you apply a recursive formatting with Go Templates (Helm)? in which I fixed some problems and the final solution could be:
{{- define "flattenYaml" -}}
{{- $dict := . -}}
{{- $prefix := $dict.prefix -}}
{{- $data := $dict.data -}}
{{- $knd := kindOf $data -}}
{{- if eq $knd "map" }}
{{- range (keys $data) }}
{{- $key := . }}
{{- $prefixedKey := (printf "%s.%s" $prefix $key) }}
{{- $value := get $data $key }}
{{- $valueKind := kindOf $value }}
{{- if eq $valueKind "map" }}
{{- include "flattenYaml" (dict "prefix" ($prefixedKey) "data" $value) }}
{{- else }}
{{- printf "%s=%s\n" $prefixedKey (toJson $value) }}
{{- end }}
{{- end }}
{{- else }}
{{ toJson . }}#k({{ $knd }})
{{- end }}
{{- end -}}
for more details see my answer there.

helm: how to check if a service with prefix already exists in namespace

I want to implement some k8s services only if there is a service with suffix "mysuffix" in the namespace. I tried the following but doesn't work
{{- $previousReleaseInstalled := false -}}
{{- range $index, $service := (lookup "v1" "Service" .Release.Namespace "").items }}
{{- if hasSuffix "mysuffix" "$service.name" }}
{{- $previousReleaseInstalled := true -}}
{{- end }}
{{- end }}
{{- if $previousReleaseInstalled -}}
implement some services
{{- end }}
Your lookup function is almost correct. The issue with the assignment of the $previousReleaseInstalled variable. You need to use = instead of := inside the range. Check this answer for the details Why doesn't this change the value of the variable in the range loop in Helm?
Another issue is the wrong key name. You should use $service.metadata.name instead of $service.name, and remove the quotes around the $service.metadata.name
{{- $previousReleaseInstalled := false -}}
{{- range $index, $service := (lookup "v1" "Service" .Release.Namespace
"").items }}
{{- if hasSuffix "mysuffix" $service.metadata.name }}
{{- $previousReleaseInstalled = true -}}
{{- end }}
{{- end }}
{{- if $previousReleaseInstalled -}}
implement some services
{{- end }}
Another important thing to note, the lookup function always returns empty response when used with the helm template command. https://helm.sh/docs/chart_template_guide/function_list/#lookup

How can I apply template function to a range result in Helm?

My goal is to convert values in Values.yaml into the following:
CUSTOM_VARIABLE: "TEST_ENV_1=devil,TEST_ENV_2=god,TEST_ENV_3=angel"
### Values.yaml
env:
TEST_ENV_1: devil
TEST_ENV_2: god
TEST_ENV_3: angel
The below template almost does this but I'm getting comma at the end: TEST_ENV_1=devil,TEST_ENV_2=god,TEST_ENV_3=angel,.
### _envVars.tpl
{{ define "envVars" }}
...
- name: CUSTOM_VARIABLE
value: "
{{- range $key, $value := .Values.env -}}
{{- printf "%s=%s," $key $value -}}
{{- end -}}
"
...
{{- end }}
Is there a way to apply template function (e.g. trunc to remove last symbol) to a range result in my case?
try something like
{{range $i, $e := $}}
{{if $i}},{{end}}
{{$e}}{{end}}
If actually look for the index and if it's zero it's wont to add the , at last. here is if is not behave like normal it checks the index also.
{{- range $i, $e := . -}}
{{if $i}}, {{end}}prefix_{{$e}}
{{- end}}
above loop will give output like : prefix_one, prefix_two, prefix_three
https://play.golang.org/p/KuRh55BHna8
Read more at : https://groups.google.com/g/golang-nuts/c/XBScetK-guk/m/Bh7ZFz6R3wQJ
If you write the range call into a helper template, Helm has an include extension function that calls a template and captures its output as a string.
{{/* Render the map-type template parameter to a key=value,key=value,
list, ending with a trailing comma. */}}
{{- define "custom.variable.format" -}}
{{- range $key, $value := . -}}
{{ $key }}={{ $value }},
{{- end -}}
{{- end -}}
- name: CUSTOM_VARIABLE
value: {{ include "custom.variable.format" .Values.env | trimSuffix "," | quote }}
(It is probably cleaner to not generate the comma at all, as #HarshManvar's answer proposes.)

Is it possible to define variables use if/else condition in helm chart?

In my values.yaml I have:
isLocal: false
localEnv:
url: abcd
prodEnv:
url: defg
Then I have a service.yaml:
{{- if .Values.isLocal }}
{{- $env := .Values.localEnv }}
{{- else}}
{{- $env := .Values.prodEnv }}
{{- end}}
url: {{ $env.url}}
Unfortunately I got a 'undefined variable "$env"' error, does anyone have idea how to achieve this? Thanks!
One more way would be to create the variable before starting the if/else block. For example:
{{- $env := .Values.prodEnv -}}
{{ if .Values.isLocal }}
{{- $env = .Values.localEnv -}}
{{ end}}
Notice that I've not used the := operator inside the if block as the variable is already created.
and then
url: {{ $env.url}}
The Go text/template documentation notes:
A variable's scope extends to the "end" action of the control structure ("if", "with", or "range") in which it is declared....
so your declarations of $env go out of scope at the end of the {{ if }}...{{ end }} block, which isn't so useful.
Helm also includes (almost all of) a support template library called Sprig which includes a ternary function, which acts sort of like an inline "if" statement. For your example you could write
{{- $env := ternary .Values.localEnv .Values.prodEnv .Values.isLocal -}}
(Also consider just writing totally separate Helm values files for each environment, and installing your chart with helm install -f prod.yaml, instead of trying to encapsulate every possible environment in a single file.)
You actually can define the variable $env outside the if block and assign its value using = with if block.
{{- $env := "" }}
{{- if .Values.isLocal }}
{{- $env = .Values.localEnv }}
{{- else}}
{{- $env = .Values.prodEnv }}
{{- end}}
url: {{ $env.url}}
Please note: := will declare the variable while assigning the value. On the other hand, = will assign the value only.
If you use := in if, it will declare a new local variable $env which will not impact the value of $env declared outside the if block.

Adding news lines when defining collection

I am trying to define a collection (dict), and I would like to add a new line on each definition (for readability), Eg:
{{ $deployment := dict
"Release" .Release
"Chart" .Chart
"Values" .Values }}
But when I do this, helm respond a parse error :
Error: parse error in "XXX": template: XXX:2: unclosed action
Error: UPGRADE FAILED: parse error in "XXX": template: XXX:2: unclosed action
Is there a way in HELM to do this?
I achieved this by defining the dict first and then setting one key per line.
{{- $myDict := dict "" "" -}}
{{- $_ := set $myDict "myKey1" "myValue1" -}}
{{- $_ := set $myDict "myKey2" "myValue2" -}}
{{- $_ := set $myDict "myKey3" "myValue3" -}}
{{- $_ := set $myDict "myKey4" "myValue4" -}}
Bonus Tip: Since dict get function is available seemingly in only helm3 and later, you can use this hack to get a value from a dict to a string.
{{/* Hack needed until helm 3 which has 'get' for 'dict' */}}
{{- $myValue3Var := pluck "myKey3" $myDict | first -}}
TLDR;
It's impossible to declare dict in multiline way, like with Perl fat comma operator.
Please check the reference of "Sprig: Template functions for Go templates."
Instead you could use this sort of hacky way to achieve similar result:
Keep each key value pair in separate line, in Global Values file for readability:
# values.yaml
--
global:
someMap:
coffee: robusta
origin: Angola
crema: yes
Define helper template in _helpers.tpl:
{{- define "mychart.labels.standard"}}
{{- $global := default (dict) .Values.global.someMap -}}
Release: {{ .Release.Name | quote }}
Chart: {{ .Chart.Name }}
Values:
{{- $global := default (dict) .Values.global.someMap -}}
{{- range $key, $value := $global }}
{{ $key }}: {{ $value }}
{{- end }}
{{- end -}}
Include it in another template:
helm_data:
{{- $global := default (dict) .Values.global -}}
{{- range $key, $value := $global }}
{{ $key }}: {{ $value }}
{{- end }}
{{ include "mychart.labels.standard" . | nindent 0 -}}
Render it to verify the result (helm template --name dict-chart .)
---
# Source: mychart/templates/data_type.yaml
helm_data:
someMap: map[crema:true origin:Angola coffee:robusta]
Release: "dict-chart"
Chart: mychart
Values:
coffee: robusta
crema: true
origin: Angol
It seems it's impossible to do so. The Helm templating system is basically the Go templating system. As stated in the Go templating docs:
Except for raw strings, actions may not span newlines, although comments can.
For people coming across this question, this functionality works in recent versions of HELM. For me, OPs example works as-is (Helm v3.8.2).
(I came across this question myself due to a mismatched ) in my template.)