Helm 可选的嵌套变量

Joe*_*e J 18 go-templates kubernetes kubernetes-helm

如何在值文件中创建一个可选块,然后在模板中引用它?

例如,假设我有一个如下所示的值文件:

# values.yaml
foo:
   bar: "something"
Run Code Online (Sandbox Code Playgroud)

然后我有一个如下所示的 helm 模板:

{{ .Values.foo.bar }}
Run Code Online (Sandbox Code Playgroud)

如果我想让值文件中的 foo.bar 成为可选怎么办?如果foo键不存在于值中,则会引发错误。

我试过添加为 if 条件。但是,如果foo缺少密钥,这仍然会失败:

{{ if .Values.foo.bar }}
{{ .Values.foo.bar }}
{{ end }}
Run Code Online (Sandbox Code Playgroud)

任何想法都非常感谢。

Tor*_*rey 119

简单的解决方法

用括号将每个可为空的级别括起来()

{{ ((.Values.foo).bar) }}
Run Code Online (Sandbox Code Playgroud)

或者

{{ if ((.Values.foo).bar) }}
{{ .Values.foo.bar }}
{{ end }}
Run Code Online (Sandbox Code Playgroud)

它是如何工作的?

Helm 使用 gotext/template并继承那里的行为。

每对括号都()可以被视为一个pipeline

来自文档(https://pkg.go.dev/text/template#hdr-Actions

这是:

默认文本表示(与 fmt.Print 打印的相同)...

随着行为:

如果管道的值为空,则不会生成任何输出...空值为 false、0、任何 nil 指针或接口值以及长度为零的任何数组、切片、映射或字符串。

因此,通过用括号将每个可为空级别包裹起来,当它们被链接时,前驱 nil 指针会优雅地不向后继生成任何输出,依此类推,从而实现嵌套可为空字段的解决方法。

  • 干杯; 这看起来效果很好。你在哪里找到的?我正在努力寻找相关文档 (4认同)
  • @ZimbiX 谢谢!我最初是从 Github 问题上读到这个用法的,然后就记住了它。找不到原始线程了:(。我添加了一些来自 go 的参考。希望这会有所帮助。 (2认同)

Mat*_*att 24

大多数图表会将父对象默认为空地图,values.yaml因此它始终存在。

foo: {}
Run Code Online (Sandbox Code Playgroud)

然后{{ if .Values.foo.bar }}工作。

如果这不可能,请测试两个键:

{{ if .Values.foo }}
{{ if .Values.foo.bar }}
{{ .Values.foo.bar }}
{{ end }}
{{ end }}
Run Code Online (Sandbox Code Playgroud)

and由于and评估所有参数,即使第一个参数为假,在这种情况下使用该函数也不起作用。

也有hasKey来自包括功能小枝如果你需要检查falsey或空值的存在:

{{ if hasKey .Values.foo "bar" }}
Run Code Online (Sandbox Code Playgroud)


Ed *_*all 18

使用with

with运营商。这将当前范围限制为 的级别.Values.foo,并且如果.foo缺少该块,则会默默地忽略该块:

{{- with .Values.foo }}
  {{- .bar }}
{{- end }}
Run Code Online (Sandbox Code Playgroud)


Dav*_*aze 11

我成功使用的一种技术是使用变量来保存外部块的值,然后可以使用模板构造,如defaultSprig 的dict助手。

{{- $foo := .Values.foo | default dict -}}
Bar is {{ $foo.bar | default "not in the values file" }}
Run Code Online (Sandbox Code Playgroud)

如果foo文件中没有,这将提供一个后备字典,因此 then$foo始终被定义,您可以$foo.bar在其中查找。


SeB*_*.Fr 7

sprig 中实现了一个新函数,dig它可以解决这个问题,请参阅此处http://masterminds.github.io/sprig/dicts.html

尚未发布,因此不太可能很快掌舵。

同时,我修改了@Samuel 解决方案以模仿新的挖掘功能。

{{- define "dig" -}}
  {{- $mapToCheck := index . "map" -}}
  {{- $keyToFind := index . "key" -}}
  {{- $default := index . "default" -}}
  {{- $keySet := (splitList "." $keyToFind) -}}
  {{- $firstKey := first $keySet -}}
  {{- if index $mapToCheck $firstKey -}} {{/* The key was found */}}
    {{- if eq 1 (len $keySet) -}}{{/* The final key in the set implies we're done */}}
      {{- index $mapToCheck $firstKey -}}
    {{- else }}{{/* More keys to check, recurse */}}
      {{- include "dig" (dict "map" (index $mapToCheck $firstKey) "key" (join "." (rest $keySet)) "default" $default) }}
    {{- end }}
  {{- else }}{{/* The key was not found */}}
      {{- $default -}}
  {{- end }}
{{- end }}
Run Code Online (Sandbox Code Playgroud)

你可以这样称呼它

$regKey := include "dig" (dict "map" .Values "key" "global.registryKey" "default" "") 
Run Code Online (Sandbox Code Playgroud)