cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
9432
Views
10
Helpful
9
Comments
Toru Okatsu
Cisco Employee
Cisco Employee

1. About Cobra SDK

REST API is the basic interface of ACI and Cobra SDK is the library to access the API from python programs.

Following documents delivered with APIC describe REST API and Cobra SDK.

REST APIC User Guilde can also be access on Cisco Web Site.

 

2. About this example

This is an example to get the interface status information from the APIC with a python code.

 

The code is tested with 1.0(0.483) APIC code and Python2.7.8.

1.0(483) is pre-FCS release.

 

3. Use lookupByClass() method

The first example is to use lookupByClass() method in cobra.mit.access.MoDirectory.

lookupByClass has two argument like lookupByClass(class, parent_dn)

class is the name of the class to be searched for.

parent_dn is the distinguish name of the parent object.

But the parent name doesn’t have to be the direct parent of the target class.

 

By specifying the parent dn, you can get the management objects related to specific dn.

In this case, I specify the node dn like topology/pod-1/node-101. Each management object includes its own dn. Based on that dn, by searching for children classes, you can retrieve information under the specific class.

In this example, two type of management objects are gotten. One is an instance of "l1PhysIf" class and another is an instance of "ethpmPhysIf". The reason why these two objects are needed in this case is that "l1PhysIf" class has the administrative status and "ethpmPhysIf" has the operational status.

 

#!/usr/bin/env python
#
# Written by Mike Timm @ cisco System, March 2014
# Revised by Toru Okatsu @ Cisco Systems, June 11th 2014


# list of packages that should be imported for this code to work
import re
import cobra.mit.access
import cobra.mit.session

APIC = <Your APIC IP address in string>
USER = <username of APIC admin>
PASS = <password of APIC admin>

# get an interface name and an index 
# the index is slot_id * 200 + port_id
# assume one slot has no more than 200 ports
def getIfName(intf):
    # phy interface name is like phys-[eth1/98]
    name = None
    idx = None

    match = re.search('\[(eth\d+/\d+)\]', str(intf.dn))
    if match:
        name = match.group(1)
        match = re.search('(\d+)/(\d+)', name)
        if match:
            idx = 200*int(match.group(1)) + int(match.group(2))

    return name, idx 

########
# Main #
########

# log into an APIC and create a directory object

url = "https://" + APIC
ls = cobra.mit.session.LoginSession(url, USER, PASS, secure=False, timeout=180) 
md = cobra.mit.access.MoDirectory(ls)
md.login()

# Get the list of pods

pods = md.lookupByClass("fabricPod", parentDn='topology')
for mo in pods:
    print "name = {}".format(mo.rn)

for pod in pods:

    # Get nodes under one pod
    dn = pod.dn
    nodes = md.lookupByClass("fabricNode", parentDn=dn)
    for node in nodes:
        print "Node: {:10s} Name: {:10s} Role: {:10s}".format(node.rn, node.name, node.role)

    for node in nodes:
        # Skip APICs and unsupported switches
        if node.role == 'controller' or node.fabricSt != 'active':
             continue

        print "\nNode Name: " + node.name

        # l1PhysIf has the name of interface and admin status
        # ethpmPhysIf has the operation status
        dn = str(node.dn) + '/sys'
        intfs = md.lookupByClass("l1PhysIf", parentDn=dn) 
        pmifs = md.lookupByClass("ethpmPhysIf", parentDn=dn)

        iftable = {}
        for intf in intfs:
            name, idx = getIfName(intf)
            if name and idx:
                iftable[idx] = [name, intf.adminSt, "Unknown"]
        for intf in pmifs:
            name, idx = getIfName(intf)
            if name and idx:
                list = iftable[idx]
                list[2] = intf.operSt
                iftable[idx] = list

        # print the interface status
        for idx, list in sorted(iftable.items()):
            print list[0], list[1], list[2]

 

4. Use query() method

The second example is to use query() method in cobra.mit.access.MoDirectory.

lookupByClass has one argument like lookupByClass(queryObject)

queryObject is an object to store multiple query parameters.

