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