【问题标题】:Overriding a variable in a loop in consul-template在领事模板的循环中覆盖变量
【发布时间】:2016-01-13 08:29:54
【问题描述】:

我在 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

其中.Namegeoserver_dev_hello_org,并且有一个server_name=geoserver.hello.org 标记。我希望在.Tags 范围循环结束时,$server_name 的值应该是 geoserver.hello.org,但它仍然具有 geoserver.dev.hello.org 的原始值。

如何使循环覆盖$server_name(并在找到值时退出循环)?

【问题讨论】:

标签: templates go consul consul-template


【解决方案1】:

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 }}

【讨论】:

  • 不错不错不错不错
【解决方案2】:

内部$server_name 和外部$server_name 是不同的变量。您不能在 Go 模板中从外部范围设置变量:http://play.golang.org/p/0fuOmqXrSK

您可以尝试重写您的模板以打印内部if 内的acl 等部分,除非您只需要执行该部分一次,否则它将起作用。 Go 模板不是为复杂逻辑设计的脚本语言,它是一种显示预先计算信息的工具。如果您愿意,请在类固醇上使用 fmt.Printf。包括搜索和替换在内的所有逻辑都应该在 Go 中,它会更快、更安全、更易于维护和调试。

【讨论】:

  • 谢谢。在 consul-template 中,我猜我需要写一个 plugin 才能为此编写 Go 代码?
  • @ℝaphink 查看他们的文档,您似乎可以用任何语言编写插件,而不仅仅是 Go。另外,现在我想到了,将循环之后的部分移动到内部实际上并不是一个坏主意,除非您需要确保它只打印一次。
  • 其实在这种情况下,如果我为server_name.Name 打印一行也不会有什么坏处,所以我实际上可能会这样做。
【解决方案3】:

由于Go 1.11 release,可以通过模板中的赋值来修改变量。所以现在可以工作了:

  {{ $v := "init" }}
  {{ if true }}
    {{ $v = "changed" }}
  {{ end }}
  v: {{ $v }} {{/* "changed" */}}

这个版本是 introduced 到 Consul Template 的 v0.25.1 版本。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多