Score:0

ansible/jinja extract multiple attributes from complex json return, rejecting specific matches

vn flag

I'm trying to extract multiple attributes from a complex payload returned from an API call while rejecting members that have a certain value in the 'name' field. Consider the following payload:

{
"npod_volumes": {
    "changed": false,
    "failed": false,
    "volumes": [
        {
            "accessible_by_host_uuids": [
                "9e8ba77c-8e09-4c69-b893-876742f83f34",
                "ad5a5431-17e1-4023-8373-a6cf64cc5151",
                "3333a278-414b-45d1-8972-611115c76f87",
                "1e36d01a-f936-4249-9045-28232bb103e7"
            ],
            "boot": false,
            "creation_time": "2022-01-26T18:25:46",
            "current_owner_host_uuid": "ad5a5431-17e1-4023-8373-a6cf64cc5151",
            "expiration_time": null,
            "lun_uuids": [
                "8cfe80b6-5773-41bd-b175-e6e495ca0023",
                "8e54f045-89dd-462a-bab4-552ed745ed24",
                "136d7028-2b20-41c7-8b30-e104d211242c",
                "4e7aac12-3b29-41c7-b016-36556feea9f1"
            ],
            "name": "VMware_Lenovo_VV7",
            "natural_backup_host_uuid": "9e8ba77c-8e09-4c69-b893-876742f83f34",
            "natural_backup_spu_serial": "xxxxxxxx",
            "natural_owner_host_uuid": "ad5a5431-17e1-4023-8373-a6cf64cc5151",
            "natural_owner_spu_serial": "xxxxxxxx",
            "npod_uuid": "4b60437a-f8dc-4c80-b4b2-51b64b790487",
            "read_only_snapshot": false,
            "size_bytes": 4000000000000,
            "snapshot_parent_uuid": null,
            "snapshot_uuids": null,
            "sync_state": "InSync",
            "uuid": "ed73e3a0-25e2-4672-8048-84ad4468c0d7",
            "wwn": "6f497c2006174fed000ab00000007000"
        },
        {
            "accessible_by_host_uuids": [
                "9e8ba77c-8e09-4c69-b893-876742f83f34",
                "1e36d01a-f936-4249-9045-28232bb103e7",
                "ad5a5431-17e1-4023-8373-a6cf64cc5151",
                "3333a278-414b-45d1-8972-611115c76f87"
            ],
            "boot": false,
            "creation_time": "2022-01-26T18:25:40",
            "current_owner_host_uuid": "9e8ba77c-8e09-4c69-b893-876742f83f34",
            "expiration_time": null,
            "lun_uuids": [
                "49e511b7-2b5f-4727-ac63-de12c4b6eb45",
                "2baba8a4-dd23-4be4-ad9d-47580efa60d2",
                "4ff844d6-c677-4c2a-a2e5-c13a5c062b3c",
                "21e7f0c8-5f1a-438f-b503-e568f3691c01"
            ],
            "name": "VMware_Lenovo_VV4",
            "natural_backup_host_uuid": "ad5a5431-17e1-4023-8373-a6cf64cc5151",
            "natural_backup_spu_serial": "xxxxxxxx",
            "natural_owner_host_uuid": "9e8ba77c-8e09-4c69-b893-876742f83f34",
            "natural_owner_spu_serial": "xxxxxxxx",
            "npod_uuid": "4b60437a-f8dc-4c80-b4b2-51b64b790487",
            "read_only_snapshot": false,
            "size_bytes": 4000000000000,
            "snapshot_parent_uuid": null,
            "snapshot_uuids": null,
            "sync_state": "InSync",
            "uuid": "cc3991e2-5443-4bd0-a75d-3e8341d26282",
            "wwn": "6f497c2006174fed000ab00000004000"
        },
        {
            "accessible_by_host_uuids": [
                "ad5a5431-17e1-4023-8373-a6cf64cc5151"
            ],
            "boot": true,
            "creation_time": "2022-01-26T18:25:46",
            "current_owner_host_uuid": "ad5a5431-17e1-4023-8373-a6cf64cc5151",
            "expiration_time": null,
            "lun_uuids": [
                "d5ce25a9-15d1-4e36-878e-5e645ef0c557"
            ],
            "name": "VMware_Lenovo_server-09.tme.nebulon.com_os",
            "natural_backup_host_uuid": "9e8ba77c-8e09-4c69-b893-876742f83f34",
            "natural_backup_spu_serial": "xxxxxxxx",
            "natural_owner_host_uuid": "ad5a5431-17e1-4023-8373-a6cf64cc5151",
            "natural_owner_spu_serial": "xxxxxxxx",
            "npod_uuid": "4b60437a-f8dc-4c80-b4b2-51b64b790487",
            "read_only_snapshot": false,
            "size_bytes": 20000000000,
            "snapshot_parent_uuid": null,
            "snapshot_uuids": null,
            "sync_state": "InSync",
            "uuid": "bdbce49d-834d-438e-a56d-9c384bc229c0",
            "wwn": "6f497c2006174fed000ab00000000000"
        }
    ]
}

}

