I have values.yml file that takes in a list of ports with this format and default values:
Ports:
- number: 443
protocol: http
The script that output the list of port to use as my input gives me this format:
port_list=$(./get_ports.sh)
output:
- 80
- 8080
I want the resulting rendered template to be
Ports:
- number: 80
- number: 8080
How would I accomplish this? I tried the following in my template file:
{{- with .Values.Ports }}
Ports:
{{- toYaml . | nindent 8 }}
{{- end }}
using helm template and setting values.Ports=$port_list
, it ended up giving me a pipe and an extra dash like below, which I do not know where they come from, how do I accomplish getting to the format I want above based on the input?
Ports:
|-
- number: 80
- number: 8080
As a bonus, I would also like to have a default protocol in my port list when the protocol isn't specified.
Ports:
- number: 80
protocol: http
- number: 8080
protocol: http
Is there a clean way to do this with just templating?
First, you have to know about the YAML syntax about string. You can find it by searching on the internet. For example: see YAML Multiline.
|
enables multiline string and -
chops the trailing \n
from the end of the string.
The reason for appearing |-
is the output of the script get_ports.sh
(is being treated as a single string). You can test this,
port_list=$(get_ports.sh)
# pass this to the `--set` flag in both of the following ways
# 01: pass the var $port_list
--set ports=$port_list
# 02: directly pass the value of the var $port_list
--set ports="- 80
- 8080"
For both of the tests you have the same output as follows:
ports:
|-
- 80
- 8080
If you put a newline at the end of the output of your script, then you will see the -
has disappeared.
--set ports="- 80
- 8080
"
The output is like as following:
ports:
|
- 80
- 8080
Now try in a different way. Change your template to like this one:
{{- if .Values.ports }}
{{- print "ports:" | nindent 2 }}
{{- range $_, $p := .Values.ports }}
- number: {{ $p }}
protocol: http
{{- end }}
{{- end }}
This template expects the value of your ports in the --set
flag as a list (not a string). According to my knowledge at the time of writing this answer, to provide a list value in --set
flag either of the followings can be used:
--set ports={80\,8080}
--set ports[0]=80,ports[1]=8080
Now the output is same as you want.
$ helm template test . --set ports={80\,8080}
ports:
- number: 80
protocol: http
- number: 8080
protocol: http
So all you need to process the output of get_ports.sh
. That's it.
You may need to adjust the indentation in the template