Consul-template语法

consul-template解析以Go Template格式编写的文件,若是您不熟悉语法,请阅读Go的文档和示例。除Go提供的模板功能外,Consul Template还提供如下功能。html

1. API函数

API函数与远程API调用交互,与Consul和Vault等外部服务进行通讯。node

datacentersgit

查询Consul其中全部数据中心。github

1
{{ datacenter }}

例如:golang

1
2
{{ range datacenters }}
{{ . }}{{ end }}

结果:web

dc1
dc2

能够指定一个可选的布尔值,指示Consul Template忽略没法访问或没有当前leader的数据中心。启用此选项须要执行O(N + 1)操做,所以不建议在性能较高的环境中使用。正则表达式

1
2
// Ignores datacenters which are inaccessible
{{ datacenters true }}

fileredis

读取并输出磁盘上本地文件的内容。若是没法读取文件,则会发生错误。当文件更改时,Consul Template将获取更改并从新渲染模板。后端

1
{{ file "<PATH>" }}

例如:api

1
{{ file "/path/to/my/file" }}

结果:

file contents

这不会处理嵌套模板。有关呈现嵌套模板的方法,请参阅executeTemplate

key

查询Consul获取给定键路径的值。若是密钥不存在,Consul Template将中止渲染,直到键值存在。要避免阻塞,请使用keyOrDefaultkeyExists

1
{{ key "<PATH>@<DATACENTER>" }}

例如:

1
{{ key "service/redis/maxconns" }}

结果:

15

keyExists

查询Consul获取给定键路径的值。若是密钥存在,则返回true,不然返回false。与key不一样,若是key不存在,则此功能不会阻塞。这对于控制流程颇有用。

1
{{ keyExists "<PATH>@<DATACENTER>" }}

<DATACENTER>属性是可选的;若是省略,则使用本地数据中心(后面其余参数若无特殊说明,则同理)。

例如:

1
2
3
4
5
{{ if keyExists "app/beta_active" }}
 # ...
{{ else }}
 # ...
{{ end }}

keyOrDefault

查询Consul获取给定键路径的值。若是key不存在,则将使用默认值。与key不一样,若是键值不存在,则此功能不会阻塞流程。

1
{{ keyOrDefault "<PATH>@<DATACENTER>" "<DEFAULT>" }}

例如:

1
{{ keyOrDefault "service/redis/maxconns" "5" }}

结果:

5

请注意,Consul Template使用多阶段执行。在评估的第一阶段,Consul Template将没有来自Consul的数据,所以将始终回退到默认值。从Consul的后续读取将在下一个模板传递中从Consul(若是key存在)中提取实际值。这很重要,由于这意味着因为keyOrDefault中缺乏键值,Consul Template永远不会“阻塞”模板的渲染。即便key存在,若是Consul还没有返回key的数据,也将使用默认值。

ls

查询给定键路径上全部顶级键值对

1
{{ ls "<PATH>@<DATACENTER>" }}

例如:

1
2
{{ range ls "service/redis" }}
{{ .Key }}:{{ .Value }}{{ end }}
maxconns:15
minconns:5

node

查询consul节点

1
{{node "<NAME>@<DATACENTER>"}}

<NAME>属性是可选的;若是省略,则使用本地agent节点。

例如:

1
2
{{ with node }}
{{ .Node.Address }}{{ end }}

结果:

10.5.2.6

查询一个同的节点

1
2
{{ with node "node1@dc2" }}
{{ .Node.Address }}{{ end }}

结果:

10.4.2.6

要访问TaggedAddressesMeta等地图数据,请使用Go’s text/template 地图索引。

nodes

查询全部consul节点

1
{{ nodes "@<DATACENTER>~<NEAR>" }}

<NEAR>属性是可选的;若是省略,则以词法顺序指定结果。若是提供了节点名称,则结果按照提供的节点的最短往返时间排序。若是提供_agent,则结果按照到本地代理的最短往返时间排序。

例如:

1
2
{{ range nodes }}
{{ .Address }}{{ end }}

结果:

10.4.2.13
10.46.2.5

要按最短的响应时间查询获取不一样的数据中心:

1
2
{{ range nodes "@dc2~_agent" }}
{{ .Address }}{{ end }}

secret

查询给定路径上的密码。

1
{{ secret "<PATH>" "<DATA>" }}

