cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
1387
Views
5
Helpful
2
Replies

enumerate through objects in aci

Pauwl
Level 1
Level 1

Hi,

 

I am working on my first python scripts in aci through the cobra libraries.

I have made some scripts with arya, and have now created some scripts to create ports en policies for our new servers.

I am looking for an example to loop through several objects in aci. What I particular am lookinf for, is a way to loop through all the AEP's, and search in each AEP for a particular string.

 

Can anyone help my with a piece of base code where I can start from?

1 Accepted Solution

Accepted Solutions

Claudia de Luna
Spotlight
Spotlight

Hi @Pauwl,

 

Here is an example of iterating through AEPs.  This is part of a validation script I run after building out an ACI fabric to verify that the configuration is what was expected.

 

I use argparse to customize the verification run so that is what you see in the first if statement. I'm either running all the verification sections or maybe just the AEP verification section.   You can basically ignore all of that.

 

get_query is just a lookup function I have that returns the appropriate URI which for an AEP is:

get_query['aep'] = '/api/node/mo/uni/infra.json?query-target=subtree&target-subtree-class=infraAttEntityP'

 

Your AEP data will be in the variable response.  You can disregard most of that statement as you are using the SDK (vs using the requests module).

 

the rest is pretty basic.  I set a counter so I can count  how many AEPs there are and then pint out each one with a totals at the end (Note that this can be done by getting the length of the response as well)

 

##### AEP #####

if arguments.all or arguments.aeps:
print('\n----AEPs----\n')
counter = 0
response = requests.get(APIC_URL + get_query('aep'), cookies=cookies, verify=False).json()['imdata']

for line in response:
counter += 1

# items in the attributes dictionary
print('\t' + line['infraAttEntityP']['attributes']['name'])

print(f"\nTotal AEPs in Fabric = {counter}")

 

The output looks like this:

(aci_build) Claudias-iMac:aci_build claudia$ python aci_fabric_step6_validation.py -e -f sandbox-credentials.txt TEST

===========Running ACI STEP 6: Verification Script===========
===========      With the following options       ===========
project         : TEST      
all             : False     
aeps            : True      
phydoms         : False     
vlan_pools      : False     
fab_podpol      : False     
tenants         : False     
faults          : False     
health_all      : False     
nodes           : False     
bds             : None      
epgs            : None      
contracts       : None      
filters         : None      
network_vrf     : None      
l3out           : None      
custom          : None      
filename        : sandbox-credentials.txt


**************************************************
User admin Validating Configuration on APIC https://sandboxapicdc.cisco.com/
**************************************************



----AEPs----

        default
        SnV_phys
        SnV_corporate_external
        Heroes_corporate_external
        Heroes_phys
        FH_PHYS_DOM_AttEntityP
        AEP_INT_profile
        BMH-AAEP
        VPC-AAEP
        in-band-AEP
        PIOTR_AttEntityP
        PRD-EXT-SVI-AEP
        PRD-SVR-ACC-AEP
        PIOTR_2_AttEntityP

Total AEPs in Fabric = 14
(aci_build) Claudias-iMac:aci_build claudia$ 

The raw returned data looks like this:

