在 Helm 模板中解压 Go 映射值

Unpack a Go map value in a Helm template

对于我想象中 Go 模板 / Helm 中经常出现的问题,我似乎找不到一个简单有效的解决方案。基本上,给定一个 values.yaml 这样的:

ingress:
  hosts:
  - host: busy-a.local
    paths:
    - backend:
        serviceName:busy-a
        servicePort: 80
      path: /busy/[A-Z0-9]{1}

和一个 templates/ingress.yaml 像这样:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: {{.Values.project}}-ingress
  annotations:
    nginx.ingress.kubernetes.io/use-regex: "true"
spec:
  rules:
  {{- range .Values.ingress.hosts }}
    - host: {{ .host | quote }}
      http:
        paths:
        {{- range .paths }}
          - path: {{ .path }}
            backend:
              serviceName: {{ .backend.serviceName }} # this works
              servicePort: {{ .backend.servicePort }} # but can we shorthand backend?
        {{- end }}
  {{- end }}

但是,"unpack" .paths range 中的 backend 地图会不会比 backend: {{.backend}} 更容易?然而,它似乎并没有那样工作。

...
    paths:
      - path: /busy/[A-Z0-9]{3}
        backend: map[serviceName:busy-a servicePort:80]

在 Go 模板或 Sprig 扩展中解包或分配整个对象的首选方法是什么?

Helm 有 a couple of barely-documented functions,其中之一是 toYaml。这接受任意对象并以 YAML 格式写出,未缩进。

在你的情况下,你可以通过组合 toYamlindent:

来实现你想要的
spec:
  ...
            backend:
{{ .backend | trim | indent 14 }}
{{/* above line intentionally at left margin */}}

由于 toYaml 可以很好地处理嵌套对象,考虑到您的输入和输出,我可能会将其应用到更高的位置:

spec:
  rules:
  {{- range .Values.ingress.hosts }}
    - host: {{ .host | quote }}
      http:
        paths: {{- .paths | toYaml | trim | nindent 10 }}
  {{- end }}

toYaml 将始终发出尾随换行符,因此我倾向于 trim 关闭它以便更好地控制它。在最后一个示例中,我使用 nindent 插入一个 leading 换行符,使模板更紧凑一些。