Ansible: как исправить выходные цитаты to_nice_yaml и разрывы строк?

#ansible #yaml #escaping #line-breaks #quoting

#ansible #yaml #экранирование #разрывы строк #цитирование

Вопрос:

У меня есть этот файл YAML (я свел свой вопрос к минимуму):

 scalar: simple_value
empty:
list:
  - 1
  - 2
  - 3
complex:
  - first:
      one: 1
      two: 2
  - second:
      one: 3
      two: 4
weird: "{{ '{{' }} something {{ '}}' }}"
weirder: "{{ '{{' }} 'TTT' if something == 'blah' else 'FFF' {{ '}}' }}"
weirdest: "amp;lcub2; ansible_date_time.year amp;rcub2;.amp;lcub2; ansible_date_time.month amp;rcub2;.amp;lcub2; ansible_date_time.day amp;rcub2;"
 

и этот сборник пьес:

 ---
- hosts: localhost
  tasks:
    - name: Load
      include_vars:
        file: ./vars.yml
        name: object
    - name: Write
      copy:
        content: "{{ object | to_nice_yaml(indent=2) }}"
        dest: ./outv.yml
 

Выходной файл выглядит следующим образом:

 complex:
- first:
    one: 1
    two: 2
- second:
    one: 3
    two: 4
empty: null
list:
- 1
- 2
- 3
scalar: simple_value
weird: '{{ something }}'
weirder: '{{ ''TTT'' if something == ''blah'' else ''FFF'' }}'
weirdest: 'amp;lcub2; ansible_date_time.year amp;rcub2;.amp;lcub2; ansible_date_time.month
  amp;rcub2;.amp;lcub2; ansible_date_time.day amp;rcub2;'
 

Хотя я думаю, что отступы как в выходных, так и во входных списках являются правильными и эквивалентными и что экранирование Jinja обрабатывается должным образом, я не уверен в weirder кавычках значений.
И я не понимаю разрыва строки для weirdest значения ‘s.

YAMLint говорит, что все в порядке, но на самом деле восстанавливает «нормальную» кавычку и повторно соединяет разрыв строки во время проверки синтаксиса.

Есть ли способ принудительно использовать двойные кавычки с помощью filter to_nice_yaml (или любого другого фильтра)?

Есть ли способ избежать этого разрыва строки (или, может быть, для этого есть причина)?

Ответ №1:

Что касается разрыва строки, который вы наблюдаете weirdest , это объясняется в документации:

Фильтры to_yaml и to_nice_yaml используют библиотеку PyYAML, которая по умолчанию имеет ограничение на длину строки в 80 символов. Это приводит к неожиданному разрыву строки после 80-го символа (если после 80-го символа есть пробел) Чтобы избежать такого поведения и генерировать длинные строки, используйте width опцию. Вы должны использовать жестко заданное число для определения ширины вместо конструкции like float("inf") , потому что фильтр не поддерживает проксирование функций Python.
Например:

 {{ some_variable | to_yaml(indent=8, width=1337) }} 
{{ some_variable | to_nice_yaml(indent=8, width=1337) }}
 

Источник: https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#formatting-data-yaml-and-json


Затем, сразу после этого объяснения в документации, они также указывают на тот факт, что:

Фильтр поддерживает передачу через другие параметры YAML. Полный список см. В документации PyYAML.

Итак, есть что-то о строке в двойных кавычках, которую нужно получить оттуда: default_style='"'

Более подробную информацию можно найти здесь.


Итак, сборник пьес:

 - hosts: all
  gather_facts: no
      
  tasks:
    - copy:
        content:  "{{ object | to_nice_yaml(indent=2, width=1337, default_style='"') }}"
        dest: ./outv.yml
      vars:
        object:
          scalar: simple_value
          empty:
          list:
            - 1
            - 2
            - 3
          complex:
            - first:
                one: 1
                two: 2
            - second:
                one: 3
                two: 4
          weird: "{{ '{{' }} something {{ '}}' }}"
          weirder: "{{ '{{' }} 'TTT' if something == 'blah' else 'FFF' {{ '}}' }}"
          weirdest: "amp;lcub2; ansible_date_time.year amp;rcub2;.amp;lcub2; ansible_date_time.month amp;rcub2;.amp;lcub2; ansible_date_time.day amp;rcub2;"
 

Выдает файл outv.yml, содержащий:

 "complex":
- "first":
    "one": !!int "1"
    "two": !!int "2"
- "second":
    "one": !!int "3"
    "two": !!int "4"
"empty": !!null "null"
"list":
- !!int "1"
- !!int "2"
- !!int "3"
"scalar": "simple_value"
"weird": "{{ something }}"
"weirder": "{{ 'TTT' if something == 'blah' else 'FFF' }}"
"weirdest": "amp;lcub2; ansible_date_time.year amp;rcub2;.amp;lcub2; ansible_date_time.month amp;rcub2;.amp;lcub2; ansible_date_time.day amp;rcub2;"
 

Обратите внимание, что синтаксис !!int и !!null называется явной типизацией в YAML и объясняется в связанной документации.