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.