<DATA>属性是可选的;若是省略,请求将是一个密码vault read(HTTP GET)请求。若是提供,请求将是vault write(HTTP PUT / POST)请求。

例如:

1
2
{{ with secret "secret/passwords" }}
{{ .Data.wifi }}{{ end }}

结果:

FORWARDSoneword

要访问版本化的密码值(对于K / V版本2后端):

1
2
{{ with secret "secret/passwords?version=1" }}
{{ .Data.data.wifi }}{{ end }}

省略?version参数时,将获取最新版本的密码。引用密码值时请注意嵌套的.Data.data语法。有关使用K/V v2后端的详细信息,请参阅Vault文档

使用Vault版本0.10.0 / 0.10.1时,密码路径必须以“data”为前缀,即上述示例的secret/data/passwords。对于0.10.1以后的Vault版本,这不是必需的,由于consul-template将检测正在使用的KV后端版本。版本2 KV后端在0.10.0以前不存在,所以这些是惟一受影响的版本。

使用write生成PKI证书的示例:

1
2
{{ with secret "pki/issue/my-domain-dot-com" "common_name=foo.example.com" }}
{{ .Data.certificate }}{{ end }}

参数必须是key = value对,而且每对必须是函数的本身的参数:

请始终考虑在磁盘上以纯文本形式保密的内容的安全隐患。若是***者可以访问该文件,他们将能够访问纯文本机密。

请注意,Vault不支持阻塞查询。所以,若是密码被更改,Consul Template将不会当即从新加载,就像Consul的键值存储同样。 Consul Template将在原始密码的租约期限的一半时间内获取新密码。例如,Vault的通用密码后端中的大多数项目都有默认的30天租约。这意味着Consul Template将每15天更新一次密码。所以,建议在生成初始密钥时使用较小的租约期限,以迫使Consul Template更频繁地续订。

在使用将与Vault交互的模板时,还要考虑启用error_on_missing_key。默认状况下,Consul Template使用Go的模板语言。访问不存在的结构字段或映射键时,默认为打印""。这可能不是理想的行为,尤为是在处理密码或其余数据时。所以,建议您设置:

template {
 error_on_missing_key = true
}

您还可使用ifwith block来防止空值。

1
2
3
4
5
{{ with secret "secret/foo"}}
{{ if .Data.password }}
password = "{{ .Data.password }}"
{{ end }}
{{ end }}

secrets

查询Vault以获取给定路径上的密码列表。并不是全部节点都支持列表。

1
{{ secrets "<PATH>" }}

例如:

1
2
{{ range secrets "secret/" }}
{{ . }}{{ end }}

结果:

bar
foo
zip

要迭代并列出Vault中通用密码后端中的每一个密码:

1
2
3
4
{{ range secrets "secret/" }}
{{ with secret (printf "secret/%s" .) }}{{ range $k, $v := .Data }}
{{ $k }}: {{ $v }}
{{ end }}{{ end }}{{ end }}

你可能永远不会这样作。

另请注意,Vault不支持阻塞查询。要了解其含义,请阅读secret末尾的注释。

service

根据健康情况查询服务

1
{{ service "<TAG>.<NAME>@<DATACENTER>~<NEAR>|<FILTER>" }}

<TAG>属性是可选的;若是省略,将查询全部节点。

<FILTER>属性是可选的;若是省略,则仅返回健康服务。提供过滤器容许客户端过滤服务。

上面的示例是在“east-aws”数据中心查询Consul的健康“web”服务。tag和datacenter属性是可选的。要查询当前数据中心的“Web”服务的全部节点(不管标签如何):

1
2
{{ range service "web" }}
server {{ .Name }}{{ .Address }}:{{ .Port }}{{ end }}

结果,使用名为“web”的逻辑服务呈现全部健康节点的IP地址::

server web01 10.5.2.45:2492
server web02 10.2.6.61:2904

默认状况下,仅返回健康服务。要列出全部服务,请传递“any”过滤器,这将返回注册到代理的全部服务,不管其状态如何。:

1
{{ service "web|any" }}

要按特定的运行情况集过滤服务,请指定以逗号分隔的运行情况列表:

1
{{ service "web|passing,warning" }}

这将根据Consul中定义的节点和服务级别检查返回被视为“经过”或“警告”的服务。请注意,逗号表示“或”,而不是“和”。

注意:如下内容存在架构差别:

1
2
{{ service "web" }}
{{ service "web|passing" }}

