Helm tpl function to render a file does not work - kubernetes-helm

I am trying to render a file using the tpl function. I am retrieving the content of the file using Files.Get, which works fine until I use tpl function on it.
My input file is:
apiVersion: autoscaling/v2beta2
My helm template is:
{{- $files := .Files }}
{{- tpl ($files.Get "files/autoscaling.yaml" ) . -}}
I had to use $files because it would throw the error:
at <.Files.Get>: can't evaluate field Files in type interface {}
The output that I see when I run the helm template is
Error: template: subchart-demoapp/templates/sub-deployments.yaml:5:47: executing "subchart-demoapp/templates/sub-deployments.yaml" at <.>: wrong type for value; expected chartutil.Values; got string
helm.go:84: [debug] template: subchart-demoapp/templates/sub-deployments.yaml:5:47: executing "subchart-demoapp/templates/sub-deployments.yaml" at <.>: wrong type for value; expected chartutil.Values; got string
My helm version is:
version.BuildInfo{Version:"v3.2.1", GitCommit:"fe51cd1e31e6a202cba7dead9552a6d418ded79a", GitTreeState:"clean", GoVersion:"go1.13.10"}
Thanks for any help.

Figured it out. tpl function when used in a range block needs the top-level context as the second argument. Ref: Helm Issue
Replaced the . with $ and it works as expected.

Related

Use regex in helm template

I'm trying to provide a condition inside my helm template to check for a valid (or a rather invalid) hostname using regexMatch function.
Here's my line of code that I'm using:
{{- if regexMatch "(?:[0-9]{1,3}\.){3}[0-9]{1,3}$" .Values.hostname }}
The related part in the values file is a simple one:
hostname: 10.10.10.10
However, I'm hitting a syntax error with no real explanation:
Error: parse error at (api-gateway/templates/ingress.yml:1): invalid syntax
When I've tried to use the example from the docs: https://helm.sh/docs/chart_template_guide/function_list/#regexmatch-mustregexmatch
it obviously worked, so I wonder why my code isn't working.
Turns out that I needed to use a double backslash to make it work:
{{- if regexMatch "(?:[0-9]{1,3}\\.){3}[0-9]{1,3}$" .Values.hostname }}

Syntax Error in Yaml File - missed comma between flow collection entries

We have an application deployed in AKS , the kubernetes version we were using is 1.15 now we want to upgrade the Kubernetes to 1.16, I notice that some of the APIs have been deprecated in 1.16.We have deployment.yaml file in which I had to change the from
apiVersion: extensions/v1beta1 to apiVersion: apps/v1 for Deployment.
after doing this change I see that the deployment YAML is failing lint test for another entry :
- name : APP_HOST
{{- range $host := .Values.ingress.hosts }}
value: {{ $host }}
{{- end }}
Error :
npx yaml-lint yamllint deployment.yaml
npx: installed 45 in 14.04s
× YAML Lint failed for deployment.yaml
× missed comma between flow collection entries at line 88, column 11:
{{- range $host := .Values.ingress ...
Can some one help me with the syntax needed for this. Mind you it was working fine before. Not sure if I have added and extra space or corrupted the file.
Thanks
The syntax you have looks like a correct Helm template, including correct whitespace controls. However, it is not valid YAML; the template {{ ... }} syntax looks at least a little bit like an inline mapping { key: value }, and this confuses the linter.
You can't run the un-rendered Helm template files through yamllint or another plain YAML validator. You can run helm template to render the template to plain text, and then run yamllint on that. The current version of Helm will try to parse the produced YAML as it generates it, so just running helm template will give you some protection against whitespace errors.

Helm Charts - How do I use `default` on undefined object property values?

Using Helm, I was under the impression default would be the fallback if a variable is not defined. However, it doesn't appear Helm can get to values in sub-object hashes:
type: {{ default "NodePort" .Values.fpm.service.type }}
If .Values.fpm.service or service.type is not defined, it should use 9000.
However, attempting to template this throws a nil pointer error:
<.Values.fpm.service.type>: nil pointer evaluating interface {}.type
Is there a way to simply perform this level of variable testing? Or am I subjected to an if/else test?
The intent of this is to optionally define .fpm.service (and [..].type) within your values.yaml file.
(I'm building a Helm Library chart to handle optional definitions by main charts)
According to the official Helm doc (Using Default Function), the syntax is different and you should use it this way:
type: {{ .Values.fpm.service.type | default "NodePort" | quote }}
Doesn't look like there's really a good way to stop Helm from trying to dive into non-existing objects. I moved into a single line if condition, and it worked:
type: {{ if .Values.fpm.service -}} {{ .default "NodePort" .Values.fpm.service.type | quote }} {{- else -}} "NodePort" {{- end }}
This way, I check if fpm.service exists first, before trying .type check. It works, whether .service and .service.type is or is not defined.

Using an include statement as the default value

I am creating a helm chart in which I want to specify a default for a value using a template function. Specifically I want to either use the override value image.name, or default to the template function chart.name:
{{ .Values.image.name | default include chart.name . }}
But when linting the chart I have the following error:
[ERROR] templates/: render error in "chart/templates/deployment.yaml": template: chart/templates/deployment.yaml:22:81: executing "chart/templates/deployment.yaml" at <include>: wrong number of args for include: want 2 got 0
Is it possible to use an included template function as the default value? Or can I only use literals?
You can. Just enclose your include statement in parentheses:
{{ .Values.image.name | default (include "chart.name" .)}}
Please see using the default function

helm template: how do i assign the result of a template to a variable

I'm trying to do something like:
{{- $cassandrafullname := template "cassandra.fullname" . -}}
but I'm getting this error on a dry run:
Error: UPGRADE FAILED: parse error in "cassandra/templates/service.yaml": template: cassandra/templates/service.yaml:1: unexpected <template> in command
The reason why I have this issue is because I am unable to use the template cassandra.fullname within a range, so I'm trying to put the value into a variable and use it in the range instead. So if there's a solution for that, it would also be accepted!
Helm defines an include function which is identical to the standard template, except that it returns the rendered output instead of outputting it. You should be able to write
{{- $cassandrafullname := include "cassandra.fullname" . -}}
Unfortunately this does not work with fromYaml, so you can't read yaml structs into pipeline operations as usual. A rather big shortcoming. Lots of times I need to filter a list into another list, but this seems impossible with helm:
{{- define "sometpl" -}}
- bla: dibla
- oki: doki
{{- end -}}
---
{{- $v := include "sometpl" . | fromYaml }}
some: {{- $v | toYaml | nindent 2 }}
Will give
some:
Error: 'error unmarshaling JSON: while decoding JSON: json: cannot unmarshal array
into Go value of type map[string]interface {}'