| Trees | Indices | Help |
|
|---|
|
|
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 __doc__="""ZDeviceLoader.py
15
16 load devices from a GUI screen in the ZMI
17
18 $Id: ZDeviceLoader.py,v 1.19 2004/04/22 02:14:12 edahl Exp $"""
19
20 __version__ = "$Revision: 1.19 $"[11:-2]
21
22 import socket
23 from logging import StreamHandler, Formatter, getLogger
24 log = getLogger("zen.DeviceLoader")
25
26 import transaction
27 from zope.interface import implements
28 from AccessControl import ClassSecurityInfo
29 from AccessControl import Permissions as permissions
30
31 from OFS.SimpleItem import SimpleItem
32
33 from Products.ZenUtils.Utils import isXmlRpc, setupLoggingHeader
34 from Products.ZenUtils.Utils import binPath, clearWebLoggingStream
35 from Products.ZenUtils.Exceptions import ZentinelException
36 from Products.ZenModel.Exceptions import DeviceExistsError, NoSnmp
37 from Products.ZenModel.Device import manage_createDevice
38 from Products.ZenWidgets import messaging
39 from Products.Jobber.interfaces import IJobStatus
40 from Products.Jobber.jobs import ShellCommandJob
41 from Products.Jobber.status import SUCCESS, FAILURE
42 from ZenModelItem import ZenModelItem
43 from zExceptions import BadRequest
44 from Products.ZenModel.interfaces import IDeviceLoader
45
46
48 """make a DeviceLoader"""
49 if not id: id = "DeviceLoader"
50 d = ZDeviceLoader(id)
51 context._setObject(id, d)
52
53 if REQUEST is not None:
54 REQUEST['RESPONSE'].redirect(context.absolute_url()
55 +'/manage_main')
56
58 implements(IDeviceLoader)
59
60 context = None
61 request = None
62 deviceobj = None
63
66
68 """
69 Various ways of doing this should be implemented in subclasses.
70 """
71 raise NotImplementedError
72
74 """
75 Delete the device object, presumably because discovery failed.
76 """
77 if self.deviceobj is not None:
78 try:
79 self.deviceobj._p_jar.sync()
80 except AttributeError:
81 pass
82 else:
83 if self.deviceobj.isTempDevice():
84 # Flag's still True, so discovery failed somehow. Clean up
85 # the device object.
86 self.deviceobj.deleteDevice(True, True, True)
87 self.deviceobj = None
88
89 - def load_device(self, deviceName, devicePath='/Discovered',
90 discoverProto='snmp', performanceMonitor='localhost',
91 manageIp="", zProperties=None, deviceProperties=None):
92 """
93 Load a single device into the database.
94 """
95 # Make the config dictionaries the proper type
96 try:
97 if zProperties is None:
98 zProperties = {}
99 if deviceProperties is None:
100 deviceProperties = {}
101
102 # Remove spaces from the name
103 deviceName = deviceName.replace(' ', '')
104 manageIp = manageIp.replace(' ', '')
105
106 # If we're not discovering and we have no IP, attempt the IP lookup
107 # locally
108 if discoverProto=='none':
109 if not manageIp:
110 try:
111 manageIp = socket.gethostbyname(deviceName)
112 except socket.error:
113 pass
114
115 # move the zProperties required by manage_createDevice to
116 # deviceProperties
117 for key in 'zSnmpCommunity', 'zSnmpPort', 'zSnmpVer':
118 if zProperties.has_key(key):
119 deviceProperties[key] = zProperties.pop(key)
120
121 # Make a device object in the database
122 self.deviceobj = manage_createDevice(self.context, deviceName,
123 devicePath,
124 performanceMonitor=performanceMonitor,
125 manageIp=manageIp,
126 zProperties=zProperties,
127 **deviceProperties)
128
129 # Flag this device as temporary. If discovery goes well, zendisc will
130 # flip this to False.
131 self.deviceobj._temp_device = True
132
133 # If we're not discovering, we're done
134 if discoverProto=='none':
135 return self.deviceobj
136
137 # Otherwise, time for zendisc to do its thing
138 self.run_zendisc(deviceName, devicePath, performanceMonitor)
139
140 finally:
141 # Check discovery's success and clean up accordingly
142 self.cleanup()
143
144 return self.deviceobj
145
146
148 implements(IDeviceLoader)
149
151 """
152 In this subclass, just create the zendisc command and return it. The
153 job will do the actual running.
154 """
155 # Commit to database so everybody can find the new device
156 transaction.commit()
157
158 jobid = self.context.getUid()
159
160 zm = binPath('zendisc')
161 zendiscCmd = [zm]
162 zendiscOptions = ['run', '--now','-d', deviceName,
163 '--monitor', performanceMonitor,
164 '--deviceclass', devicePath,
165 '--job', jobid]
166 zendiscCmd.extend(zendiscOptions)
167 self.zendiscCmd = zendiscCmd
168
174
175
177 - def __init__(self, jobid, deviceName, devicePath="/Discovered", tag="",
178 serialNumber="", rackSlot=0, productionState=1000,
179 comments="", hwManufacturer="", hwProductName="",
180 osManufacturer="", osProductName="", locationPath="",
181 groupPaths=[], systemPaths=[], performanceMonitor="localhost",
182 discoverProto="snmp", priority=3, manageIp="",
183 zProperties=None):
184
185 # Store device name for later finding
186 self.deviceName = deviceName
187 self.devicePath = devicePath
188 self.performanceMonitor = performanceMonitor
189 self.discoverProto = discoverProto
190 self.manageIp = manageIp.replace(' ', '')
191
192 # Save the device stuff to set after adding
193 self.zProperties = zProperties
194 self.deviceProps = dict(tag=tag,
195 serialNumber=serialNumber,
196 rackSlot=rackSlot,
197 productionState=productionState,
198 comments=comments,
199 hwManufacturer=hwManufacturer,
200 hwProductName = hwProductName,
201 osManufacturer = osManufacturer,
202 osProductName = osProductName,
203 locationPath = locationPath,
204 groupPaths = groupPaths,
205 systemPaths = systemPaths,
206 priority = priority)
207
208 # Set up the job, passing in a blank command (gets set later)
209 super(DeviceCreationJob, self).__init__(jobid, '')
210
211
213 # Store zProperties on the job
214 self.getStatus().setZProperties(**self.zProperties)
215
216 self._v_loader = JobDeviceLoader(self)
217 # Create the device object and generate the zendisc command
218 try:
219 self._v_loader.load_device(self.deviceName, self.devicePath,
220 self.discoverProto,
221 self.performanceMonitor, self.manageIp,
222 self.zProperties, self.deviceProps)
223 except Exception, e:
224 transaction.commit()
225 log = self.getStatus().getLog()
226 log.write(e.args[0])
227 log.finish()
228 self.finished(FAILURE)
229 else:
230 self.cmd = self._v_loader.zendiscCmd
231 super(DeviceCreationJob, self).run(r)
232
240
245
247 # Commit to database so everybody can find the new device
248 transaction.commit()
249 collector = self.deviceobj.getPerformanceServer()
250 collector._executeZenDiscCommand(deviceName, devicePath,
251 performanceMonitor,
252 REQUEST=self.request)
253
254
256 """Load devices into the DMD database"""
257
258 portal_type = meta_type = 'DeviceLoader'
259
260 manage_options = ((
261 {'label':'ManualDeviceLoader', 'action':'manualDeviceLoader'},
262 ) + SimpleItem.manage_options)
263
264
265 security = ClassSecurityInfo()
266
267 factory_type_information = (
268 {
269 'immediate_view' : 'addDevice',
270 'actions' :
271 (
272 { 'id' : 'status'
273 , 'name' : 'Status'
274 , 'action' : 'addDevice'
275 , 'permissions' : (
276 permissions.view, )
277 },
278 )
279 },
280 )
281
284
285
286 - def loadDevice(self, deviceName, devicePath="/Discovered",
287 tag="", serialNumber="",
288 zSnmpCommunity="", zSnmpPort=161, zSnmpVer=None,
289 rackSlot=0, productionState=1000, comments="",
290 hwManufacturer="", hwProductName="",
291 osManufacturer="", osProductName="",
292 locationPath="", groupPaths=[], systemPaths=[],
293 performanceMonitor="localhost",
294 discoverProto="snmp",priority=3,REQUEST=None):
295 """
296 Load a device into the database connecting its major relations
297 and collecting its configuration.
298 """
299 device = None
300 if not deviceName: return self.callZenScreen(REQUEST)
301 xmlrpc = isXmlRpc(REQUEST)
302 if REQUEST and not xmlrpc:
303 handler = setupLoggingHeader(self, REQUEST)
304
305 loader = WeblogDeviceLoader(self, REQUEST)
306
307 try:
308 device = loader.load_device(deviceName, devicePath, discoverProto,
309 performanceMonitor,
310 zProperties=dict(
311 zSnmpCommunity=zSnmpCommunity,
312 zSnmpPort=zSnmpPort,
313 zSnmpVer=zSnmpVer
314 ),
315 deviceProperties=dict(
316 tag=tag,
317 serialNumber=serialNumber,
318 rackSlot=rackSlot,
319 productionState=productionState,
320 comments=comments,
321 hwManufacturer=hwManufacturer,
322 hwProductName=hwProductName,
323 osManufacturer=osManufacturer,
324 osProductName=osProductName,
325 locationPath=locationPath,
326 groupPaths=groupPaths,
327 systemPaths=systemPaths,
328 priority=priority
329 ))
330 except (SystemExit, KeyboardInterrupt):
331 raise
332 except ZentinelException, e:
333 log.info(e)
334 if xmlrpc: return 1
335 except DeviceExistsError, e:
336 log.info(e)
337 if xmlrpc: return 2
338 except NoSnmp, e:
339 log.info(e)
340 if xmlrpc: return 3
341 except Exception, e:
342 log.exception(e)
343 log.exception('load of device %s failed' % deviceName)
344 transaction.abort()
345 if device is None:
346 log.error("Unable to add the device %s" % deviceName)
347 else:
348 log.info("Device %s loaded!" % deviceName)
349
350 if REQUEST and not xmlrpc:
351 self.loaderFooter(device, REQUEST.RESPONSE)
352 clearWebLoggingStream(handler)
353 if xmlrpc: return 0
354
355 - def addManufacturer(self, newHWManufacturerName=None,
356 newSWManufacturerName=None, REQUEST=None):
357 """add a manufacturer to the database"""
358 mname = newHWManufacturerName
359 field = 'hwManufacturer'
360 if not mname:
361 mname = newSWManufacturerName
362 field = 'osManufacturer'
363 try:
364 self.getDmdRoot("Manufacturers").createManufacturer(mname)
365 except BadRequest, e:
366 if REQUEST:
367 messaging.IMessageSender(self).sendToBrowser(
368 'Error',
369 str(e),
370 priority=messaging.WARNING
371 )
372 else:
373 raise e
374
375 if REQUEST:
376 REQUEST[field] = mname
377 return self.callZenScreen(REQUEST)
378
379
380 security.declareProtected('Change Device', 'setHWProduct')
382 """set the productName of this device"""
383 if not hwManufacturer and REQUEST:
384 messaging.IMessageSender(self).sendToBrowser(
385 'Error',
386 'Please select a HW Manufacturer',
387 priority=messaging.WARNING
388 )
389 return self.callZenScreen(REQUEST)
390
391 self.getDmdRoot("Manufacturers").createHardwareProduct(
392 newHWProductName, hwManufacturer)
393 if REQUEST:
394 REQUEST['hwProductName'] = newHWProductName
395 return self.callZenScreen(REQUEST)
396
397
398 security.declareProtected('Change Device', 'setOSProduct')
400 """set the productName of this device"""
401 if not osManufacturer and REQUEST:
402 messaging.IMessageSender(self).sendToBrowser(
403 'Error',
404 'Please select an OS Manufacturer.',
405 priority=messaging.WARNING
406 )
407 return self.callZenScreen(REQUEST)
408
409 self.getDmdRoot("Manufacturers").createSoftwareProduct(
410 newOSProductName, osManufacturer, isOS=True)
411 if REQUEST:
412 REQUEST['osProductName'] = newOSProductName
413 return self.callZenScreen(REQUEST)
414
415
416 security.declareProtected('Change Device', 'addLocation')
418 """add a location to the database"""
419 try:
420 self.getDmdRoot("Locations").createOrganizer(newLocationPath)
421 except BadRequest, e:
422 if REQUEST:
423 messaging.IMessageSender(self).sendToBrowser(
424 'Error',
425 str(e),
426 priority=messaging.WARNING
427 )
428 else:
429 raise e
430
431 if REQUEST:
432 REQUEST['locationPath'] = newLocationPath
433 return self.callZenScreen(REQUEST)
434
435
436 security.declareProtected('Change Device', 'addSystem')
438 """add a system to the database"""
439 try:
440 self.getDmdRoot("Systems").createOrganizer(newSystemPath)
441 except BadRequest, e:
442 if REQUEST:
443 messaging.IMessageSender(self).sendToBrowser(
444 'Error',
445 str(e),
446 priority=messaging.WARNING
447 )
448 else:
449 raise e
450
451 syss = REQUEST.get('systemPaths', [])
452 syss.append(newSystemPath)
453 if REQUEST:
454 REQUEST['systemPaths'] = syss
455 return self.callZenScreen(REQUEST)
456
457
458 security.declareProtected('Change Device', 'addDeviceGroup')
460 """add a device group to the database"""
461 try:
462 self.getDmdRoot("Groups").createOrganizer(newDeviceGroupPath)
463 except BadRequest, e:
464 if REQUEST:
465 messaging.IMessageSender(self).sendToBrowser(
466 'Error',
467 str(e),
468 priority=messaging.WARNING
469 )
470 else:
471 raise e
472
473 groups = REQUEST.get('groupPaths', [])
474 groups.append(newDeviceGroupPath)
475 if REQUEST:
476 REQUEST['groupPaths'] = groups
477 return self.callZenScreen(REQUEST)
478
479
480 security.declareProtected('Change Device', 'setPerformanceMonitor')
482 """add new performance monitor to the database"""
483 try:
484 self.getDmdRoot("Monitors").getPerformanceMonitor(newPerformanceMonitor)
485 except BadRequest, e:
486 if REQUEST:
487 messaging.IMessageSender(self).sendToBrowser(
488 'Error',
489 str(e),
490 priority=messaging.WARNING
491 )
492 else:
493 raise e
494 if REQUEST:
495 REQUEST['performanceMonitor'] = newPerformanceMonitor
496 return self.callZenScreen(REQUEST)
497
498
500 """setup logging package to send to browser"""
501 root = getLogger()
502 self._v_handler = StreamHandler(response)
503 fmt = Formatter("""<tr class="tablevalues">
504 <td>%(asctime)s</td><td>%(levelname)s</td>
505 <td>%(name)s</td><td>%(message)s</td></tr>
506 """, "%Y-%m-%d %H:%M:%S")
507 self._v_handler.setFormatter(fmt)
508 root.addHandler(self._v_handler)
509 root.setLevel(10)
510
511
513 alog = getLogger()
514 if getattr(self, "_v_handler", False):
515 alog.removeHandler(self._v_handler)
516
517
526
| Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0beta1 on Mon Oct 19 14:44:31 2009 | http://epydoc.sourceforge.net |