I'm looking for a solution to control the input values(defined in values.yaml). I would like to check if the input value is authorized.
Example:
values.yaml
provider: aws
services:
- nginx
- varnish
- php
And in another file(maybe _helpers.tpl?)
authorized_providers:
- aws
- azure
authorized_services:
- nginx
- php
And raise an error(custom message if it's possible) to indicate that the input values are not supported/authorized.
My goal is to avoid to generate a Kubernetes configmap with unsupported values(helm install works but this configuration will generate container errors).
EDIT:
I finally found a solution using "required" with some tricks. Following my example with my values.yaml config file.
I define in _helpers.tpl:
{{/*
Define the authorized Value for the parameter: .Values.provider
*/}}
{{- define "authorized.provider" }}
{{- printf "aws,azure" }}
{{- end }}
{{/*
Define the error message if the .Values.provider doesn't respect the authorized.provider condition.
*/}}
{{- define "error.provider" }}
{{- $provider := include "authorized.provider" . }}
{{- printf "Invalid value set for .Values.provider - Must be one of %s" $provider }}
{{- end }}
{{/*
Define the authorized Value for the parameter: .Values.services
*/}}
{{- define "authorized.services" }}
{{- printf "nginx,php" }}
{{- end }}
{{/*
Define the error message if the .Values.services doesn't respect the authorized.services condition.
*/}}
{{- define "error.services" }}
{{- $services := include "authorized.services" . }}
{{- printf "Invalid value set for .Values.services - Authorized values are %s" $services }}
{{- end }}
And next, I've created another file: input-values-validation.yaml
{{- $provider := include "authorized.provider" . }}
{{- $errorProvider := include "error.provider" . }}
{{- if not (has .Values.provider (splitList "," $provider)) }}
{{ required $errorProvider .Values.foo }}
{{- end }}
{{- $services := include "authorized.services" . }}
{{- $errorServices := include "error.Services" . }}
{{- $root := . -}}
{{- range .Values.services }}
{{- if not (has . (splitList "," $services)) }}
{{ required $errorServices $root.Values.foo }}
{{- end }}
{{- end }}
Output if bad input value:
==> Linting
[ERROR] templates/: render error in "templates/input-values-validation.yaml": template: templates/input-values-validation.yaml:12:3: executing "templates/input-values-validation.yaml" at<required $errorServ...>: error calling required: Invalid value set for .Values.services - Authorized values are nginx,php
Infos:
".Values.foo" must never be set in the values.yaml file. I used it to fail the "required" check and raise the error. I've tried to put the content of "input-values-validation.yaml" in the _helpers.tpl file but this generate an error "[ERROR] templates/: rendering template failed: runtime error: invalid memory address or nil pointer dereference". It seems that the "required" function must be used only in yaml files.
So with this solution, I'm able to define the authorized values in the _helpers.tpl file and generate a "custom" error message. And if in the futur I support more providers/services(my example), I'll only need to modify the value in "authorized.provider" and "authorized.services".
I've not seen it done with helm2, at least not in a scan of the official charts, the attempt to define common functions in an incubator chart.
The trickiest bit is being able to give a good error - the closest I've seen is the sprig fail function
But helm3 should provide for this kind of validation, either with schemas or lua
Otherwise perhaps you could do it like:
aws:
nginx: false
varnish: false
php: true
So that the chart user chooses which services they want with a true/false