Curious as to how you can easily dump data on an APIC from the Object Store or API using Python?
This answer was provided to by Mike Timm:
The APIC used to have a quickly thrown together object dumper known as dekhore, however this seems to have been removed. I have attached the original dekhore script with some path mangling lines commented out so it can run as is if you just upload it to an APIC, but this is not ideal. Another way to dump data from the object store using python on the APIC is to do it manually using what we call pysdk directly. What follows are some examples.
I will be showing the interactive shell but you can just as easily write a python script to do this. A python script would need the standard hashbang or would need to be run as python /path/to/script/script.py. The standard hashbang would look like this:
Also the scripts permissions would need to be changed via the command:
chmod +x /path/to/script/script.py
One other oddity that we discovered recently is that scripts saved in /bootflash are not allowed to be executed. So the script will need to be saved outside of /bootflash. The users home directory or a subdirectory of their homedirectory is probably fine.
To get into the interactive python shell you simply type python at the iBash prompt:
Python 2.6.6 (r266:84292, Sep 11 2012, 08:34:23)
[GCC 4.4.6 20120305 (Red Hat 4.4.6-4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
The easiest way to utilize pysdk is to import what is known as the FsCmdContext and then get a Managed Object Directory from it. Since we are on an APIC already, this will utilize the CLI to traverse the MIT directory and do lookups of Dn's and classes via Python. This can be done in a script or via the interactive Python shell as long as it is done on the APIC itself. Here I show how to do this in the interactive Python shell only but the same concept applies to an on APIC script:
>>> from insieme.cli.executor import FsCmdContext
>>> ctx = FsCmdContext()
>>> moDir = ctx.getMoDirectory()
The MoDirectory object has many methods that can be seen if you execute a help(moDir) at this point.
| Methods defined here:
| __init__(self, **kwargs)
| commit(self, mo, reloadMo=True, **options)
| create(self, className, parentMoOrDn=None, **creationProps)
| createExplicitRelation(self, relClassName, srcMoOrDn, targetMoOrDn)
| createNamedRelation(self, relClassName, srcMoOrDn, **creationProps)
| endSubscription(self, subId, **options)
| exists(self, dn, **options)
| fetchChildren(self, parentMo, childClass=None, pfilter=None, **options)
| fetchRelations(self, parentMo, pfilter=None, **options)
| lookupByClass(self, className, parentDn=None, pfilter=None, **options)
| lookupByDn(self, dn, **options)
| lookupFaults(self, dn, pfilter=None, **options)
| lookupHealths(self, dn, pfilter=None, **options)
| lookupRecord(self, recType, affectedDn, id, **options)
| lookupRecords(self, recType, affectedDn, pfilter=None, **options)
| lookupStats(self, dn, className, filterObj=None, **options)
| lookupUrl(self, url, **options)
| setFaultAck(self, dn, code, ack, **options)
| subscribeToDn(self, dn, callback, **options)
| Data descriptors defined here:
| dictionary for instance variables (if defined)
| list of weak references to the object (if defined)
[These are going off the top of my head and have not been verified]
Here is an example of doing a lookupByClass, note how just looking at an object it is printed and formatted pretty nicely for you.
>>> faultInst = moDir.lookupByClass('faultInst')
ack : no
cause : inoperable
changeSet : operState (Old: operable, New: inoperable)
code : F0023
created : 2014-08-05T08:33:18.092-07:00
descr : Provider inoperable
dn : topology/pod-1/node-1/local/svc-extXMLApi-id-255/uni/userext/tacacsext/tacacsplusprovider-172.23.96.196/fault-F0023
domain : security
highestSeverity : minor
lastTransition : 2014-08-05T08:35:41.703-07:00
lc : raised
modTs : 0
occur : 1
origSeverity : minor
prevSeverity : minor
rn : fault-F0023
rule : aaa-tacacs-plus-provider-tacacs-plus-provider-inoperable
severity : minor
subject : security-provider
type : operational
Another thing about the class query is that you get a list.
You can also query by a specific Dn and again the result is printed nicely (but you don't get a list).
>>> uni = moDir.lookupByDn('uni')
dn : uni
lcOwn : local
modTs : 2014-08-03T16:43:28.164-07:00
monPolDn : uni/fabric/monfab-default
rn : uni
uid : 0
Retrieving data ...