Package Products :: Package ZenUtils :: Module snmp
[hide private]
[frames] | no frames]

Source Code for Module Products.ZenUtils.snmp

  1  ########################################################################### 
  2  # 
  3  # This program is part of Zenoss Core, an open source monitoring platform. 
  4  # Copyright (C) 2010, Zenoss Inc. 
  5  # 
  6  # This program is free software; you can redistribute it and/or modify it 
  7  # under the terms of the GNU General Public License version 2 as published by 
  8  # the Free Software Foundation. 
  9  # 
 10  # For complete information please visit: http://www.zenoss.com/oss/ 
 11  # 
 12  ########################################################################### 
 13   
 14  from twisted.internet import reactor 
 15  from twisted.internet.defer import Deferred 
 16  from pynetsnmp.twistedsnmp import AgentProxy 
17 18 19 -class SnmpConfig(object):
20 succeeded = None 21 sysName = None 22 23 @property
24 - def port(self):
25 return self._port
26 27 @property
28 - def community(self):
29 return self._community
30 31 @property
32 - def weight(self):
33 return self._weight is None and self.defaultWeight or self._weight
34 35
36 - def __init__(self, ip, weight=None, port=161, timeout=2.5, retries=2, 37 community='public'):
38 self._ip = ip 39 self._weight = weight 40 self._port = port 41 self._timeout = timeout 42 self._retries = retries 43 self._community = community
44 45
46 - def __str__(self):
47 return "(%s) %s:%s, SNMP%s, timeout=%ss, retries=%s, community=%s" % ( 48 self.weight, self._ip, self._port, self.version, self._timeout, 49 self._retries, self.community)
50 51
52 - def getAgentProxy(self):
53 return AgentProxy( 54 ip=self._ip, 55 port=self._port, 56 timeout=self._timeout, 57 tries=self._retries, 58 snmpVersion=self.version, 59 community=self._community)
60 61
62 - def test(self, oid='.1.3.6.1.2.1.1.5.0'):
63 self._proxy = self.getAgentProxy() 64 self._proxy.open() 65 return self._proxy.get([oid]).addBoth(self.enrichResult)
66 67
68 - def enrichResult(self, result):
69 self._proxy.close() 70 if isinstance(result, dict) and bool(result): 71 # one and only one key/value pair _should_ be available in result, 72 # and we only need the value (the device name) 73 self.sysName = result.values()[0] 74 self.succeeded = True 75 else: 76 self.succeeded = False 77 78 return self
79
80 81 -class SnmpV1Config(SnmpConfig):
82 version = 'v1' 83 defaultWeight = 10
84
85 86 -class SnmpV2cConfig(SnmpConfig):
87 version = 'v2c' 88 defaultWeight = 20
89
90 91 -class SnmpV3Config(SnmpConfig):
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
108 - def __str__(self):
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
123 - def getAgentProxy(self):
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
153 - def enrichResult(self, result):
154 self._proxy.close() 155 if isinstance(result, dict) \ 156 and len(result.keys()) > 0 \ 157 and not result.keys()[0].startswith('.1.3.6.1.6.3.15.1.1.'): 158 self.sysName = result.values()[0] 159 self.succeeded = True 160 else: 161 self.succeeded = False 162 163 return self
164
165 166 -class SnmpAgentDiscoverer(object):
167 _bestsofar = None 168
169 - def _handleResult(self, result):
170 if not hasattr(result, 'weight'): 171 # http://dev.zenoss.org/trac/ticket/6268 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 # Record this result as the best so far. 180 if self._bestsofar: 181 if result.weight > self._bestsofar.weight: 182 self._bestsofar = result 183 else: 184 self._bestsofar = result 185 186 # Short-circuit the rest of the tests if this result's weight is 187 # higher than any still pending. 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 # We got responses to all of our queries without being able to short- 198 # circuit the test. Return the best match or none. 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 self._pending = configs 208 self._d = Deferred() 209 210 for c in configs: 211 c.test().addBoth(self._handleResult) 212 213 return self._d
214 215 216 if __name__ == '__main__': 217 """ 218 The following snmpd.conf is a good one to run the following tests on. 219 220 rocommunity zenosszenoss 221 rouser noauthtest noauth 222 createUser noauthtest MD5 "zenosszenoss" 223 rouser authtest 224 createUser authtest SHA "zenosszenoss" 225 rouser privtest 226 createUser privtest SHA "zenosszenoss" DES "zenosszenoss" 227 """
228 - def printAndExit(result):
229 print result 230 reactor.stop()
231 232 configs = [ 233 SnmpV3Config('127.0.0.1', weight=33, securityName='privtest', 234 authType='SHA', authPassphrase='zenosszenoss', 235 privType='DES', privPassphrase='zenosszenoss'), 236 237 SnmpV3Config('127.0.0.1', weight=32, securityName='authtest', 238 authType='SHA', authPassphrase='zenosszenoss'), 239 240 SnmpV3Config('127.0.0.1', weight=31, securityName='noauthtest'), 241 242 SnmpV2cConfig('127.0.0.1', weight=22, community='zenosszenoss'), 243 SnmpV2cConfig('127.0.0.1', weight=21, community='public'), 244 245 SnmpV1Config('127.0.0.1', weight=12, community='zenosszenoss'), 246 SnmpV1Config('127.0.0.1', weight=11, community='public'), 247 ] 248 249 sad = SnmpAgentDiscoverer() 250 sad.findBestConfig(configs).addBoth(printAndExit) 251 reactor.run() 252