| 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
105 # If we're not discovering and we have no IP, attempt the IP lookup
106 # locally
107 if discoverProto=='none':
108 if not manageIp:
109 try:
110 manageIp = socket.gethostbyname(deviceName)
111 except socket.error:
112 pass
113
114 # move the zProperties required by manage_createDevice to
115 # deviceProperties
116 for key in 'zSnmpCommunity', 'zSnmpPort', 'zSnmpVer':
117 if zProperties.has_key(key):
118 deviceProperties[key] = zProperties.pop(key)
119
120 # Make a device object in the database
121 self.deviceobj = manage_createDevice(self.context, deviceName,
122 devicePath,
123 performanceMonitor=performanceMonitor,
124 manageIp=manageIp,
125 zProperties=zProperties,
126 **deviceProperties)
127
128 # Flag this device as temporary. If discovery goes well, zendisc will
129 # flip this to False.
130 self.deviceobj._temp_device = True
131
132 # If we're not discovering, we're done
133 if discoverProto=='none':
134 return self.deviceobj
135
136 # Otherwise, time for zendisc to do its thing
137 self.run_zendisc(deviceName, devicePath, performanceMonitor)
138
139 finally:
140 # Check discovery's success and clean up accordingly
141 self.cleanup()
142
143 return self.deviceobj
144
145
147 implements(IDeviceLoader)
148
150 """
151 In this subclass, just create the zendisc command and return it. The
152 job will do the actual running.
153 """
154 # Commit to database so everybody can find the new device
155 transaction.commit()
156
157 jobid = self.context.getUid()
158
159 zm = binPath('zendisc')
160 zendiscCmd = [zm]
161 zendiscOptions = ['run', '--now','-d', deviceName,
162 '--monitor', performanceMonitor,
163 '--deviceclass', devicePath,
164 '--job', jobid]
165 zendiscCmd.extend(zendiscOptions)
166 self.zendiscCmd = zendiscCmd
167
173
174
176 - def __init__(self, jobid, deviceName, devicePath="/Discovered", tag="",
177 serialNumber="", rackSlot=0, productionState=1000,
178 comments="", hwManufacturer="", hwProductName="",
179 osManufacturer="", osProductName="", locationPath="",
180 groupPaths=[], systemPaths=[], performanceMonitor="localhost",
181 discoverProto="snmp", priority=3, manageIp="",
182 zProperties=None):
183
184 # Store device name for later finding
185 self.deviceName = deviceName
186 self.devicePath = devicePath
187 self.performanceMonitor = performanceMonitor
188 self.discoverProto = discoverProto
189 self.manageIp = manageIp
190
191 # Save the device stuff to set after adding
192 self.zProperties = zProperties
193 self.deviceProps = dict(tag=tag,
194 serialNumber=serialNumber,
195 rackSlot=rackSlot,
196 productionState=productionState,
197 comments=comments,
198 hwManufacturer=hwManufacturer,
199 hwProductName = hwProductName,
200 osManufacturer = osManufacturer,
201 osProductName = osProductName,
202 locationPath = locationPath,
203 groupPaths = groupPaths,
204 systemPaths = systemPaths,
205 priority = priority)
206
207 # Set up the job, passing in a blank command (gets set later)
208 super(DeviceCreationJob, self).__init__(jobid, '')
209
210
212 # Store zProperties on the job
213 self.getStatus().setZProperties(**self.zProperties)
214
215 self._v_loader = JobDeviceLoader(self)
216 # Create the device object and generate the zendisc command
217 try:
218 self._v_loader.load_device(self.deviceName, self.devicePath,
219 self.discoverProto,
220 self.performanceMonitor, self.manageIp,
221 self.zProperties, self.deviceProps)
222 except Exception, e:
223 transaction.commit()
224 log = self.getStatus().getLog()
225 log.write(e.args[0])
226 log.finish()
227 self.finished(FAILURE)
228 else:
229 self.cmd = self._v_loader.zendiscCmd
230 super(DeviceCreationJob, self).run(r)
231
239
244
246 # Commit to database so everybody can find the new device
247 transaction.commit()
248 collector = self.deviceobj.getPerformanceServer()
249 collector._executeZenDiscCommand(deviceName, devicePath,
250 performanceMonitor,
251 REQUEST=self.request)
252
253
255 """Load devices into the DMD database"""
256
257 portal_type = meta_type = 'DeviceLoader'
258
259 manage_options = ((
260 {'label':'ManualDeviceLoader', 'action':'manualDeviceLoader'},
261 ) + SimpleItem.manage_options)
262
263
264 security = ClassSecurityInfo()
265
266 factory_type_information = (
267 {
268 'immediate_view' : 'addDevice',
269 'actions' :
270 (
271 { 'id' : 'status'
272 , 'name' : 'Status'
273 , 'action' : 'addDevice'
274 , 'permissions' : (
275 permissions.view, )
276 },
277 )
278 },
279 )
280
283
284
285 - def loadDevice(self, deviceName, devicePath="/Discovered",
286 tag="", serialNumber="",
287 zSnmpCommunity="", zSnmpPort=161, zSnmpVer=None,
288 rackSlot=0, productionState=1000, comments="",
289 hwManufacturer="", hwProductName="",
290 osManufacturer="", osProductName="",
291 locationPath="", groupPaths=[], systemPaths=[],
292 performanceMonitor="localhost",
293 discoverProto="snmp",priority=3,REQUEST=None):
294 """
295 Load a device into the database connecting its major relations
296 and collecting its configuration.
297 """
298 device = None
299 if not deviceName: return self.callZenScreen(REQUEST)
300 xmlrpc = isXmlRpc(REQUEST)
301 if REQUEST and not xmlrpc:
302 handler = setupLoggingHeader(self, REQUEST)
303
304 loader = WeblogDeviceLoader(self, REQUEST)
305
306 try:
307 device = loader.load_device(deviceName, devicePath, discoverProto,
308 performanceMonitor,
309 zProperties=dict(
310 zSnmpCommunity=zSnmpCommunity,
311 zSnmpPort=zSnmpPort,
312 zSnmpVer=zSnmpVer
313 ),
314 deviceProperties=dict(
315 tag=tag,
316 serialNumber=serialNumber,
317 rackSlot=rackSlot,
318 productionState=productionState,
319 comments=comments,
320 hwManufacturer=hwManufacturer,
321 hwProductName=hwProductName,
322 osManufacturer=osManufacturer,
323 osProductName=osProductName,
324 locationPath=locationPath,
325 groupPaths=groupPaths,
326 systemPaths=systemPaths,
327 priority=priority
328 ))
329 except (SystemExit, KeyboardInterrupt):
330 raise
331 except ZentinelException, e:
332 log.info(e)
333 if xmlrpc: return 1
334 except DeviceExistsError, e:
335 log.info(e)
336 if xmlrpc: return 2
337 except NoSnmp, e:
338 log.info(e)
339 if xmlrpc: return 3
340 except Exception, e:
341 log.exception(e)
342 log.exception('load of device %s failed' % deviceName)
343 transaction.abort()
344 if device is None:
345 log.error("Unable to add the device %s" % deviceName)
346 else:
347 log.info("Device %s loaded!" % deviceName)
348
349 if REQUEST and not xmlrpc:
350 self.loaderFooter(device, REQUEST.RESPONSE)
351 clearWebLoggingStream(handler)
352 if xmlrpc: return 0
353
354 - def addManufacturer(self, newHWManufacturerName=None,
355 newSWManufacturerName=None, REQUEST=None):
356 """add a manufacturer to the database"""
357 mname = newHWManufacturerName
358 field = 'hwManufacturer'
359 if not mname:
360 mname = newSWManufacturerName
361 field = 'osManufacturer'
362 try:
363 self.getDmdRoot("Manufacturers").createManufacturer(mname)
364 except BadRequest, e:
365 if REQUEST:
366 messaging.IMessageSender(self).sendToBrowser(
367 'Error',
368 str(e),
369 priority=messaging.WARNING
370 )
371 else:
372 raise e
373
374 if REQUEST:
375 REQUEST[field] = mname
376 return self.callZenScreen(REQUEST)
377
378
379 security.declareProtected('Change Device', 'setHWProduct')
381 """set the productName of this device"""
382 if not hwManufacturer and REQUEST:
383 messaging.IMessageSender(self).sendToBrowser(
384 'Error',
385 'Please select a HW Manufacturer',
386 priority=messaging.WARNING
387 )
388 return self.callZenScreen(REQUEST)
389
390 self.getDmdRoot("Manufacturers").createHardwareProduct(
391 newHWProductName, hwManufacturer)
392 if REQUEST:
393 REQUEST['hwProductName'] = newHWProductName
394 return self.callZenScreen(REQUEST)
395
396
397 security.declareProtected('Change Device', 'setOSProduct')
399 """set the productName of this device"""
400 if not osManufacturer and REQUEST:
401 messaging.IMessageSender(self).sendToBrowser(
402 'Error',
403 'Please select an OS Manufacturer.',
404 priority=messaging.WARNING
405 )
406 return self.callZenScreen(REQUEST)
407
408 self.getDmdRoot("Manufacturers").createSoftwareProduct(
409 newOSProductName, osManufacturer, isOS=True)
410 if REQUEST:
411 REQUEST['osProductName'] = newOSProductName
412 return self.callZenScreen(REQUEST)
413
414
415 security.declareProtected('Change Device', 'addLocation')
417 """add a location to the database"""
418 try:
419 self.getDmdRoot("Locations").createOrganizer(newLocationPath)
420 except BadRequest, e:
421 if REQUEST:
422 messaging.IMessageSender(self).sendToBrowser(
423 'Error',
424 str(e),
425 priority=messaging.WARNING
426 )
427 else:
428 raise e
429
430 if REQUEST:
431 REQUEST['locationPath'] = newLocationPath
432 return self.callZenScreen(REQUEST)
433
434
435 security.declareProtected('Change Device', 'addSystem')
437 """add a system to the database"""
438 try:
439 self.getDmdRoot("Systems").createOrganizer(newSystemPath)
440 except BadRequest, e:
441 if REQUEST:
442 messaging.IMessageSender(self).sendToBrowser(
443 'Error',
444 str(e),
445 priority=messaging.WARNING
446 )
447 else:
448 raise e
449
450 syss = REQUEST.get('systemPaths', [])
451 syss.append(newSystemPath)
452 if REQUEST:
453 REQUEST['systemPaths'] = syss
454 return self.callZenScreen(REQUEST)
455
456
457 security.declareProtected('Change Device', 'addDeviceGroup')
459 """add a device group to the database"""
460 try:
461 self.getDmdRoot("Groups").createOrganizer(newDeviceGroupPath)
462 except BadRequest, e:
463 if REQUEST:
464 messaging.IMessageSender(self).sendToBrowser(
465 'Error',
466 str(e),
467 priority=messaging.WARNING
468 )
469 else:
470 raise e
471
472 groups = REQUEST.get('groupPaths', [])
473 groups.append(newDeviceGroupPath)
474 if REQUEST:
475 REQUEST['groupPaths'] = groups
476 return self.callZenScreen(REQUEST)
477
478
479 security.declareProtected('Change Device', 'setPerformanceMonitor')
481 """add new performance monitor to the database"""
482 try:
483 self.getDmdRoot("Monitors").getPerformanceMonitor(newPerformanceMonitor)
484 except BadRequest, e:
485 if REQUEST:
486 messaging.IMessageSender(self).sendToBrowser(
487 'Error',
488 str(e),
489 priority=messaging.WARNING
490 )
491 else:
492 raise e
493 if REQUEST:
494 REQUEST['performanceMonitor'] = newPerformanceMonitor
495 return self.callZenScreen(REQUEST)
496
497
499 """setup logging package to send to browser"""
500 root = getLogger()
501 self._v_handler = StreamHandler(response)
502 fmt = Formatter("""<tr class="tablevalues">
503 <td>%(asctime)s</td><td>%(levelname)s</td>
504 <td>%(name)s</td><td>%(message)s</td></tr>
505 """, "%Y-%m-%d %H:%M:%S")
506 self._v_handler.setFormatter(fmt)
507 root.addHandler(self._v_handler)
508 root.setLevel(10)
509
510
512 alog = getLogger()
513 if getattr(self, "_v_handler", False):
514 alog.removeHandler(self._v_handler)
515
516
525
| Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0beta1 on Thu May 7 11:46:22 2009 | http://epydoc.sourceforge.net |