一、流控制语句介绍
控制结构(在模板语言中称为"actions")提供给你和模板作者控制模板迭代流的能力。 Helm的模板语言提供了以下控制结构:
if
/else
, 用来创建条件语句with
, 用来指定范围range
, 提供"for each"类型的循环
除了这些之外,还提供了一些声明和使用命名模板的关键字:
define
在模板中声明一个新的命名模板template
导入一个命名模板block
声明一种特殊的可填充的模板块
二、详细说明
2.1 if/else
条件判断,不同的条件做不同的事情
结构
{{ if PIPELINE }}
# Do something
{{ else if OTHER PIPELINE }}
# Do something else
{{ else }}
# Default case
{{ end }}
注意我们讨论的是 管道 而不是值。这样做的原因是要清楚地说明控制结构可以执行整个管道,而不仅仅是计算一个值。
如果是以下值时,管道会被设置为 false:
- 布尔false
- 数字0
- 空字符串
nil
(空或null)- 空集合(
map
,slice
,tuple
,dict
,array
)
在所有其他条件下,条件都为true。
[root@master ~]# vim mychart/templates/configmap.yaml
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 }}
[root@master ~]# helm install --dry-run goodly-guppy ./mychart
NAME: goodly-guppy
LAST DEPLOYED: Fri Jul 5 11:27:28 2024
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
HOOKS:
MANIFEST:
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: goodly-guppy-configmap
data:
myvalue: "Hello World"
drink: "coffee"
food: "CW"
mug: "true"
注意在YAML中有一个空行,为什么?当模板引擎运行时,它 移除了 {{
和 }}
里面的内容,但是留下的空白完全保持原样。
YAML认为空白是有意义的,因此管理空白变得很重要。幸运的是,Helm模板有些工具可以处理此类问题。
首先,模板声明的大括号语法可以通过特殊的字符修改,并通知模板引擎取消空白。{{-
(包括添加的横杠和空格)表示向左删除空白, 而 -}}
表示右边的空格应该被去掉。 一定注意空格就是换行
要确保-
和其他命令之间有一个空格。 {{- 3 }}
表示“删除左边空格并打印3”,而{{-3 }}
表示“打印-3”。
修改后的模板如下:
[root@master ~]# vim mychart/templates/configmap.yaml
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 }}
[root@master ~]# helm install --dry-run goodly-guppy ./mychart
NAME: goodly-guppy
LAST DEPLOYED: Fri Jul 5 11:31:28 2024
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
HOOKS:
MANIFEST:
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: goodly-guppy-configmap
data:
myvalue: "Hello World"
drink: "coffee"
food: "CW"
mug: "true"
2.2 with
这个用来控制变量范围
点(.)
是对 当前作用域 的引用。因此 .Values
就是告诉模板在当前作用域查找Values
对象。
{{ with PIPELINE }}
# restricted scope
{{ end }}
with
允许你为特定对象设定当前作用域(.
)
比如,我们已经在使用.Values.favorite
。 修改配置映射中(.)的作用域指向 .Values.favorite
:
[root@master ~]# vim mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Hello World"
{{- with .Values.favorite }}
drink: {{ .drink | default "tea" | quote }}
food: {{ .food | upper | quote }}
{{- end }}
[root@master ~]# helm install --dry-run goodly-guppy ./mychart
NAME: goodly-guppy
LAST DEPLOYED: Fri Jul 5 14:18:13 2024
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
HOOKS:
MANIFEST:
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: goodly-guppy-configmap
data:
myvalue: "Hello World"
drink: "coffee"
food: "CW"
注意现在我们可以引用.drink
和.food
了,而不必限定他们。因为with
语句设置了(.)指向 .Values.favorite
但是这里有个注意事项,在限定的作用域内,无法使用(.)
访问父作用域的对象。
示例如下:
{{- with .Values.favorite }}
drink: {{ .drink | default "tea" | quote }}
food: {{ .food | upper | quote }}
release: {{ .Release.Name }}
{{- end }}
这样会报错因为Release.Name
不在.
限定的作用域内。
我们可以使用($)从父作用域中访问Release.Name
对象。当模板开始执行后$
会被映射到根作用域,且执行过程中不会更改。 下面这种方式也可以正常工作:
{{- with .Values.favorite }}
drink: {{ .drink | default "tea" | quote }}
food: {{ .food | upper | quote }}
release: {{ $.Release.Name }}
{{- end }}
使用$从父作用域中访问Release.Name对象。
2.3 range
很多编程语言支持使用for
循环,foreach
循环,或者类似的方法机制。 在Helm的模板语言中,在一个集合中迭代的方式是使用range
操作符。
[root@master ~]# vim mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Hello World"
{{- with .Values.favorite }}
drink: {{ .drink | default "tea" | quote }}
food: {{ .food | upper | quote }}
{{- end }}
toppings: |-
{{- range .Values.pizzaToppings }}
- {{ . | title | quote }}
{{- end }}
[root@master ~]# helm install --dry-run goodly-guppy ./mychart
NAME: goodly-guppy
LAST DEPLOYED: Fri Jul 5 14:33:03 2024
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
HOOKS:
MANIFEST:
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: goodly-guppy-configmap
data:
myvalue: "Hello World"
drink: "coffee"
food: "PIZZA"
toppings: |-
- "Mushrooms"
- "Cheese"
- "Peppers"
- "Onions"
range
方法“涵盖”(迭代)pizzaToppings
列表。但现在发生了有意思的事情。 就像with
设置了.
的作用域,range
操作符也做了同样的事。每一次循环,.
都会设置为当前的披萨配料。 也就是说,第一次.
设置成了mushrooms
,第二次迭代设置成了cheese
,等等。
toppings: |-
行是声明的多行字符串。正如例子中所示,|-
标识在YAML中是指多行字符串。
range也
可被用于迭代有键值对的集合(像map
或dict
)。