/
snmp_session.py
123 lines (113 loc) · 4.1 KB
/
snmp_session.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# This file is part of opentsdb-snmp.
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at your
# option) any later version. This program is distributed in the hope that it
# will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
# General Public License for more details. You should have received a copy
# of the GNU Lesser General Public License along with this program. If not,
# see <http://www.gnu.org/licenses/>.
from netsnmp import Session, Varbind, VarList
from socket import gethostbyname
import logging
class SNMPSession:
def __init__(self, host, community,
version=2, timeout=2000000,
retries=0, max_repetitions=49):
self.session = None
self.host = host
self.community = community
self.version = version
self.timeout = timeout
self.retries = retries
self.max_rep = max_repetitions
def connect(self):
#resolve hostname
try:
ip = gethostbyname(self.host)
except:
self.session = None
return None
self.session = Session(
DestHost=ip,
Community=self.community,
Version=self.version,
UseNumeric=1,
Timeout=self.timeout,
Retries=self.retries,
)
def walk(self, oid, stripoid=True, expect_str=False):
vb = Varbind(oid)
vl = VarList(vb)
self.session.walk(vl)
ret = {}
for v in vl:
if v.tag is None:
continue
full_oid = v.tag
(full_oid, val) = handle_vb(v, expect_str)
if stripoid:
full_oid = full_oid.replace(oid + ".", '')
ret[full_oid] = val
return ret
def bulkwalk(self, oid,
stripoid=True, startidx=None,
endidx=None, expect_str=False):
ret = {}
if oid[0] != ".":
oid = "." + oid
startindexpos = startidx
runningtreename = oid
stop = False
while (runningtreename.startswith(oid) and stop is False):
vrs = VarList(Varbind(runningtreename, startindexpos))
result = self.session.getbulk(0, self.max_rep, vrs)
if self.session.ErrorInd:
logging.warn(
"walk failed on: {0} ({1})".format(
self.host, self.session.ErrorStr
)
)
key = None
if not result:
logging.warn("got no result: %s %s", self.host, oid)
break
""" Print output from running getbulk"""
for i in vrs:
if endidx and int(i.iid) > int(endidx):
stop = True
break
if not i.tag.startswith(oid):
break
(full_oid, val) = handle_vb(i, expect_str)
key = full_oid.replace(oid + ".", "")
if stripoid:
ret[key] = val
else:
ret[full_oid] = val
""" Set startindexpos for next getbulk """
if not vrs[-1].iid or not key or stop:
break
startindexpos = vrs[-1].iid
""" Refresh runningtreename from last result"""
runningtreename = vrs[-1].tag
return ret
def get(self, oid):
return self.session.get(oid)[0]
def handle_vb(vb, expect_str):
if vb.iid or vb.iid == 0:
full_oid = vb.tag + "." + vb.iid
else:
full_oid = vb.tag
if vb.type == "OCTETSTR" and not expect_str:
if vb.val == "**" or vb.val.find("###") >= 0:
return (full_oid, None)
try:
val = float(vb.val)
return (full_oid, val)
except ValueError:
return (full_oid, int(vb.val.encode("hex"), 16))
else:
return (full_oid, vb.val)