前者将返回Consul认为“健康”的全部服务并经过。后者将返回在Consul代理注册的全部服务并执行客户端的过滤。做为通常规则,若是您只想要健康的服务,请不要单独使用passing参数,只须要省略第二个参数便可。

services

查询全部的服务

1
{{ services "@<DATACENTER>" }}

例如:

1
2
{{ range services }}
{{ .Name }}: {{ .Tags | join "," }}{{ end }}

结果:

node01 tag1,tag2,tag3

tree

查询指定路径键值对

1
{{ tree "<PATH>@<DATACENTER>" }}

例如:

1
2
{{ range tree "service/redis" }}
{{ .Key }}:{{ .Value }}{{ end }}

结果:

minconns 2
maxconns 12
nested/config/value "value"

不像lstree返回带前缀的全部键值,就像Unix的tree命令。

2. Scratch暂存器

暂存器在模板的上下文中可用于存储临时数据或计算。 Scratch数据不在模板之间共享,也不在调用之间缓存。

scratch.Key

若是数据存在于命名键的暂存器中,则返回布尔值。即便该键的数据为“nil”,仍然会返回true。

1
{{ scratch.Key "foo" }}

scratch.Get

返回指定键的暂存器中的值。若是数据不存在,则返回“nil”。

1
{{ scratch.Get "foo" }}

scratch.Set

将给定值保存在给定键上。若是该值已存在,则会被覆盖。

1
{{ scratch.Set "foo" "bar" }}

scratch.SetX

此行为与Set彻底相同,但若是值已存在则不会覆盖。

1
{{ scratch.SetX "foo" "bar" }}

scratch.MapSet

将值保存在映射的命名键中。若是该值已存在,则会被覆盖。

1
{{ scratch.MapSet "vars" "foo" "bar" }}

scratch.MapSetX

此行为与MapSet彻底相同,但若是值已存在则不会覆盖。

1
{{ scratch.MapSetX "vars" "foo" "bar" }}

scratch.MapValues

返回指定映射中全部值的排序列表(按键)。

1
{{ scratch.MapValues "vars" }}

3. Helper Functions辅助函数

与API函数不一样,辅助函数不查询远程服务。这些函数对于解析数据,格式化数据,执行数学等很是有用。

base64Decode

接受base64编码的字符串并返回解码的结果,若是给定的字符串不是有效的base64字符串,则返回错误。

1
{{ base64Decode "aGVsbG8=" }}

结果:

hello

base64Encode

接受一个字符串并返回一个base64编码的字符串。

1
{{ base64Encode "hello" }}

结果:

aGVsbG8=

base64URLDecode

接受base64编码的URL安全字符串并返回解码结果,若是给定字符串不是有效的base64 URL安全字符串,则返回错误。

1
{{ base64URLDecode "aGVsbG8=" }}

结果:

hello

base64URLEncode

接受一个字符串并返回base-64编码的URL安全字符串。

1
{{ base64Encode "hello" }}

结果:

aGVsbG8=

byKey

接受tree调用返回的对的列表,并建立一个按顶级目录对进行分组的映射。

例如此目录列表:

groups/elasticsearch/es1
groups/elasticsearch/es2
groups/elasticsearch/es3
services/elasticsearch/check_elasticsearch
services/elasticsearch/check_indexes

使用如下模板

1
2
3
{{ range $key, $pairs := tree "groups" | byKey }}{{ $key }}:
{{ range $pair := $pairs }}  {{ .Key }}={{ .Value }}
{{ end }}{{ end }}

结果:

elasticsearch:
 es1=1
 es2=1
 es3=1

请注意,最顶层的键是从Key值中删除的。剥离后没有前缀的键将从列表中删除。

结果键值对被键控为一个映射,所以能够按键查找单个值:

1
2
3
4
{{ $weights := tree "weights" }}
{{ range service "release.web" }}
 {{ $weight := or (index $weights .Node) 100 }}
 server {{ .Node }} {{ .Address }}:{{ .Port }} weight {{ $weight }}{{ end }}

byTag

获取serviceservices函数返回的服务列表,并建立一个按标签对服务进行分组的映射

1
2
3
{{ range $tag, $services := service "web" | byTag }}{{ $tag }}
{{ range $services }} server {{ .Name }} {{ .Address }}:{{ .Port }}
{{ end }}{{ end }}

contains

肯定是否在可迭代元素内。

