kubernetes Helm模板:子键索引

ioekq8ef  于 2023-10-17  发布在  Kubernetes
关注(0)|答案(2)|浏览(138)

我想实现下面的场景。

全局变量

global:
  env:
    name: prod

图表特定变量

env:
  name: dev

我想有优先级的图表特定>全局变量
在我的图表中,我想使用类似于

containers:
          - name: "{{- include "tester.getValueWithPrecedence" (list . "env.name") -}}"

这是_helpers.tpl函数

{{- define "tester.getValueWithPrecedence" -}}
{{- $top := index . 0 }}
{{- $var := index . 1 }}
{{- if hasKey $top.Values $var -}}
{{- index $top.Values $var -}}
{{- else if hasKey $top.Values.global $var -}}
{{- index $top.Values.global $var -}}
{{- end -}}
{{- end -}}

我认为问题是env.name键没有被解释为子键,而是一个字符串。
有没有办法做到这一点?
任何帮助都非常感谢。

tuwxkamq

tuwxkamq1#

这很难按照你描述的方式来做。
正如您所注意到的,核心问题是hasKeyindex都希望它们的参数作为map中的单个键,而不是点分隔的字符串。index可以接受多个参数-index .Values "env" "name"-但不能接受单个列表类型的参数,并且没有一种好的方法将列表扩展为多个参数。(否则dig模板函数可能是答案的一部分。
你仍然可以写一个模板函数来完成这个任务,但是它会有点复杂。您可以编写一个遍历路径组件列表的递归模板,并使用首选字典和回退调用它。

{{- include "f" (list .Values .Values.global (list "env" "name")) }}
{{- include "f" (list .Values.env .Values.global.env (list "name")) }}

实现技巧是pluck将采用单个路径步骤和多个字典(同样,作为位置参数而不是列表),并将该步骤返回到包含它的所有字典中。这意味着pluck的返回值有三种情况:
1.它什么也不返回,我们在两个字典中都漏掉了;
1.它只返回一个字典;或
1.它从两个字典中返回一个子键。
一旦我们弄清楚了我们在哪种情况下,类似地,要么我们在列表的末尾,要么我们不在,我们可以递归或相应地返回值。
所以我可以写(未经测试):

{{- define "f" -}}
  {{- $first := index . 0 }}
  {{- $second := index . 1 }}
  {{- $path := index . 2 }}
  {{- $result := pluck (first $path) $first $second }}
  {{- if eq 0 (len $result) }}
    {{- "" }}
  {{- else if eq 1 (len $path) }}
    {{- first $result }}
  {{- else if eq 1 (len $result) }}
    {{- include "f" (list (first $result) dict (rest $path) }}
  {{- else }}
    {{- include "f" (list (index $result 0) (index $result 1) (rest $path) }}
  {{- end }}
{{- end }}

这里需要注意的另一件重要的事情是,无论.Values中是什么,define d函数只会产生一个字符串作为其结果。在这个例子中,我返回一个空字符串的“未找到”的情况。
根据您使用它的频率,可能不值得花精力写出这个非常通用的函数。

env:
  - name: ENVIRONMENT
    value: {{ dig "env" "name" (dig "global" "env" "name" .Values) .Values }}

根据您的用例,它还可以帮助您了解每个部署的helm install -f值覆盖图表的values.yaml文件。因此,您不需要在values.yaml中写入默认值,而是检查用户是否在不同的路径上提供了覆盖;您可以使用相同的.Values.env.name和用户覆盖将优先. global名称暗示了父子图表关系,并且父图表值将优先于子图表values.yaml中的默认值。不过,还有其他合理的设置,您确实需要您所询问的更通用的方法。

4si2a6ki

4si2a6ki2#

我想出了一个更简单的方法。

{{/* Define getmethekey function */}}
{{- define "tester.getmethekey" -}}
{{- $root := first . -}}
{{- $keys := rest . -}}
{{- $value := $root.Values -}}

{{- range $index, $key := $keys -}}
  {{- if kindIs "map" $value -}}
    {{- if hasKey $value $key -}}
      {{- $value = index $value $key -}}
    {{- else -}}
      {{- $value = "" -}}
    {{- end -}}
  {{- else -}}
    {{- $value = "" -}}
  {{- end -}}
{{- end -}}

{{- $value -}}
{{- end -}}

输入将是

- name: "{{- include "tester.getmethekey" (list . "env" "name") -}}"

Values.yaml

env:
  name: rajesh

相关问题