response: 
 [{'infraAttEntityP': {'attributes': {'annotation': '', 'childAction': '', 'configIssues': '', 'descr': '', 'dn': 'uni/infra/attentp-default', 'extMngdBy': '', 'lcOwn': 'local', 'modTs': '2020-02-19T15:00:07.599+00:00', 'monPolDn': 'uni/fabric/monfab-default', 'name': 'default', 'nameAlias': '', 'ownerKey': '', 'ownerTag': '', 'status': '', 'uid': '0'}}}, {'infraAttEntityP': {'attributes': {'annotation': '', 'childAction': '', 'configIssues': '', 'descr': '', 'dn': 'uni/infra/attentp-SnV_phys', 'extMngdBy': '', 'lcOwn': 'local', 'modTs': '2020-02-19T15:03:17.629+00:00', 'monPolDn': 'uni/fabric/monfab-default', 'name': 'SnV_phys', 'nameAlias': '', 'ownerKey': '', 'ownerTag': '', 'status': '', 'uid': '15374'}}}, {'infraAttEntityP': {'attributes': {'annotation': '', 'childAction': '', 'configIssues': '', 'descr': '', 'dn': 'uni/infra/attentp-SnV_corporate_external', 'extMngdBy': '', 'lcOwn': 'local', 'modTs': '2020-02-19T15:03:17.629+00:00', 'monPolDn': 'uni/fabric/monfab-default', 'name': 'SnV_corporate_external', 'nameAlias': '', 'ownerKey': '', 'ownerTag': '', 'status': '', 'uid': '15374'}}}, {'infraAttEntityP': {'attributes': {'annotation': '', 'childAction': '', 'configIssues': '', 'descr': '', 'dn': 'uni/infra/attentp-Heroes_corporate_external', 'extMngdBy': '', 'lcOwn': 'local', 'modTs': '2020-02-19T15:03:17.629+00:00', 'monPolDn': 'uni/fabric/monfab-default', 'name': 'Heroes_corporate_external', 'nameAlias': '', 'ownerKey': '', 'ownerTag': '', 'status': '', 'uid': '15374'}}}, {'infraAttEntityP': {'attributes': {'annotation': '', 'childAction': '', 'configIssues': '', 'descr': '', 'dn': 'uni/infra/attentp-Heroes_phys', 'extMngdBy': '', 'lcOwn': 'local', 'modTs': '2020-02-19T15:03:17.629+00:00', 'monPolDn': 'uni/fabric/monfab-default', 'name': 'Heroes_phys', 'nameAlias': '', 'ownerKey': '', 'ownerTag': '', 'status': '', 'uid': '15374'}}}, {'infraAttEntityP': {'attributes': {'annotation': '', 'childAction': '', 'configIssues': '', 'descr': '', 'dn': 'uni/infra/attentp-FH_PHYS_DOM_AttEntityP', 'extMngdBy': '', 'lcOwn': 'local', 'modTs': '2020-02-19T15:06:06.087+00:00', 'monPolDn': 'uni/fabric/monfab-default', 'name': 'FH_PHYS_DOM_AttEntityP', 'nameAlias': '', 'ownerKey': '', 'ownerTag': '', 'status': '', 'uid': '15374'}}}, {'infraAttEntityP': {'attributes': {'annotation': '', 'childAction': '', 'configIssues': '', 'descr': '', 'dn': 'uni/infra/attentp-AEP_INT_profile', 'extMngdBy': '', 'lcOwn': 'local', 'modTs': '2020-02-20T09:35:48.261+00:00', 'monPolDn': 'uni/fabric/monfab-default', 'name': 'AEP_INT_profile', 'nameAlias': '', 'ownerKey': '', 'ownerTag': '', 'status': '', 'uid': '15374'}}}, {'infraAttEntityP': {'attributes': {'annotation': '', 'childAction': '', 'configIssues': '', 'descr': '', 'dn': 'uni/infra/attentp-BMH-AAEP', 'extMngdBy': '', 'lcOwn': 'local', 'modTs': '2020-02-20T10:46:09.936+00:00', 'monPolDn': 'uni/fabric/monfab-default', 'name': 'BMH-AAEP', 'nameAlias': '', 'ownerKey': '', 'ownerTag': '', 'status': '', 'uid': '15374'}}}, {'infraAttEntityP': {'attributes': {'annotation': '', 'childAction': '', 'configIssues': '', 'descr': '', 'dn': 'uni/infra/attentp-VPC-AAEP', 'extMngdBy': '', 'lcOwn': 'local', 'modTs': '2020-02-20T11:01:18.057+00:00', 'monPolDn': 'uni/fabric/monfab-default', 'name': 'VPC-AAEP', 'nameAlias': '', 'ownerKey': '', 'ownerTag': '', 'status': '', 'uid': '15374'}}}, {'infraAttEntityP': {'attributes': {'annotation': '', 'childAction': '', 'configIssues': '', 'descr': '', 'dn': 'uni/infra/attentp-in-band-AEP', 'extMngdBy': '', 'lcOwn': 'local', 'modTs': '2020-02-20T12:26:53.913+00:00', 'monPolDn': 'uni/fabric/monfab-default', 'name': 'in-band-AEP', 'nameAlias': '', 'ownerKey': '', 'ownerTag': '', 'status': '', 'uid': '15374'}}}, {'infraAttEntityP': {'attributes': {'annotation': '', 'childAction': '', 'configIssues': '', 'descr': '', 'dn': 'uni/infra/attentp-PIOTR_AttEntityP', 'extMngdBy': '', 'lcOwn': 'local', 'modTs': '2020-02-20T12:35:19.702+00:00', 'monPolDn': 'uni/fabric/monfab-default', 'name': 'PIOTR_AttEntityP', 'nameAlias': '', 'ownerKey': '', 'ownerTag': '', 'status': '', 'uid': '15374'}}}, {'infraAttEntityP': {'attributes': {'annotation': '', 'childAction': '', 'configIssues': '', 'descr': '', 'dn': 'uni/infra/attentp-PRD-EXT-SVI-AEP', 'extMngdBy': '', 'lcOwn': 'local', 'modTs': '2020-02-20T12:39:15.719+00:00', 'monPolDn': 'uni/fabric/monfab-default', 'name': 'PRD-EXT-SVI-AEP', 'nameAlias': '', 'ownerKey': '', 'ownerTag': '', 'status': '', 'uid': '15374'}}}, {'infraAttEntityP': {'attributes': {'annotation': '', 'childAction': '', 'configIssues': '', 'descr': '', 'dn': 'uni/infra/attentp-PRD-SVR-ACC-AEP', 'extMngdBy': '', 'lcOwn': 'local', 'modTs': '2020-02-20T12:39:15.719+00:00', 'monPolDn': 'uni/fabric/monfab-default', 'name': 'PRD-SVR-ACC-AEP', 'nameAlias': '', 'ownerKey': '', 'ownerTag': '', 'status': '', 'uid': '15374'}}}, {'infraAttEntityP': {'attributes': {'annotation': '', 'childAction': '', 'configIssues': '', 'descr': '', 'dn': 'uni/infra/attentp-PIOTR_2_AttEntityP', 'extMngdBy': '', 'lcOwn': 'local', 'modTs': '2020-02-20T12:51:45.817+00:00', 'monPolDn': 'uni/fabric/monfab-default', 'name': 'PIOTR_2_AttEntityP', 'nameAlias': '', 'ownerKey': '', 'ownerTag': '', 'status': '', 'uid': '15374'}}}]

