使用 helm 模板助手创建过滤列表

Creating a filtered list using helm template helpers

我正在尝试使用 helm 模板助手根据每个列表成员中的一个键的值从我的 values.yaml 文件中的列表中过滤掉值。

我的图表目前由这些文件组成 -
values.yaml -

namespaces:
- name: filter
  profiles:
  - nonProduction
- name: dont-filter
  profiles:
  - production  
clusterProfile: production

templates/namespaces.yaml

apiVersion: v1
kind: List
items:
{{ $filteredList := include "filteredNamespaces" . }}
{{ range $filteredList }}
  {{ .name }}
{{- end -}}

templates/_profile-match.tpl

{{/* vim: set filetype=mustache: */}}
{{- define "filteredNamespaces" -}}
  {{ $newList := list }}
  {{- range .Values.namespaces }}
    {{- if has $.Values.clusterProfile .profiles -}}
      {{ $newList := append $newList . }}
    {{- end -}}
  {{ end -}}
  {{ $newList }}
{{- end -}}

问题是在我的帮助文件中,$newList 变量只填充在 range 循环的范围内,我最终得到一个返回到 [=16 的空列表=]模板。
有什么办法解决这个问题吗?我是不是采取了错误的方法来解决这个问题?

尽管所有 Go 模板都是几乎 通用函数,但它们有一些限制。这些限制之一是它们只能 return 一个字符串;你不能写像 mapfilter 这样的基本功能助手,因为你不能 return 结果列表。

如您所示,进行过滤的更直接的方法是将其移至调用方的位置(如果需要在多个位置可能会重复该条件):

items:
{{- range .Values.namespaces }}
{{- if has $.Values.clusterProfile .profiles }}
  - {{ .name }}
{{- end }}
{{- end }}

让这个工作如您所愿的一种 hacky 方法是将列表编组为其他一些基于字符串的格式,例如 JSON:

{{- define "filteredNamespaces" -}}
...
{{ toJson $newList }}
{{- end -}}

{{- range include "filteredNamespaces" . | fromJson -}}...{{- end -}}

另请记住,您可以使用 helm install -f 选项注入 Helm 值文件。因此,与其列出选项的每个排列然后过滤掉您不想要的选项,不如重组它,以便 namespaces: 仅包含您实际想要使用的名称空间列表,但随后您使用不同的值每个配置文件的文件。

我不得不处理一个非常相似的问题。我给出了一个最小示例,说明如何过滤和使用生成的模板作为列表 (Helm 3)。

_helpers.tpl:

{{- define "FilteredList" -}}

  {{ $newList := list }}
  {{- range .Values.my_list }}
    {{ $newList = append $newList .pvc }}
  {{- end }}

  {{ toJson $newList }}
{{- end }}

pvc.yaml:

{{- range include "FilteredList" . | fromJsonArray }}
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: {{ . }}
spec:
  resources:
    requests:
      storage: 1G
---
{{- end }}

values.yaml:

my_list:
  - name: foo
    pvc: pvc-one
  - name: foo2
    pvc: pvc-two
  - name: foo3
    pvc: pvc-three

如您所料生成 3 个 PVC 资源。
请注意这里的两件事,这与问题和接受的答案不同:

  • 追加和覆盖列表时,我们使用 = 而不是 :=。请注意 Helm 3 docs for "append" 提供的示例:$new = append $myList 6.
    我其实不知道为什么需要=,我这边的快速研究没有任何结果。

  • 使用 fromJsonArray 从 JSON 字符串中恢复列表。然而这个函数是not documented yet which is very unfortunate and the main reason i provide this extra answer. You can find it in Helm's source

我们遇到了类似的问题,感谢 提供的答案,我们得以解决这个问题。为了google的缘故,我也会在这里提供:)

我们的 values.yaml 包括我们所有的秘密引用,我们想根据当前正在部署的服务过滤这些秘密。

我们在 values.yaml 中添加了一个新数组(名为 selectedSecrets),这是当前部署所需的机密列表。然后,在函数的帮助下,仅将秘密引用传递给部署,这些引用包含在 selectedSecrets 中。请注意,如果 selectedSecrets 不存在,则以下函数 returns 是 secretRefs 的原始完整列表。

{{- define "FilteredSecrets" -}}

    {{ $result := .Values.secretRefs }}
    {{ $selectedSecrets := .Values.selectedSecrets }}
    {{- if gt (len $selectedSecrets) 0 -}}
        {{ $result = list }}
        {{ range $secret := .Values.secretRefs }}
            {{ if has $secret.name $selectedSecrets }}
                {{ $result = append $result $secret }}
            {{- end -}}
        {{- end }}
    {{- end -}}
    {{ toJson $result }}
{{- end }}

部署中的相关部分:

containers:
  - env:
    {{- range include "FilteredSecrets" . | fromJsonArray }}
    {{- range $env := .envs }}
    - name: {{ $env.name }}
      valueFrom:
      secretKeyRef:
        key: {{ $env.name }}
        name: {{ .name }}
        optional: {{ $env.optional }}
    {{- end }}
    {{- end }}