Загрузка CloudFormation YAML с помощью Python


У меня есть набор YAML шаблонов формирования облака AWS, которые я недавно преобразовал из JSON.

При использовании JSON я смог загрузить эти шаблоны и преобразовать их с помощью jinja, чтобы создать из них некоторую документацию markdown. Я пытаюсь сделать то же самое с YAML в python.

Я использую синтаксис функции shorthand в шаблонах cloudformation, который использует Теги YAML. например
Properties:
  MinSize: !Ref ClusterSize
  MaxSize: !Ref ClusterSize

При попытке загрузить их с помощью пакета ruamel.yaml Конструктор терпит неудачу, потому что он не может обрабатывать Теги, потому что он не знает о них.

Есть ли способ обойти это, чтобы я мог загрузить документ YAML, чтобы я мог получить/запросить выходные данные и ресурсы?

1 2

1 ответ:

Вы ошибаетесь, что ruamel.yaml не может обрабатывать теги. Но, конечно, вы должны предоставить информацию о том, как обрабатывать любые неизвестные теги, он не может угадать, какие данные вы хотите загрузить с !Ref:

import ruamel.yaml

yaml_str = """\
Properties:
  MinSize: !Ref ClusterSize
  MaxSize: !Ref ClusterSize
"""


class Blob(object):
    def update(self, value):
        self.value = value

    def __str__(self):
        return str(self.value)


def my_constructor(self, node):
    data = Blob()
    yield data
    value = self.construct_scalar(node)
    data.update(value)

ruamel.yaml.SafeLoader.add_constructor(u'!Ref', my_constructor)

data = ruamel.yaml.safe_load(yaml_str)
print('data', data['Properties']['MinSize'])

Отпечатки пальцев:

ClusterSize

Если вы хотите избавиться от множества различных тегов и не заботитесь о том, чтобы "все было строкой", вы также можете сделать:

import ruamel.yaml

yaml_str = """\
Properties:
  MinSize: !Ref ClusterSize
  MaxSize: !Ref ClusterSize
  SizeList:
     - !abc 1
     - !xyz 3
"""


def general_constructor(loader, tag_suffix, node):
    return node.value


ruamel.yaml.SafeLoader.add_multi_constructor(u'!', general_constructor)


data = ruamel.yaml.safe_load(yaml_str)
print(data)

Что дает:

{'Properties': {'SizeList': ['1', '3'], 'MinSize': 'ClusterSize', 'MaxSize': 'ClusterSize'}}

(обратите внимание, что скаляры 1 и 3 загружаются в виде строки вместо нормального целое число)