在头盔图中我必须遵循价值观
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 -}}
但是在掌舵模板中,我不能重新分配索引的价值,因为我的第4行正在尝试,因为我退出
server.1 = a-1
...
server.1 = b-2
如何使用Sprig / Helm模板语言计算全局索引0到4(在我的情况下为1到5)?
我有办法做到这一点涉及一些技巧,深受功能编程经验的启发。
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模板引擎几乎肯定不是尾递归),这个技巧将无法正常工作,这有点试图将标准编程语言方法强加于模板语言上不太适合它。但是......它有效。