Verify if path value is unique in helm template

4/10/2020

I'm trying to check if my path value is unique. This is my value.yml example:

 ingresses:
  - name: ingress-1
    path: /route2
    host: example.com
  - name: ingress-2
    path: /route2
    host: example.com

In this example I want to exclude or concatenate the second route. This is my ingress.yml template:

{{- range $ingress := .Values.ingresses -}}
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: sampleName
  labels:
    app: sampleName
    deploymentStrategy: sampleStrategy
spec:
  rules:
    - host: "{{ $ingress.host }}"
      http:
        paths:
          - backend:
              serviceName: SampleName
              servicePort: 80
            path: /sampleApp/{{ $ingress.path }}
---
{{- end -}}

I'm in range context, so I can't check another ingresses. Do you have any idea how to do this

-- Pierre Malherbe
go-templates
kubernetes-helm

1 Answer

4/10/2020

Since (as you note) you can't enforce uniqueness across multiple Ingress objects, I'd probably accept that "one service declares the same endpoint" is just a specific case of "the same endpoint can be declared multiple times" and do nothing.

Helm templates have access to a support library called Sprig that allows some more general-purpose data structures. If you just want to check that there aren't duplicates, you can use a dictionary:

{{- $paths := dict -}}
{{- range $ingress := .Values.ingresses -}}
{{- if hasKey $paths $ingress.path -}}
{{- printf "Duplicate ingress path %s" $ingress.path | fail -}}
{{- else -}}
{{- $_ := set $paths $ingress.path $ingress.path -}}
{{- end -}}
{{- end -}}

You can use a similar approach to only emit the first Ingress object that has a given path (don't fail if the key exists, do include the template for it immediately after the set).

-- David Maze
Source: StackOverflow