The queryObject is an instance of cobra.mit.request.ClassQuery class.

By setting multiple query parameters, you can make the query() method to do more complicated search.

 

In the previous example lookupByClass() is called twice to get two different objects.

One is "l1PhysIf" and another is "ethpmPhysIf".

They are a parent and a child objects.

APIC REST API has a feature to get children or subtree of an object.

query() method support this type of query.

 

The below is the replace of the blue part of the first example.

md.query() gets both "l1PhysIf" and "ethpmPhysIf" at one call.

It makes the code more simple.

 

        # l1PhysIf has the name of interface and admin status
        # ethpmPhysIf has the operation status
        dn = str(node.dn) + '/l1PhysIf'
        q = cobra.mit.request.ClassQuery(dn)
        q.subtree = 'children'
        q.subClassFilter = 'ethpmPhysIf'
        intfs = md.query(q)

        iftable = {}
        for intf in intfs:
            name, idx = getIfName(intf)
            if name and idx:
                for child in intf.children:
                    if child.rn == 'phys':
                        iftable[idx] = [name, intf.adminSt, child.operSt]

        # print the interface status
        for idx, list in sorted(iftable.items()):
            print list[0], list[1], list[2]

 

5. Sample output

This is the sample of the output by this example code.

(sdk483)[tokatsu@localhost sdk483]$ python get_if_status.py
name = pod-1
Node: node-103   Name: spine-1    Role: spine     
Node: node-101   Name: leaf-1     Role: leaf      
Node: node-104   Name: spine-2    Role: spine     
Node: node-1     Name: apic1      Role: controller
Node: node-102   Name: leaf-2     Role: leaf      

Node Name: spine-1
eth1/1 up up
eth1/2 up down
eth1/3 up up
eth1/4 up down
eth1/5 up down
eth1/6 up down
eth1/7 up down
eth1/8 up down
  :
  :

 

 

 

Comments
taoli
Cisco Employee
Cisco Employee

Good.

Brian Tilburgs
Level 1
Level 1

This is a great help for me! thanks.

One extra thing I'd like to do is find all objects with a specific "Tag". does anybody know how to do that?

Thanks,

Brian

gmonroy
Cisco Employee
Cisco Employee

Brian,

Once tags have been set, you can find all objects that has that tag with the following GET. Note that the example is searching for all objects with the tag 'tenants':

GET https://192.0.20.123/api/tag/tenants.xml

RESPONSE:
<imdata>
    <fvTenant
        dn="uni/tn-ExampleCorp" 
        name="ExampleCorp"
    />
</imdata>

Please note this was pulled from the APIC RESTful API User Guide

Cheers,

Gabriel

Leon
Level 1
Level 1

when running the second part of the code ( query for interface status ) , I received the following error.. any ideas ?

Traceback (most recent call last):
File "get_if_status.py", line 64, in <module>
intfs = md.query(q)

< output omitted >
KeyError: 'FECMode'

Robert Correiro
Level 1
Level 1

Hi Leon,

Can you please confirm the version of Cobra SDK you're running (version of the eggs) and the version of the ACI fabric you're running script against?

I believe the KeyError issue is due to a mismatch between the versions, where the API has changed.

Hope this helps.

Leon
Level 1
Level 1

Thanks for the reply Robert, I do actually have version mismatched between the eggs and APIC. I will update it and report back.

Leon

Leon
Level 1
Level 1

updating the egg version worked. Thanks!

Thanks for the example, only discovered it now.

Unfortunately I don't quite understand the second part. It works, but I don't know why.

dn = str(node.dn) + '/l1PhysIf'
q = cobra.mit.request.ClassQuery(dn)

ClassQuery expects a class name. l1PhysIf is a class name, but it is concatenated with the DN of the node. Can someone shed some light? What am I missing?

Thanks

lsalati
Level 1
Level 1

Hello,

this piece of code is very useful. But can you advise how to modified it if there are FEX connected to the leafs?

 

Kind Regards,

Luca

Getting Started

Find answers to your questions by entering keywords or phrases in the Search bar above. New here? Use these resources to familiarize yourself with the community: