confd 模板语法
2021-10-20 tech linux confd 21 mins 2 图 7476 字
本文是 confd 在 github 上的文档的翻译和此文的摘抄,该文档详细介绍了confd模板的语法和结构。另外,最后我列出一些我个人常用的表达式,方便未来复用。
一、模板源
模板源以TOML编写并已 .toml 作为后缀的来定义的。默认情况下,模板源存储在/etc/confd/conf.d
目录下。模板源使用Go的库: text/template
.。
必要参数
dest
(字符串) - 目标文件。keys
(字符串数组) - 键数组。src
(字符串) - 配置模板的相对路径 。
可选参数
gid
(int) - 应该拥有该文件的gid。默认为有效的gid。mode
(字符串) - 文件的权限模式。uid
(int) - 应该拥有该文件的uid。默认为有效的uid。reload_cmd
(字符串) - 重新加载配置的命令。check_cmd
(字符串)- 检查配置的命令。prefix
(字符串) - 键前缀的字符串。
[template]
src = "nginx.conf.tmpl"
dest = "/etc/nginx/nginx.conf"
uid = 0
gid = 0
mode = "0644"
keys = [
"/nginx",
]
check_cmd = "/usr/sbin/nginx -t -c {{.src}}"
reload_cmd = "/usr/sbin/service nginx restart"
二、模板函数
map
创建接口和字符串的键值映射
{{$endpoint := map "name" "elasticsearch" "private_port" 9200 "public_port" 443}}
name: {{index $endpoint "name"}}
private-port: {{index $endpoint "private_port"}}
public-port: {{index $endpoint "public_port"}}
如果您是子模板并且想要向其传递多个值,则特别有用。
base
path.Base函数的别名 。
{{with get "/key"}}
key: {{base .Key}}
value: {{.Value}}
{{end}}
exists
判断键是否存在。如果找不到键,则返回false。
{{if exists "/key"}}
value: {{getv "/key"}}
{{end}}
get
返回键与其键匹配的键值对。如果未找到键,则返回错误。
{{with get "/key"}}
key: {{.Key}}
value: {{.Value}}
{{end}}
gets
返回与其key匹配所有键值对,如果未找到键,则返回错误。
{{range gets "/*"}}
key: {{.Key}}
value: {{.Value}}
{{end}}
getv
返回与其键或可选的默认值匹配的字符串,如果未找到键且未给出默认值,则返回错误。
value: {{getv "/key"}}
getv默认值
value: {{getv "/key" "default_value"}}
getvs
返回与其键匹配所有值的字符串,如果未找到密钥,则返回错误。
{{range getvs "/*"}}
value: {{.}}
{{end}}
getenv
返回在os.Getenv 中检索由键命名的环境变量的值。如果变量不存在,该值将为空。(可选)您可以提供一个默认值,如果该键不存在,将返回该值。
export HOSTNAME=`hostname`
hostname: {{getenv "HOSTNAME"}}
getenv默认值
ipaddr: {{getenv "HOST_IP" "127.0.0.1"}}
datetime
是time.Now的别名
Generated by confd {{datetime}}
输出:
Generated by confd 2015-01-23 13:34:56.093250283 -0800 PST
Generated by confd {{datetime.Format "Jan 2, 2006 at 3:04pm (MST)"}}
输出:
Generated by confd Jan 23, 2015 at 1:34pm (EST)
更多用法,请参阅官方时间用法。
split
包装器 strings.Split。分隔输入的字符串并返回一个子字符串切片。
{{ $url := split (getv "/deis/service") ":" }}
host: {{index $url 0}}
port: {{index $url 1}}
toUpper
strings.ToUpper的 别名 返回大写字符串。
key: {{toUpper "value"}}
toLower
strings.ToLower的 别名 。返回小写字符串。
key: {{toLower "Value"}}
json
返回map[string]interface{}形式的json值。
lookupSRV
net.LookupSRV 包装器 。通过组合net.SRV结构的所有字段按字母顺序对SRV记录进行排序,以减少不必要的配置重新加载。
{{range lookupSRV "mail" "tcp" "example.com"}}
target: {{.Target}}
port: {{.Port}}
priority: {{.Priority}}
weight: {{.Weight}}
{{end}}
etcd添加键值
etcdctl set /services/zookeeper/host1 '{"Id":"host1", "IP":"192.168.10.11"}'
etcdctl set /services/zookeeper/host2 '{"Id":"host2", "IP":"192.168.10.12"}'
创建模板源
[template]
src = "services.conf.tmpl"
dest = "/tmp/services.conf"
keys = [
"/services/zookeeper/"
]
创建模板
{{range gets "/services/zookeeper/*"}}
{{$data := json .Value}}
id: {{$data.Id}}
ip: {{$data.IP}}
{{end}}
map遍历
一旦解析了JSON,就可以使用普通的Go模板函数遍历它 index
。
更高级的结构,如下所示:
{
"animals": [
{"type": "dog", "name": "Fido"},
{"type": "cat", "name": "Misse"}
]
}
它可以像这样遍历:
{{$data := json (getv "/test/data/")}}
type: {{ (index $data.animals 1).type }}
name: {{ (index $data.animals 1).name }}
{{range $data.animals}}
{{.name}}
{{end}}
jsonArray
从接口返回json数组,例如: [“a”, “b”, “c”]`。
{{range jsonArray (getv "/services/data/")}}
val: {{.}}
{{end}}
ls
返回匹配路径的所有子键,字符串等。如果找不到路径,则返回空列表。
{{range ls "/deis/services"}}
value: {{.}}
{{end}}
lsdir
返回匹配路径的所有子键,字符串等。注意它只返回也有子键的子键。如果找不到路径,则返回空列表。
{{range lsdir "/deis/services"}}
value: {{.}}
{{end}}
dir
返回制定键的父目录。
{{with dir "/services/data/url"}}
dir: {{.}}
{{end}}
join
strings.Join 函数的别名 。
{{$services := getvs "/services/elasticsearch/*"}}
services: {{join $services ","}}
replace
strings.place 函数的别名 。
{{$backend := getv "/services/backend/nginx"}}
backend = {{replace $backend "-" "_" -1}}
lookupIP
net.LookupIP 函数的包装器 。包装器还按字母顺序排序IP地址。这一点至关重要,因为在动态环境中,DNS服务器通常会混淆链接到域名的地址。这将导致不必要的配置重新加载。
{{range lookupIP "some.host.local"}}
server {{.}};
{{end}}
atoi
strconv.Atoi 函数的别名 。
{{seq 1 (atoi (getv "/count"))}}
三、我的例子
-
需要end包裹的关键字
- range
- with
-
获取环境变量
{{$hostname := getenv "KELU_HOSTNAME"}} hostname="{{$hostname}}"
-
取值with
{{with get (printf "/confd/%s/config" $hostname)}} {{ with get $node }}
-
循环range
{{range $key, $dir := lsdir "/confd"}} {{ $node := printf "/confd/%s/config" $dir }} # 字符串拼接+赋值 {{ with get $node }} {{ $data := json .Value }} {{end}} {{end}}
-
对比 eq/ne
{{if $data.isTrue }} {{if ne $data.name "kelu"}}
eq Returns the boolean truth of arg1 == arg2 ne Returns the boolean truth of arg1 != arg2 lt Returns the boolean truth of arg1 < arg2 le Returns the boolean truth of arg1 <= arg2 gt Returns the boolean truth of arg1 > arg2 ge Returns the boolean truth of arg1 >= arg2
-
字符串拼接printf
{{ $config := (printf "/haproxy/%s/config" $haproxy)}}
-
解析 json
{{ with get $node }}{{ $data := json .Value }}
-
数组长度len
{{$dir := lsdir "/confd"}} {{$count := len $dir}}
and Returns the boolean AND of its arguments by returning the first empty argument or the last argument, that is, "and x y" behaves as "if x then y else x". All the arguments are evaluated. call Returns the result of calling the first argument, which must be a function, with the remaining arguments as parameters. Thus "call .X.Y 1 2" is, in Go notation, dot.X.Y(1, 2) where Y is a func-valued field, map entry, or the like. The first argument must be the result of an evaluation that yields a value of function type (as distinct from a predefined function such as print). The function must return either one or two result values, the second of which is of type error. If the arguments don't match the function or the returned error value is non-nil, execution stops. html Returns the escaped HTML equivalent of the textual representation of its arguments. This function is unavailable in html/template, with a few exceptions. index Returns the result of indexing its first argument by the following arguments. Thus "index x 1 2 3" is, in Go syntax, x[1][2][3]. Each indexed item must be a map, slice, or array. slice slice returns the result of slicing its first argument by the remaining arguments. Thus "slice x 1 2" is, in Go syntax, x[1:2], while "slice x" is x[:], "slice x 1" is x[1:], and "slice x 1 2 3" is x[1:2:3]. The first argument must be a string, slice, or array. js Returns the escaped JavaScript equivalent of the textual representation of its arguments. len Returns the integer length of its argument. not Returns the boolean negation of its single argument. or Returns the boolean OR of its arguments by returning the first non-empty argument or the last argument, that is, "or x y" behaves as "if x then x else y". All the arguments are evaluated. print An alias for fmt.Sprint printf An alias for fmt.Sprintf println An alias for fmt.Sprintln urlquery Returns the escaped value of the textual representation of its arguments in a form suitable for embedding in a URL query. This function is unavailable in html/template, with a few exceptions.
-
获取字符串最后一个单词base
{{base $dir}}
-
反释义
原文:
在模板中要在外部包裹{{}}
再加双引号:
-
数组解析jsonArray
etcd中的数据为:
/confd/local/ip/static ["1.2.3.4","5.6.7.8"]
{{range jsonArray (getv "/confd/local/ip/static")}}allow {{.}};{{end}}
-
字符串拆分为数组 spilt
etcd中的数据为:
/a/b/c/d {"target":"a,b,c,d"}
{{ $backend := split $data.target "," }} {{ range $backend }} ... {{ end }}