response length: 14

response type: <class 'list'>

As you work through responses you get from APIs (REST in this case), its important you are comfortable with plucking out the data you want.

 

This may help if you are not already comfortable with that.
Decomposing Data Structures

 

A suggestion is to take the response above and put it in a variable in python and play around with getting at the data you need.   This is a very worthwhile skill to cultivate!

 

Hope this helps get you started!

View solution in original post

2 Replies 2

Claudia de Luna
Spotlight
Spotlight

Hi @Pauwl,

 

Here is an example of iterating through AEPs.  This is part of a validation script I run after building out an ACI fabric to verify that the configuration is what was expected.

 

I use argparse to customize the verification run so that is what you see in the first if statement. I'm either running all the verification sections or maybe just the AEP verification section.   You can basically ignore all of that.

 

get_query is just a lookup function I have that returns the appropriate URI which for an AEP is:

get_query['aep'] = '/api/node/mo/uni/infra.json?query-target=subtree&target-subtree-class=infraAttEntityP'

 

Your AEP data will be in the variable response.  You can disregard most of that statement as you are using the SDK (vs using the requests module).

 

the rest is pretty basic.  I set a counter so I can count  how many AEPs there are and then pint out each one with a totals at the end (Note that this can be done by getting the length of the response as well)

 

##### AEP #####

if arguments.all or arguments.aeps:
print('\n----AEPs----\n')
counter = 0
response = requests.get(APIC_URL + get_query('aep'), cookies=cookies, verify=False).json()['imdata']

for line in response:
counter += 1

# items in the attributes dictionary
print('\t' + line['infraAttEntityP']['attributes']['name'])

print(f"\nTotal AEPs in Fabric = {counter}")

 

The output looks like this:

(aci_build) Claudias-iMac:aci_build claudia$ python aci_fabric_step6_validation.py -e -f sandbox-credentials.txt TEST

===========Running ACI STEP 6: Verification Script===========
===========      With the following options       ===========
project         : TEST      
all             : False     
aeps            : True      
phydoms         : False     
vlan_pools      : False     
fab_podpol      : False     
tenants         : False     
faults          : False     
health_all      : False     
nodes           : False     
bds             : None      
epgs            : None      
contracts       : None      
filters         : None      
network_vrf     : None      
l3out           : None      
custom          : None      
filename        : sandbox-credentials.txt


**************************************************
User admin Validating Configuration on APIC https://sandboxapicdc.cisco.com/
**************************************************



