So far, we’ve seen how to place information into a template. But that information is placed into the template unmodified. Sometimes we want to transform the supplied data in a way that makes it more useable to us.
目前,我们已经知道如何将信息放入模版中。但是这些信息未被修改就被放入了模版中。由时我们希望将提供的数据进行转换,从而使其对用户更可用。
Let’s start with a best practice: When injecting strings from the .Values
object into the template, we ought to quote these strings. We can do that by calling the quote
function in the template directive:
当将一个
.Values
对象注入模版时,我们应该引用这些字符串。可以通过调用模版指令中的quote
函数来实现。
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Hello World"
drink: {{ quote .Values.favorite.drink }}
food: {{ quote .Values.favorite.food }}
Template functions follow the syntax functionName arg1 arg2...
. In the snippet above, quote .Values.favorite.drink
calls the quote
function and passes it a single argument.
模版函数运行使用
functionName arg1,arg2..
的语言。在上例中,quote .Values.favorite.drink
,会调用quote
函数并向其传递一个参数。
Helm has over 60 available functions. Some of them are defined by the Go template language itself. Most of the others are part of the Sprig template library. We’ll see many of them as we progress through the examples.
helm 拥有超过60个可用的函数,其中一些使用Go template language 自身的函数,大多数使用的是Sprig template library
。
While we talk about the “Helm template language” as if it is Helm-specific, it is actually a combination of the Go template language, some extra functions, and a variety of wrappers to expose certain objects to the templates. Many resources on Go templates may be helpful as you learn about templating.
当我们讨论”Helm模板语言”时,好像它是特定于Helm的,实际上是由Go模板语言,一些额外的函数以及用于 向模板公开某些对象的包装器组合而成。很多Go模板的资源有助于你学习模板。
Pipelines 管道符
One of the powerful features of the template language is its concept of pipelines. Drawing on a concept from UNIX, pipelines are a tool for chaining together a series of template commands to compactly express a series of transformations. In other words, pipelines are an efficient way of getting several things done in sequence. Let’s rewrite the above example using a pipeline.
模版语言提供的一个强大的功能是管道符的概念。借鉴Unix中的概念,管道符是将一系列模版命令转换为紧凑表达式的工具。换句话说,管道符是将按顺序完成任务的高效的方式。现在用管道符来重写上述例子。
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Hello World"
drink: {{ .Values.favorite.drink | quote }}
food: {{ .Values.favorite.food | quote }}
In this example, instead of calling quote ARGUMENT
, we inverted the order. We “sent” the argument to the function using a pipeline (|
): .Values.favorite.drink | quote
. Using pipelines, we can chain several functions together:
在此例中,我们没有使用
quote ARGUMENT
的形式,而是使用了倒置命令。我们使用管道将参数发送给函数.Value.favorite.drink | quote。
通过使用管道,可以将很多函数链接在一起。
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Hello World"
drink: {{ .Values.favorite.drink | quote }}
food: {{ .Values.favorite.food | upper | quote }}
Inverting the order is a common practice in templates. You will see
.val | quote
more often thanquote .val
. Either practice is fine.在模版中,使用倒置的顺序是很常见的。可以看到
.val | quote
而不quote .val
。尽管两种方式都可以
When evaluated, that template will produce this:
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: trendsetting-p-configmap
data:
myvalue: "Hello World"
drink: "coffee"
food: "PIZZA"
Note that our original pizza
has now been transformed to "PIZZA"
.
When pipelining arguments like this, the result of the first evaluation (.Values.favorite.drink
) is sent as the last argument to the function. We can modify the drink example above to illustrate with a function that takes two arguments: repeat COUNT STRING
:
当使用管道符来传递参数时,结果的第一部分(
.Values.favorite.drink
)是作为最后一个参数传递给了函数。可以修改上述饮料实例,用一个函数带两个参数说明:repeat COUNT STRING
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Hello World"
drink: {{ .Values.favorite.drink | repeat 5 | quote }}
food: {{ .Values.favorite.food | upper | quote }}
The repeat
function will echo the given string the given number of times, so we will get this for output:
repeat
函数会返回给定字符串指定的次数。所以会得到以下输出结果:
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: melting-porcup-configmap
data:
myvalue: "Hello World"
drink: "coffeecoffeecoffeecoffeecoffee"
food: "PIZZA"
Using the default
function 使用default 函数
One function frequently used in templates is the default
function: default DEFAULT_VALUE GIVEN_VALUE
. This function allows you to specify a default value inside of the template, in case the value is omitted. Let’s use it to modify the drink example above:
default 模版中频繁使用到的函数:
default DEFAULT_VALUEGIVEN_VALUE
.此函数允许在模版内部定义默认值,以防该值被忽略。
drink: {{ .Values.favorite.drink | default "tea" | quote }}
If we run this as normal, we’ll get our coffee
:
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: virtuous-mink-configmap
data:
myvalue: "Hello World"
drink: "coffee"
food: "PIZZA"
Now, we will remove the favorite drink setting from values.yaml
:
favorite:
#drink: coffee
food: pizza
Now re-running helm install --dry-run --debug fair-worm ./mychart
will produce this YAML:
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: fair-worm-configmap
data:
myvalue: "Hello World"
drink: "tea"
food: "PIZZA"
In an actual chart, all static default values should live in the values.yaml
, and should not be repeated using the default
command (otherwise they would be redundant). However, the default
command is perfect for computed values, which can not be declared inside values.yaml
. For example:
在实际的chart中,所有静态的默认值都应该防止在
values.yaml
中,并且不能重复使用default
命令。然而default
命令适合用于定义不能直接在values.yaml
中指定的计算资源。
drink: {{ .Values.favorite.drink | default (printf "%s-tea" (include "fullname" .)) }}
In some places, an if
conditional guard may be better suited than default
. We’ll see those in the next section.
在某些情况下,使用
if
进行条件监控,会比使用default
更好。
Template functions and pipelines are a powerful way to transform information and then insert it into your YAML. But sometimes it’s necessary to add some template logic that is a little more sophisticated than just inserting a string. In the next section we will look at the control structures provided by the template language.
模版函数和管道描述符是转换消息并插入自己的yaml文件中的高效方式。但有时需要插入一些模版逻辑,比仅仅插入一个字符串要复杂一些。下一部分,我们会看到模版语言提供的控制结构
Using the lookup
function 使用lookup函数
The lookup
function can be used to look up resources in a running cluster. The synopsis of the lookup function is lookup apiVersion, kind, namespace, name -> resource or resource list
.
lookup
函数可以在运行的集群中查找资源。语法形式是
lookup apiVersion,kind,namespace,name->resource or resource list
parameter | type |
---|---|
apiVersion | string |
kind | string |
namespace | string |
name | string |
Both name
and namespace
are optional and can be passed as an empty string (""
).
The following combination of parameters are possible:
name
和namespace
都是可选的,可以传入空字符串可以使用以下参数的组合:
Behavior | Lookup function |
---|---|
kubectl get pod mypod -n mynamespace |
lookup "v1" "Pod" "mynamespace" "mypod" |
kubectl get pods -n mynamespace |
lookup "v1" "Pod" "mynamespace" "" |
kubectl get pods --all-namespaces |
lookup "v1" "Pod" "" "" |
kubectl get namespace mynamespace |
lookup "v1" "Namespace" "" "mynamespace" |
kubectl get namespaces |
lookup "v1" "Namespace" "" "" |
When lookup
returns an object, it will return a dictionary. This dictionary can be further navigated to extract specific values.
The following example will return the annotations present for the mynamespace
object:
lookup
会返回一个字典对象。这个字典可以进一步被引导以获取特定值。以下例子将返回
mynamespace
对象的注释 :
(lookup "v1" "Namespace" "" "mynamespace").metadata.annotations
When lookup
returns a list of objects, it is possible to access the object list via the items
field:
lookup
返回一个对象列表时,可以通过items
字段访问对象
{{ range $index, $service := (lookup "v1" "Service" "mynamespace" "").items }}
{{/* do something with each service */}}
{{ end }}
When no object is found, an empty value is returned. This can be used to check for the existence of an object.
当对象未被找到时,会返回控制。这个控制可以用来检测对象是否存在。
The lookup
function uses Helm’s existing Kubernetes connection configuration to query Kubernetes. If any error is returned when interacting with calling the API server (for example due to lack of permission to access a resource), helm’s template processing will fail.
lookup
函数会使用helm现存的和k8s连接配置和查询k8s。如果在与api服务器交互时发生错误(例如缺乏访问某种资源的权限),helm的模版处理过程会失败
Keep in mind that Helm is not supposed to contact the Kubernetes API Server during a helm template
or a helm install|update|delete|rollback --dry-run
, so the lookup
function will return an empty list (i.e. dict) in such a case.
需要注意使用
helm template
或helm install |update|delete|rollback --dry-run
时,helm不会和k8s api 服务器进行交互,因此lookup
函数会返回一个空列表。
Operators are functions 运算符都是函数
For templates, the operators (eq
, ne
, lt
, gt
, and
, or
and so on) are all implemented as functions. In pipelines, operations can be grouped with parentheses ((
, and )
).
Now we can turn from functions and pipelines to flow control with conditions, loops, and scope modifiers.
对于模版来说,运算符eq,ne,lt,gt,and,or等等都是以函数的形式实现的。在管道符中,操作可以使用括号进行包裹。现在我们可以从函数和管道符返回条件控制流,循环,和范围修饰符。