1
2
3
4
5
6
7
8
9
10
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
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
72
73
74
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
202
203
210
211
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
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
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
290
291
292 security.declareProtected(ZEN_CHANGE_DEVICE_PRODSTATE, 'setProdState')
293 - def setProdState(self, state, deviceNames=None,
294 isOrganizer=False, REQUEST=None):
304
305
306 - def setPriority(self, priority, deviceNames=None,
307 isOrganizer=False, REQUEST=None):
317
318
335
336
337 - def setGroups(self, groupPaths=None, deviceNames=None,
338 isOrganizer=False, REQUEST=None):
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):
366
367 - def unlockDevices(self, deviceNames=None, isOrganizer=False, REQUEST=None):
374
375 - def lockDevicesFromDeletion(self, deviceNames=None,
376 sendEventWhenBlocked=None, isOrganizer=False, REQUEST=None):
383
384 - def lockDevicesFromUpdates(self, deviceNames=None,
385 sendEventWhenBlocked=None, isOrganizer=False, REQUEST=None):
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
427
428
448
449
471
472
479
486
493
494 - def _status(self, type, devrel="devices"):
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
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