----AEPs----

        default
        SnV_phys
        SnV_corporate_external
        Heroes_corporate_external
        Heroes_phys
        FH_PHYS_DOM_AttEntityP
        AEP_INT_profile
        BMH-AAEP
        VPC-AAEP
        in-band-AEP
        PIOTR_AttEntityP
        PRD-EXT-SVI-AEP
        PRD-SVR-ACC-AEP
        PIOTR_2_AttEntityP

Total AEPs in Fabric = 14
(aci_build) Claudias-iMac:aci_build claudia$ 

The raw returned data looks like this:

response: 
 [{'infraAttEntityP': {'attributes': {'annotation': '', 'childAction': '', 'configIssues': '', 'descr': '', 'dn': 'uni/infra/attentp-default', 'extMngdBy': '', 'lcOwn': 'local', 'modTs': '2020-02-19T15:00:07.599+00:00', 'monPolDn': 'uni/fabric/monfab-default', 'name': 'default', 'nameAlias': '', 'ownerKey': '', 'ownerTag': '', 'status': '', 'uid': '0'}}}, {'infraAttEntityP': {'attributes': {'annotation': '', 'childAction': '', 'configIssues': '', 'descr': '', 'dn': 'uni/infra/attentp-SnV_phys', 'extMngdBy': '', 'lcOwn': 'local', 'modTs': '2020-02-19T15:03:17.629+00:00', 'monPolDn': 'uni/fabric/monfab-default', 'name': 'SnV_phys', 'nameAlias': '', 'ownerKey': '', 'ownerTag': '', 'status': '', 'uid': '15374'}}}, {'infraAttEntityP': {'attributes': {'annotation': '', 'childAction': '', 'configIssues': '', 'descr': '', 'dn': 'uni/infra/attentp-SnV_corporate_external', 'extMngdBy': '', 'lcOwn': 'local', 'modTs': '2020-02-19T15:03:17.629+00:00', 'monPolDn': 'uni/fabric/monfab-default', 'name': 'SnV_corporate_external', 'nameAlias': '', 'ownerKey': '', 'ownerTag': '', 'status': '', 'uid': '15374'}}}, {'infraAttEntityP': {'attributes': {'annotation': '', 'childAction': '', 'configIssues': '', 'descr': '', 'dn': 'uni/infra/attentp-Heroes_corporate_external', 'extMngdBy': '', 'lcOwn': 'local', 'modTs': '2020-02-19T15:03:17.629+00:00', 'monPolDn': 'uni/fabric/monfab-default', 'name': 'Heroes_corporate_external', 'nameAlias': '', 'ownerKey': '', 'ownerTag': '', 'status': '', 'uid': '15374'}}}, {'infraAttEntityP': {'attributes': {'annotation': '', 'childAction': '', 'configIssues': '', 'descr': '', 'dn': 'uni/infra/attentp-Heroes_phys', 'extMngdBy': '', 'lcOwn': 'local', 'modTs': '2020-02-19T15:03:17.629+00:00', 'monPolDn': 'uni/fabric/monfab-default', 'name': 'Heroes_phys', 'nameAlias': '', 'ownerKey': '', 'ownerTag': '', 'status': '', 'uid': '15374'}}}, {'infraAttEntityP': {'attributes': {'annotation': '', 'childAction': '', 'configIssues': '', 'descr': '', 'dn': 'uni/infra/attentp-FH_PHYS_DOM_AttEntityP', 'extMngdBy': '', 'lcOwn': 'local', 'modTs': '2020-02-19T15:06:06.087+00:00', 'monPolDn': 'uni/fabric/monfab-default', 'name': 'FH_PHYS_DOM_AttEntityP', 'nameAlias': '', 'ownerKey': '', 'ownerTag': '', 'status': '', 'uid': '15374'}}}, {'infraAttEntityP': {'attributes': {'annotation': '', 'childAction': '', 'configIssues': '', 'descr': '', 'dn': 'uni/infra/attentp-AEP_INT_profile', 'extMngdBy': '', 'lcOwn': 'local', 'modTs': '2020-02-20T09:35:48.261+00:00', 'monPolDn': 'uni/fabric/monfab-default', 'name': 'AEP_INT_profile', 'nameAlias': '', 'ownerKey': '', 'ownerTag': '', 'status': '', 'uid': '15374'}}}, {'infraAttEntityP': {'attributes': {'annotation': '', 'childAction': '', 'configIssues': '', 'descr': '', 'dn': 'uni/infra/attentp-BMH-AAEP', 'extMngdBy': '', 'lcOwn': 'local', 'modTs': '2020-02-20T10:46:09.936+00:00', 'monPolDn': 'uni/fabric/monfab-default', 'name': 'BMH-AAEP', 'nameAlias': '', 'ownerKey': '', 'ownerTag': '', 'status': '', 'uid': '15374'}}}, {'infraAttEntityP': {'attributes': {'annotation': '', 'childAction': '', 'configIssues': '', 'descr': '', 'dn': 'uni/infra/attentp-VPC-AAEP', 'extMngdBy': '', 'lcOwn': 'local', 'modTs': '2020-02-20T11:01:18.057+00:00', 'monPolDn': 'uni/fabric/monfab-default', 'name': 'VPC-AAEP', 'nameAlias': '', 'ownerKey': '', 'ownerTag': '', 'status': '', 'uid': '15374'}}}, {'infraAttEntityP': {'attributes': {'annotation': '', 'childAction': '', 'configIssues': '', 'descr': '', 'dn': 'uni/infra/attentp-in-band-AEP', 'extMngdBy': '', 'lcOwn': 'local', 'modTs': '2020-02-20T12:26:53.913+00:00', 'monPolDn': 'uni/fabric/monfab-default', 'name': 'in-band-AEP', 'nameAlias': '', 'ownerKey': '', 'ownerTag': '', 'status': '', 'uid': '15374'}}}, {'infraAttEntityP': {'attributes': {'annotation': '', 'childAction': '', 'configIssues': '', 'descr': '', 'dn': 'uni/infra/attentp-PIOTR_AttEntityP', 'extMngdBy': '', 'lcOwn': 'local', 'modTs': '2020-02-20T12:35:19.702+00:00', 'monPolDn': 'uni/fabric/monfab-default', 'name': 'PIOTR_AttEntityP', 'nameAlias': '', 'ownerKey': '', 'ownerTag': '', 'status': '', 'uid': '15374'}}}, {'infraAttEntityP': {'attributes': {'annotation': '', 'childAction': '', 'configIssues': '', 'descr': '', 'dn': 'uni/infra/attentp-PRD-EXT-SVI-AEP', 'extMngdBy': '', 'lcOwn': 'local', 'modTs': '2020-02-20T12:39:15.719+00:00', 'monPolDn': 'uni/fabric/monfab-default', 'name': 'PRD-EXT-SVI-AEP', 'nameAlias': '', 'ownerKey': '', 'ownerTag': '', 'status': '', 'uid': '15374'}}}, {'infraAttEntityP': {'attributes': {'annotation': '', 'childAction': '', 'configIssues': '', 'descr': '', 'dn': 'uni/infra/attentp-PRD-SVR-ACC-AEP', 'extMngdBy': '', 'lcOwn': 'local', 'modTs': '2020-02-20T12:39:15.719+00:00', 'monPolDn': 'uni/fabric/monfab-default', 'name': 'PRD-SVR-ACC-AEP', 'nameAlias': '', 'ownerKey': '', 'ownerTag': '', 'status': '', 'uid': '15374'}}}, {'infraAttEntityP': {'attributes': {'annotation': '', 'childAction': '', 'configIssues': '', 'descr': '', 'dn': 'uni/infra/attentp-PIOTR_2_AttEntityP', 'extMngdBy': '', 'lcOwn': 'local', 'modTs': '2020-02-20T12:51:45.817+00:00', 'monPolDn': 'uni/fabric/monfab-default', 'name': 'PIOTR_2_AttEntityP', 'nameAlias': '', 'ownerKey': '', 'ownerTag': '', 'status': '', 'uid': '15374'}}}]

response length: 14

response type: <class 'list'>

As you work through responses you get from APIs (REST in this case), its important you are comfortable with plucking out the data you want.

 

This may help if you are not already comfortable with that.
Decomposing Data Structures

 

A suggestion is to take the response above and put it in a variable in python and play around with getting at the data you need.   This is a very worthwhile skill to cultivate!

 

Hope this helps get you started!

Hi Claudia,

 

Thank you for your answer. 

I had already solved it with a small piece of code.

If someone is interested:

 

(moDir is the var for the previous login and session declared earlier)
allaep = moDir.lookupByClass("infraAttEntityP", parentDn='uni/infra') for aep in allaep: print aep.name #do something else with the output

In my case I wanted to check is the aep name contained a certain string. That worked like a charm.

 

Thank you and have a nice weekend.

Save 25% on Day-2 Operations Add-On License