1
2
3
4
5
6
7
8
9
10
11 import logging
12 from twisted.internet import reactor
13 from twisted.internet.defer import Deferred
14 from pynetsnmp.twistedsnmp import AgentProxy
15
16 _LOG = logging.getLogger("zen.ZenUtils.snmp")
19 succeeded = None
20 sysName = None
21
22 @property
25
26 @property
28 return self._community
29
30 @property
32 return self._weight is None and self.defaultWeight or self._weight
33
34
35 - def __init__(self, ip, weight=None, port=161, timeout=2.5, retries=2,
36 community='public'):
43
44
46 return "(%s) %s:%s, SNMP%s, timeout=%ss, retries=%s, community=%s" % (
47 self.weight, self._ip, self._port, self.version, self._timeout,
48 self._retries, self.community)
49
50
59
60
61 - def test(self, oid='.1.3.6.1.2.1.1.5.0'):
66
67
79
84
89
92 version = 'v3'
93 defaultWeight = 30
94
95 - def __init__(self, ip, weight=None, port=161, timeout=2.5, retries=2,
96 community='public', securityName=None, authType=None,
97 authPassphrase=None, privType=None, privPassphrase=None):
98 super(SnmpV3Config, self).__init__(
99 ip, weight, port, timeout, retries, community)
100
101 self._securityName = securityName
102 self._authType = authType
103 self._authPassphrase = authPassphrase
104 self._privType = privType
105 self._privPassphrase = privPassphrase
106
107
109 v3string = "securityName=%s" % self._securityName
110 if self._authType:
111 v3string += ", authType=%s, authPassphrase=%s" % (
112 self._authType, self._authPassphrase)
113
114 if self._privType:
115 v3string += " privType=%s, privPassphrase=%s" % (
116 self._privType, self._privPassphrase)
117
118 return "(%s) %s:%s, SNMP%s, timeout=%ss, retries=%s, %s" % (
119 self.weight, self._ip, self._port, self.version, self._timeout,
120 self._retries, v3string)
121
122
124 cmdLineArgs = ['-u', self._securityName]
125
126 if self._privType:
127 cmdLineArgs += [
128 '-l', 'authPriv',
129 '-x', self._privType,
130 '-X', self._privPassphrase]
131 elif self._authType:
132 cmdLineArgs += [
133 '-l', 'authNoPriv']
134 else:
135 cmdLineArgs += [
136 '-l', 'noAuthNoPriv']
137
138 if self._authType:
139 cmdLineArgs += [
140 '-a', self._authType,
141 '-A', self._authPassphrase]
142
143 return AgentProxy(
144 ip=self._ip,
145 port=self._port,
146 timeout=self._timeout,
147 tries=self._retries,
148 snmpVersion=self.version,
149 community=self._community,
150 cmdLineArgs=cmdLineArgs)
151
152
164
165
166 -class SnmpAgentDiscoverer(object):
167 _bestsofar = None
168
169 - def _handleResult(self, result):
170 if not hasattr(result, 'weight'):
171
172 return
173
174 for i, p in enumerate(self._pending):
175 if p.weight == result.weight:
176 self._pending.pop(i)
177
178 if result.succeeded:
179
180 if self._bestsofar:
181 if result.weight > self._bestsofar.weight:
182 self._bestsofar = result
183 else:
184 self._bestsofar = result
185
186
187
188 for config in self._pending:
189 if config.weight >= self._bestsofar.weight:
190 break
191 else:
192 if not self._d.called:
193 self._d.callback(self._bestsofar)
194
195 return
196
197
198
199 if len(self._pending) < 1 and not self._d.called:
200 self._d.callback(self._bestsofar)
201
202
203 - def findBestConfig(self, configs):
204 """
205 Returns the best SnmpConfig in the provided configs list.
206 """
207 _LOG.debug("findBestConfig: configs=%s" % configs)
208 self._pending = configs
209 self._d = Deferred()
210
211 for c in configs:
212 c.test().addBoth(self._handleResult)
213
214 return self._d
215
216
217 if __name__ == '__main__':
218 """
219 The following snmpd.conf is a good one to run the following tests on.
220
221 rocommunity zenosszenoss
222 rouser noauthtest noauth
223 createUser noauthtest MD5 "zenosszenoss"
224 rouser authtest
225 createUser authtest SHA "zenosszenoss"
226 rouser privtest
227 createUser privtest SHA "zenosszenoss" DES "zenosszenoss"
228 """
232
233 configs = [
234 SnmpV3Config('127.0.0.1', weight=33, securityName='privtest',
235 authType='SHA', authPassphrase='zenosszenoss',
236 privType='DES', privPassphrase='zenosszenoss'),
237
238 SnmpV3Config('127.0.0.1', weight=32, securityName='authtest',
239 authType='SHA', authPassphrase='zenosszenoss'),
240
241 SnmpV3Config('127.0.0.1', weight=31, securityName='noauthtest'),
242
243 SnmpV2cConfig('127.0.0.1', weight=22, community='zenosszenoss'),
244 SnmpV2cConfig('127.0.0.1', weight=21, community='public'),
245
246 SnmpV1Config('127.0.0.1', weight=12, community='zenosszenoss'),
247 SnmpV1Config('127.0.0.1', weight=11, community='public'),
248 ]
249
250 sad = SnmpAgentDiscoverer()
251 sad.findBestConfig(configs).addBoth(printAndExit)
252 reactor.run()
253