Access items in a sub-array

I am using the ovirt_snapshot_info module to obtain information about our VM snapshots. I register the output and it contains an array of values, 1 for each VM, then within that output, there’s an array of values called ovirt_snapshots (See sample below). I’m trying to get to the “description” value for each snapshot, but for the life of me, I can’t get it to work. I’d appreciate any thoughts or ideas.

My sample output:

TASK [Show results] ************************************************************
ok: [localhost] => {
“msg”: {
“changed”: false,
“msg”: “All items completed”,
“results”: [
{
“ansible_loop_var”: “item”,
“changed”: false,
“failed”: false,
“invocation”: {
“module_args”: {
“description”: null,
“fetch_nested”: false,
“nested_attributes”: ,
“snapshot_id”: null,
“vm”: “vm1”
}
},
“item”: “vm1”,
“ovirt_snapshots”: [
{
“cdroms”: ,
“date”: “2022-05-12 13:13:19.186000+00:00”,
“description”: “Snapshot before 12.2 update may122022”,
“disks”: ,
“href”: “/ovirt-engine/api/vms/1eadb46c-e8a9-4ecd-b375-15b93079e1b3/snapshots/187b0431-b7fa-4b29-9dbc-d5298c0ba3e4”,
“id”: “187b0431-b7fa-4b29-9dbc-d5298c0ba3e4”,
“nics”: ,
“persist_memorystate”: true,
“snapshot_status”: “ok”,
“snapshot_type”: “regular”,

My playbook code:

  • name: Show results
    ansible.builtin.debug:
    msg: “{{ result }}”
    with_nested:
  • “{{ item.ovirt_snapshots }}”
    loop:
  • “{{ result.results }}”

Thanks,
Harry

  • name: Show results
    ansible.builtin.debug:
    msg: “{{ item }}”
    loop:
  • “{{ result.results.ovirt_snapshots }}”

How about this?

Walter

Nope. I get: "list object has no attribute ‘ovirt_snapshots’.

Thanks,
Harry

  • name: Show results
    ansible.builtin.debug:

msg: “{{ item }}”
loop:

  • “{{ result.results[0].ovirt_snapshots }}”

Walter

That works, but it only shows the info for the first VM. There are 22 total. What I’d like to have is the VM name and list of all of that VMs snapshots, so I need to be able to traverse through the output at the VM level, then travers that VM’s ovirt_snapshots data.

Thanks,
Harry

How about this?

  • name: Show results
    ansible.builtin.debug:

msg: “{{ item }}”
loop:

  • “{{ result.results | json_query(‘[*].ovirt_snapshots’) }}”

Walter

So that gives me the data under each VM’s ovirt_snapshots, but I still can’t access the “description” data. I tried this:

  • name: Show results
    ansible.builtin.debug:
    msg: “{{ item }}”
    with_nested:
  • “{{ item[0].description }}”
    loop:
  • “{{ result.results | json_query(‘[*].ovirt_snapshots’) }}”

And it shows me the same information with or without the “with_nested” clause in there.

Thanks,
Harry

  • name: Show results
    ansible.builtin.debug:

msg: “{{ item.description }}”
loop:

  • “{{ result.results | json_query(‘[*].ovirt_snapshots’) }}”

Walter

Still no good:

TASK [Show results] ***********************************************************************************************************************************************************************************
fatal: [localhost]: FAILED! => {“msg”: “The task includes an option with an undefined variable. The error was: ‘description’ is undefined. ‘description’ is undefined\n\nThe error appears to be in ‘/root/vm_snapshot_info.yml’: line 48, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n - name: Show results\n ^ here\n”}

  • name: Show results
    ansible.builtin.debug:
    msg: “{{ item,description }}”
    loop:
  • “{{ result.results | json_query(‘[*].ovirt_snapshots’) }}”

Thanks,
Harry

Can you share the output from this:

  • name: Show results
    ansible.builtin.debug:

msg: “{{ item }}”
loop:

  • “{{ result.results | json_query(‘[*].ovirt_snapshots’) }}”

I suspect at this point it is just a matter of constructing the right reference in ‘item’.

Walter

Here ya go (I pulled out a bunch of output that just muddied up everything:

“msg”: [
[
{
“date”: “2021-04-10 00:19:25.785000+00:00”,
“description”: “Active VM”,
“href”: “/ovirt-engine/api/vms/e0abbe35-3c4c-463b-8d08-587618d2465d/snapshots/22e82416-71b4-4808-b315-4cf7d713ae31”,
“id”: “22e82416-71b4-4808-b315-4cf7d713ae31”,
“persist_memorystate”: false,
“snapshot_status”: “ok”,
“snapshot_type”: “active”
},
{
“cdroms”: ,
“date”: “2023-02-22 09:02:48.843000+00:00”,
“description”: “Snapshot of VM1 2023-02-22”,
“disks”: ,
/* Redacted extra output /
},
{
“cdroms”: [],
“date”: “2023-02-23 09:03:23.519000+00:00”,
“description”: “Snapshot of VM1 2023-02-23”,
“disks”: [],
/
Redacted extra output */
}
]
]
}

Thanks,
Harry

Try this reference:

  • name: Show results
    ansible.builtin.debug:

msg: “{{ item[‘description’] }}”
loop:

  • “{{ result.results | json_query(‘[*].ovirt_snapshots’) }}”

Walter

That was close, but you used a comma instead of a period in “{{ item.description }}”.

I tried it 4 ways:
msg: “{{ item.description }}”
msg: “{{ item[‘description’] }}”
msg: “{{ item[0].description }}”
msg: “{{ item[0][‘description’] }}”

and all 4 give me the following error:

TASK [Show results] ***********************************************************************************************************************************************************************************
fatal: [localhost]: FAILED! => {“msg”: “The task includes an option with an undefined variable. The error was: ‘list object’ has no attribute ‘description’. ‘list object’ has no attribute ‘description’\n\nThe error appears to be in ‘/root/vm_snapshot_info.yml’: line 48, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n - name: Show results\n ^ here\n”}

Thanks,
Harry

Again, without the play including the “loop:” we have no idea what “item” looks like.

When you get something like the error you quoted, where it’s looking at an object (a list object by that message) and you don’t know how to reference data contained within, just take off all the other bits and have debug show you

msg: “{{ item }}”

Then work your way one level at a time until you get the expression right.

I get what you’re saying, but when I just debug print {{ item }} using the results variable, I see all of the snapshots listed. If I add in the loop and use {{ item[0] }}, I see the same information, and description is included. But when I try to add description to the output, I am told that it doesn’t exist. So I’m at the “until you get the expression right” phase, but no matter what I use, the expression isn’t right.

  • name: Gather VM Snapshot info
    redhat.rhv.ovirt_snapshot_info:
    auth: “{{ ovirt_auth }}”
    vm: “{{ item }}”
    register: result
    with_items:

  • “vm1”

  • name: Show results
    ansible.builtin.debug:
    msg: “{{ item[0].description }}”
    loop:

  • “{{ result.results | json_query(‘[*].ovirt_snapshots’) }}”

Thanks,
Harry

OK, I think I have it:

  • name: Show results
    ansible.builtin.debug:
    msg: “{{ item }}”
    loop:
  • “{{ result.results | json_query(‘[].ovirt_snapshots[].description’) }}”

This gives me what I want, to a point. I would like to print the VM name too, and that is at result.results[*].item. Any ideas on how I can adde that?

Thanks,
Harry

OK, finally figured it out. Used with_nested and was able to print both items:

  • name: Show results
    ansible.builtin.debug:
    msg: “{{ item[0] }} - {{ item[1] }}”
    with_nested:
  • “{{ result.results | json_query(‘[*].item’) }}”
  • “{{ result.results | json_query(‘[].ovirt_snapshots[].description’) }}”

Thanks,
Harry