PySNMP form dictionary from table

818 views Asked by At

I am trying to output the ifTbale table from a Cisco switch using the PySNMP module.

Here is my current code:

from pysnmp.hlapi import *

for (errorIndication,
     errorStatus,
     errorIndex,
     values) in nextCmd(SnmpEngine(),
                          CommunityData('public', mpModel=0),
                          UdpTransportTarget(('172.20.19.14', 161)),
                          ContextData(),
                          ObjectType(ObjectIdentity('IF-MIB', 'ifIndex')),
                          ObjectType(ObjectIdentity('IF-MIB', 'ifDescr')),
                          ObjectType(ObjectIdentity('IF-MIB', 'ifType')),
                          ObjectType(ObjectIdentity('IF-MIB', 'ifSpeed')),
                          lexicographicMode=False):

    print('======================')

    for v in values:
        print(str(v))

So this works, as it outputs following:

======================
IF-MIB::ifIndex.10028 = 10028
IF-MIB::ifDescr.10028 = FastEthernet0/28
IF-MIB::ifType.10028 = 'ethernetCsmacd'
IF-MIB::ifSpeed.10028 = 100000000
======================
IF-MIB::ifIndex.10029 = 10029
IF-MIB::ifDescr.10029 = FastEthernet0/29
IF-MIB::ifType.10029 = 'ethernetCsmacd'
IF-MIB::ifSpeed.10029 = 100000000
======================
IF-MIB::ifIndex.10030 = 10030
IF-MIB::ifDescr.10030 = FastEthernet0/30
IF-MIB::ifType.10030 = 'ethernetCsmacd'
IF-MIB::ifSpeed.10030 = 10000000
...

I would like to eventually change this into a function, but at the moment I am wondering how I can get this into a nested dictionary.

I would like the data in the following format: {ifIndex{ifDescr, ifType, ifSpeed}}

which would look like this: {10028{ifDescr: 'FastEthernet0/28', ifType: 'ethernetCsmacd', ifSpeed: '100000000'}}

I am unsure how to tackle this problem though, as I am unable to build the dictionary.

EDIT: I have managed to get a dictionary with the following code:

print('======================')
raw_dict = {str(v).split('.')[0].split(':')[2]: str(v).split('.')[1].split()[2] for v in values}
print(raw_dict.items())
if_dict = {raw_dict['ifIndex']: {k: v} for k, v in raw_dict.items()}
print(if_dict)

But it is not iterating through all the values in raw_dict.

This is the output:

======================
dict_items([('ifSpeed', '100000000'), ('ifIndex', '10048'), ('ifDescr', 'FastEthernet0/48'), ('ifType', "'ethernetCsmacd'")])
{'10048': {'ifType': "'ethernetCsmacd'"}}
======================
dict_items([('ifSpeed', '1000000000'), ('ifIndex', '10101'), ('ifDescr', 'GigabitEthernet0/1'), ('ifType', "'ethernetCsmacd'")])
{'10101': {'ifType': "'ethernetCsmacd'"}}
======================
dict_items([('ifSpeed', '1000000000'), ('ifIndex', '10102'), ('ifDescr', 'GigabitEthernet0/2'), ('ifType', "'ethernetCsmacd'")])
{'10102': {'ifType': "'ethernetCsmacd'"}}
======================
dict_items([('ifSpeed', '4294967295'), ('ifIndex', '10501'), ('ifDescr', 'Null0'), ('ifType', "'other'")])
{'10501': {'ifType': "'other'"}}
1

There are 1 answers

0
Ilya Etingof On BEST ANSWER

So you want to build a dict like this:

{10028: {ifDescr: 'FastEthernet0/28',
         ifType: 'ethernetCsmacd',
         ifSpeed: '100000000'}}

For that you need MIB object name (e.g. ifDescr), MIB object instance ID (e.g. 10028) and SNMP object value (e.g. FastEthernet0/28). Let me propose the following code to weed out these components from SNMP response var-bindings:

myDict = collections.defaultdict(collections.defaultdict)

for varBind in varBinds:
    varName, varValue = varName
    mibName, objectName, objectInstanceId = varName.getMibSymbol()

    idx = '.'.join([str(indexPart) for indexPart in objectInstanceId])

    myDict[idx][objectName] = varValue

Keep in mind that the code above implies that PySNMP has MIB(s) for response OIDs loaded so it could turn response OIDs into symbolic values like ifDescr.

I'm not sure what do you mean by "not iterating through all the values".