How to use without function with helm (go) templating?

5/27/2020

I am using helm to deploy namespaces on our kubernetes clusters.

This is the template:

{{- range $namespaces := .Values.namespaces }}
{{- if ne $namespaces.name "default" }}    
apiVersion: v1
kind: Namespace
metadata:
  name: {{ $namespaces.name }}
  labels:
    name: {{ $namespaces.name }}
{{- end }}

The values file:

namespaces:
  - name: default
  - name: ingress-controller
  - name: rbac-manager
  - name: velero
  - name: test1
  - name: test2
  - name: test3

This works fine, but now I want to set a specific label for certain namespaces. default, ingress-controller, rbac-manager and velero are namespaces I don't want to set the label for, but only for team specific namespaces.. in this case test{1,2,3}. But these variable. So instead of using the has function:

{{ if has .Values.favorite.drink (list "coffee" "thee" "milk") }}mug: true{{ end }}

I would like to use the without function, but I am doing something wrong so hopefull someone can help me out with this one:

{{- range $namespaces := .Values.namespaces }}
{{- if ne $namespaces.name "default" }}    
apiVersion: v1
kind: Namespace
metadata:
  name: {{ $namespaces.name }}
  labels:
    name: {{ $namespaces.name }}
{{ $custom := without $namespaces.name "default" "ingress-controller" "rbac-manager" "velero" }}
{{- if eq $custom.name }}
    namespace: custom
{{- end }}
---
{{- end }}
{{- end }}

When I run this I get error:

Error: UPGRADE FAILED: template: namespaces/templates/namespaces.yaml:10:14: executing "namespaces/templates/namespaces.yaml" at <without $namespaces.name "default" "ingress-controller" "rbac-manager" "velero">: error calling without: Cannot find without on type string

I get the same error when I use:

{{- range $namespaces := .Values.namespaces }}
{{- if ne $namespaces.name "default" }}    
apiVersion: v1
kind: Namespace
metadata:
  name: {{ $namespaces.name }}
  labels:
    name: {{ $namespaces.name }}
{{ $custom := without $namespaces.name (list "default" "ingress-controller" "rbac-manager" "velero") }}
{{- if eq $custom.name }}
    namespace: custom
{{- end }}
---
{{- end }}
{{- end }}
-- bramvdk
go-templates
kubernetes-helm

2 Answers

5/27/2020

I know it is not really an answer on getting it to work with the without function, but I got it work with this:

{{ range $namespaces := .Values.namespaces }}
{{ if ne $namespaces.name "default" }}    
apiVersion: v1
kind: Namespace
metadata:
  name: {{ $namespaces.name }}
  labels:
    name: {{ $namespaces.name }}
{{ if (not (has $namespaces.name (list "default" "ingress-controller" "rbac-manager" "velero"))) }}
    namespace: custom
{{ end }}
{{ end }}
{{ end }}
-- bramvdk
Source: StackOverflow

5/27/2020

You are trying to pass a string as a first parameter to without function, while it requires a list.

Here's an example on how you can do it with without function. I removed redundant name key from namespaces array though.

values.yaml

namespaces:
  - default
  - ingress-controller
  - rbac-manager
  - velero
  - test1
  - test2
  - test3

namespace.yaml

{{ $compare := without .Values.namespaces list "default" "ingress-controller" "rbac-manager" "velero" }}
{{- range $namespace := .Values.namespaces }}
{{- if ne $namespace "default" }}    
apiVersion: v1
kind: Namespace
metadata:
  name: {{ $namespace }}
  labels:
    name: {{ $namespace }}
{{- if has $namespace $compare }}
    namespace: custom
{{- end }}
---
{{- end }}
{{- end }}

As withoutfunction is returning a list, first we create a list without specified values. Than we iterate over namespaces and check whether $custom list has the value or not.

-- edbighead
Source: StackOverflow