遍历嵌套的 YAML Object 树

Iterate over a nested YAML Object Tree

我有一个 yaml object,它描述了一个组织的结构:

orgas:
  - key: orga1
    description: "Description of orga"
  - key: orga2
    description: "Description of orga"
  - key: orga3
    description: "Description of orga"
    children:
      - key: sub-orga1
        description: "Description of sub-orga"
  - key: orga4
    description: "Description of orga"
    children:
      - key: sub-orga2
        description: "Description of sub-orga"
      - key: sub-orga3
        description: "Description of sub-orga"
        children:
          - key: sub-sub-orga1
            description: "Description of sub-sub-orga"
      - key: sub-orga4
        description: "Description of sub-orga"
        children:
          - key: sub-sub-orga2
            description: "Description of sub-sub-orga"

基本上,您有一个性高潮列表,每个性高潮都可以具有属性 'key'、'description' 和 'children',而这些属性又可以包含更多性高潮。

我想扁平化和迭代整个数据结构,以在 IPA 中将这些组织创建为组。为了正确创建组元素,对于我需要知道的每个性高潮:

结果应如下所示:

  - key: orga1
    description: "Description of orga"
  - key: orga2
    description: "Description of orga"
  - key: orga3
    description: "Description of orga"
  - key: orga4
    description: "Description of orga"
  - key: sub-orga1
    description: "Description of sub-orga"
    parents: ["orga3"]
  - key: sub-orga2
    description: "Description of sub-orga"
    parents: ["orga4"]
  - key: sub-orga3
    description: "Description of sub-orga"
    parents: ["orga4"]
  - key: sub-orga4
    description: "Description of sub-orga"
    parents: ["orga4"]
  - key: sub-sub-orga1
    description: "Description of sub-orga"
    parents: ["sub-orga3", "orga4"]
  - key: sub-sub-orga2
    description: "Description of sub-orga"
    parents: ["sub-orga4", "orga4"]

这在 Ansible 中可行吗?

这可能更容易在 python 中直接使用自定义过滤器进行管理。这是我制作的示例,我认为它符合您的标准,但需要一些强化才能在更广泛的场景中使用。

项目结构为:

.
├── filter_plugins
│   └── orgas_utils.py
└── playbook.yml

filter_plugins/orgas_utils.py

中的自定义插件
#!/usr/bin/python
class FilterModule(object):

    def __init__(self):
        self.orga_nodes_list=[]

    def filters(self):
        return {
            'orgas_flattened': self.orgas_flattened
        }

    def _process_orga(self, orga, direct_parent=None):
        if direct_parent:
            current_parents = [x for x in self.orga_nodes_list if x['key'] == direct_parent][0]['parents'] + [direct_parent]
        else:
            current_parents = []

        current_node= {
            'key': orga['key'],
            'description': orga['description'],
            'parents': current_parents
        }

        self.orga_nodes_list.append(current_node)

        for child in (orga['children'] if 'children' in orga.keys() else []):
            self._process_orga(child, direct_parent=current_node['key'])

    def orgas_flattened(self, orgas):
        for orga in orgas:
            self._process_orga(orga)
        return self.orga_nodes_list

和测试playbook.yml

---
- hosts: localhost
  gather_facts: false

  vars:
    orgas:
      - key: orga1
        description: "Description of orga"
      - key: orga2
        description: "Description of orga"
      - key: orga3
        description: "Description of orga"
        children:
          - key: sub-orga1
            description: "Description of sub-orga"
      - key: orga4
        description: "Description of orga"
        children:
          - key: sub-orga2
            description: "Description of sub-orga"
          - key: sub-orga3
            description: "Description of sub-orga"
            children:
              - key: sub-sub-orga1
                description: "Description of sub-sub-orga"
          - key: sub-orga4
            description: "Description of sub-orga"
            children:
              - key: sub-sub-orga2
                description: "Description of sub-sub-orga"

  tasks:
    - name: Show list processed by custom filter
      debug:
        msg: "{{ orgas | orgas_flattened }}"

给出:

PLAY [localhost] **************************************************************************************************************************************************************************************************

TASK [Show list processed by custom filter] ***********************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": [
        {
            "description": "Description of orga",
            "key": "orga1",
            "parents": []
        },
        {
            "description": "Description of orga",
            "key": "orga2",
            "parents": []
        },
        {
            "description": "Description of orga",
            "key": "orga3",
            "parents": []
        },
        {
            "description": "Description of sub-orga",
            "key": "sub-orga1",
            "parents": [
                "orga3"
            ]
        },
        {
            "description": "Description of orga",
            "key": "orga4",
            "parents": []
        },
        {
            "description": "Description of sub-orga",
            "key": "sub-orga2",
            "parents": [
                "orga4"
            ]
        },
        {
            "description": "Description of sub-orga",
            "key": "sub-orga3",
            "parents": [
                "orga4"
            ]
        },
        {
            "description": "Description of sub-sub-orga",
            "key": "sub-sub-orga1",
            "parents": [
                "orga4",
                "sub-orga3"
            ]
        },
        {
            "description": "Description of sub-orga",
            "key": "sub-orga4",
            "parents": [
                "orga4"
            ]
        },
        {
            "description": "Description of sub-sub-orga",
            "key": "sub-sub-orga2",
            "parents": [
                "orga4",
                "sub-orga4"
            ]
        }
    ]
}

PLAY RECAP ********************************************************************************************************************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0