在舵图中,我必须遵循以下值
dataCenters:
- name: a
replicas: 3
- name: b
replicas: 2
生成模板时,我希望输出如下所示
server.1 = a-1
server.2 = a-2
server.3 = a-3
server.4 = b-1
server.5 = b-2
我尝试了这段代码
{{- $index := 0 -}}
{{ range $dc := .Values.cluster.dataCenters -}}
{{ range $seq := (int $dc.replicas | until) -}}
{{- $index := (add $index 1) -}}
server.{{ $index }}={{ $dc.name }}-{{ $seq }}
{{ end -}}
{{ end -}}
但是在头盔模板中,我没关系,您可以在尝试第四行时重新分配索引的值,因此我可以退出
server.1 = a-1
...
server.1 = b-2
如何使用Sprig / Helm模板语言计算全局索引 0至4 (在我的情况下为1至5)?
答案 0 :(得分:1)
我有一种方法可以做到这一点,其中涉及一些技巧,而这很大程度上是受函数式编程经验的启发。
Go / Helm模板使用单个参数,但是sprig库使您能够创建列表,而text/template index
函数使您可以从列表中选择内容。这样,您就可以编写一个“函数”模板,该模板带有多个参数,并打包到一个列表中。
假设我们要写出此输出的一行。我们需要跟踪(全局)我们在哪个服务器号,(当前数据中心内)在哪个副本号,当前数据中心记录以及我们尚未发出的记录。如果我们不在当前列表的末尾,则打印其余数据中心的记录;否则,为当前副本打印一行,并为下一个服务器/副本索引重复。
{{ define "emit-dc" -}}
{{ $server := index . 0 -}}
{{ $n := index . 1 -}}
{{ $dc := index . 2 -}}
{{ $dcs := index . 3 -}}
{{ if gt $n (int64 $dc.replicas) -}}
{{ template "emit-dcs" (list $server $dcs) -}}
{{ else -}}
server.{{ $server }}: {{ $dc.name }}-{{ $n }}
{{ template "emit-dc" (list (add1 $server) (add1 $n) $dc $dcs) -}}
{{ end -}}
{{ end -}}
在顶层,我们知道下一个服务器号的索引以及数据中心的列表。如果该列表为空,我们就完成了。否则,我们可以从列表中的第一个数据中心开始发出行。
{{ define "emit-dcs" -}}
{{ $server := index . 0 -}}
{{ $dcs := index . 1 -}}
{{ if ne 0 (len $dcs) -}}
{{ template "emit-dc" (list $server 1 (first $dcs) (rest $dcs)) -}}
{{ end -}}
{{ end -}}
然后,在您的实际资源定义(例如ConfigMap定义)中,您可以使用第一个服务器编号来调用此模板:
{{ template "emit-dcs" (list 1 .Values.dataCenters) -}}
将所有内容复制到虚拟Helm图表中,您可以验证输出:
% helm template .
---
# Source: x/templates/test.yaml
server.1: a-1
server.2: a-2
server.3: a-3
server.4: b-1
server.5: b-2
我怀疑如果服务器的数量远远超过数百个(Go模板引擎几乎肯定不是 tail递归),则此技巧将无法正常工作,并且这在某种程度上试图强加于人尚未针对模板语言设计的标准编程语言方法。但是...有效。