Need help parsing output from VMware collection

I’m trying to use the community.vmware collection to automate the creation of a number of VMs (fine with that bit), where I am coming unstuck is parsing the output of community.vmware.vmware_datastore_info

“datastores”: [
{
“name”: “datastore1”,
“summary”: {
“_vimtype”: “vim.Datastore.Summary”,
“accessible”: true,
“capacity”: 119990648832,
“datastore”: “vim.Datastore:656bd379-a008a098-6ed8-d05099c155c9”,
“freeSpace”: 84916830208,
“maintenanceMode”: null,
“multipleHostAccess”: null,
“name”: “datastore1”,
“type”: “VMFS”,
“uncommitted”: 3793282394,
“url”: “/vmfs/volumes/656bd379-a008a098-6ed8-d05099c155c9”
}
},
{
“name”: “datastore2”,
“summary”: {
“_vimtype”: “vim.Datastore.Summary”,
“accessible”: true,
“capacity”: 239981297664,
“datastore”: “vim.Datastore:656bd392-48951fa8-1f7f-d05099c155c9”,
“freeSpace”: 238469251072,
“maintenanceMode”: null,
“multipleHostAccess”: null,
“name”: “datastore2”,
“type”: “VMFS”,
“uncommitted”: 0,
“url”: “/vmfs/volumes/656bd392-48951fa8-1f7f-d05099c155c9”
}
}
]

---
# find free space on cluster datastores
- name: Retrieve information on free space in each datastore
  community.vmware.vmware_datastore_info:
    hostname: "{{ '<host>>' }}"
    username: "{{ 'root' }}"
    password: "{{ '<password>>' }}"
    validate_certs: False
    schema: vsphere
    properties:
      - name
      - summary
  delegate_to: localhost
  register: info

- name: datastore info output
  ansible.builtin.debug:
    msg="{{ info }}"
#    msg="{{ info | type_debug}}"

So the output is of type “dict” but I can’t seem identify the correct syntax to extract the fields i want from the output. I want to extract the datastore name and the available free space to evaluate whether I have enough free space to deploy on that datastore (make sense?).

Can someone who knows what their doing point me the in the right direction, or offer some example code?

I tried using map to pull the relevant fields but I can’t make this work, there is a gap in my understanding…

Like this:

$ cat newbie01.yml
---
# newbie01.yml
- name: Result stuff
  hosts: localhost
  gather_facts: false
  vars:
    info:
      "datastores": [
        {
        "name": "datastore1",
        "summary": {
        "_vimtype": "vim.Datastore.Summary",
        "accessible": true,
        "capacity": 119990648832,
        "datastore": "vim.Datastore:656bd379-a008a098-6ed8-d05099c155c9",
        "freeSpace": 84916830208,
        "maintenanceMode": null,
        "multipleHostAccess": null,
        "name": "datastore1",
        "type": "VMFS",
        "uncommitted": 3793282394,
        "url": "/vmfs/volumes/656bd379-a008a098-6ed8-d05099c155c9"
        }
        },
        {
        "name": "datastore2",
        "summary": {
        "_vimtype": "vim.Datastore.Summary",
        "accessible": true,
        "capacity": 239981297664,
        "datastore": "vim.Datastore:656bd392-48951fa8-1f7f-d05099c155c9",
        "freeSpace": 238469251072,
        "maintenanceMode": null,
        "multipleHostAccess": null,
        "name": "datastore2",
        "type": "VMFS",
        "uncommitted": 0,
        "url": "/vmfs/volumes/656bd392-48951fa8-1f7f-d05099c155c9"
        }
        }
        ]
  tasks:
    - name: Show names, freeSpace
      ansible.builtin.debug:
        msg: '{{ item }}'
      loop:
        - '{{ info.datastores | map(attribute="name") |
           zip(info.datastores | map(attribute="summary.freeSpace")) }}'

$ ansible-playbook newbie01.yml
PLAY [Result stuff] ********************************************************************************************

TASK [Show names, freeSpace] ********************************************************************************************
ok: [localhost] => (item=[['datastore1', 84916830208], ['datastore2', 238469251072]]) => {
    "msg": [
        [
            "datastore1",
            84916830208
        ],
        [
            "datastore2",
            238469251072
        ]
    ]
}

PLAY RECAP **********************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Or another way to say it is:

if info.datastores[0].summary.freeSpace > lower_limit:
    deploy_on(info.datastores[0].name)

That’s pseudo-code, but the expression is right.

1 Like

Thank you Sir! You’ve been a big help to me, much appreciated!

2 Likes

Next stupid question, how do I loop through every value in the dictionary “index”

e.g. info.datastores[0].name
info.datastores[0].summary.freeSpace

until:
info.datastores[n].name
info.datastores[n].summary.freeSpace

where n is the final integer in the index ?

I want to be able to examine every datastore for free space and also only deploy on a select set of datastores whose name corresponds to a particular pattern…

i.e.

How do I translate this example in the ansible documentation to my particular use case:

  • name: Count our fruit
    ansible.builtin.debug:
    msg: “{{ item }} with index {{ my_idx }}”
    loop:
    • apple
    • banana
    • pear
      loop_control:
      index_var: my_idx

I’d do something like this maybe:

    - name: Conditional deploy on datastore
      ansible.builtin.include_tasks:
        file: deploy_on_datastore.yml
      vars:
        min_free_space: 4916830208
      when:
        - datastore.summary.freeSpace > min_free_space
        - datastore['summary']['type'] == 'VMFS'      # another way to address "summary"
        - datastore.name is regex("^data.*[13579]$")  # odd-numbered datastore#
        - datastore.name is regex("a.t.*e")           # another arbitrary conditon
      loop: '{{ info.datastores }}'
      loop_control:
        loop_var: datastore