From this return, I need to store the "name" and "wwn" fields for each volume. Additionally, I need to reject any volume that contains "_os" in the "name" field.

I can get the information using a json_query, but haven't figured out how to reject the volumes with "_os" in their names using this approach.

- name: Set volume name and WWN
  set_fact:
    volume_pairs: "{{ npod_volumes | json_query(volume_query) }}"
  vars: 
    volume_query: "volumes[].{name: name, wwn: wwn}"
  tags: volumes

This gives the following output which includes the unwanted "VMware_Lenovo_server-09.tme.nebulon.com_os" volume.

ok: [127.0.0.1] => {
"volume_pairs": [
    {
        "name": "VMware_Lenovo_VV7",
        "wwn": "6f497c2006187474000ab00000007000"
    },
    {
        "name": "VMware_Lenovo_VV4",
        "wwn": "6f497c2006187474000ab00000004000"
    },
    {
        "name": "VMware_Lenovo_server-09.tme.nebulon.com_os",
        "wwn": "6f497c2006187474000ab00000000000"
    }
]

}

Thanks in advance for your time and consideration!

Score:0
vn flag

So I landed on this solution. Using 'rejectattr' I omit all volumes that contain "_os" in the name. Probably could be done in a more elegant way that excludes my needing to use a json query, but it gets the job done.

  - name: Filter out OS volumes
    set_fact:
      shared_volumes: "{{ npod_volumes.volumes | 
                        rejectattr('name', 'contains', '_os') | 
                        sort(attribute='name') | list }}"
    register: result
    tags: volumes  

  # This builds a list of volumes names and their WWNs
  - name: Set volume name and WWN
    set_fact:
      volume_pairs: "{{ shared_volumes | json_query(volume_query) }}"
    vars: 
      volume_query: "[].{name: name, wwn: wwn}"
    tags: volumes



# {
#     "volume_pairs": [
#         {
#             "name": "VMware_Lenovo_VV4",
#             "wwn": "6f497c2006187474000ab00000004000"
#         },
#         {
#             "name": "VMware_Lenovo_VV5",
#             "wwn": "6f497c2006187474000ab00000005000"
#         },
#         {
#             "name": "VMware_Lenovo_VV6",
#             "wwn": "6f497c2006187474000ab00000006000"
#         },
#         {
#             "name": "VMware_Lenovo_VV7",
#             "wwn": "6f497c2006187474000ab00000007000"
#         }
#     ]
# }
Zeitounator avatar
fr flag
In most situation (e.g. later looping on the list of dicts), you most probably can drop the `json_query` step and directly use `shared_volumes` addressing only the needed attributes for each element (`name` and `wwn`). Mind that `json_query` already goes over your entire list to copy the reduced elements in a new variable. Using them in first place is probably better as far as processing resources usage is concerned.
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.