Search code examples
kubernetes-helmkubernetes-ingress

Nested loop in helm charts


I have a nested ingress value in the helm charts values.yml as below

  hosts:
    - host:
      paths:
        - path: /
          pathType: Prefix
    - host: ppa
      paths:
        - path: /api/v1/ppob
          pathType: Prefix
        - path: /api/v1/pgob
          pathType: Prefix

with this, I'm trying to print all the routes through notes.txt with the code as


1. Get the application URL by running these commands:
{{- $domainname := .Values.npdomain -}}
{{- $fullName := include "ppgp.fullname" . -}}
{{ println }}
{{- if .Values.ingress.enabled }}
{{- range $host := .Values.ingress.hosts }}
  {{- range .paths }}
  http{{ if $.Values.ingress.tls }}s{{ end }}://{{ if .host }}{{ .host }}.{{ $domainname }}{{ else }}{{ $fullName }}.{{ $domainname }}{{ end }}{{ .paths.path }}
  {{- end }}
{{- end }}
{{- end }}

the output I'm expecting is if tls is enabled

https://ppgp.mydomainvar
https://ppa.mydomainvar/api.v1/ppob
https://ppa.mydomainvar/api.v1/pgob

The output I get is

https://ppgp.mydomainvar
https://ppgp.mydomainvar/api.v1/ppob
https://ppgp.mydomainvar/api.v1/pgob

I know something is incorrect, but I cannot figure it out as I have two .host blocks and I have two .path in the second .host block.

Appreciate it if someone could help with this.

Thanks in advance


Solution

  • Where you check .host you are in the innermost range loop. In that context, . is one of the items from one of the paths: lists.

    You already have a reference $host to the parent item in the hosts: list, and so the easiest fix is to change .host to $host.host the places where it appears.

    Rather than immediately drilling down to the deepest level of the values structure and then trying to construct values from the parent context, you also might consider creating each of the parts of the URL at the level it appears. Each item in paths: belongs to the same hosts: entry and will have the same host part of the URL, for example; this will make the line that emits the URL a little clearer. That might look like:

    {{- $domainname := .Values.npdomain -}}
    {{- $fullName := include "ppgp.fullname" . -}}
    {{- with .Values.ingress }}
      {{- if .enabled }}
        {{- $scheme := empty .tls | ternary "https" "http" }}
        {{- range .hosts }}
          {{- $host := printf "%s.%s" (.host | default $fullName) $domainName }}
          {{- range .paths }}
            {{- printf "%s://%s/%s" $scheme $host .path }}
    {{ end }}
        {{- end }}
      {{- end }}
    {{- end }}