| 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__ = """DeviceOrganizer
15 Base class for device organizers
16 """
17
18 from itertools import ifilter
19 from types import StringTypes
20
21 from AccessControl import ClassSecurityInfo
22 from Globals import InitializeClass
23
24 from Organizer import Organizer
25 from DeviceManagerBase import DeviceManagerBase
26 from Commandable import Commandable
27 from ZenMenuable import ZenMenuable
28 from MaintenanceWindowable import MaintenanceWindowable
29 from AdministrativeRoleable import AdministrativeRoleable
30
31 from Products.CMFCore.utils import getToolByName
32
33 from Products.ZenRelations.RelSchema import *
34 from Products.ZenWidgets.interfaces import IMessageSender
35
36 from ZenossSecurity import *
37
38 from Products.ZenUtils.Utils import unused
39 from Products.ZenWidgets import messaging
40
41 import logging
42 LOG = logging.getLogger('ZenModel.DeviceOrganizer')
43
44 -class DeviceOrganizer(Organizer, DeviceManagerBase, Commandable, ZenMenuable,
45 MaintenanceWindowable, AdministrativeRoleable):
46 """
47 DeviceOrganizer is the base class for device organizers.
48 It has lots of methods for rolling up device statistics and information.
49 """
50
51 security = ClassSecurityInfo()
52
53 # Screen action bindings (and tab definitions)
54 factory_type_information = (
55 {
56 'immediate_view' : 'deviceOrganizerStatus',
57 'actions' :
58 (
59 { 'id' : 'status'
60 , 'name' : 'Status'
61 , 'action' : 'deviceOrganizerStatus'
62 , 'permissions' : (ZEN_VIEW, )
63 },
64 { 'id' : 'events'
65 , 'name' : 'Events'
66 , 'action' : 'viewEvents'
67 , 'permissions' : (ZEN_VIEW, )
68 },
69 # { 'id' : 'historyEvents'
70 # , 'name' : 'History'
71 # , 'action' : 'viewHistoryEvents'
72 # , 'permissions' : (ZEN_VIEW, )
73 # },
74 { 'id' : 'manage'
75 , 'name' : 'Administration'
76 , 'action' : 'deviceOrganizerManage'
77 , 'permissions' : (ZEN_MANAGE_DMD,)
78 },
79 )
80 },
81 )
82
83 _relations = Organizer._relations + (
84 ("maintenanceWindows", ToManyCont(
85 ToOne, "Products.ZenModel.MaintenanceWindow", "productionState")),
86 ("adminRoles", ToManyCont(
87 ToOne,"Products.ZenModel.AdministrativeRole","managedObject")),
88 ('userCommands', ToManyCont(
89 ToOne, 'Products.ZenModel.UserCommand', 'commandable')),
90 ('zenMenus', ToManyCont(
91 ToOne, 'Products.ZenModel.ZenMenu', 'menuable')),
92 )
93
94 security.declareProtected(ZEN_COMMON, "getSubDevices")
96 """
97 Get all the devices under an instance of a DeviceOrganizer
98
99 @param devfilter: Filter function applied to returned list
100 @type devfilter: function
101 @return: Devices
102 @rtype: list
103
104 """
105 catalog = getToolByName(self.dmd.Devices, self.dmd.Devices.default_catalog)
106
107 if not 'path' in catalog.indexes():
108 LOG.warn('Please run zenmigrate to create device path indexes.')
109 return self.getSubDevices_recursive(devfilter)
110
111 brains = catalog(path="/".join(self.getPhysicalPath()))
112 devices = (b.getObject() for b in brains)
113 devices = ifilter(lambda dev:self.checkRemotePerm(ZEN_VIEW, dev),
114 devices)
115 devices = ifilter(devfilter, devices)
116 return list(devices)
117
118 security.declareProtected(ZEN_VIEW, "getSubDevicesGen")
120 """get all the devices under and instance of a DeviceGroup"""
121 catalog = getToolByName(self.dmd.Devices, self.dmd.Devices.default_catalog)
122
123 if not 'path' in catalog.indexes():
124 LOG.warn('Please run zenmigrate to create device path indexes.')
125 yield self.getSubDevicesGen_recursive(devfilter)
126
127 brains = catalog(path="/".join(self.getPhysicalPath()))
128 devices = (b.getObject() for b in brains)
129 devices = ifilter(lambda dev:self.checkRemotePerm(ZEN_VIEW, dev),
130 devices)
131 for device in devices:
132 yield device
133
134 security.declareProtected(ZEN_COMMON, "getSubDevices_recursive")
136 devrelobj = getattr(self, devrel, None)
137 if not devrelobj:
138 raise AttributeError( "%s not found on %s" % (devrel, self.id) )
139 devices = filter(devfilter, devrelobj())
140 devices = [ dev for dev in devices
141 if self.checkRemotePerm(ZEN_VIEW, dev)]
142 for subgroup in self.children(checkPerm=False):
143 devices.extend(subgroup.getSubDevices_recursive(devfilter, devrel))
144 return devices
145
146 security.declareProtected(ZEN_VIEW, "getSubDevicesGen")
148 """get all the devices under and instance of a DeviceGroup"""
149 devrelobj = getattr(self, devrel, None)
150 if not devrelobj:
151 raise AttributeError( "%s not found on %s" % (devrel, self.id) )
152 for dev in devrelobj.objectValuesGen():
153 yield dev
154 for subgroup in self.children():
155 for dev in subgroup.getSubDevicesGen_recursive(devrel):
156 yield dev
157
159 """get all the devices under and instance of a DeviceGroup"""
160 devices = getattr(self, devrel, None)
161 if not devices:
162 raise AttributeError( "%s not found on %s" % (devrel, self.id) )
163
164
166 """Return monitored components for devices within this DeviceOrganizer.
167 """
168 cmps = []
169 for dev in self.getSubDevicesGen():
170 cmps.extend(dev.getMonitoredComponents())
171 return cmps
172
173
175 """Count all devices within a device group and get the
176 ping and snmp counts as well"""
177 devices = getattr(self, devrel)
178 pingStatus = 0
179 snmpStatus = 0
180 devCount = devices.countObjects()
181 for dev in devices():
182 if dev.getPingStatusNumber() > 0:
183 pingStatus += 1
184 if dev.getSnmpStatusNumber() > 0:
185 snmpStatus += 1
186 counts = [devCount, pingStatus, snmpStatus]
187 for group in self.children():
188 sc = group.getAllCounts()
189 for i in range(3): counts[i] += sc[i]
190 return counts
191
192
194 """count all devices with in a device group"""
195 unused(devrel)
196 count = self.devices.countObjects()
197 for group in self.children():
198 count += group.countDevices()
199 return count
200
201
203 """aggrigate ping status for all devices in this group and below"""
204 status = self._status("Ping", devrel)
205 for group in self.children():
206 status += group.pingStatus()
207 return status
208
209
211 """aggrigate snmp status for all devices in this group and below"""
212 status = self._status("Snmp", devrel)
213 for group in self.children():
214 status += group.snmpStatus()
215 return status
216
217
219 """Build a device list for set methods"""
220 if isinstance(deviceNames, basestring):
221 deviceNames = [deviceNames]
222 return [d.primaryAq() for d in self.getSubDevices()
223 if deviceNames is None or d.id in deviceNames
224 or d.getPrimaryId() in deviceNames]
225
226
228 """Return list of all organizers excluding our self."""
229 targets = filter(lambda x: x != self.getOrganizerName(),
230 self.dmd.Devices.getOrganizerNames())
231 targets.sort(lambda x,y: cmp(x.lower(), y.lower()))
232 return targets
233
234
236 """Move Devices from one DeviceClass to Another"""
237 if deviceNames is None:
238 if REQUEST:
239 messaging.IMessageSender(self).sendToBrowser(
240 'Error',
241 'No devices were selected',
242 priority=messaging.WARNING
243 )
244 return self.callZenScreen(REQUEST)
245 deviceNames = [ x.split('/')[-1] for x in deviceNames ]
246 return self.dmd.Devices.moveDevices(moveTarget, deviceNames, REQUEST)
247
248
249 - def _handleOrganizerCall(self, arg=None, deviceNames=None, \
250 isOrganizer=False, REQUEST=None, \
251 deviceMethod=None):
252 """ Handle the many many methods that simply call one
253 method on device differently"""
254 #check to see if we have the essentials to work with
255 if not deviceMethod: return
256 if deviceNames is None and not isOrganizer:
257 if REQUEST:
258 messaging.IMessageSender(self).sendToBrowser(
259 'Error',
260 'No devices were selected',
261 priority=messaging.WARNING
262 )
263 return self.callZenScreen(REQUEST)
264 for dev in self._buildDeviceList(deviceNames):
265 devMethod = getattr(dev, deviceMethod, None)
266 if devMethod and arg:
267 devMethod(arg)
268 elif devMethod:
269 devMethod()
270
271
274 """build the standard return message for the various set
275 methods"""
276 if checkPaths:
277 if paths:
278 if type(paths) not in StringTypes:
279 paths = ", ".join(paths)
280 message += paths
281 else:
282 message = "%s unset" % message.split(" ")[0]
283 if self.REQUEST.has_key('oneKeyValueSoInstanceIsntEmptyAndEvalToFalse'):
284 return message
285 else:
286 IMessageSender(self).sendToBrowser(title, message)
287 return self.callZenScreen(self.REQUEST)
288
289
292 """Set production state of all devices in this Organizer.
293 """
294 self._handleOrganizerCall(state, deviceNames, isOrganizer, \
295 REQUEST, "setProdState")
296 if REQUEST:
297 statename = self.convertProdState(state)
298 msg = "Production state set to %s for %s." % (statename,
299 " ".join(deviceNames))
300 return self._buildReturnMessage("Production State Changed", msg)
301
302
305 """Set prioirty of all devices in this Organizer.
306 """
307 self._handleOrganizerCall(priority, deviceNames, isOrganizer, \
308 REQUEST, "setPriority")
309 if REQUEST:
310 priname = self.convertPriority(priority)
311 msg = "Priority set to %s for %s." % (priname,
312 " ".join(deviceNames))
313 return self._buildReturnMessage('Priority Changed', msg)
314
315
316 - def setPerformanceMonitor(self, performanceMonitor=None, deviceNames=None,
317 isOrganizer=False, REQUEST=None):
318 """ Provide a method to set performance monitor from any organizer """
319 if not performanceMonitor:
320 if REQUEST:
321 messaging.IMessageSender(self).sendToBrowser(
322 'Error',
323 'No monitor was selected',
324 priority=messaging.WARNING
325 )
326 return self.callZenScreen(REQUEST)
327 self._handleOrganizerCall(performanceMonitor, deviceNames, isOrganizer, \
328 REQUEST, "setPerformanceMonitor")
329 if REQUEST:
330 msg = "Collector set to %s" % (performanceMonitor)
331 return self._buildReturnMessage('Collector Set', msg)
332
333
336 """ Provide a method to set device groups from any organizer """
337 if not groupPaths: groupPaths = []
338 self._handleOrganizerCall(groupPaths, deviceNames, isOrganizer, \
339 REQUEST, "setGroups")
340 if REQUEST:
341 msg = "Groups set to"
342 return self._buildReturnMessage('Groups Set', msg, groupPaths, True)
343
344
345 - def setSystems(self, systemPaths=None, deviceNames=None,
346 isOrganizer=False, REQUEST=None):
347 """ Provide a method to set device systems from any organizer """
348 if not systemPaths: systemPaths = []
349 self._handleOrganizerCall(systemPaths, deviceNames, isOrganizer, \
350 REQUEST, "setSystems")
351 if REQUEST:
352 msg = "Systems set to"
353 return self._buildReturnMessage('Systems Set', msg, systemPaths, True)
354
355 - def setLocation(self, locationPath="", deviceNames=None,
356 isOrganizer=False, REQUEST=None):
357 """ Provide a method to set device location from any organizer """
358 self._handleOrganizerCall(locationPath, deviceNames, isOrganizer, \
359 REQUEST, "setLocation")
360 if REQUEST:
361 msg = "Location set to %s" % locationPath
362 return self._buildReturnMessage('Location Set', msg)
363
365 """Unlock devices"""
366 self._handleOrganizerCall(None, deviceNames, isOrganizer, \
367 REQUEST, "unlock")
368 if REQUEST:
369 msg = "Devices unlocked"
370 return self._buildReturnMessage('Devices Unlocked', msg)
371
372 - def lockDevicesFromDeletion(self, deviceNames=None,
373 sendEventWhenBlocked=None, isOrganizer=False, REQUEST=None):
374 """Lock devices from being deleted"""
375 self._handleOrganizerCall(sendEventWhenBlocked, deviceNames, isOrganizer, \
376 REQUEST, "lockFromDeletion")
377 if REQUEST:
378 msg = "Devices locked from deletion"
379 return self._buildReturnMessage('Devices Locked', msg)
380
381 - def lockDevicesFromUpdates(self, deviceNames=None,
382 sendEventWhenBlocked=None, isOrganizer=False, REQUEST=None):
383 """Lock devices from being deleted or updated"""
384 self._handleOrganizerCall(sendEventWhenBlocked, deviceNames, isOrganizer, \
385 REQUEST, "lockFromUpdates")
386 if REQUEST:
387 msg = "Devices locked from updates and deletion"
388 return self._buildReturnMessage('Devices Locked', msg)
389
390
392 """No action.
393 Index of subdevices will happen in manage_addAdministrativeRole
394 """
395 pass
396
398 """No action.
399 Unindex of subdevices will happen in manage_deleteAdministrativeRole
400 """
401 pass
402
404 """
405 Overrides AdministrativeRoleable.manage_addAdministrativeRole
406 Adds an administrator to this DeviceOrganizer
407
408 @param userid: User to make an administrator of this Organizer
409 @type userid: string
410 """
411 AdministrativeRoleable.manage_addAdministrativeRole(self, newId)
412 for dev in self.getSubDevices():
413 dev = dev.primaryAq()
414 dev.setAdminLocalRoles()
415 if REQUEST:
416 messaging.IMessageSender(self).sendToBrowser(
417 'Role Added',
418 'Administrative role %s was added.' % newId
419 )
420 return self.callZenScreen(REQUEST)
421
422
425 """
426 Overrides AdministrativeRoleable.manage_editAdministrativeRoles
427 Edit the administrators to this DeviceOrganizer
428 """
429 AdministrativeRoleable.manage_editAdministrativeRoles(
430 self,ids,role,level)
431 for dev in self.getSubDevices():
432 dev = dev.primaryAq()
433 dev.setAdminLocalRoles()
434 if REQUEST:
435 messaging.IMessageSender(self).sendToBrowser(
436 'Role Added',
437 'Administrative roles were updated: %s' % ', '.join(ids)
438 )
439 return self.callZenScreen(REQUEST)
440
441
443 """
444 Overrides AdministrativeRoleable.manage_deleteAdministrativeRole
445 Deletes administrators to this DeviceOrganizer
446
447 @param delids: Users to delete from this Organizer
448 @type delids: tuple of strings
449 """
450 AdministrativeRoleable.manage_deleteAdministrativeRole(self, delids)
451 for dev in self.getSubDevices():
452 dev = dev.primaryAq()
453 dev.setAdminLocalRoles()
454 if REQUEST:
455 if delids:
456 messaging.IMessageSender(self).sendToBrowser(
457 'Roles Deleted',
458 'Administrative roles were deleted: %s' % ', '.join(delids)
459 )
460 return self.callZenScreen(REQUEST)
461
462
464 """reset Community on all devices in this Organizer.
465 """
466 [ d.manage_snmpCommunity() for d in self.getSubDevices() ]
467 if REQUEST:
468 return self.callZenScreen(REQUEST)
469
471 """reset ip on all devices in this Organizer.
472 """
473 [ d.setManageIp() for d in self.getSubDevices() ]
474 if REQUEST:
475 return self.callZenScreen(REQUEST)
476
478 """model all devices in this Organizer.
479 """
480 [ d.collectDevice() for d in self.getSubDevices() ]
481 if REQUEST:
482 return self.callZenScreen(REQUEST)
483
485 """build status info for device in this device group"""
486 status = 0
487 statatt = "get%sStatusNumber" % type
488 devices = getattr(self, devrel, None)
489 if not devices:
490 raise AttributeError( "%s not found on %s" % (devrel, self.id) )
491 for device in devices():
492 if getattr(device, statatt, -1)() > 0:
493 status += 1
494 return status
495
497 """colors for status fields for device groups"""
498 retval = '#00ff00'
499 if status == -1:
500 retval = "#d02090"
501 elif status == 1:
502 retval = '#ffff00'
503 elif status == 2:
504 retval = '#ff9900'
505 elif status > 2:
506 retval = '#ff0000'
507 return retval
508
510 ''' Called by Commandable.doCommand() to ascertain objects on which
511 a UserCommand should be executed.
512 '''
513 return self.getSubDevices()
514
516 return self.getPrimaryUrlPath() + '/deviceOrganizerManage'
517
519 """ Return all Links on all interfaces on all
520 Devices in this Organizer
521 """
522 alllinks = []
523 if recursive:
524 devices = self.getSubDevicesGen()
525 else:
526 devices = self.devices.objectValuesGen()
527 for device in devices:
528 alllinks.extend(list(device.getLinks()))
529 return alllinks
530
531 security.declareProtected(ZEN_VIEW, 'getIconPath')
533 """ Override the zProperty icon path and return a folder
534 """
535 return "/zport/dmd/img/icons/folder.png"
536
537 security.declareProtected(ZEN_VIEW, 'getPrettyLink')
539 """ Gets a link to this object, plus an icon """
540 href = self.getPrimaryUrlPath().replace('%','%%')
541 linktemplate = "<a href='"+href+"' class='prettylink'>%s</a>"
542 icon = ("<div class='device-icon-container'> "
543 "<img class='device-icon' src='%s'/> "
544 "</div>") % self.getIconPath()
545 name = self.getPrimaryDmdId()
546 if noicon: icon=''
547 if shortDesc: name = self.id
548 rendered = icon + name
549 if not self.checkRemotePerm("View", self):
550 return rendered
551 else:
552 return linktemplate % rendered
553
554 InitializeClass(DeviceOrganizer)
555
| Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0beta1 on Thu May 7 11:46:22 2009 | http://epydoc.sourceforge.net |