Templates define a single application configuration template.
Templates are stored under the /etc/confd/templates
directory by default.
Templates are written in Go's text/template
.
Alias for the path.Base function.
{{with get "/key"}}
key: {{base .Key}}
value: {{.Value}}
{{end}}
Checks if the key exists. Return false if key is not found.
{{if exists "/key"}}
value: {{getv "/key"}}
{{end}}
Returns the KVPair where key matches its argument. Returns an error if key is not found.
{{with get "/key"}}
key: {{.Key}}
value: {{.Value}}
{{end}}
Returns the KVPair where key matches its argument and the value has been encrypted. Returns an error if key is not found.
{{with cget "/key"}}
key: {{.Key}}
value: {{.Value}}
{{end}}
Returns all KVPair, []KVPair, where key matches its argument. Returns an error if key is not found.
{{range gets "/*"}}
key: {{.Key}}
value: {{.Value}}
{{end}}
Returns all KVPair, []KVPair, where key matches its argument and the values have been encrypted. Returns an error if key is not found.
{{range cgets "/*"}}
key: {{.Key}}
value: {{.Value}}
{{end}}
Returns the value as a string where key matches its argument. Returns an error if key is not found.
value: {{getv "/key"}}
Returns the encrypted value as a string where key matches its argument. Returns an error if key is not found.
value: {{cgetv "/key"}}
Returns all values, []string, where key matches its argument. Returns an error if key is not found.
{{range getvs "/*"}}
value: {{.}}
{{end}}
Returns all encrypted values, []string, where key matches its argument. Returns an error if key is not found.
{{range cgetvs "/*"}}
value: {{.}}
{{end}}
Alias for os.Getenv
export HOSTNAME=`hostname`
hostname: {{getenv "HOSTNAME"}}
Alias for time.Now
# Generated by confd {{datetime}}
Outputs:
# Generated by confd 2015-01-23 13:34:56.093250283 -0800 PST
# Generated by confd {datetime.Format("Jan 2, 2006 at 3:04pm (MST)")}
Outputs:
# Generated by confd Jan 23, 2015 at 1:34pm (EST)
See the time package for more usage: http://golang.org/pkg/time/
Wrapper for strings.Split. Splits the input string on the separating string and returns a slice of substrings.
{{ $url := split (getv "/deis/service") ":" }}
host: {{index $url 0}}
port: {{index $url 1}}
Alias for strings.ToUpper Returns uppercased string.
key: {{toUpper "value"}}
Alias for strings.ToLower. Returns lowercased string.
key: {{toLower "Value"}}
Returns an map[string]interface{} of the json value.
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}}
Once you have parsed the JSON, it is possible to traverse it with normal Go
template functions such as index
.
A more advanced structure, like this:
{
"animals": [
{"type": "dog", "name": "Fido"},
{"type": "cat", "name": "Misse"}
]
}
It can be traversed like this:
{{$data := json (getv "/test/data/")}}
type: {{ (index $data.animals 1).type }}
name: {{ (index $data.animals 1).name }}
{{range $data.animals}}
{{.name}}
{{end}}
Returns a []interface{} from a json array such as ["a", "b", "c"]
.
{{range jsonArray (getv "/services/data/")}}
val: {{.}}
{{end}}
Returns all subkeys, []string, where path matches its argument. Returns an empty list if path is not found.
{{range ls "/deis/services"}}
value: {{.}}
{{end}}
Returns all subkeys, []string, where path matches its argument. It only returns subkeys that also have subkeys. Returns an empty list if path is not found.
{{range lsdir "/deis/services"}}
value: {{.}}
{{end}}
Returns the parent directory of a given key.
{{with dir "/services/data/url"}}
dir: {{.}}
{{end}}
Alias for the strings.Join function.
{{$services := getvs "/services/elasticsearch/*"}}
services: {{join $services ","}}
etcdctl set /nginx/domain 'example.com'
etcdctl set /nginx/root '/var/www/example_dotcom'
etcdctl set /nginx/worker_processes '2'
etcdctl set /app/upstream/app1 "10.0.1.100:80"
etcdctl set /app/upstream/app2 "10.0.1.101:80"
/etc/confd/templates/nginx.conf.tmpl
worker_processes {{getv "/nginx/worker_processes"}};
upstream app {
{{range getvs "/app/upstream/*"}}
server {{.}};
{{end}}
}
server {
listen 80;
server_name www.{{getv "/nginx/domain"}};
access_log /var/log/nginx/{{getv "/nginx/domain"}}.access.log;
error_log /var/log/nginx/{{getv "/nginx/domain"}}.log;
location / {
root {{getv "/nginx/root"}};
index index.html index.htm;
proxy_pass http://app;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Output: /etc/nginx/nginx.conf
worker_processes 2;
upstream app {
server 10.0.1.100:80;
server 10.0.1.101:80;
}
server {
listen 80;
server_name www.example.com;
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log;
location / {
root /var/www/example_dotcom;
index index.html index.htm;
proxy_pass http://app;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
This examples show how to use a combination of the templates functions to do nested iteration.
etcdctl mkdir /services/web/cust1/
etcdctl mkdir /services/web/cust2/
etcdctl set /services/web/cust1/2 '{"IP": "10.0.0.2"}'
etcdctl set /services/web/cust2/2 '{"IP": "10.0.0.4"}'
etcdctl set /services/web/cust2/1 '{"IP": "10.0.0.3"}'
etcdctl set /services/web/cust1/1 '{"IP": "10.0.0.1"}'
[template]
src = "services.conf.tmpl"
dest = "/tmp/services.conf"
keys = [
"/services/web"
]
{{range $dir := lsdir "/services/web"}}
upstream {{base $dir}} {
{{$custdir := printf "/services/web/%s/*" $dir}}{{range gets $custdir}}
server {{$data := json .Value}}{{$data.IP}}:80;
{{end}}
}
server {
server_name {{base $dir}}.example.com;
location / {
proxy_pass {{base $dir}};
}
}
{{end}}
Output:/tmp/services.conf
upstream cust1 {
server 10.0.0.1:80;
server 10.0.0.2:80;
}
server {
server_name cust1.example.com;
location / {
proxy_pass cust1;
}
}
upstream cust2 {
server 10.0.0.3:80;
server 10.0.0.4:80;
}
server {
server_name cust2.example.com;
location / {
proxy_pass cust2;
}
}
Go's text/template
package is very powerful. For more details on it's capabilities see its documentation.