流控制
控制结构(在模板语言中称为“actions”)提供给您和模板作者控制模板迭代流的能力。Helm的模板语言提供了以下控制结构:
if/else,用来创建条件语句
with,用来指定范围
range,提供“for each”类型的循环
除了这些之外,还提供了一些声明和使用命令模板的关键字:
define在模板中声明一个新的命名模板
template导入一个命名模板
block声明一种特殊的可填充的模板块
该部分,我们会讨论关于if,with,和range。其他部分会在该指南的“命名模板”部分说明。
If/Else
第一个控制结构是在按照条件在一个模板中包含一个块文本。即if/else块。
基本的条件结构看起来像这样:
{{ if PIPELINE }}
# Do something
{{ else if OTHER PIPELINE }}
{{ else }}
# Default case
{{ end }}
注意我们讨论的是管道而不是值。这样做的原因是要清楚地说明控制结构可以执行整个管道,而不仅仅是计算一个值。
如果是以下值时,管道会被设置为false:
布尔false
数字0
空字符串
nil(空或null)
空集合(map,slice,tuple,dict,array)
在所有其他条件下,条件都为true。
让我们先在配置映射中添加一个简单的条件。如果饮品是coffee会添加另一个配置:
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Hello World"
drink: {{ .Values.favorite.drink | default "tea" | quote }}
food: {{ .Values.favorite.food | upper | quote }}
{{ if eq .Values.favorite.drink "coffee" }}mug: "true"{{ end }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Hello World"
drink: {{ .Values.favorite.drink | default "tea" | quote }}
food: {{ .Values.favorite.food | upper | quote }}
{{ if eq .Values.favorite.drink "coffee" }}mug: "true"{{ end }}
由于我们在最后一个例子中注释了drink: coffee,输出中就不会包含mug: "true"标识。但如果将这行添加到values.yaml文件中,输入就会是这样:
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: eyewitness-elk-configmap
data:
myvalue: "Hello World:
drink: "coffee"
food: "PIZZA"
mug: "true"
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: eyewitness-elk-configmap
data:
myvalue: "Hello World"
drink: "coffee"
food: "PIZZA"
mug: "true"
控制空格
查看条件时,我们需要快速了解一下模板中控制空白的方式,格式化之前的例子,使其更易于阅读:
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Hello World"
drink: {{ .Values.favorite.drink | default "tea" | quote }}
food: {{ .Values.favorite.food | upper | quote }}
{{ if eq .Values.favorite.drink "coffee" }}
mug: "true"
{{ end }}
初始情况下,看起来没问题。但是如果通过模板引擎运行时,我们将得到一个不幸的结果:
$ helm install --dry-run --debug ./chart
$ helm install --dry-run --debug ./mychart
SERVER: "localhost:44134"
CHART PATH: /Users/mattbutcher/Code/Go/src/helm.sh/helm/_scratch/mychart
Error: YAML parse error on mychart/templates/configmap.yaml: error converting YAML to JSON: yaml: line 9: did not find expected key
发生了啥?因为空格导致生成了错误的YAML。
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: eyewitness-elk-configmap
data:
myvalue: "Hello World"
drink: "coffee"
food: "PIZZA"
mug: "true"
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: eyewitness-elk-configmap
data:
myvalue: "Hello World"
drink: "coffee"
food: "PIZZA"
mug: "true"
mug的缩进是不对的。取消缩进重新执行以下:
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Hello World"
drink: {{ .Values.favorite.drink | default "tea" | quote }}
food: {{ .Values.favorite.food | upper | quote }}
{{ if eq .Values.favorite.drink "coffee" }}
mug: "true"
{{ end }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Hello World"
drink: {{ .Values.favorite.drink | default "tea" | quote }}
food: {{ .Values.favorite.food | upper | quote }}
{{ if eq .Values.favorite.drink "coffee" }}
mug: "true"
{{ end }}
这个就得到了合法的YAML,但是看起来还是有点滑稽:
# Source: mychart/templates/configmap.yaml
apiVersion: v1
metadata:
name: telling-chimp-configmap
data:
myvalue: "Hello World"
drink: "coffee"
food: "PIZZA"
mug: "true"
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: telling-chimp-configmap
data:
myvalue: "Hello World"
drink: "coffee"
food: "PIZZA"
mug: "true"
注意在YAML中有一个空行,为什么?当模板引擎运行时,它移除了{{和}}里面的内容,但是留下的空白完全保持原样。
YAML认为空白是有意义的,因此管理空白变得很重要。幸运的是,Helm模板有些工具可以处理此类问题。
首先,模板声明的大括号语法可以通过特殊的字符修改,并通知模板引擎取消空白。{{- (包括添加的横杠和空格)表示向左删除空白,而 -}}表示右边的空格应该被去掉。一定注意空格就是换行
小贴士:要确保-和其他命令之间有一个空格。{{- 3 }}表示“删除左边空格并打印3”,而{{-3 }}表示“打印-3”。
使用这个语法,我们就可修改我们的模板,去掉新加的空白行:
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Hello World"
drink: {{ .Values.favorite.drink | default "tea" | quote }}
food: {{ .Values.favorite.food | upper | quote }}
{{- if eq .Values.favorite.drink "coffee" }}
mug: "true"
{{- end }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Hello World"
drink: {{ .Values.favorite.drink | default "tea" | quote }}
food: {{ .Values.favorite.food | upper | quote }}
{{- if eq .Values.favorite.drink "coffee" }}
mug: "true"
{{- end }}
只是为了把这一点搞清楚,我们来调整上述内容,用一个*来代替每个循环此规则被删除的空白,在行尾的*表示删除新行的字符:
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Hello World"
drink: {{ .Values.favorite.drink | default "tea" | quote }}
food: {{ .Values.favorite.food | upper | quote }}*
**{{- if eq .Values.favorite.drink "coffee" }}
mug: "true"*
**{{- end }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Hello World"
drink: {{ .Values.favorite.drink | default "tea" | quote }}
food: {{ .Values.favorite.food | upper | quote }}*
**{{- if eq .Values.favorite.drink "coffee" }}
mug: "true"*
**{{- end }}
记住这一点,我们可以通过Helm运行模板并查看结果:
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: clunky-cat-configmap
data:
myvalue: "Hello World"
drink: "coffee"
food: "PIZZA"
mug: "true"
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: clunky-cat-configmap
data:
myvalue: "Hello World"
drink: "coffee"
food: "PIZZA"
mug: "true"
要注意这个删除字符的更改,很容易意外地出现情况:
food: {{ .Values.favorite.food | upper | quote }}
{{- if eq .Values.favorite.drink "coffee" -}}
mug: "true"
{{- end -}}
food: {{ .Values.favorite.food | upper | quote }}
{{- if eq .Values.favorite.drink "coffee" -}}
mug: "true"
{{- end -}}
这样会变成food: "PIZZA"mug:"true",因为这把两边的新行都删除了。
小贴士:关于模板中的空白控制,请查看 官方Go模板文档
template package - text/template - Go Packages
最终,有时这更容易告诉模板系统如何缩进,而不是试图控制模板指令间的间距。因此,您有时会发现使用indent方法{{ indent 2 "mug:"true" }}会很有用。
————————————
仅用于本人学习
来源:Helm | Docs