计算 Kubernetes Sprig/helm 模板中两个范围的全局索引?

Caculating the global index for two ranges in Kubernetes Sprig/helm templates?

在 Helm Chart 中,我必须遵循以下值

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

但是在 helm 模板中,我不认为你可以重新分配索引的值,因为我的第 4 行正在尝试,因此我退出了

server.1 = a-1
...
server.1 = b-2

如何使用 Sprig/Helm 模板语言计算全局索引 0 到 4(我的情况是 1 到 5)?

我有一个方法可以做到这一点,其中涉及一些技巧,很大程度上受到函数式编程经验的启发。

Go/Helm 模板采用单个参数,但 sprig library gives you the ability to create lists, and the text/template index 函数可让您从列表中挑选内容。这使您可以编写一个 "function" 模板,该模板采用多个参数,打包到一个列表中。

假设我们要写出一行输出。我们需要跟踪我们所在的服务器编号(全局)、我们所在的副本编号(在当前数据中心内)、当前数据中心记录以及我们尚未发出的记录。如果我们超过了当前列表的末尾,则打印其余数据中心的记录;否则为当前副本打印一行并为下一个 server/replica 索引重复。

{{ 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 模板引擎几乎可以肯定不是 尾递归),这个技巧将无法正常工作,并且这个在某种程度上试图将标准编程语言方法强加于并非完全为其设计的模板语言。但是...它有效。