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

Source Code for Module Products.ZenUtils.snmp

  1  ############################################################################## 
  2  #  
  3  # Copyright (C) Zenoss, Inc. 2010, all rights reserved. 
  4  #  
  5  # This content is made available according to terms specified in 
  6  # License.zenoss under the directory where your Zenoss product is installed. 
  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") 
17 18 -class SnmpConfig(object):
19 succeeded = None 20 sysName = None 21 22 @property
23 - def port(self):
24 return self._port
25 26 @property
27 - def community(self):
28 return self._community
29 30 @property
31 - def weight(self):
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'):
37 self._ip = ip 38 self._weight = weight 39 self._port = port 40 self._timeout = timeout 41 self._retries = retries 42 self._community = community
43 44
45 - def __str__(self):
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
51 - def getAgentProxy(self):
52 return AgentProxy( 53 ip=self._ip, 54 port=self._port, 55 timeout=self._timeout, 56 tries=self._retries, 57 snmpVersion=self.version, 58 community=self._community)
59 60
61 - def test(self, oid='.1.3.6.1.2.1.1.5.0'):
62 _LOG.debug("SnmpConfig.test: oid=%s" % oid) 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 _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 """
229 - def printAndExit(result):
230 print result 231 reactor.stop()
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