Home > Back-end >  Helm templating.. values match
Helm templating.. values match

Time:02-17

Wondering whether it's possible to use a port if it exists in the values, else use http.. something like this;

svc:
  app:
    ports:
      - port: 8080
        name: http
      - port: 8090
        name: metrics
  app2:
    ports:
      - port: 8080
        name: http

Some service expose their metrics over http and some have metrics ports.. So I'd like to template it something like;

{{ define "app.service.ports" }}
{{ range (index .Values.svc (include "app.refName" .) "ports") }}
- name: {{ .name }}
{{ end }}
{{ end }}

This will pull each port name right, but I want to pull metrics if it exists, else pull http.. can someone point me in the right direction?

CodePudding user response:

Neither the Go text/template language nor the Helm extensions have any way to do a generic lookup in a complex structure like this. Instead you need to manually iterate through the list and use a variable to remember what you've seen.

{{- $ports := index .Values "svc" (include "app.refName" .) "ports" -}}

{{-/* Set up variables to remember what we've seen.  Initialize them
      to an empty dictionary, which is false in a conditional. -*/}}
{{- $httpPort := dict -}}
{{- $metricsPort := dict -}}

{{-/* Scan the list of ports. */-}}
{{- range $port := range $ports -}}
  {{- if eq $port.name "metrics" -}}
    {{- $metricsPort = $port -}}
  {{- else if eq $port.name "http" -}}
    {{- $httpPort = $port -}}
  {{- end -}}
{{- end -}}

{{-/* Emit the metrics port if it exists, else the HTTP port. */-}}
{{- coalesce $metricsPort $httpPort | toYaml -}}

In a higher-level language you could imagine searching a list, and for each dictionary element, accepting it if it has a name key with value metrics. This usually involves passing a lambda or anonymous function to a find() function, and the text/template language has no support for that.

  • Related