Ansible объединить перечисленные словари - PullRequest
1 голос
/ 05 февраля 2020

В настоящее время я создаю Ansible playbook, который предоставляет мне две переменные ниже. Мне нужно объединить их в одну переменную, где ipAddresses совпадают, как показано в примере ниже.

---
- hosts: localhost
  gather_facts: no
  vars:
    sites:
        - siteGroupId: 123
          siteName: name123
          siteDevices:
            - ipAddress: 1.1.1.1
            - ipAddress: 2.2.2.2
        - siteGroupId: 456
          siteName: name456
          siteDevices:
            - ipAddress: 3.3.3.3
            - ipAddress: 4.4.4.4

    devices:
        - ipAddress: 1.1.1.1
          deviceName: name123-a.tld
        - ipAddress: 2.2.2.2
          deviceName: name123-b.tld
        - ipAddress: 3.3.3.3
          deviceName: name456-a.tld
        - ipAddress: 4.4.4.4
          deviceName: name456-b.tld

Ожидаемый результат:

sites:
    - siteGroupId: 123
        siteName: name123
        siteDevices:
            - ipAddress: 1.1.1.1
              deviceName: name123-a.tld
            - ipAddress: 2.2.2.2
              deviceName: name123-b.tld
    - siteGroupId: 456
        siteName: name456
        siteDevices:
            - ipAddress: 3.3.3.3
              deviceName: name456-a.tld
            - ipAddress: 4.4.4.4
              deviceName: name456-b.tld

То, что мне удалось до сих пор с приведенным ниже кодом является то, что я добавляю имя к сайту, но получаю 4 сайта (дублированный идентификатор siteGroupID в качестве вывода).

---
- hosts: localhost
  gather_facts: no
  vars:
    sites:
    - siteGroupId: 123
      siteName: name123
      siteDevices:
        - ipAddress: 1.1.1.1
        - ipAddress: 2.2.2.2
    - siteGroupId: 456
      siteName: name456
      siteDevices:
        - ipAddress: 3.3.3.3
        - ipAddress: 4.4.4.4

    devices:
      - ipAddress: 1.1.1.1
        deviceName: name123-a.tld
      - ipAddress: 2.2.2.2
        deviceName: name123-b.tld
      - ipAddress: 3.3.3.3
        deviceName: name456-a.tld
      - ipAddress: 4.4.4.4
        deviceName: name456-b.tld

  tasks:
    - set_fact:
        tmpVar1: "{{ item.0 | combine({'siteDevices': [ item.1 | combine(devices | selectattr('ipAddress','equalto',item.1.ipAddress) | first) ] }) }}"
      loop: "{{lookup('subelements', sites, 'siteDevices', {'skip_missing': True})}}"
      register: tmpVar2

    - name: tmpVar1
      debug:
        msg: "{{ tmpVar1 }}"

    - name: tmpVar2
      debug:
        msg: "{{ tmpVar2 }}"

    - set_fact:
        sites: "{{ tmpVar2.results | map(attribute='ansible_facts.tmpVar1') | list }}"

    - name: SITES
      debug:
        msg: "{{ sites }}"

ВЫХОД:

        {
            "siteDevices": [
                {
                    "deviceName": "name123-a.tld", 
                    "ipAddress": "1.1.1.1"
                }
            ], 
            "siteGroupId": 123, 
            "siteName": "name123"
        }, 
        {
            "siteDevices": [
                {
                    "deviceName": "name123-b.tld", 
                    "ipAddress": "2.2.2.2"
                }
            ], 
            "siteGroupId": 123, 
            "siteName": "name123"
        },
        {
            "siteDevices": [
                {
                    "deviceName": "name456-a.tld", 
                    "ipAddress": "3.3.3.3"
                }
            ], 
            "siteGroupId": 456, 
            "siteName": "name456"
        }, 
        {
            "siteDevices": [
                {
                    "deviceName": "name456-b.tld", 
                    "ipAddress": "4.4.4.4"
                }
            ], 
            "siteGroupId": 456, 
            "siteName": "name456"
        }

1 Ответ

0 голосов
/ 05 февраля 2020

Задачи

    - set_fact:
        devices_dict: "{{ devices|
                          items2dict(key_name='ipAddress',
                                     value_name='deviceName') }}"
    - set_fact:
        sites2: "{{ sites2|default([]) + [
                    item|
                    combine({'siteDevices':
                             dict(my_ipAddress|
                                  zip(my_ipAddress|
                                      map('extract', devices_dict)))|
                             dict2items(key_name='ipAddress',
                                        value_name='deviceName')})] }}"
      vars:
        my_ipAddress: "{{ item.siteDevices|json_query('[].ipAddress') }}"
      loop: "{{ sites }}"
    - debug:
        var: sites2

дают

    "sites2": [
        {
            "siteDevices": [
                {
                    "deviceName": "name123-a.tld", 
                    "ipAddress": "1.1.1.1"
                }, 
                {
                    "deviceName": "name123-b.tld", 
                    "ipAddress": "2.2.2.2"
                }
            ], 
            "siteGroupId": 123, 
            "siteName": "name123"
        }, 
        {
            "siteDevices": [
                {
                    "deviceName": "name456-a.tld", 
                    "ipAddress": "3.3.3.3"
                }, 
                {
                    "deviceName": "name456-b.tld", 
                    "ipAddress": "4.4.4.4"
                }
            ], 
            "siteGroupId": 456, 
            "siteName": "name456"
        }
    ]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...