| Trees | Indices | Help |
|
|---|
|
|
1 ##############################################################################
2 #
3 # Copyright (C) Zenoss, Inc. 2007, 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 sys
12 import logging
13 log = logging.getLogger("zen.SnmpClient")
14
15 from twisted.internet import reactor, error, defer
16 from twisted.python import failure
17 from twisted.internet.error import TimeoutError
18
19 from Products.ZenUtils.snmp import SnmpV1Config, SnmpV2cConfig
20 from Products.ZenUtils.snmp import SnmpAgentDiscoverer
21
22 from pynetsnmp.twistedsnmp import snmpprotocol, Snmpv3Error
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
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 self.proxy = None
55
57 if self.proxy is not None: self.proxy.close()
58 srcport = snmpprotocol.port()
59 self.proxy = self.connInfo.createSession(srcport.protocol)
60 self.proxy.open()
61
63 """Start snmp collection.
64 """
65 log.debug("Starting %s", self.connInfo.summary())
66 self.initSnmpProxy()
67 drive(self.doRun).addBoth(self.clientFinished)
68
69
70 # FIXME: cleanup --force option #2660
72 """Check to see if a cisco box has changed.
73 """
74 device = self.device
75 yield self.proxy.get(['.1.3.6.1.4.1.9.9.43.1.1.1.0'])
76 lastpolluptime = device.getLastPollSnmpUpTime()
77 log.debug("lastpolluptime = %s", lastpolluptime)
78 result = True
79 try:
80 lastchange = driver.next().values()[0]
81 log.debug("lastchange = %s", lastchange)
82 if lastchange <= lastpolluptime:
83 log.info("skipping cisco device %s no change detected",
84 device.id)
85 result = False
86 else:
87 device.setLastPollSnmpUpTime(lastchange)
88 except Exception:
89 pass
90 yield defer.succeed(result)
91
92
94 # test snmp connectivity
95 log.debug("Testing SNMP configuration")
96 yield self.proxy.walk('.1.3')
97 try:
98 driver.next()
99 except TimeoutError, ex:
100 log.info("Device timed out: " + self.connInfo.summary())
101 if self.options.discoverCommunity:
102 yield self.findSnmpCommunity()
103 snmp_config = driver.next()
104 if not snmp_config:
105 log.warn(
106 'Failed to rediscover the SNMP connection info for %s',
107 self.device.manageIp)
108 return
109 if snmp_config.version:
110 self.connInfo.zSnmpVer = snmp_config.version
111 if snmp_config.port:
112 self.connInfo.zSnmpPort = snmp_config.port
113 if snmp_config.community:
114 self.connInfo.zSnmpCommunity = snmp_config.community
115 self.connInfo.changed = True
116 self.initSnmpProxy()
117 else:
118 return
119 except Snmpv3Error, ex:
120 log.info("Cannot connect to SNMP agent: {0}".format(self.connInfo.summary()))
121 return
122 except Exception, ex:
123 log.exception("Unable to talk: " + self.connInfo.summary())
124 return
125
126 changed = True
127 # FIXME: cleanup --force option #2660
128 if not self.options.force and self.device.snmpOid.startswith(".1.3.6.1.4.1.9"):
129 yield drive(self.checkCiscoChange)
130 changed = driver.next()
131 if changed:
132 yield drive(self.collect)
133
135 def inner(driver):
136 """
137 Twisted driver class to iterate through devices
138
139 @param driver: Zenoss driver
140 @type driver: Zenoss driver
141 @return: successful result is a list of IPs that were added
142 @rtype: Twisted deferred
143 """
144 log.info("Rediscovering SNMP connection info for %s",
145 self.device.id)
146
147 communities = list(self.device.zSnmpCommunities)
148 communities.reverse()
149
150 configs = []
151 weight = 0
152 port = int(self.device.zSnmpPort)
153 for community in communities:
154 weight+=1
155 configs.append(SnmpV1Config(
156 self.device.manageIp, weight=weight,
157 port=port,
158 timeout=self.connInfo.zSnmpTimeout,
159 retries=self.connInfo.zSnmpTries,
160 community=community))
161 configs.append(SnmpV2cConfig(
162 self.device.manageIp, weight=weight+1000, port=port,
163 timeout=self.connInfo.zSnmpTimeout,
164 retries=self.connInfo.zSnmpTries,
165 community=community))
166
167 yield SnmpAgentDiscoverer().findBestConfig(configs)
168 driver.next()
169 return drive(inner)
170
171
173 maxOidsPerRequest = getattr(self.device, 'zMaxOIDPerRequest', DEFAULT_MAX_OIDS_BACK)
174 log.debug("Using a max of %s OIDs per request", maxOidsPerRequest)
175 for plugin in self.plugins:
176 try:
177 log.debug('running %s', plugin)
178 pname = plugin.name()
179 self._tabledata[pname] = {}
180 log.debug("sending queries for plugin %s", pname)
181 if plugin.snmpGetMap:
182 results = {}
183 for oid in plugin.snmpGetMap.getoids():
184 yield self.proxy.get([oid])
185 results.update(driver.next())
186 self._getdata[pname] = results
187 for tmap in plugin.snmpGetTableMaps:
188 rowSize = len(tmap.getoids())
189 maxRepetitions = max(maxOidsPerRequest / rowSize, 1)
190 yield self.proxy.getTable(tmap.getoids(),
191 maxRepetitions=maxRepetitions,
192 limit=sys.maxint)
193 self._tabledata[pname][tmap] = driver.next()
194 except Exception, ex:
195 if not isinstance( ex, error.TimeoutError ):
196 log.exception("device %s plugin %s unexpected error",
197 self.hostname, pname)
198
199
201 """Return data for this client in the form
202 ((plugin, (getdata, tabledata),)
203 getdata = {'.1.2.4.5':"value",}
204 tabledata = {tableMap : {'.1.2.3.4' : {'.1.2.3.4.1': "value",...}}}
205 """
206 data = []
207 for plugin in self.plugins:
208 pname = plugin.name()
209 getdata = self._getdata.get(pname,{})
210 tabledata = self._tabledata.get(pname,{})
211 if getdata or tabledata:
212 data.append((plugin, (getdata, tabledata)))
213 return data
215 log.info("snmp client finished collection for %s" % self.hostname)
216 if isinstance(result, failure.Failure):
217 from twisted.internet import error
218 if isinstance(result.value, error.TimeoutError):
219 log.warning("Device %s timed out: are "
220 "your SNMP settings correct?", self.hostname)
221 elif isinstance(result.value, Snmpv3Error):
222 log.warning("Connection to device {0.hostname} failed: {1.value.message}".format(self, result))
223 else:
224 log.exception("Device %s had an error: %s",self.hostname,result)
225 self.proxy.close()
226 """tell the datacollector that we are all done"""
227 if self.datacollector:
228 self.datacollector.clientFinished(self)
229 else:
230 reactor.stop()
231
234
236 "build options list that both telnet and ssh use"
237 if not usage:
238 usage = "%prog [options] hostname[:port] oids"
239 if not parser:
240 from optparse import OptionParser
241 parser = OptionParser(usage=usage)
242
243 parser.add_option('--snmpCommunity',
244 dest='snmpCommunity',
245 default=defaultSnmpCommunity,
246 help='Snmp Community string')
247
248
249 if __name__ == "__main__":
250 import pprint
251 logging.basicConfig()
252 log = logging.getLogger()
253 log.setLevel(20)
254 import sys
255 sys.path.append("plugins")
256 from plugins.zenoss.snmp.InterfaceMap import InterfaceMap
257 ifmap = InterfaceMap()
258 sc = SnmpClient("gate.confmon.loc", community="zentinel", plugins=[ifmap,])
259 reactor.run()
260 pprint.pprint(sc.getResults())
261
| Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1.1812 on Mon Jul 30 17:11:19 2012 | http://epydoc.sourceforge.net |