在 consul-template 的循环中覆盖变量
Overriding a variable in a loop in consul-template
我在领事模板中使用以下模板:
{{ range services }}
{{ $server_name := .Name | replaceAll "_" "." }}
{{ range .Tags }}
{{ if . | regexMatch "server_name=" }}
# found matching server_name in {{ . }}
{{ $server_name := . | regexReplaceAll ".*=" "" }}
{{ end }}
{{ end }}
# server_name = {{ $server_name }}
acl host_{{ .Name }} hdr(host) -i {{ $server_name }}
use_backend {{ .Name }}_backend if host_{{ .Name }}
{{ end }}
产生
# found matching server_name in server_name=geoserver.hello.org
# server_name = geoserver.dev.hello.org
acl host_geoserver_dev_hello_org hdr(host) -i geoserver.dev.hello.org
use_backend geoserver_dev_hello_org_backend if host_geoserver_dev_hello_org
其中 .Name
是 geoserver_dev_hello_org
并且有一个 server_name=geoserver.hello.org
标签。我希望在 .Tags
范围循环结束时,$server_name
应该具有值 geoserver.hello.org
,但它仍然具有其原始值 geoserver.dev.hello.org
。
我怎样才能使循环覆盖 $server_name
(并在找到值时退出循环)?
内部$server_name
和外部$server_name
是不同的变量。您不能在 Go 模板中从外部范围设置变量:http://play.golang.org/p/0fuOmqXrSK.
您可以尝试重写您的模板以在内部 if
中打印 acl
等部分,除非您只需要执行该部分一次,否则这将起作用。 Go 模板不是设计为复杂逻辑的脚本语言,它是显示 pre-computed 信息的工具。 fmt.Printf
如果你愿意的话。包括搜索和替换在内的所有逻辑都应该在 Go 中,它会更快、更安全、更易于维护和调试。
在 consul-template
模板中,您可以使用 the scratch - 在模板的整个生命周期内都可用的临时键值存储。
您的代码如下所示:
{{ range services }}
{{ $server_name := .Name | replaceAll "_" "." }}
{{ scratch.Set "server_name" $server_name }}
{{ range .Tags }}
{{ if . | regexMatch "server_name=" }}
# found matching server_name in {{ . }}
{{ $server_name := . | regexReplaceAll ".*=" "" }}
{{ scratch.Set "server_name" $server_name }}
{{ end }}
{{ end }}
# server_name = {{ scratch.Get "server_name" }}
acl host_{{ .Name }} hdr(host) -i {{ $server_name }}
use_backend {{ .Name }}_backend if host_{{ .Name }}
{{ end }}
自 Go 1.11 release 以来,可以通过模板中的赋值来修改变量。现在可以使用了:
{{ $v := "init" }}
{{ if true }}
{{ $v = "changed" }}
{{ end }}
v: {{ $v }} {{/* "changed" */}}
此版本已 introduced to Consul Template with the v0.25.1 发布。
我在领事模板中使用以下模板:
{{ range services }}
{{ $server_name := .Name | replaceAll "_" "." }}
{{ range .Tags }}
{{ if . | regexMatch "server_name=" }}
# found matching server_name in {{ . }}
{{ $server_name := . | regexReplaceAll ".*=" "" }}
{{ end }}
{{ end }}
# server_name = {{ $server_name }}
acl host_{{ .Name }} hdr(host) -i {{ $server_name }}
use_backend {{ .Name }}_backend if host_{{ .Name }}
{{ end }}
产生
# found matching server_name in server_name=geoserver.hello.org
# server_name = geoserver.dev.hello.org
acl host_geoserver_dev_hello_org hdr(host) -i geoserver.dev.hello.org
use_backend geoserver_dev_hello_org_backend if host_geoserver_dev_hello_org
其中 .Name
是 geoserver_dev_hello_org
并且有一个 server_name=geoserver.hello.org
标签。我希望在 .Tags
范围循环结束时,$server_name
应该具有值 geoserver.hello.org
,但它仍然具有其原始值 geoserver.dev.hello.org
。
我怎样才能使循环覆盖 $server_name
(并在找到值时退出循环)?
内部$server_name
和外部$server_name
是不同的变量。您不能在 Go 模板中从外部范围设置变量:http://play.golang.org/p/0fuOmqXrSK.
您可以尝试重写您的模板以在内部 if
中打印 acl
等部分,除非您只需要执行该部分一次,否则这将起作用。 Go 模板不是设计为复杂逻辑的脚本语言,它是显示 pre-computed 信息的工具。 fmt.Printf
如果你愿意的话。包括搜索和替换在内的所有逻辑都应该在 Go 中,它会更快、更安全、更易于维护和调试。
在 consul-template
模板中,您可以使用 the scratch - 在模板的整个生命周期内都可用的临时键值存储。
您的代码如下所示:
{{ range services }}
{{ $server_name := .Name | replaceAll "_" "." }}
{{ scratch.Set "server_name" $server_name }}
{{ range .Tags }}
{{ if . | regexMatch "server_name=" }}
# found matching server_name in {{ . }}
{{ $server_name := . | regexReplaceAll ".*=" "" }}
{{ scratch.Set "server_name" $server_name }}
{{ end }}
{{ end }}
# server_name = {{ scratch.Get "server_name" }}
acl host_{{ .Name }} hdr(host) -i {{ $server_name }}
use_backend {{ .Name }}_backend if host_{{ .Name }}
{{ end }}
自 Go 1.11 release 以来,可以通过模板中的赋值来修改变量。现在可以使用了:
{{ $v := "init" }}
{{ if true }}
{{ $v = "changed" }}
{{ end }}
v: {{ $v }} {{/* "changed" */}}
此版本已 introduced to Consul Template with the v0.25.1 发布。