1
2
3
4
5
6
7
8
9
10
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 from zope.event import notify
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 from Products.Zuul.catalog.events import IndexingEvent
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, getObjectsFromCatalog
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
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
70
71
72
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 devices = getObjectsFromCatalog(catalog, {
112 'path': "/".join(self.getPhysicalPath())}, LOG)
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 devices = getObjectsFromCatalog(catalog, {
128 'path': "/".join(self.getPhysicalPath())}, LOG)
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
200
201
208
209
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
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
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
290 security.declareProtected(ZEN_CHANGE_DEVICE_PRODSTATE, 'setProdState')
291 - def setProdState(self, state, deviceNames=None,
292 isOrganizer=False, REQUEST=None):
302
303
304 - def setPriority(self, priority, deviceNames=None,
305 isOrganizer=False, REQUEST=None):
315
316
333
334
335 - def setGroups(self, groupPaths=None, deviceNames=None,
336 isOrganizer=False, REQUEST=None):
337 """ Provide a method to set device groups from any organizer """
338 if not groupPaths: groupPaths = []
339 self._handleOrganizerCall(groupPaths, deviceNames, isOrganizer, \
340 REQUEST, "setGroups")
341 if REQUEST:
342 msg = "Groups set to"
343 return self._buildReturnMessage('Groups Set', msg, groupPaths, True)
344
345
346 - def setSystems(self, systemPaths=None, deviceNames=None,
347 isOrganizer=False, REQUEST=None):
348 """ Provide a method to set device systems from any organizer """
349 if not systemPaths: systemPaths = []
350 self._handleOrganizerCall(systemPaths, deviceNames, isOrganizer, \
351 REQUEST, "setSystems")
352 if REQUEST:
353 msg = "Systems set to"
354 return self._buildReturnMessage('Systems Set', msg, systemPaths, True)
355
356 - def setLocation(self, locationPath="", deviceNames=None,
357 isOrganizer=False, REQUEST=None):
364
365 - def unlockDevices(self, deviceNames=None, isOrganizer=False, REQUEST=None):
372
373 - def lockDevicesFromDeletion(self, deviceNames=None,
374 sendEventWhenBlocked=None, isOrganizer=False, REQUEST=None):
381
382 - def lockDevicesFromUpdates(self, deviceNames=None,
383 sendEventWhenBlocked=None, isOrganizer=False, REQUEST=None):
390
391
393 """No action.
394 Index of subdevices will happen in manage_addAdministrativeRole
395 """
396 pass
397
399 """No action.
400 Unindex of subdevices will happen in manage_deleteAdministrativeRole
401 """
402 pass
403
425
426
446
447
469
470
477
484
491
492 - def _status(self, type, devrel="devices"):
493 """build status info for device in this device group"""
494 status = 0
495 statatt = "get%sStatusNumber" % type
496 devices = getattr(self, devrel, None)
497 if not devices:
498 raise AttributeError( "%s not found on %s" % (devrel, self.id) )
499 for device in devices():
500 if getattr(device, statatt, -1)() > 0:
501 status += 1
502 return status
503
505 """colors for status fields for device groups"""
506 retval = '#00ff00'
507 if status == -1:
508 retval = "#d02090"
509 elif status == 1:
510 retval = '#ffff00'
511 elif status == 2:
512 retval = '#ff9900'
513 elif status > 2:
514 retval = '#ff0000'
515 return retval
516
518 ''' Called by Commandable.doCommand() to ascertain objects on which
519 a UserCommand should be executed.
520 '''
521 return self.getSubDevices()
522
525
527 """ Return all Links on all interfaces on all
528 Devices in this Organizer
529 """
530 alllinks = []
531 if recursive:
532 devices = self.getSubDevicesGen()
533 else:
534 devices = self.devices.objectValuesGen()
535 for device in devices:
536 alllinks.extend(list(device.getLinks()))
537 return alllinks
538
539 security.declareProtected(ZEN_VIEW, 'getIconPath')
541 """ Override the zProperty icon path and return a folder
542 """
543 return "/zport/dmd/img/icons/folder.png"
544
545 security.declareProtected(ZEN_VIEW, 'getPrettyLink')
547 """ Gets a link to this object, plus an icon """
548 href = self.getPrimaryUrlPath().replace('%','%%')
549 linktemplate = "<a href='"+href+"' class='prettylink'>%s</a>"
550 icon = ("<div class='device-icon-container'> "
551 "<img class='device-icon' src='%s'/> "
552 "</div>") % self.getIconPath()
553 name = self.getPrimaryDmdId()
554 if noicon: icon=''
555 if shortDesc: name = self.id
556 rendered = icon + name
557 if not self.checkRemotePerm("View", self):
558 return rendered
559 else:
560 return linktemplate % rendered
561
562 InitializeClass(DeviceOrganizer)
563