[Из песочницы] Некоторые приемы YAML
В этом посте я расскажу про не очень известные особенности языка YAML.
Пролог
Системное администрирование за последние несколько лет несколько изменилось. Вместо маленьких скриптиков на bash у нас теперь огромные проекты системы конфигурации. Puppet с миллионом модулей готов «отконфигурять» для нас любую машинку, все поставить и все настроить. И конечно же, венчает это торжество автоматизации Hiera — система управления системой управления.
В начале идея выделения всех конфигурационных данных в иерархическую структуру и редактирования красивых и удобных YAML файлов кажется невероятно соблазнительной, особенно если вспомнить множество форматов конфиг-файлов, создатели которых, кажется, участвовали в соревнованиях по оригинальности мышления. Однако очень уже скоро мы оказываемся с тысячами строк YAML. Давайте посмотрим как можно использовать YAML чтобы наши конфигурации было легче читать и поддерживать.
Примеры
Многострочный текст
Очень часто нужно запихнуть в hiera многострочный текст. Для этого есть 3 способа.
multiliners:
ugly_multiline: "ugly\nugly\nugly\nugly\n"
multiline_with_line_ending: |
multiline text
with ending
multiline_without_line_ending: |-
multiline text
without ending
Пожалуйста, теперь, когда вы узнали, как делать многострочный текст, не используйте первый способ.Однострочный текст
Иногда нужно запихать в одну строку много под-строк. В YAML и это можно делать как минимум тремя способами.
singleliners:
simple:
single
line
text
single-line-text: >-
single
line
text
single-line-text-with-line-ending: >
single
line
text
Интересно, что все 3 способа могут использоваться где угодно, например, в списках:
commands:
- do something with --a long --list of --parameters
- do something
with
--a long
--list of
--parameters
JSON-style
YAML с версии 1.2 — это подмножество JSON. То есть, все, что правильно для JSON, годится и для YAML. Иногда это можно использовать для улучшения читаемости.
json:
vm-profiles-yaml:
small:
cpu: 2
ram: 2
disk: 10
os: rhel6
large:
cpu: 4
ram: 4
disk: 10
os: rhel6
vm-profiles-json:
small: { cpu: 2, ram: 2, disk: 10, os: rhel6 }
large: { cpu: 4, ram: 4, disk: 10, os: rhel6 }
Очевидным недостатком последней конструкции является то, что при изменении одного параметра меняется вся строчка, да и выравнивание может тоже напортить историю в GIT. Однако читаемость того стоит.Матрицы
Еще одним случаем использования JSON-style можно считать определение матриц.
matrices:
matrix_json_style: [
[1, 0, 0],
[0, 1, 0],
[0, 0, 1],
]
matrix_yaml_style:
- [1, 0, 0]
- [0, 1, 0]
- [0, 0, 1]
Наследование
Не ожидали? Я тоже удивился. Оказывается в YAML есть еще и наследование.
inheritance:
_basic: &basic
cpu: 2
ram: 2
disk: 10
os: rhel6
vm-profiles:
small:
<<: *basic
cpu: 1
large:
<<: *basic
cpu: 4
Или, если переписать еще короче, используя JSON, можно получить красивую табличку:
inheritance:
_basic: &basic
cpu: 2
ram: 2
disk: 10
os: rhel6
vm-profiles:
small: {<<: *basic, cpu: 1}
large: {<<: *basic, cpu: 4}
Ссылки
В предыдущем примере мы рассмотрели наследование, и вы наверное заметили элементы & и *. Эти элементы позволяют определить ссылку на элемент и затем его использовать.
references:
value1: &reference "Don't repeat yourself!"
value2: *reference
Проверка
Ну, и напоследок, однострочник для проверки YAML файлов:
# requires PyYAML
alias yaml2json='python -c "import sys,yaml,json;sys.tracebacklimit=0;print(json.dumps(yaml.load(open(sys.argv[1]).read()), indent=2))"'
Почитать
Спецификация формата YAML 1.2
И да пребудет с вами KISS и DRY.