A Python C Extension package to query SNMP tables and table subsets based on the Net-SNMP libraries.
The project aims to bring SNMP table query functionality for Python.
The API is currently not yet stable. Implementation works and is tested on following targets
IMO it would be good to eventually integrate the table functions into a more complete, all-in-one Python SNMP Client package. If you are the maintainer of such a package and like the idea, please let me know.
I currently do monkey patching of the original Net-SNMP Python Bindings to fake that integration, but are looking forward for better options.
Prerequisites:
Download and extract the source package, then
~/netsnmptable$ python setup.py build
~/netsnmptable$ sudo python setup.py install
This software is released under the LGPLv3 license.
Some re-used code is copyrighted. See the LICENSE file for full license text and the original copyright notices.
Here are some examples how to use netsnmptable.
import netsnmp
import netsnmptable
# create a table object
session = netsnmp.Session(Version=2, DestHost='localhost', Community='public')
table = session.table_from_mib('HOST-RESOURCES-MIB::hrStorageTable')
# go and get the table...
tbldict = table.get_entries()
if (netsnmp_session.ErrorNum):
print("Can't query HOST-RESOURCES-MIB:hrStorageTable.")
exit(-1)
print("{:10s} {:25s} {:10s} {:10s} {:10s}".format("Index", "Description", "Units", "Size", "Used"))
row_keys = sorted(list(tbldict.keys()))
for row_key in row_keys:
row = tbldict[row_key]
cell_list = [element.val if element else "" for element in
[row.get('hrStorageIndex'), row.get('hrStorageDescr'),
row.get('hrStorageAllocationUnits'), row.get('hrStorageSize'),
row.get('hrStorageUsed')]]
print("{:10s} {:25s} {:10s} {:10s} {:10s}".format(*cell_list))
Results in
Index Description Units Size Used
1 Physical memory 1024 2054128 233540
3 Virtual memory 1024 3099628 361064
6 Memory buffers 1024 2054128 14564
7 Cached memory 1024 82232 82232
8 Shared memory 1024 0
10 Swap space 1024 1045500 127524
31 /dev 4096 2560 0
32 / 4096 10063200 2495552
33 /sys/fs/fuse/connections 4096 0 0
34 /run/vmblock-fuse 512 0 0
35 /media/sources 4096 121833215 92355036
36 /media/sandboxes 4096 121833215 92355036
37 /media/cdrom0 2048 32876 32876
Tables with more than one index are no problem. The row key tuple just gets more elements.
Let's setup following table in snmpd.conf:
table MYTABLETEST::testTable
# idx1 idx2 aValue anotherValue
add_row MYTABLETEST::testTable "OuterIdx_1" "InnerIdx_1" 1 2
add_row MYTABLETEST::testTable "OuterIdx_1" "InnerIdx_2" 3 4
add_row MYTABLETEST::testTable "OuterIdx_2" "InnerIdx_1" 5 6
add_row MYTABLETEST::testTable "OuterIdx_2" "InnerIdx_2" 7 8
add_row MYTABLETEST::testTable "OuterIdx_3" "InnerIdx_1" 9 10
add_row MYTABLETEST::testTable "OuterIdx_3" "InnerIdx_2" 11 12
Now query it with
import netsnmp
import netsnmptable
import pprint
from types import MethodType
def varbind_to_repr(self):
return self.type + ":" + self.val
netsnmp.Varbind.__repr__ = MethodType(varbind_to_repr, None, netsnmp.Varbind)
session = netsnmp.Session(Version=2, DestHost='localhost', Community='public')
table = session.table_from_mib('MYTABLETEST::testTable')
tbldict = table.get_entries()
pprint.pprint(tbldict)
This gives
{('OuterIdx_1', 'InnerIdx_1'): {'aValue': INTEGER32:1,
'anotherValue': INTEGER32:2},
('OuterIdx_1', 'InnerIdx_2'): {'aValue': INTEGER32:3,
'anotherValue': INTEGER32:4},
('OuterIdx_2', 'InnerIdx_1'): {'aValue': INTEGER32:5,
'anotherValue': INTEGER32:6},
('OuterIdx_2', 'InnerIdx_2'): {'aValue': INTEGER32:7,
'anotherValue': INTEGER32:8},
('OuterIdx_3', 'InnerIdx_1'): {'aValue': INTEGER32:9,
'anotherValue': INTEGER32:10},
('OuterIdx_3', 'InnerIdx_2'): {'aValue': INTEGER32:11,
'anotherValue': INTEGER32:12}}
Say we want to fetch from the same table, but only entries for "OuterIdx_2".
session = netsnmp.Session(Version=2, DestHost='localhost', Community='public')
table = session.table_from_mib('MYTABLETEST::testTable')
tbldict = table.get_entries(iid = netsnmptable.str_to_varlen_iid("OuterIdx_2"))
pprint.pprint(tbldict)
Results in
{('OuterIdx_2', 'InnerIdx_1'): {'aValue': INTEGER32:5,
'anotherValue': INTEGER32:6},
('OuterIdx_2', 'InnerIdx_2'): {'aValue': INTEGER32:7,
'anotherValue': INTEGER32:8}}
Thanks to Pieter Hollants pieter@hollants.com for python-netsnmpagent. The tests.testagent package is heavily based on it.
Other people also tackle the hassle of dealing with SNMP in Python and found interesting approaches. Below is an incomplete and unordered list.