Package Products :: Package ZenModel :: Module DeviceOrganizer
[hide private]
[frames] | no frames]

Source Code for Module Products.ZenModel.DeviceOrganizer

  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")
97 - def getSubDevices(self, devfilter=None):
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")
121 - def getSubDevicesGen(self):
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")
137 - def getSubDevices_recursive(self, devfilter=None, devrel="devices"):
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")
149 - def getSubDevicesGen_recursive(self, devrel="devices"):
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
160 - def getSubDevicesGenTest(self, devrel="devices"):
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
167 - def getMonitoredComponents(self):
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
176 - def getAllCounts(self, devrel="devices"):
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
195 - def countDevices(self, devrel="devices"):
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
204 - def pingStatus(self, devrel="devices"):
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
212 - def snmpStatus(self, devrel="devices"):
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
220 - def _buildDeviceList(self, deviceNames):
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
229 - def deviceClassMoveTargets(self):
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
237 - def moveDevicesToClass(self, moveTarget, deviceNames=None, REQUEST=None):
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
274 - def _buildReturnMessage(self, title, message, paths=None, \ 275 checkPaths=False):
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')
293 - def setProdState(self, state, deviceNames=None, 294 isOrganizer=False, REQUEST=None):
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
306 - def setPriority(self, priority, deviceNames=None, 307 isOrganizer=False, REQUEST=None):
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
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):
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
367 - def unlockDevices(self, deviceNames=None, isOrganizer=False, REQUEST=None):
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
394 - def index_object(self, idxs=None):
395 """No action. 396 Index of subdevices will happen in manage_addAdministrativeRole 397 """ 398 pass
399
400 - def unindex_object(self):
401 """No action. 402 Unindex of subdevices will happen in manage_deleteAdministrativeRole 403 """ 404 pass
405
406 - def manage_addAdministrativeRole(self, newId, REQUEST=None):
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
429 - def manage_editAdministrativeRoles(self, ids=(), role=(), 430 level=(), REQUEST=None):
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
450 - def manage_deleteAdministrativeRole(self, delids=(), REQUEST=None):
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
473 - def manage_snmpCommunity(self, REQUEST=None):
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
480 - def setManageIp(self, REQUEST=None):
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
487 - def collectDevice(self, REQUEST=None):
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
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
506 - def statusColor(self, status):
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
519 - def getUserCommandTargets(self):
520 ''' Called by Commandable.doCommand() to ascertain objects on which 521 a UserCommand should be executed. 522 ''' 523 return self.getSubDevices()
524
525 - def getUrlForUserCommands(self):
526 return self.getPrimaryUrlPath() + '/deviceOrganizerManage'
527 540 541 security.declareProtected(ZEN_VIEW, 'getIconPath')
542 - def getIconPath(self):
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')
563 564 InitializeClass(DeviceOrganizer) 565