1
2
3
{{ if .Tags | contains "production" }}
# ...
{{ end }}

containsAll

若是全部值都在可迭代元素内,则返回true,不然返回false。若是值列表为空,则返回true。

1
2
3
{{ if containsAll $requiredTags .Tags }}
# ...
{{ end }}

containsAny

若是任意一个值在可迭代元素内,则返回true,不然返回false。若是值列表为空,则返回false。

1
2
3
{{ if containsAny $acceptableTags .Tags }}
# ...
{{ end }}

containsNone

若是没有值在可迭代元素内,则返回true,不然返回false。若是值列表为空,则返回true。

1
2
3
{{ if containsNone $forbiddenTags .Tags }}
# ...
{{ end }}

containsNotAll

若是某些值不在可迭代元素内,则返回true,不然返回false。若是值列表为空,则返回false。

1
2
3
{{ if containsNotAll $excludingTags .Tags }}
# ...
{{ end }}

env

读取当前进程可访问的给定环境变量。

1
{{ env "CLUSTER_ID" }}

能够连接此函数来操做输出:

1
{{ env "CLUSTER_ID" | toLower }}

例如,读取给定的环境变量,若是它不存在或为空,则使用默认值12345:

1
{{ or (env "CLUSTER_ID") "12345" }}

executeTemplate

执行并返回已定义的模板。

1
2
3
4
5
6
7
8
9
10
11
12
13
{{ define "custom" }}my custom template{{ end }}

This is my other template:
{{ executeTemplate "custom" }}

And I can call it multiple times:
{{ executeTemplate "custom" }}

Even with a new context:
{{ executeTemplate "custom" 42 }}

Or save it to a variable:
{{ $var := executeTemplate "custom" }}

explode

treels调用获取结果并将其转换为深度嵌套的映射以进行解析/遍历。

1
{{ tree "config" | explode }}

注意:在失败后,您将丢失有关键值对的全部元数据。但还能够访问深层嵌套值:

1
2
{{ with tree "config" | explode }}
{{ .a.b.c }}{{ end }}

indent

经过在每行前面添加N个空格来缩进文本块。

1
{{ tree "foo" | explode | toYAML | indent 4 }}

in

肯定针是否在可迭代元素内。

1
2
3
{{ if in .Tags "production" }}
# ...
{{ end }}

loop

接受不一样的参数,并根据这些参数区分其行为。

若是给出一个整数的循环,它将返回一个从0开始并循环到但不包括给定整数的goroutine:

1
2
{{ range loop 5 }}
# Comment{{end}}

若是给定两个整数,则此函数将返回从第一个整数开始并循环到但不包括第二个整数的goroutine:

例如:

1
2
{{ range $i := loop 5 8 }}
stanza-{{ $i }}{{ end }}

结果:

stanza-5
stanza-6
stanza-7

注意:因为函数返回goroutine而不是切片,所以没法获取索引和元素。换句话说,如下内容无效

1
2
3
# Will NOT work!
{{ range $i, $e := loop 5 8 }}
# ...{{ end }}

join

字符串链接:

1
{{ $items | join "," }}

trimSpace

获取给定的字符串并将其解析为布尔值:

{{ "true" | parseBool }}

这能够与键和条件检查结合使用,例如:

1
{{ if key "feature/enabled" | parseBool }}{{ end }}

parseFloat

获取给定的字符串并将其解析为基数为10的float64:

1
{{ "1.2" | parseFloat }}

parseInt

获取给定的字符串并将其解析为base-10 int64:

{{ "1" | parseInt }}

这能够与其余助手结合使用,例如:

1
2
{{ range $i := loop key "config/pool_size" | parseInt }}
# ...{{ end }}

parseJSON

获取给定的输入(一般是键中的值)并将结果解析为JSON:

1
{{ with $d := key "user/info" | parseJSON }}{{ $d.name }}{{ end }}

注意:Consul Template会屡次评估模板,而且在第一次评估时,键的值将为空(由于还没有加载任何数据)。这意味着模板必须防止空响应。

parseUint

获取给定的字符串并将其解析为base-10 int64:

1
{{ "1" | parseUint }}

plugin

获取插件和可选有效加载的名称并执行Consul Template插件。

1
{{ plugin "my-plugin" }}

该插件能够采用任意数量的字符串参数,也能够是生成字符串的管道的目标。这一般与用于自定义的JSON过滤器结合使用:

