Package DataCollector :: Module SnmpClient
[hide private]
[frames] | no frames]

Source Code for Module DataCollector.SnmpClient

  1  ########################################################################### 
  2  # 
  3  # This program is part of Zenoss Core, an open source monitoring platform. 
  4  # Copyright (C) 2007, 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  import sys 
 15  import logging 
 16  log = logging.getLogger("zen.SnmpClient") 
 17   
 18  from twisted.internet import reactor, error, defer 
 19  from twisted.python import failure 
 20  from twisted.internet.error import TimeoutError 
 21   
 22  from pynetsnmp.twistedsnmp import snmpprotocol 
 23   
 24  import Globals 
 25   
 26  from Products.ZenUtils.Driver import drive 
 27   
 28  global defaultTries, defaultTimeout 
 29  defaultTries = 2 
 30  defaultTimeout = 1 
 31  defaultSnmpCommunity = 'public' 
 32   
 33  DEFAULT_MAX_OIDS_BACK = 40 
 34   
 35  from BaseClient import BaseClient 
 36   
37 -class SnmpClient(BaseClient):
38
39 - def __init__(self, hostname, ipaddr, options=None, device=None, 40 datacollector=None, plugins=[]):
41 BaseClient.__init__(self, device, datacollector) 42 global defaultTries, defaultTimeout 43 self.hostname = hostname 44 self.device = device 45 self.options = options 46 self.datacollector = datacollector 47 self.plugins = plugins 48 49 self._getdata = {} 50 self._tabledata = {} 51 52 from Products.ZenHub.services.PerformanceConfig import SnmpConnInfo 53 self.connInfo = SnmpConnInfo(device) 54 srcport = snmpprotocol.port() 55 self.proxy = self.connInfo.createSession(srcport.protocol)
56 57
58 - def run(self):
59 """Start snmp collection. 60 """ 61 log.debug("Starting %s", self.connInfo.summary()) 62 self.proxy.open() 63 drive(self.doRun).addBoth(self.clientFinished)
64 65 66 # FIXME: cleanup --force option #2660
67 - def checkCiscoChange(self, driver):
68 """Check to see if a cisco box has changed. 69 """ 70 device = self.device 71 yield self.proxy.get(['.1.3.6.1.4.1.9.9.43.1.1.1.0']) 72 lastpolluptime = device.getLastPollSnmpUpTime() 73 log.debug("lastpolluptime = %s", lastpolluptime) 74 result = True 75 try: 76 lastchange = driver.next().values()[0] 77 log.debug("lastchange = %s", lastchange) 78 if lastchange <= lastpolluptime: 79 log.info("skipping cisco device %s no change detected", 80 device.id) 81 result = False 82 else: 83 device.setLastPollSnmpUpTime(lastchange) 84 except Exception: 85 pass 86 yield defer.succeed(result)
87 88
89 - def doRun(self, driver):
90 # test snmp connectivity 91 log.debug("Testing SNMP configuration") 92 yield self.proxy.walk('.1.3') 93 try: 94 driver.next() 95 except TimeoutError, ex: 96 log.info("Device timed out: " + self.connInfo.summary()) 97 return 98 except Exception, ex: 99 log.exception("Unable to talk: " + self.connInfo.summary()) 100 return 101 102 changed = True 103 # FIXME: cleanup --force option #2660 104 if not self.options.force and self.device.snmpOid.startswith(".1.3.6.1.4.1.9"): 105 yield drive(self.checkCiscoChange) 106 changed = driver.next() 107 if changed: 108 yield drive(self.collect)
109 110
111 - def collect(self, driver):
112 for plugin in self.plugins: 113 try: 114 log.debug('running %s', plugin) 115 pname = plugin.name() 116 self._tabledata[pname] = {} 117 log.debug("sending queries for plugin %s", pname) 118 if plugin.snmpGetMap: 119 yield self.proxy.get(plugin.snmpGetMap.getoids()) 120 self._getdata[pname] = driver.next() 121 for tmap in plugin.snmpGetTableMaps: 122 rowSize = len(tmap.getoids()) 123 maxRepetitions = max(DEFAULT_MAX_OIDS_BACK / rowSize, 1) 124 yield self.proxy.getTable(tmap.getoids(), 125 maxRepetitions=maxRepetitions, 126 limit=sys.maxint) 127 self._tabledata[pname][tmap] = driver.next() 128 except Exception, ex: 129 if not isinstance( ex, error.TimeoutError ): 130 log.exception("device %s plugin %s unexpected error", 131 self.hostname, pname)
132 133
134 - def getResults(self):
135 """Return data for this client in the form 136 ((plugin, (getdata, tabledata),) 137 getdata = {'.1.2.4.5':"value",} 138 tabledata = {tableMap : {'.1.2.3.4' : {'.1.2.3.4.1': "value",...}}} 139 """ 140 data = [] 141 for plugin in self.plugins: 142 pname = plugin.name() 143 getdata = self._getdata.get(pname,{}) 144 tabledata = self._tabledata.get(pname,{}) 145 if getdata or tabledata: 146 data.append((plugin, (getdata, tabledata))) 147 return data
148
149 - def clientFinished(self, result):
150 log.info("snmp client finished collection for %s" % self.hostname) 151 if isinstance(result, failure.Failure): 152 from twisted.internet import error 153 if isinstance(result.value, error.TimeoutError): 154 log.warning("Device %s timed out: are " 155 "your SNMP settings correct?", self.hostname) 156 else: 157 log.error("Device %s had an error: %s", self.hostname, result) 158 self.proxy.close() 159 """tell the datacollector that we are all done""" 160 if self.datacollector: 161 self.datacollector.clientFinished(self) 162 else: 163 reactor.stop()
164 165 166
167 -def buildOptions(parser=None, usage=None):
168 "build options list that both telnet and ssh use" 169 170 if not usage: 171 usage = "%prog [options] hostname[:port] oids" 172 173 if not parser: 174 from optparse import OptionParser 175 parser = OptionParser(usage=usage) 176 177 parser.add_option('--snmpCommunity', 178 dest='snmpCommunity', 179 default=defaultSnmpCommunity, 180 help='Snmp Community string')
181 182 183 if __name__ == "__main__": 184 import pprint 185 logging.basicConfig() 186 log = logging.getLogger() 187 log.setLevel(20) 188 import sys 189 sys.path.append("plugins") 190 from plugins.zenoss.snmp.InterfaceMap import InterfaceMap 191 ifmap = InterfaceMap() 192 sc = SnmpClient("gate.confmon.loc", community="zentinel", plugins=[ifmap,]) 193 reactor.run() 194 pprint.pprint(sc.getResults()) 195