多行YAML输入到Mustache模板输出作为JSON



我有以下shell sippet

inputs="ingress_test_inputs.yaml"
auth_annotations="    # type of authentication
    nginx.ingress.kubernetes.io/auth-type: basic
    # name of the secret that contains the user/password definitions
    nginx.ingress.kubernetes.io/auth-secret: basic-auth
    # message to display with an appropriate context why the authentication is required
    nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - foo'"
echo "---" >$inputs
echo "namespace: qa" >> $inputs
echo "auth_annotations: ${auth_annotations}" >> $inputs
echo "----- Ingress inputs (${inputs}) -----"
cat $inputs
echo 'apiversion: extenstions/v1beta
kind: Ingress
metadata:
  name: aname
  annotations:
    kubernetes.io/ingress.class: "nginx-internal"
    nginx.ingress.kubernetes.io/server-snippet: |
      add_header Content-Security-Policy      "frame-ancestors 'self'";
      {{{auth_annotations}}}
spec:
  rules:
    - host: bla-bla-bla.{{namespace}}.example.com' >ingress.mustache
echo "----- Raw Ingress (ingress.mustache): -----"
cat ingress.mustache
mustache $inputs ingress.mustache > ingress-1.0.yaml
echo "----- Will apply the following ingress: -----"
cat ingress-1.0.yaml

但是,当我运行此操作时,auth_annotations的输出似乎将转换为json格式(=>在末尾的元素和逗号之间)(请参阅spec:)...

之前的列表。
----- Ingress inputs (ingress_test_inputs.yaml) -----
---
namespace: qa
auth_annotations:     # type of authentication
    nginx.ingress.kubernetes.io/auth-type: basic
    # name of the secret that contains the user/password definitions
    nginx.ingress.kubernetes.io/auth-secret: basic-auth
    # message to display with an appropriate context why the authentication is required
    nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - foo'
----- Raw Ingress (ingress.mustache): -----
apiversion: extenstions/v1beta
kind: Ingress
metadata:
  name: aname
  annotations:
    kubernetes.io/ingress.class: "nginx-internal"
    nginx.ingress.kubernetes.io/server-snippet: |
      add_header Content-Security-Policy      "frame-ancestors self";
      {{{auth_annotations}}}
----- Will apply the following ingress: -----
apiversion: extenstions/v1beta
kind: Ingress
metadata:
  name: aname
  annotations:
    kubernetes.io/ingress.class: "nginx-internal"
    nginx.ingress.kubernetes.io/server-snippet: |
      add_header Content-Security-Policy      "frame-ancestors self";
      {"nginx.ingress.kubernetes.io/auth-type"=>"basic", "nginx.ingress.kubernetes.io/auth-secret"=>"basic-auth", "nginx.ingress.kubernetes.io/auth-realm"=>"Authentication Required - foo"}

我本来希望我的原始yaml完好无损地粘贴到这些线条中。它甚至剥夺了评论(我并不真正在乎),但是,这不是我期望的行为。为什么小胡子对单线输入以不同的方式处理多线输入?

我尝试搜索类似的问题,但无法提出答案。

编辑:添加了一个单行变量,用于比较输入。

这里有几个问题:

  • 小胡子不知道ingress.mustache是yaml文件。它不会像YAML一样解析,实际上假设是HTML(因为它将逃脱HTML特殊字符,与HTML实体相关)。

    由此引起的问题是,在提示您的价值插入您的价值时,小胡子不知道当前的凹痕等$inputs

  • 小胡子使用yaml进行输入,但不能用于输出。您看到的是小胡子的auth_annotations值表示。胡子将yaml解析为内部结构,不知道您希望将其呈现为yaml。

  • 问题不是单线与多行,而是简单的内容(标量)与复杂的内容(映射)。

要能够正确地缩小变量,您必须用胡须走过结构,然后通过部分插入它们。但是,胡子无法仅超过序列的映射值。因此

auth_annotations="    # type of authentication
    - {key: nginx.ingress.kubernetes.io/auth-type, value: basic}
      # name of the secret that contains the user/password definitions
    - {key: nginx.ingress.kubernetes.io/auth-secret, value: basic-auth}
      # message to display with an appropriate context why the authentication is required
    - {key: nginx.ingress.kubernetes.io/auth-realm, value: 'Authentication Required - foo'}"

然后,您可以使用小胡子部分通过修改模板来插入它以迭代列表:

echo 'apiversion: extenstions/v1beta
kind: Ingress
metadata:
  name: aname
  annotations:
    kubernetes.io/ingress.class: "nginx-internal"
    nginx.ingress.kubernetes.io/server-snippet: |
      add_header Content-Security-Policy      "frame-ancestors 'self'";
    {{#auth_annotations}}
    {{key}}: {{value}}
    {{/auth_annotations}}
spec:
  rules:
    - host: bla-bla-bla.{{namespace}}.example.com' >ingress.mustache

这是脚本的删除版本,它证明了问题。

inputs="ingress_test_inputs.yaml"
auth_annotations="
    foo: bar baz
    sam: jam man"
echo "namespace: qa" > $inputs
echo "auth_annotations: ${auth_annotations}" >> $inputs
echo "----- Ingress inputs (${inputs}) -----"
cat $inputs
echo '---
metadata:
  annotations:
    nginx/thing:
      another_thing:
      {{{auth_annotations}}}
spec:
  rules:
    - host: bla-bla-bla.{{{ namespace }}}.example.com' >ingress.mustache
echo "----- Raw Ingress (ingress.mustache): -----"
cat ingress.mustache
mustache $inputs ingress.mustache > ingress-1.0.yaml
echo "----- Will apply the following ingress: -----"
cat ingress-1.0.yaml

这给出了与我发布的原始问题相同的问题。

----- Ingress inputs (ingress_test_inputs.yaml) -----
namespace: qa
auth_annotations:
    foo: bar baz
    sam: jam man
----- Raw Ingress (ingress.mustache): -----
---
metadata:
  annotations:
    nginx/thing:
      another_thing:
      {{{auth_annotations}}}
spec:
  rules:
    - host: bla-bla-bla.{{{ namespace }}}.example.com
----- Will apply the following ingress: -----
---
metadata:
  annotations:
    nginx/thing:
      another_thing:
      {"foo"=>"bar baz", "sam"=>"jam man"}
spec:
  rules:
    - host: bla-bla-bla.qa.example.com

但是,如果我用" mo"替换"小胡子",这是bash实现,它有效: -

----- Ingress inputs (ingress_test_inputs.yaml) -----
namespace: qa
auth_annotations:
    foo: bar baz
    sam: jam man
----- Raw Ingress (ingress.mustache): -----
---
metadata:
  annotations:
    nginx/thing:
      another_thing:
      {{{auth_annotations}}}
spec:
  rules:
    - host: bla-bla-bla.{{{ namespace }}}.example.com
----- Will apply the following ingress: -----
namespace: qa
auth_annotations:
    foo: bar baz
    sam: jam man
---
metadata:
  annotations:
    nginx/thing:
      another_thing:
spec:
  rules:
    - host: bla-bla-bla..example.com

在我看来,这暗示了Ruby Gem中的一个错误,因为它是输出的一部分时无法正确处理YAML。

最新更新