ansible-aci
ansible-aci copied to clipboard
ACI lookup plugin (DCNE-110)
Community Note
- Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
- Please do not leave "+1" or other comments that do not add relevant new information or questions, they generate extra noise for issue followers and do not help prioritize the request
- If you are interested in working on this issue or have submitted a pull request, please leave a comment
Description
An Ansible lookup plugin would be helpful to query the REST API from the APIC and directly store the returned data (list) in a task / role variable or to define an Ansible loop
. Currently, an aci_rest
operation is needed as a dedicated task. The problem here is, that there is no way to register a variable for aci_rest
operations to store the output. Therefore, a lookup plugin would be helpful
Example usage:
tasks:
- name: "Lookup test 1"
vars:
aci_query_target_filters:
match: "and"
filters:
- attribute: "fvTenant.name"
operator: "eq"
value: "common"
ansible.builtin.debug:
msg: "{{ query('aci_lookup',
host='apic1.example.com',
port=443,
username='apic_admin',
password='apic_adminPw',
query_scope='class',
query_object='fvTenant',
query_target='self',
target_subtree_class=['fvAEPg', 'fvBD'],
query_target_filters=aci_query_target_filters) }}"
Of course, all possible REST options shall be implemented (e.g. rsp_subtree
, rsp_subtree_class
, ....)
New or Affected Module(s):
- Proposed lookup name:
aci_lookup
APIC version and APIC Platform
not relevant, because this is a generic approach
Collection versions
- cisco.aci 2.1.0
References
- #0000
I like it. It would be great to export the results to a CSV file as an option.
So I wrote it myself to fulfill my project requirements and it's really helpful to fillout variables based on lookups within a single task. However I did the whole thing very quick and potentially very dirty so it does not make sense to contribute
Hi @netgab,
I am not sure what you mean with your remark: "The problem here is, that there is no way to register a variable for aci_rest operations to store the output". Could you please elaborate a bit more what your exact requirement is and why this is not possible with current aci_rest module?
Hi @akinross,
so the "problem" is as follows (maybe it's because of lacking Ansible skills) :)
If someone wants to query information from ACI using aci_rest
, each query requires a dedicated Ansible task
.
Example:
- name: "ACI REST query operation"
cisco.aci.aci_rest:
#...
method: get
path: "/api/class/fvTenant.json"
delegate_to: localhost
register: aci_query_result
If I want to query a lot of stuff, I need one task per query and register one "fact" per query. My initial statement:
The problem here is, that there is no way to register a variable for aci_rest operations to store the output.
is not quite correct, because aci_rest
provides a register
option.
However a lookup
plugin allows you to perform complex single tasks like:
- name: "Check if baremetal EPGs exists"
vars:
queryFilter:
filters:
- attribute: "fvAEPg.name"
value: "{{ item.name }}"
epgQuery: "{{ lookup('aci_lookup',
host=apic_connection,
username=apic_username,
password=apic_password,
validate_certs=(apic_validate_cert | default(True) | bool),
query_object='fvAEPg',
query_target_filter=queryFilter) }}"
ansible.builtin.assert:
that: "epgQuery | length == 1"
fail_msg: "EPG {{ item.name }} does not exist - abort"
success_msg: "EPG {{ item.name }} exists - continue"
loop: "{{ epgs }}"
loop_control:
label: "{{ item.name }}"
I'm (right now) not saying you cannot solve this using aci_rest
, but you need at least two tasks to get this.... and this might become very complex, because if checking the example above:
Based on a list of EPG names (variable epgs
), the task checks if the epgs exists in ACI using a query.
The variable epgQuery
above is the result from the lookup plugin, which is at the end of the day a list of dictionaries (imdata
).
If you use aci_query
in a loop and register a variable, I guess the variable will be somehow magically concanated... so at the end of the day if the task is done, we have a new fact (hopefully), containing a list of dictionaries (imdata
). An alternative would be to query all EPGs without a loop and register the result... It doesn't matter...
We cannot do an assert
or anything else within this task, because the task action is aci_rest
.
Now we need to check whether our EPGs (names in the list epgs
) exists within this registered fact. So we need to verify if an loop item exists within a list of complex dictionaries.
Either you can solve this somehow with inner
and outer
loop magic or using special stuff like map
, selectattr
, json_query
magic... At least I'm not clever enough for this. Even if I manage it, I don't understand this jq
expression when I check back to my code after some time.
I'm keen to learn how to solve my little task
above with the use of aci_rest
only.
Hi @netgab,
Yes you would need two tasks but is that a bad thing?
A possibility would be to do some sort of assert like:
- name: query epgs
vars:
epgs:
- consumer_epg_a
- missing_epg
cisco.aci.aci_rest:
<<: *aci_info
method: get
path: /api/class/uni/tn-common/fvAEPg.json?query-target-filter=eq(fvAEPg.name,"{{ item }}")
register: query_result_class_epg
loop: "{{ epgs }}"
- name: assert epgs
vars:
input_epg: "{{ item.item }}"
output_epg: "{{ (item.imdata | length != 0) | ternary(item.imdata.0.fvAEPg.attributes.name, 'MISSING') }}"
ansible.builtin.assert:
that: input_epg == output_epg
loop: "{{ query_result_class_epg.results }}"
Hi @akinross, nicely done ... I have some tasks, with four or more variables, which are filled by the lookup plugin. But anyway. I thought it's a good idea and simplifies stuff for the user (similar to the great Netbox lookup plugin https://docs.ansible.com/ansible/latest/collections/netbox/netbox/nb_lookup_lookup.html).
Anyway - I solved it myself and wrote such a plugin. Since there are not a lot of "thumbsup" regarding this issue here, you may close it.
Hi @netgab,
We will keep this issue open in case there is more interest in time. For now this has low priority, but in time perhaps there will be more interest from the community. Thank you for the idea contribution.