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'"}}
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".