Home > Net >  Retrieve nested value on a list in Ansible
Retrieve nested value on a list in Ansible

Time:12-15

I am producing from VMware datastores collection a list of volumes and their associated tags

I formated them in a JSON type output to be able to feed another system later. The output is working but for the tags section I would like to keep only the name and category_name not the other properties.

This is my playbook :

  ---
- name: Fetching Datastores
  hosts: localhost
  tasks: 
  - name: Gather info from datacenter about specific datastore
    community.vmware.vmware_datastore_info:
     hostname: 'myesxiHost'
     username: 'administrator'
     password: 'Password'
     validate_certs: False
     show_tag: true
    delegate_to: localhost
    register: ds_info

  - set_fact:
      ds_info_eph: "{{ ds_info_eph|default([])   [ {
          'name': item.name,
          'type': item.type,
          'capacity': item.capacity,
          'tag': item.tags
          } ] }}"
    loop: "{{ ds_info.datastores }}"

  - name: Output info
    debug:
      msg: "{{ ds_info_eph }}"

This playbook give me the following output :

ok: [localhost] => {
    "msg": [
        
        {
            "capacity": 499826819072,
            "name": "ESX01_SSD4",
            "tag": [
                {
                    "category_id": "urn:vmomi:InventoryServiceCategory:017ad796-b931-4f5b-bd4a-8fee7adaf124:GLOBAL",
                    "category_name": "Tier",
                    "description": "",
                    "id": "urn:vmomi:InventoryServiceTag:6112eeac-ed81-48d4-b7d9-81084b8a415a:GLOBAL",
                    "name": "Gold"
                }
            ],
            "type": "VMFS"
        },
        {
            "capacity": 499826819072,
            "name": "ESX01_SSD3",
            "tag": [
                {
                    "category_id": "urn:vmomi:InventoryServiceCategory:017ad796-b931-4f5b-bd4a-8fee7adaf124:GLOBAL",
                    "category_name": "Tier",
                    "description": "",
                    "id": "urn:vmomi:InventoryServiceTag:6112eeac-ed81-48d4-b7d9-81084b8a415a:GLOBAL",
                    "name": "Gold"
                }
            ],
            "type": "VMFS"
        },
        {
            "capacity": 499826819072,
            "name": "ESX01_SSD5",
            "tag": [
                {
                    "category_id": "urn:vmomi:InventoryServiceCategory:017ad796-b931-4f5b-bd4a-8fee7adaf124:GLOBAL",
                    "category_name": "Tier",
                    "description": "",
                    "id": "urn:vmomi:InventoryServiceTag:6112eeac-ed81-48d4-b7d9-81084b8a415a:GLOBAL",
                    "name": "Gold"
                }
            ],
            "type": "VMFS"
        },
        {
            "capacity": 239981297664,
            "name": "ESX01_SSD2",
            "tag": [
                {
                    "category_id": "urn:vmomi:InventoryServiceCategory:017ad796-b931-4f5b-bd4a-8fee7adaf124:GLOBAL",
                    "category_name": "Tier",
                    "description": "",
                    "id": "urn:vmomi:InventoryServiceTag:6112eeac-ed81-48d4-b7d9-81084b8a415a:GLOBAL",
                    "name": "Gold"
                }
            ],
            "type": "VMFS"
        },
        {
            "capacity": 248034361344,
            "name": "ESX01_SSD1",
            "tag": [
                {
                    "category_id": "urn:vmomi:InventoryServiceCategory:017ad796-b931-4f5b-bd4a-8fee7adaf124:GLOBAL",
                    "category_name": "Tier",
                    "description": "",
                    "id": "urn:vmomi:InventoryServiceTag:6112eeac-ed81-48d4-b7d9-81084b8a415a:GLOBAL",
                    "name": "Gold"
                }
            ],
            "type": "VMFS"
        }
    ]
}

Instead I would like to have this output :

ok: [localhost] => {
    "msg": [

        {
            "capacity": 499826819072,
            "name": "ESX01_SSD4",
            "tag": [
                {
                    "category_name": "Tier",
                    "name": "Gold"
                }
            ],
            "type": "VMFS"
        },
        {
            "capacity": 499826819072,
            "name": "ESX01_SSD3",
            "tag": [
                {
                    "category_name": "Tier",
                    "name": "Gold"
                }
            ],
            "type": "VMFS"
        },
        {
            "capacity": 499826819072,
            "name": "ESX01_SSD5",
            "tag": [
                {
                    "category_name": "Tier",
                    "name": "Gold"
                }
            ],
            "type": "VMFS"
        },
        {
            "capacity": 239981297664,
            "name": "ESX01_SSD2",
            "tag": [
                {
                    "category_name": "Tier",
                    "name": "Gold"
                }
            ],
            "type": "VMFS"
        },
        {
            "capacity": 248034361344,
            "name": "ESX01_SSD1",
            "tag": [
                {
                    "category_name": "Tier",
                    "name": "Gold"
                }
            ],
            "type": "VMFS"
        }
    ]
}

But on the tag section I tried to do in the playbook the following to get only the name and not all the tag item list : 'tag': item.tags.name but I'v got the following error fatal: [localhost]: FAILED! => {"msg": "Unexpected templating type error occurred on ({{ ds_info_eph|default([]) [ { 'name': item.name, 'type': item.type, 'capacity': item.capacity, 'tag': item.tags.name } ] }}): can only concatenate str (not \"list\") to str"}

My understanding is somehow in that set_fac I have to loop again to get only the tag name and tag category_name but I didn't figure out how to.

Thank you for your help !

CodePudding user response:

Select the attributes from the tag lists, e.g.

    - set_fact:
        _tags: "{{ ds_info_eph|
                   map(attribute='tag')|
                   map('items2dict', 'category_name', 'name')}}"

gives

  _tags:
  - Tier: Gold
  - Tier: Gold
  - Tier: Gold
  - Tier: Gold
  - Tier: Gold

Combine the dictionaries

    - set_fact:
        result: "{{ result|d([])   [item.0|combine({'tag': item.1})] }}"
      with_together:
        - "{{ ds_info_eph }}"
        - "{{ _tags|map('dict2items', 'category_name', 'name') }}"

gives

  result:
  - capacity: 499826819072
    name: ESX01_SSD4
    tag:
      category_name: Tier
      name: Gold
    type: VMFS
  - capacity: 499826819072
    name: ESX01_SSD3
    tag:
      category_name: Tier
      name: Gold
    type: VMFS
  - capacity: 499826819072
    name: ESX01_SSD5
    tag:
      category_name: Tier
      name: Gold
    type: VMFS
  - capacity: 239981297664
    name: ESX01_SSD2
    tag:
      category_name: Tier
      name: Gold
    type: VMFS
  - capacity: 248034361344
    name: ESX01_SSD1
    tag:
      category_name: Tier
      name: Gold
    type: VMFS
  • Related