#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
опцию. Вы должны использовать жестко заданное число для определения ширины вместо конструкции likefloat("inf")
, потому что фильтр не поддерживает проксирование функций Python.
Например:{{ some_variable | to_yaml(indent=8, width=1337) }} {{ some_variable | to_nice_yaml(indent=8, width=1337) }}
Затем, сразу после этого объяснения в документации, они также указывают на тот факт, что:
Фильтр поддерживает передачу через другие параметры 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 и объясняется в связанной документации.