如何使用Go Templates(Helm)实现递归格式化扁平化YAML对象?
Helm 递归扁平化嵌套YAML实现方案
Helm 模板没有提供原生递归循环语法,要实现嵌套结构遍历扁平化,可通过命名模板自调用的方式实现,遍历过程中通过字典传递当前拼接的键前缀上下文即可。
实现步骤
- 首先在chart的
_helpers.tpl文件中添加递归扁平化的命名模板:
{{/* 递归遍历嵌套Map结构,输出扁平化键值对 */}} {{- define "flatten.nested" -}} {{- $prefix := .prefix -}} {{- $currentData := .data -}} {{- range $k, $v := $currentData -}} {{- 拼接当前层级的键,根节点无前缀时直接用当前key,非根节点用「前缀.当前key」格式 -}} {{- $fullKey := ternary (printf "%s.%s" $prefix $k) $k (ne $prefix "") -}} {{- if kindIs "map" $v -}} {{- 遇到嵌套Map时,把当前拼接好的键作为新前缀,自调用模板继续往下遍历 -}} {{- include "flatten.nested" (dict "prefix" $fullKey "data" $v) -}} {{- else -}} {{- 叶子节点直接输出键值对,字符串类型加引号,数值等其他类型保留原格式 -}} {{ $fullKey }}={{ if kindIs "string" $v }}"{{ $v }}"{{ else }}{{ $v }}{{ end }} {{- end -}} {{- end -}} {{- end -}}
- 在需要输出扁平化内容的模板位置调用该模板,传入初始空前缀和要处理的YAML对象即可,比如要处理
.Values.some_map节点:
{{- include "flatten.nested" (dict "prefix" "" "data" .Values.some_map) -}}
渲染效果验证
传入给定的输入YAML:
some_map: with: different indentation: levels: and nested: sub: maps: "42" and_more: maps: 42
最终渲染输出和预期完全一致:
some_map.with="different" some_map.indentation.levels="and" some_map.nested.sub.maps="42" some_map.nested.and_more.maps=42
自定义调整说明
如果需要修改格式规则,直接调整对应逻辑即可:
- 要修改键的层级分隔符,把
printf "%s.%s"里的.替换成目标分隔符 - 要修改键值拼接格式(比如加特殊包裹符、调整等号两边空格),直接修改叶子节点的输出行模板
- 要支持数组类型的扁平化,可增加
kindIs "slice"的判断分支,追加数组下标的拼接逻辑
内容的提问来源于stack exchange,提问作者Roberto P. Romero
相关产品推荐
相关产品推荐

