Разбор, вероятно, недопустимый YAML с PyYaml

Я хотел бы проанализировать конфигурацию yaml, связанную с марионеткой, с помощью pyyaml. К сожалению, кажется, что pyyaml ​​не может анализировать некоторые файлы YAML из-за этой части:

base::files:

  /var/log/fpm:
    ensure: 'directory'
    mode: '777'

  /etc/nginx/ssl/cert:
   ensure: 'directory'

  /apps:
   ensure: 'directory'
   owner: user
   group: user

  ['/apps/ecert-public', '/apps/ecert-public/config', '/apps/ecert-public/releases']:
    ensure: 'directory'
    owner: 'user'
    group: 'user'

  ['/apps/site-public', '/apps/site-public/config', '/apps/site-public/releases']:
    ensure: 'directory'
    owner: 'user'
    group: 'user'

Проблема заключается в сопоставлении с несколькими значениями (внутри квадратных скобок). Я получаю следующее сообщение об ошибке при попытке проанализировать эту часть с помощью pyyaml:

при построении сопоставления в "/hieradata/node/wc-de.yaml", строка 133, столбец 3, обнаружен нехэшируемый ключ в "/hieradata/node/wc-de.yaml", строка 212, столбец 3

Некоторые валидаторы YAML говорят, что это действительный YAML (например: http://www.yamllint.com/), но у большинства из них, которые я пробовал, также есть проблемы с анализом этой части. Кто-нибудь знает, как я могу решить эту проблему с помощью pyyaml? К сожалению, я не могу изменить сам YAML, поэтому мне нужно решение, чтобы разобрать его как есть.


person Thomas S.    schedule 08.02.2019    source источник
comment
Любое сопоставление может иметь несколько значений. У вас есть сопоставление с ключом, который является не скаляром, а последовательностью, которая является допустимым YAML, но одна из вещей, которые PyYAML не может обрабатывать.   -  person Anthon    schedule 08.02.2019
comment
YAML не накладывает никаких ограничений на сопоставление ключей, кроме того, что они уникальны. В частности, это не требует, чтобы они были скалярами. Тем не менее, я призываю вас вернуться к вопросу о том, можете ли вы изменить YAML. Судя по его структуре, я подозреваю, что его можно переписать таким образом, чтобы это означало то же самое для модуля Puppet, который его использует, но это не так сложно для парсеров YAML.   -  person John Bollinger    schedule 09.02.2019
comment
@Anthon, многие процессоры YAML не справляются с допустимым кодом OP. Почему они терпят неудачу, на самом деле не имеет значения. Вы можете выбрать прилагательное, которое вам нравится, чтобы описать эту ситуацию, но я выбираю сложный.   -  person John Bollinger    schedule 11.02.2019


Ответы (1)


Это совершенно правильный YAML. Проблема в PyYAML. Как и все другие процессоры YAML, которые не могут загрузить это, о которых я знаю, он может анализировать этот YAML без проблем (и составлять, если процессор реализует этот шаг), но не работает на этапе конструирования процесса загрузки.

Если вы воспользуетесь ruamel.yaml (отказ от ответственности: я являюсь автором этого пакета) и внесете свой вклад в файл input.yaml:

import sys
from pathlib import Path
import ruamel.yaml

file_name = Path('input.yaml')

yaml = ruamel.yaml.YAML()
data = yaml.load(file_name)
print(data['base::files'][('/apps/ecert-public', '/apps/ecert-public/config', '/apps/ecert-public/releases')]['ensure'])
print('\n-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-\n')
yaml.dump(data, sys.stdout)

дает:

directory

-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-

base::files:

  /var/log/fpm:
    ensure: directory
    mode: '777'

  /etc/nginx/ssl/cert:
    ensure: directory

  /apps:
    ensure: directory
    owner: user
    group: user


  [/apps/ecert-public, /apps/ecert-public/config, /apps/ecert-public/releases]:
    ensure: directory
    owner: user
    group: user

  [/apps/site-public, /apps/site-public/config, /apps/site-public/releases]:
    ensure: directory
    owner: user
    group: user
person Anthon    schedule 08.02.2019
comment
Я только что понял, что у вашего модуля похожая проблема: возникает исключение, если файл YAML содержит повторяющееся сопоставление - например, если он выглядит так: `base :: test value: key base :: test value key` Однако ... для меня это не проблема. Просто хотел, чтобы вы знали. - person Thomas S.; 11.02.2019
comment
Если вы имеете в виду повторяющиеся ключи в сопоставлении, это недопустимо в YAML 1.2. В YAML 1.1 синтаксическому анализатору разрешено выдавать предупреждение и сохранять первую пару ключ / значение. Вы можете разрешить поведение версии 1.1, установив _1 _ - person Anthon; 11.02.2019