1
2
3
4
5
6
7
8
9
10
11
12
13
14 import types
15 import re
16
17 from AccessControl import ClassSecurityInfo
18 from Globals import InitializeClass
19 from Acquisition import aq_parent
20
21 from Organizer import Organizer
22 from DeviceManagerBase import DeviceManagerBase
23 from Commandable import Commandable
24 from ZenMenuable import ZenMenuable
25 from MaintenanceWindowable import MaintenanceWindowable
26 from AdministrativeRoleable import AdministrativeRoleable
27
28 from Products.AdvancedQuery import MatchRegexp, Eq, Or, In
29
30 from Products.ZenRelations.RelSchema import *
31 import simplejson
32
33 from ZenossSecurity import *
34
35 -class DeviceOrganizer(Organizer, DeviceManagerBase, Commandable, ZenMenuable,
36 MaintenanceWindowable, AdministrativeRoleable):
37 """
38 DeviceOrganizer is the base class for device organizers.
39 It has lots of methods for rolling up device statistics and information.
40 """
41
42 security = ClassSecurityInfo()
43
44
45 factory_type_information = (
46 {
47 'immediate_view' : 'deviceOrganizerStatus',
48 'actions' :
49 (
50 { 'id' : 'status'
51 , 'name' : 'Status'
52 , 'action' : 'deviceOrganizerStatus'
53 , 'permissions' : (ZEN_VIEW, )
54 },
55 { 'id' : 'events'
56 , 'name' : 'Events'
57 , 'action' : 'viewEvents'
58 , 'permissions' : (ZEN_VIEW, )
59 },
60 { 'id' : 'historyEvents'
61 , 'name' : 'History'
62 , 'action' : 'viewHistoryEvents'
63 , 'permissions' : (ZEN_VIEW, )
64 },
65 { 'id' : 'manage'
66 , 'name' : 'Administration'
67 , 'action' : 'deviceOrganizerManage'
68 , 'permissions' : (ZEN_MANAGE_DMD,)
69 },
70 )
71 },
72 )
73
74 _relations = Organizer._relations + (
75 ("maintenanceWindows", ToManyCont(
76 ToOne, "Products.ZenModel.MaintenanceWindow", "productionState")),
77 ("adminRoles", ToManyCont(
78 ToOne,"Products.ZenModel.AdministrativeRole","managedObject")),
79 ('userCommands', ToManyCont(
80 ToOne, 'Products.ZenModel.UserCommand', 'commandable')),
81 ('zenMenus', ToManyCont(
82 ToOne, 'Products.ZenModel.ZenMenu', 'menuable')),
83 )
84
85 security.declareProtected(ZEN_COMMON, "getSubDevices")
87 """
88 Get all the devices under an instance of a DeviceOrganizer
89
90 @param devfilter: Filter function applied to returned list
91 @type devfilter: function
92 @param devrel: Relationship that contains devices
93 @type devrel: string
94 @return: Devices
95 @rtype: list
96
97
98 """
99 devrelobj = getattr(self, devrel, None)
100 if not devrelobj:
101 raise AttributeError, "%s not found on %s" % (devrel, self.id)
102 devices = filter(devfilter, devrelobj())
103 devices = [ dev for dev in devices if self.checkRemotePerm(ZEN_VIEW, dev)]
104 for subgroup in self.children():
105 devices.extend(subgroup.getSubDevices(devfilter, devrel))
106 return devices
107
108
109 security.declareProtected(ZEN_VIEW, "getSubDevicesGen")
111 """get all the devices under and instance of a DeviceGroup"""
112 devrelobj = getattr(self, devrel, None)
113 if not devrelobj:
114 raise AttributeError, "%s not found on %s" % (devrel, self.id)
115 for dev in devrelobj.objectValuesGen():
116 yield dev
117 for subgroup in self.children():
118 for dev in subgroup.getSubDevicesGen(devrel):
119 yield dev
120
122 """get all the devices under and instance of a DeviceGroup"""
123 devices = getattr(self, devrel, None)
124 if not devices:
125 raise AttributeError, "%s not found on %s" % (devrel, self.id)
126
127
129 """Return monitored components for devices within this DeviceOrganizer.
130 """
131 cmps = []
132 for dev in self.getSubDevicesGen():
133 cmps.extend(dev.getMonitoredComponents())
134 return cmps
135
136
154
155
162
163
170
171
178
179
181 """Build a device list for set methods"""
182 if isinstance(deviceNames, basestring):
183 deviceNames = [deviceNames]
184 return [d for d in self.getSubDevices()
185 if deviceNames is None or d.id in deviceNames
186 or d.getPrimaryId() in deviceNames]
187
188
195
196
198 """Move Devices from one DeviceClass to Another"""
199 if deviceNames is None:
200 if REQUEST: REQUEST['message'] = "No Devices Selected"
201 return self.callZenScreen(REQUEST)
202 deviceNames = [ x.split('/')[-1] for x in deviceNames ]
203 return self.dmd.Devices.moveDevices(moveTarget, deviceNames, REQUEST)
204
205
222
239
240
243 """ Provide a method to set status monitors from any organizer """
244 if not statusMonitors:
245 if REQUEST: REQUEST['message'] = "No Monitor Selected"
246 return self.callZenScreen(REQUEST)
247 if deviceNames is None and not isOrganizer:
248 if REQUEST: REQUEST['message'] = "No Devices Selected"
249 return self.callZenScreen(REQUEST)
250 for dev in self._buildDeviceList(deviceNames):
251 dev.setStatusMonitors(statusMonitors)
252 if REQUEST:
253 if len(statusMonitors) == 1:
254 REQUEST['message'] = "Status monitor set to %s" % statusMonitors
255 elif len(statusMonitors) > 1:
256 REQUEST['message'] = "Status monitor set to %s" % ", ".join(statusMonitors)
257 else:
258 REQUEST['message'] = "Status monitor unset"
259 if REQUEST.has_key('oneKeyValueSoInstanceIsntEmptyAndEvalToFalse'):
260 return REQUEST['message']
261 else:
262 return self.callZenScreen(REQUEST)
263
282
283
286 """ Provide a method to set device groups from any organizer """
287 if deviceNames is None and not isOrganizer:
288 if REQUEST: REQUEST['message'] = "No Devices Selected"
289 return self.callZenScreen(REQUEST)
290 if not groupPaths: groupPaths = []
291 for dev in self._buildDeviceList(deviceNames):
292 dev.setGroups(groupPaths)
293 if REQUEST:
294 if len(groupPaths) == 1:
295 REQUEST['message'] = "Groups set to %s" % groupPaths
296 elif len(groupPaths) > 1:
297 REQUEST['message'] = "Groups set to %s" % ", ".join(groupPaths)
298 else:
299 REQUEST['message'] = "Groups unset"
300 if REQUEST.has_key('oneKeyValueSoInstanceIsntEmptyAndEvalToFalse'):
301 return REQUEST['message']
302 else:
303 return self.callZenScreen(REQUEST)
304
305
308 """ Provide a method to set device systems from any organizer """
309 if deviceNames is None and not isOrganizer:
310 if REQUEST: REQUEST['message'] = "No Devices Selected"
311 return self.callZenScreen(REQUEST)
312 if not systemPaths: systemPaths = []
313 for dev in self._buildDeviceList(deviceNames):
314 dev.setSystems(systemPaths)
315 if REQUEST:
316 if len(systemPaths) == 1:
317 REQUEST['message'] = "Systems set to %s" % systemPaths
318 elif len(systemPaths) > 1:
319 REQUEST['message'] = "Systems set to %s" % ", ".join(systemPaths)
320 else:
321 REQUEST['message'] = "Systems unset"
322 if REQUEST.has_key('oneKeyValueSoInstanceIsntEmptyAndEvalToFalse'):
323 return REQUEST['message']
324 else:
325 return self.callZenScreen(REQUEST)
326
341
355
370
385
386
388 """No action.
389 Index of subdevices will happen in manage_addAdministrativeRole
390 """
391 pass
392
394 """No action.
395 Unindex of subdevices will happen in manage_deleteAdministrativeRole
396 """
397 pass
398
414
415
430
431
447
448
455
462
469
470 - def _status(self, type, devrel="devices"):
481
482
484 """colors for status fields for device groups"""
485 retval = '#00ff00'
486 if status == -1:
487 retval = "#d02090"
488 elif status == 1:
489 retval = '#ffff00'
490 elif status == 2:
491 retval = '#ff9900'
492 elif status > 2:
493 retval = '#ff0000'
494 return retval
495
496
498 ''' Called by Commandable.doCommand() to ascertain objects on which
499 a UserCommand should be executed.
500 '''
501 return self.getSubDevices()
502
503
506
507
510 catalog = getattr(self, self.default_catalog)
511 filter = '(?is).*%s.*' % filter
512 filterquery = Or(
513 MatchRegexp('id', filter),
514 MatchRegexp('getDeviceIp', filter),
515 MatchRegexp('getProdState', filter),
516 MatchRegexp('getDeviceClassPath', filter)
517 )
518 query = Eq('getPhysicalPath', self.absolute_url_path()
519 ) & filterquery
520 objects = catalog.evalAdvancedQuery(query, ((orderby, orderdir),))
521 objects = list(objects)
522 totalCount = len(objects)
523 offset, count = int(offset), int(count)
524 return totalCount, objects[offset:offset+count]
525
526
527 - def getJSONDeviceInfo(self, offset=0, count=50, filter='',
528 orderby='id', orderdir='asc'):
535
536
537 - def getDeviceBatch(self, selectstatus='none', goodevids=[],
538 badevids=[], offset=0, count=50, filter='',
539 orderby='id', orderdir='asc'):
540 if not isinstance(goodevids, (list, tuple)):
541 goodevids = [goodevids]
542 if not isinstance(badevids, (list, tuple)):
543 badevids = [badevids]
544 if selectstatus=='all':
545 idquery = ~In('id', badevids)
546 else:
547 idquery = In('id', goodevids)
548 filterquery = Or(
549 MatchRegexp('id', filter),
550 MatchRegexp('getDeviceIp', filter),
551 MatchRegexp('getProdState', filter),
552 MatchRegexp('getDeviceClassPath', filter)
553 )
554 query = Eq('getPhysicalPath', self.absolute_url_path()) & idquery
555 query = query & filterquery
556 catalog = getattr(self, self.default_catalog)
557 objects = catalog.evalAdvancedQuery(query)
558 return [x['id'] for x in objects]
559
572
573
574 security.declareProtected(ZEN_VIEW, 'getIconPath')
576 """ Override the zProperty icon path and return a folder
577 """
578 return "/zport/dmd/img/icons/folder.png"
579
580 security.declareProtected(ZEN_VIEW, 'getEventPill')
582 """ Gets event pill for worst severity """
583 pill = self.ZenEventManager.getEventPillME(self, showGreen=showGreen)
584 if type(pill)==type([]) and len(pill)==1: return pill[0]
585 return pill
586
587 security.declareProtected(ZEN_VIEW, 'getPrettyLink')
589 """ Gets a link to this object, plus an icon """
590 href = self.getPrimaryUrlPath().replace('%','%%')
591 linktemplate = "<a href='"+href+"' class='prettylink'>%s</a>"
592 icon = ("<div class='device-icon-container'> "
593 "<img class='device-icon' src='%s'/> "
594 "</div>") % self.getIconPath()
595 name = self.getPrimaryDmdId()
596 if noicon: icon=''
597 if shortDesc: name = self.id
598 rendered = icon + name
599 if not self.checkRemotePerm("View", self):
600 return rendered
601 else:
602 return linktemplate % rendered
603
608
613
615 return self.ZenEventManager.getObjectsEventSummary([self], REQUEST)
616
617 InitializeClass(DeviceOrganizer)
618