我正试图使用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/_profilematch.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
循环的范围内填充,并且我最终得到一个返回到namespaces.yaml
模板的空列表
有什么办法解决这个问题吗?我是不是采取了错误的方法来解决这个问题?
尽管Go模板几乎是通用函数,但它们有几个局限性。其中一个限制是它们只返回一个字符串;您不能编写像map
或filter
这样的基本函数帮助程序,因为您不能返回结果列表。
正如您所展示的,进行过滤的更直接的方法是将其移动到调用者的位置(如果在多个地方需要,可能会重复该条件(:
items:
{{- range .Values.namespaces }}
{{- if has $.Values.clusterProfile .profiles }}
- {{ .name }}
{{- end }}
{{- end }}
实现这一功能的一种巧妙方法是将列表整理为其他基于字符串的格式,如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文档中";附加";提供:$new = append $myList 6
我真的不知道为什么需要=
,我这边的快速研究没有任何结果。使用
fromJsonArray
从JSON字符串中恢复列表。这个函数还没有被记录下来,这是非常不幸的,也是我提供这个额外答案的主要原因。然而,你可以在赫尔姆的资料中找到它。
我们遇到了类似的问题,多亏了nichoio提供的答案,我们才得以解决。为了谷歌,我也会在这里提供:(
我们的values.yaml
包含了我们所有的机密引用,我们希望根据当前正在部署的服务来过滤这些机密。
我们在values.yaml
中添加了一个新数组(名为selectedSecrets
(,它是当前部署所需的机密列表。然后,在函数的帮助下,只将机密引用传递给部署,这些引用包含在selectedSecrets
中。请注意,如果不存在selectedSecrets
,以下函数将返回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 }}