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 as published by 
  8  # the Free Software Foundation. 
  9  # 
 10  # For complete information please visit: http://www.zenoss.com/oss/ 
 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 # Screen action bindings (and tab definitions) 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 # { 'id' : 'historyEvents' 70 # , 'name' : 'History' 71 # , 'action' : 'viewHistoryEvents' 72 # , 'permissions' : (ZEN_VIEW, ) 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")
95 - def getSubDevices(self, devfilter=None):
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")
119 - def getSubDevicesGen(self):
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")
135 - def getSubDevices_recursive(self, devfilter=None, devrel="devices"):
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")
147 - def getSubDevicesGen_recursive(self, devrel="devices"):
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
158 - def getSubDevicesGenTest(self, devrel="devices"):
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
165 - def getMonitoredComponents(self):
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
174 - def getAllCounts(self, devrel="devices"):
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
193 - def countDevices(self, devrel="devices"):
194 """count all devices with in a device group""" 195 unused(devrel) 196 count = self.devices.countObjects() 197 for group in self.children(): 198 count += group.countDevices() 199 return count
200 201
202 - def pingStatus(self, devrel="devices"):
203 """aggrigate ping status for all devices in this group and below""" 204 status = self._status("Ping", devrel) 205 for group in self.children(): 206 status += group.pingStatus() 207 return status
208 209
210 - def snmpStatus(self, devrel="devices"):
211 """aggrigate snmp status for all devices in this group and below""" 212 status = self._status("Snmp", devrel) 213 for group in self.children(): 214 status += group.snmpStatus() 215 return status
216 217
218 - def _buildDeviceList(self, deviceNames):
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
227 - def deviceClassMoveTargets(self):
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
235 - def moveDevicesToClass(self, moveTarget, deviceNames=None, REQUEST=None):
236 """Move Devices from one DeviceClass to Another""" 237 if deviceNames is None: 238 if REQUEST: 239 messaging.IMessageSender(self).sendToBrowser( 240 'Error', 241 'No devices were selected', 242 priority=messaging.WARNING 243 ) 244 return self.callZenScreen(REQUEST) 245 deviceNames = [ x.split('/')[-1] for x in deviceNames ] 246 return self.dmd.Devices.moveDevices(moveTarget, deviceNames, REQUEST)
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 #check to see if we have the essentials to work with 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
272 - def _buildReturnMessage(self, title, message, paths=None, \ 273 checkPaths=False):
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):
293 """Set production state of all devices in this Organizer. 294 """ 295 self._handleOrganizerCall(state, deviceNames, isOrganizer, \ 296 REQUEST, "setProdState") 297 if REQUEST: 298 statename = self.convertProdState(state) 299 msg = "Production state set to %s for %s." % (statename, 300 " ".join(deviceNames)) 301 return self._buildReturnMessage("Production State Changed", msg)
302 303
304 - def setPriority(self, priority, deviceNames=None, 305 isOrganizer=False, REQUEST=None):
306 """Set prioirty of all devices in this Organizer. 307 """ 308 self._handleOrganizerCall(priority, deviceNames, isOrganizer, \ 309 REQUEST, "setPriority") 310 if REQUEST: 311 priname = self.convertPriority(priority) 312 msg = "Priority set to %s for %s." % (priname, 313 " ".join(deviceNames)) 314 return self._buildReturnMessage('Priority Changed', msg)
315 316
317 - def setPerformanceMonitor(self, performanceMonitor=None, deviceNames=None, 318 isOrganizer=False, REQUEST=None):
319 """ Provide a method to set performance monitor from any organizer """ 320 if not performanceMonitor: 321 if REQUEST: 322 messaging.IMessageSender(self).sendToBrowser( 323 'Error', 324 'No monitor was selected', 325 priority=messaging.WARNING 326 ) 327 return self.callZenScreen(REQUEST) 328 self._handleOrganizerCall(performanceMonitor, deviceNames, isOrganizer, \ 329 REQUEST, "setPerformanceMonitor") 330 if REQUEST: 331 msg = "Collector set to %s" % (performanceMonitor) 332 return self._buildReturnMessage('Collector Set', msg)
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):
358 """ Provide a method to set device location from any organizer """ 359 self._handleOrganizerCall(locationPath, deviceNames, isOrganizer, \ 360 REQUEST, "setLocation") 361 if REQUEST: 362 msg = "Location set to %s" % locationPath 363 return self._buildReturnMessage('Location Set', msg)
364
365 - def unlockDevices(self, deviceNames=None, isOrganizer=False, REQUEST=None):
366 """Unlock devices""" 367 self._handleOrganizerCall(None, deviceNames, isOrganizer, \ 368 REQUEST, "unlock") 369 if REQUEST: 370 msg = "Devices unlocked" 371 return self._buildReturnMessage('Devices Unlocked', msg)
372
373 - def lockDevicesFromDeletion(self, deviceNames=None, 374 sendEventWhenBlocked=None, isOrganizer=False, REQUEST=None):
375 """Lock devices from being deleted""" 376 self._handleOrganizerCall(sendEventWhenBlocked, deviceNames, isOrganizer, \ 377 REQUEST, "lockFromDeletion") 378 if REQUEST: 379 msg = "Devices locked from deletion" 380 return self._buildReturnMessage('Devices Locked', msg)
381
382 - def lockDevicesFromUpdates(self, deviceNames=None, 383 sendEventWhenBlocked=None, isOrganizer=False, REQUEST=None):
384 """Lock devices from being deleted or updated""" 385 self._handleOrganizerCall(sendEventWhenBlocked, deviceNames, isOrganizer, \ 386 REQUEST, "lockFromUpdates") 387 if REQUEST: 388 msg = "Devices locked from updates and deletion" 389 return self._buildReturnMessage('Devices Locked', msg)
390 391
392 - def index_object(self):
393 """No action. 394 Index of subdevices will happen in manage_addAdministrativeRole 395 """ 396 pass
397
398 - def unindex_object(self):
399 """No action. 400 Unindex of subdevices will happen in manage_deleteAdministrativeRole 401 """ 402 pass
403
404 - def manage_addAdministrativeRole(self, newId, REQUEST=None):
405 """ 406 Overrides AdministrativeRoleable.manage_addAdministrativeRole 407 Adds an administrator to this DeviceOrganizer 408 409 @param userid: User to make an administrator of this Organizer 410 @type userid: string 411 """ 412 413 AdministrativeRoleable.manage_addAdministrativeRole(self, newId) 414 for dev in self.getSubDevices(): 415 dev = dev.primaryAq() 416 dev.setAdminLocalRoles() 417 418 notify(IndexingEvent(self, ('allowedRolesAndUsers',), False)) 419 if REQUEST: 420 messaging.IMessageSender(self).sendToBrowser( 421 'Role Added', 422 'Administrative role %s was added.' % newId 423 ) 424 return self.callZenScreen(REQUEST)
425 426
427 - def manage_editAdministrativeRoles(self, ids=(), role=(), 428 level=(), REQUEST=None):
429 """ 430 Overrides AdministrativeRoleable.manage_editAdministrativeRoles 431 Edit the administrators to this DeviceOrganizer 432 """ 433 AdministrativeRoleable.manage_editAdministrativeRoles( 434 self,ids,role,level) 435 for dev in self.getSubDevices(): 436 dev = dev.primaryAq() 437 dev.setAdminLocalRoles() 438 439 notify(IndexingEvent(self, ('allowedRolesAndUsers',), False)) 440 if REQUEST: 441 messaging.IMessageSender(self).sendToBrowser( 442 'Role Added', 443 'Administrative roles were updated: %s' % ', '.join(ids) 444 ) 445 return self.callZenScreen(REQUEST)
446 447
448 - def manage_deleteAdministrativeRole(self, delids=(), REQUEST=None):
449 """ 450 Overrides AdministrativeRoleable.manage_deleteAdministrativeRole 451 Deletes administrators to this DeviceOrganizer 452 453 @param delids: Users to delete from this Organizer 454 @type delids: tuple of strings 455 """ 456 AdministrativeRoleable.manage_deleteAdministrativeRole(self, delids) 457 for dev in self.getSubDevices(): 458 dev = dev.primaryAq() 459 dev.setAdminLocalRoles() 460 461 notify(IndexingEvent(self, ('allowedRolesAndUsers',), False)) 462 if REQUEST: 463 if delids: 464 messaging.IMessageSender(self).sendToBrowser( 465 'Roles Deleted', 466 'Administrative roles were deleted: %s' % ', '.join(delids) 467 ) 468 return self.callZenScreen(REQUEST)
469 470
471 - def manage_snmpCommunity(self, REQUEST=None):
472 """reset Community on all devices in this Organizer. 473 """ 474 [ d.manage_snmpCommunity() for d in self.getSubDevices() ] 475 if REQUEST: 476 return self.callZenScreen(REQUEST)
477
478 - def setManageIp(self, REQUEST=None):
479 """reset ip on all devices in this Organizer. 480 """ 481 [ d.setManageIp() for d in self.getSubDevices() ] 482 if REQUEST: 483 return self.callZenScreen(REQUEST)
484
485 - def collectDevice(self, REQUEST=None):
486 """model all devices in this Organizer. 487 """ 488 [ d.collectDevice() for d in self.getSubDevices() ] 489 if REQUEST: 490 return self.callZenScreen(REQUEST)
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
504 - def statusColor(self, status):
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
517 - def getUserCommandTargets(self):
518 ''' Called by Commandable.doCommand() to ascertain objects on which 519 a UserCommand should be executed. 520 ''' 521 return self.getSubDevices()
522
523 - def getUrlForUserCommands(self):
524 return self.getPrimaryUrlPath() + '/deviceOrganizerManage'
525 538 539 security.declareProtected(ZEN_VIEW, 'getIconPath')
540 - def getIconPath(self):
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')
561 562 InitializeClass(DeviceOrganizer) 563