问:Ansible - 如何将2个哈希列表与公共键/值对合并

时间:2018-05-07 17:21:49

标签: ansible

如何使用Ansible 2.4.4

合并基于键/值对的2个哈希列表
"foo": [
    {
        "hostname": "web1.example.com",
        "guid": "73e85eb2-2ad5-4699-8a09-adf658a11ff2"
    },
    {
        "hostname": "web2.example.com",
        "guid": "827025fe-f13c-4fc8-ba51-7ff582596bbd"
    },
    {
        "hostname": "web3.example.com",
        "guid": "bba27304-c1bb-4889-aa44-125626be8488"
    }
]

"bar": [
    {
        "ipaddress": "1.1.1.1",
        "guid": "73e85eb2-2ad5-4699-8a09-adf658a11ff2"
    },
    {
        "ipaddress": "2.2.2.2",
        "guid": "827025fe-f13c-4fc8-ba51-7ff582596bbd"
    },
    {
        "ipaddress": "3.3.3.3",
        "guid": "bba27304-c1bb-4889-aa44-125626be8488"
    }
]

我想要类似的东西:

"foobar" : [
    {
        "hostname": "web1.example.com",
        "guid": "73e85eb2-2ad5-4699-8a09-adf658a11ff2",
        "ipaddress": "1.1.1.1"
    },
    {
        "hostname": "web2.example.com",
        "guid": "827025fe-f13c-4fc8-ba51-7ff582596bbd",
        "ipaddress": "2.2.2.2"
    },
    {
        "hostname": "web3.example.com",
        "guid": "bba27304-c1bb-4889-aa44-125626be8488",
        "ipaddress": "3.3.3.3"
    }
]

我已经查看了几个Ansible / Jinja2过滤器,包括联合,联合,地图,自定义插件,但没有取得多大成功。我需要能够匹配guid。

1 个答案:

答案 0 :(得分:2)

不确定是否有更聪明的方法,但要实现您所需要的,您可以使用nested query plugin循环来自2个列表变量的元素组合,找到公共字段相等的组合,然后构造一个新的字典元素并将其附加到" final"列表变量。

剧本:

- hosts: localhost
  gather_facts: false
  vars:
    foo:
      - hostname: web1.example.com
        guid: 73e85eb2-2ad5-4699-8a09-adf658a11ff2
      - hostname: web2.example.com
        guid: 827025fe-f13c-4fc8-ba51-7ff582596bbd
      - hostname: web3.example.com
        guid: bba27304-c1bb-4889-aa44-125626be8488
    bar:
      - ipaddress: 1.1.1.1
        guid: 73e85eb2-2ad5-4699-8a09-adf658a11ff2
      - ipaddress: 2.2.2.2
        guid: 827025fe-f13c-4fc8-ba51-7ff582596bbd
      - ipaddress: 3.3.3.3
        guid: bba27304-c1bb-4889-aa44-125626be8488

  tasks:

    - name: merge lists
      set_fact:
        merged_list: "{{ merged_list|default([]) + [{ 'hostname': item[0].hostname, 'guid': item[0].guid, 'ipaddress': item[1].ipaddress }] }}"
      when: "item[0].guid == item[1].guid"
      loop: "{{ query('nested', foo, bar) }}"

    - name: print results
      debug:
        var: merged_list

结果:

TASK [print results] ************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "merged_list": [
        {
            "guid": "73e85eb2-2ad5-4699-8a09-adf658a11ff2", 
            "hostname": "web1.example.com", 
            "ipaddress": "1.1.1.1"
        }, 
        {
            "guid": "827025fe-f13c-4fc8-ba51-7ff582596bbd", 
            "hostname": "web2.example.com", 
            "ipaddress": "2.2.2.2"
        }, 
        {
            "guid": "bba27304-c1bb-4889-aa44-125626be8488", 
            "hostname": "web3.example.com", 
            "ipaddress": "3.3.3.3"
        }
    ]
}