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