为了账号安全,请及时绑定邮箱和手机立即绑定

如何使用 Go Templates (Helm) 应用递归格式?

如何使用 Go Templates (Helm) 应用递归格式?

Go
温温酱 2023-01-03 14:17:25
我正在使用 helm 并给出了一个 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我没有在 helm 文档中阅读任何关于递归循环的内容,请记住示例中的递归格式( "%v.%v" if !root else "%v=%v" )可能会有所不同。
查看完整描述

3 回答

?
慕桂英546537

TA贡献1848条经验 获得超10个赞

是的,似乎{{ define支持递归使用{{ include,虽然不知道到什么深度


我掀起的 PoC 看看它是否可行


{{- define "bob" -}}

{{- $it := . -}}

{{- $knd := kindOf . -}}

{{- if eq $knd "map" }}

{{- range (keys .) }}

{{- $k := . }}

{{- $v := get $it . }}

{{- $vk := kindOf $v }}

{{- if eq $vk "map" }}

{{-   printf "%s." $k }}

{{-   include "bob" $v }}

{{- else }}

{{-   printf "%s=%s\n" $k (toJson $v) }}

{{- end }}

{{- end }}

{{- else }}

{{ toJson . }}#k({{ $knd }})

{{- end }}

{{- end -}}

调用为


{{ $fred := dict 

    "alpha" (dict "a0" "a0ch0")

    "beta" (dict "beta0" (dict "beta00" 1234))

    "charlie" (list "ch0" "ch1" "ch2") }}

data:

  theData: |

{{ toJson $fred | indent 4 }}

  toml: |

{{ include "bob" $fred | indent 4 }}

生产的


data:

  theData: |

    {"alpha":{"a0":"a0ch0"},"beta":{"beta0":{"beta00":1234}},"charlie":["ch0","ch1","ch2"]}

  toml: |

    alpha.a0="a0ch0"

    beta.beta0.beta00=1234

    charlie=["ch0","ch1","ch2"]

此外,您引用的示例似乎引用了最外层的变量名称,我认为 helm 不知道,因此您需要一个人工包装器dict才能获得该行为:{{ include "toToml" (dict "some_map" .Values.some_map) }}


查看完整回答
反对 回复 2023-01-03
?
跃然一笑

TA贡献1826条经验 获得超6个赞

这帮助/允许我解决我的问题!他的(很快,我明白了)解决方案有问题,但如果您移动具有相同前缀的值。继续他的例子:


{{ $fred := dict

    "alpha" (dict "a0" "a0ch0")

    "beta" (dict "beta0" (dict "beta00" 1234))

    "charlie" (list "ch0" "ch1" "ch2")

    "problem" (dict "beta0" (dict "1" "1" "2" "2" )) }}

data:

  theData: |

{{ toJson $fred | indent 4 }}

  toml: |

{{ include "bob" $fred | indent 4 }}

将产生:


data:

  theData: |

    {"alpha":{"a0":"a0ch0"},"beta":{"beta0":{"beta00":1234}},"charlie":["ch0","ch1","ch2"],"problem":{"beta0":{"1":"1","2":"2"}}}

  toml: |

    problem.beta0.1="1"

    2="2"

    alpha.a0="a0ch0"

    beta.beta0.beta00=1234

    charlie=["ch0","ch1","ch2"]

这是不正确的。还有另一个令人眼花缭乱的订单丢失问题,不知道为什么或如何解决它,但这并不是什么大问题。


我的额外要求是,我需要为所有行添加公共前缀。没有它,您可以定义另一个模板来简化使用,但这很简单。


免责声明:我是 helm/go-templating 的新手,所以以下可能不是最佳选择,但它应该可以解决这些问题。


再举个例子:


{{ $fred := dict

    "alpha" (dict "a0" "a0ch0")

    "beta" (dict "beta0" (dict "beta00" 1234))

    "charlie" (list "ch0" "ch1" "ch2")

    "problem" (dict "beta0" (dict "1" "1" "2" "2" )) }}

data:

  theData: |

{{ toJson $fred | indent 4 }}

  toml: |

{{ include "flattenYaml" (dict "prefix" "added_prefix" "data" $fred) | indent 4 }}

将产生:


data:

  theData: |

    {"alpha":{"a0":"a0ch0"},"beta":{"beta0":{"beta00":1234}},"charlie":["ch0","ch1","ch2"],"problem":{"beta0":{"1":"1","2":"2"}}}

  toml: |

    added_prefix.alpha.a0="a0ch0"

    added_prefix.beta.beta0.beta00=1234

    added_prefix.charlie=["ch0","ch1","ch2"]

    added_prefix.problem.beta0.1="1"

    added_prefix.problem.beta0.2="2"

flattenYaml 的模板源代码如下所示:


{{- define "flattenYaml" -}}

{{- $dict := . -}}

{{- $prefix := $dict.prefix -}}

{{- $data := $dict.data -}}

{{- $knd := kindOf $data -}}

    {{- if eq $knd "map" }}

        {{- range (keys $data) }}

            {{- $key := . }}

            {{- $prefixedKey := (printf "%s.%s" $prefix $key) }}

            {{- $value := get $data $key }}

            {{- $valueKind := kindOf $value }}

            {{- if eq $valueKind "map" }}

                {{-   include "flattenYaml" (dict "prefix" ($prefixedKey) "data" $value) }}

            {{- else }}

                {{-   printf "%s=%s\n" $prefixedKey (toJson $value) }}

            {{- end }}

        {{- end }}

    {{- else }}

        {{ toJson . }}#k({{ $knd }})

    {{- end }}

{{- end -}}

免责声明 2:我不知道原始解决方案#k ...的作用是什么,{{ toJson . }}#k({{ $knd }})如果它爆炸到您的脸上,请不要感到惊讶;)


编辑 :


    {{ toJson . }}#k({{ $knd }})

实际上吹到了我的脸上,仍然不知道#k 应该提供什么,但更换后解决了我的问题:


    {{- if ne $data nil }}

        {{- toJson $data }}

    {{- end }}


查看完整回答
反对 回复 2023-01-03
?
幕布斯7119047

TA贡献1794条经验 获得超8个赞

另一种方法


_helpers.tpl:


 {{- define "template.flattenFn" -}}

  {{- $ctx := . -}}

  {{- if or (eq (kindOf .data) "map") (eq (kindOf .data) "slice") }}

    {{- range $key, $value := .data }}

      {{- include "template.flattenFn" (dict "prefixes" (append $ctx.prefixes $key) "data" $value ) }}

    {{- end }}

  {{- else }}

    {{-   printf "\"%s\":%s, "  (join "__" .prefixes) (toJson .data) }}

  {{- end }}

{{- end -}}


{{- define "template.flatten" -}}

 {{- include "template.flattenFn" (dict "prefixes" list "data" . ) }} 

{{- end -}}

值.yaml


  environment_map:

    Log:

      Level:

        Default: Debug

      Target:

      - Name: Console

        Args:

          formatter: "JsonFormatter"

用法


{{- range $env, $value := include "template.flatten" .Values.environment_map | fromYaml }}

  - name: {{ $env }}

    value: {{ $value | quote }}

结果


    - name: Log__Level__Default

      value: "Debug"

    - name: Log__Target__0__Args__formatter

      value: "JsonFormatter"

    - name: Log__Target__0__Name

      value: "Console"


查看完整回答
反对 回复 2023-01-03
  • 3 回答
  • 0 关注
  • 200 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号