有关插件的更多信息,请参阅插件部分

1
{{ tree "foo" | explode | toJSON | plugin "my-plugin" }}

regexMatch

将参数做为正则表达式,若是在给定字符串上匹配则返回true,不然返回false

1
2
3
4
5
{{ if "foo.bar" | regexMatch "foo([.a-z]+)" }}
# ...
{{ else }}
# ...
{{ end }}

regexReplaceAll

将参数做为正则表达式,并将全部出现的正则表达式替换为给定的字符串。与go同样,您可使用$1之类的变量来引用替换字符串中的子表达式。

1
{{ "foo.bar" | regexReplaceAll "foo([.a-z]+)" "$1" }}

replaceAll

将参数做为字符串取代,并用给定的字符串替换给定字符串的全部匹配项。

1
{{ "foo.bar" | replaceAll "." "_" }}

此功能也能够与其余功能连接:

1
{{ service "web" }}{{ .Name | replaceAll ":" "_" }}{{ end }}

split

在提供的分隔符上拆分给定的字符串:

1
{{ "foo\nbar\n" | split "\n" }}

这能够与连接和管道与其余功能结合使用:

1
{{ key "foo" | toUpper | split "\n" | join "," }}

timestamp

以字符串(UTC)形式返回当前时间戳。若是没有给出参数,则结果是当前的RFC3339时间戳:

1
{{ timestamp }} // e.g. 1970-01-01T00:00:00Z

若是给出了可选参数,则它用于格式化时间戳。参考日期Mon Jan 2 15:04:05 -0700 MST 2006可用于根据须要格式化日期:

1
{{ timestamp "2006-01-02" }} // e.g. 1970-01-01

有关更多信息,请参阅Go’s time.Format

做为一种特殊状况,若是可选参数是“unix”,则以秒为单位的unix时间戳将做为字符串返回。

1
{{ timestamp "unix" }} // e.g. 0

toJSON

treels调用获取结果并将其转换为JSON对象。

1
{{ tree "config" | explode | toJSON }}

结果:

1
{"admin":{"port":"1234"},"maxconns":"5","minconns":"2"}

注意:Consul将全部KV数据存储为字符串。所以,true为“true”,1为“1”,等等。

toJSONPretty

treels调用获取结果并将其转换为漂亮打印的JSON对象,缩进两个空格。

1
{{ tree "config" | explode | toJSONPretty }}

结果:

1
2
3
4
5
6
7
{
 "admin": {
   "port": "1234"
 },
 "maxconns": "5",
 "minconns": "2",
}

toLower

将参数做为字符串并将其转换为小写。

1
{{ key "user/name" | toLower }}

参见Go’s strings.ToLower

toTitle

将参数做为字符串并将其转换为标题。

1
{{ key "user/name" | toTitle }}

参见Go’s strings.Title

toTOML

treels调用获取结果并将其转换为TOML对象。

1
{{ tree "config" | explode | toTOML }}

结果:

1
2
3
4
5
maxconns = "5"
minconns = "2"

[admin]
 port = "1134"

toUpper

将参数做为字符串并将其转换为大写。

1
{{ key "user/name" | toUpper }}

参见Go’s strings.ToUpper

toYAML

treels调用获取结果并将其转换为漂亮打印的YAML对象,缩进两个空格。

1
{{ tree "config" | explode | toYAML }}

结果:

1
2
3
4
admin:
 port: "1234"
maxconns: "5"
minconns: "2"

4. Math Functions数学函数

方便浮点数和整数值数学计算的函数

add

返回两个值的总和。

1
{{ add 1 2 }} // 3

这也能够与管道功能一块儿使用(下同)。

1
{{ 1 | add 2 }} // 3

subtract

返回第一个值与第二个值的差值。

1
{{ subtract 2 5 }} // 3
1
{{ 5 | subtract 2 }} // 3

请仔细注意参数的顺序(下同)。

multiply

返回两个值的乘积。

1
{{ multiply 2 2 }} // 4
1
{{ 2 | multiply 2 }} // 4

divide

返回第一个值的第二个值的除法。

1
{{ divide 2 10 }} // 5
1
{{ 10 | divide 2 }} // 5

modulo

返回第一个值的第二个模的模数。

1
{{ modulo 2 5 }} // 1
1
{{ 5 | modulo 2 }} // 1
相关文章
相关标签/搜索