Как проанализировать Cloudformation YAML, чтобы получить все! ImportValue из шаблона YAML? - PullRequest
1 голос
/ 02 апреля 2019

Я работаю над проектом по анализу Yaml-файла AWS Cloudformation для извлечения всего! ImportValue из шаблона YAML.

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

import ruamel.yaml

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

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

with open(cfFile, 'r') as service:
  stream = service.read()

yaml_data = ruamel.yaml.safe_load(stream)
print yaml_data

Выше кода получает содержимое указанного файла YAML, и результат выглядит следующим образом.

{'Application': {'Properties': {'ApplicationName': [ScalarNode(tag=u'tag:yaml.org,2002:str', value=u'-'),
    SequenceNode(tag=u'tag:yaml.org,2002:seq', value=[ScalarNode(tag=u'tag:yaml.org,2002:str', value=u'***'), ScalarNode(tag=u'!ImportValue', value=u'jkl')])],
   *
   *
     ScalarNode(tag=u'!ImportValue', value=u'def'),
   *
   *
     ScalarNode(tag=u'!ImportValue', value=u'rst')])]},


Итак, в ScalarNode есть куча! ImportValue (например, ScalarNode (tag = u '! ImportValue', value = u'rst ')), я действительно хочу извлечь это. Теперь эти ImportValues ​​разбросаны по шаблону в разных местах. Что было бы лучшим способом извлечь ценность из тех? В нашей облачной информации у нас есть куча YAML-файлов, некоторые из них экспортируют определенный ресурс, а другие YAML-файлы импортируют их. Итак, я хочу построить своего рода карту зависимостей (может быть, JSON-файл), которая будет отображать взаимозависимость между файлами формирования облаков.

1 Ответ

1 голос
/ 02 апреля 2019

Если вы используете загрузчик туда и обратно ruamel.yaml, вам не нужно делать ничего особенного для загрузки тега, и рекурсивный просмотр полученной структуры данных относительно прост.Соответствующий ключ должен быть передан, так как по крайней мере первый !ImportValue находится внутри последовательности под ключом.

Предполагается, что input.yaml состоит из:

Application:
  Properties:
    ApplicationName: ["-", ["**", !ImportValue "jkl"]]

  AnotherKey:
  - 42
  - nested: !ImportValue xyz

(чтоможет быть не совсем тем, что вы получили в качестве входных данных, но для демонстрационных целей) и с использованием нового ruamel.yaml API (по умолчанию используется двусторонняя загрузка / выгрузка):

import sys
from pathlib import Path
import ruamel.yaml

ta = ruamel.yaml.comments.Tag.attrib

yaml = ruamel.yaml.YAML()
data = yaml.load(Path('input.yaml'))

def process(d, key=None):
    if isinstance(d, dict):
        for k, v in d.items():
            for res in process(v, k):  # recurse and pass on new key
                yield res
    elif isinstance(d, list):
        for item in d:
            for res in process(item, key):
                yield res
    else:
       try:
           if getattr(d, ta, None).value == '!ImportValue':
               yield (key, d)
       except AttributeError:
           pass

for k, v in process(data):
   print(k, '->', v)

, который дает:

ApplicationName -> jkl
nested -> xyz
...