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
相關文章
相關標籤/搜索