Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

helm templating with toYaml

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?

like image 270
Jimmy Smith Avatar asked Jun 10 '20 15:06

Jimmy Smith


People also ask

What does toYaml do in Helm?

The above includes a template called toYaml , passes it $value , and then passes the output of that template to the indent function. Because YAML ascribes significance to indentation levels and whitespace, this is one great way to include snippets of code, but handle indentation in a relevant context.

Does Helm use Go templates?

While we talk about the "Helm template language" as if it is Helm-specific, it is actually a combination of the Go template language, some extra functions, and a variety of wrappers to expose certain objects to the templates.

What is the templating language used by Helm?

To summarise, Helm is: a templating engine for your YAML files.

What is the helm template?

The template is just a section of the ingress.yaml file that is auto-generated when you use the helm create command the full template is below.

How do I evaluate a string as a template in helm?

You can do this by using the tpl function in your Helm chart templates. To quote the Helm documentation, “The tpl function allows developers to evaluate strings as templates inside a template.” Imagine a Deployment resource template contains the following snippet:

What is helm in helm?

Helm is a convenient templating engine: it uses the Go templating engine and the helpers from the Sprig library. You can compile and deploy the pod.yaml resource above with: But the reason for such a quick uptake isn't for the templating alone. A collection of templated resources in Helm is called a chart.

What is helm for YAML?

To summarise, Helm is: a templating engine for your YAML files a convenient way for packaging collections of YAML files and distributing them in public and private registry a release manager capable of rolling back deployments


1 Answers

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

like image 188
Shudipta Sharma Avatar answered Oct 21 '22 22:10

Shudipta Sharma