многострочный ввод yaml для вывода шаблонов усов в формате JSON - PullRequest
0 голосов
/ 18 декабря 2018

У меня есть следующий фрагмент оболочки

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 будет вставлен в эти строки без изменений.Он даже удаляет комментарии (которые меня не особо интересуют), однако, это не то поведение, которого я ожидал.Почему усы относятся к многострочному вводу иначе, чем к однострочному?

Я пытался найти похожий вопрос, но не смог найти ответ.

РЕДАКТИРОВАТЬ: Добавлена ​​однострочная переменная для сравнения входных данных.

Ответы [ 2 ]

0 голосов
/ 20 декабря 2018

Вот урезанная версия скрипта, которая демонстрирует проблему.

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

На мой взгляд, это говорит об ошибке в Rubygem, так как он не обрабатывает YAML правильно, когда он является частью вывода.

0 голосов
/ 18 декабря 2018

Здесь есть несколько проблем:

  • Усы не имеют ни малейшего представления, что ingress.mustache - это файл YAML.Он не будет анализировать его как YAML и фактически предполагает, что это HTML (поскольку он будет избегать специальных символов HTML с сущностями HTML).

    Проблема, возникающая из-за этого, заключается в том, что усы не знают о текущем отступе и т. Д., Когдавам будет предложено вставить ваше значение, поэтому он не сможет вставить ваш YAML, сохранив относительную структуру без изменений, добавив к исходному отступу в вашем $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
...