Ansible - 扁平化键/值多维字典

问题描述 投票:0回答:1

我有一个多维字典来配置在哪里抓取多个发行版的图像。

- name: Test Playbook
  hosts: localhost
  gather_facts: false

  vars:

    distributions_images:
      Debian:
        12:
          name: bookworm
          images:
            cloud: <url>
            lxc: <url>
            classic: <url>
        11:
          name: bullseye
          images:
            cloud: <url>
            lxc: <url>
            classic: <url>
      Ubuntu:
        24:
          name: noble
          images:
            cloud: <url>
            lxc: <url>
            classic: <url>
            desktop: <url>
        22:
          name: jammy
          images:
            cloud: <url>
            lxc: <url>
            classic: <url>
            desktop: <url>
  tasks:

    - name: Get all images
      ansible.builtin.debug:
        var: distributions_images | <flatten_dict dim1='distribution', dim2='version'>

我想展平所有键和值以获得这种结果:

- distribution: Debian
  version: 12
  name: bookworm
  cloud: <url>
  lxc: <url>
  classic: <url>
...
- distribution: Ubuntu
  version: 22
  name: jammy
  cloud: <url>
  lxc: <url>
  classic: <url>
  desktop: <url>

我想要一个用于此目的的通用插件。是否有一个通用插件,或者为此目的编写一个自己的插件?

谢谢

ansible
1个回答
0
投票

最简单的方法可能是以所需的结构重新创建数据,然后解释它,以便您可以在 Ansible 中使用它。

为此,您可以使用 Jinja2 创建有效的 YAML 数据,然后使用

from_yaml
过滤器对其进行解释。

这是一个创建 YAML 数据并将解释后的数据存储为事实的示例任务

distributions_images_new
:

- name: Transform data into new datastructure
  set_fact:
    distributions_images_new: "{{ new_data | from_yaml }}"
  vars:
    new_data: >
      [
      {% for dist, dist_dict in distributions_images.items() %}
      {% for ver, ver_dict in dist_dict.items() %}
      {
      distribution: '{{ dist }}',
      version: '{{ ver }}',
      name: '{{ ver_dict.name }}',
      {% for k, v in ver_dict.images.items() %}
      {{ k }}: '{{ v }}',
      {% endfor %}
      },
      {% endfor %}
      {% endfor %}
      ]

结果如下:

TASK [debug] ***************************
ok: [localhost] => {
    "distributions_images_new": [
        {
            "classic": "<url>",
            "cloud": "<url>",
            "distribution": "Debian",
            "lxc": "<url>",
            "name": "bookworm",
            "version": "12"
        },
        {
            "classic": "<url>",
            "cloud": "<url>",
            "distribution": "Debian",
            "lxc": "<url>",
            "name": "bullseye",
            "version": "11"
        },
        {
            "classic": "<url>",
            "cloud": "<url>",
            "desktop": "<url>",
            "distribution": "Ubuntu",
            "lxc": "<url>",
            "name": "noble",
            "version": "24"
        },
        {
            "classic": "<url>",
            "cloud": "<url>",
            "desktop": "<url>",
            "distribution": "Ubuntu",
            "lxc": "<url>",
            "name": "jammy",
            "version": "22"
        }
    ]
}

扩展的可能性

在此代码中,您还可以轻松添加

default(...)
,以防条目不存在。

子键示例

images

{% for k, v in (ver_dict.images | default({})).items() %}

如果

images
不存在,可以定义一个空字典(
{}
)作为默认值,这样就不会出现错误。

© www.soinside.com 2019 - 2024. All rights reserved.