I have been playing around a lot more with the embedded Ansible feature of CloudForms 4.6. While this functionality was introduced in version 4.5, the ability to call a playbook method from a state machine in version 4.6 opens up a lot of possibilities.
One thing I was caught up on though was how to query VMDB collections for a specific item from within a playbook. Initially I thought it was going to be necessary to iterate through every item in the collection, something that would require a large amount of API calls and become totally impractical for larger collections. Luckily my initial thoughts were incorrect – the expansion and filtering capabilities allow for a single API query.
For example, to find a cloud tenant in the VMDB, based on the EMS reference, using a standard inline ruby method, you would do something like:
$evm.vmdb(:cloud_tenant).find_by_ems_ref( "e3bf94d9de273be572b22aa425c2c2ad" )
To achieve the same thing via the REST API, you need to run a GET query against the collection URL, expand the resources of each item in the collection, and filter on the ems_ref attribute. Here is an example using an Ansible task:
- name: Find cloud tenant uri: url: "https://cfme.parko.lab/api/cloud_tenants?\ expand=resources&filter[]=\ ems_ref=e3bf94d9de273be572b22aa425c2c2ad" register: result - set_fact: tenant_href: "{{ result.json.resources[0].href }}"
The same idea can be applied to all collections and all attributes. Even nested attributes can be referred to with the dot notation:
- name: Find some item(s) uri: url: "https://cfme.parko.lab/api/{{ collection }}?\ expand=resources&filter[]=\ {{ option }}.{{ attribute }}={{ value }}" register: result
It’s worth noting too that the attributes are not restricted to what you see returned from a standard API query. You can use all database attributes and relationships – try using an object walker or inspecting a VMDB object via the rails console to see what attributes are available.