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

Source Code for Module Products.ZenModel.Organizer

  1  ############################################################################## 
  2  #  
  3  # Copyright (C) Zenoss, Inc. 2007, all rights reserved. 
  4  #  
  5  # This content is made available according to terms specified in 
  6  # License.zenoss under the directory where your Zenoss product is installed. 
  7  #  
  8  ############################################################################## 
  9   
 10   
 11  __doc__ = """Organizer 
 12  Base class for all Zenoss organizers 
 13  """ 
 14   
 15  from Globals import InitializeClass 
 16  from Acquisition import aq_parent 
 17  from AccessControl import ClassSecurityInfo, getSecurityManager 
 18   
 19  from Products.ZenRelations.RelSchema import * 
 20  from Products.ZenUtils.Exceptions import ZentinelException 
 21  from Products.ZenWidgets import messaging 
 22  from Products.ZenMessaging.audit import audit 
 23  from Products.ZenUtils.Utils import getDisplayType, getDisplayName 
 24  from Products.ZenUtils.deprecated import deprecated 
 25   
 26  from EventView import EventView 
 27  from ZenModelRM import ZenModelRM 
 28  from ZenossSecurity import * 
29 30 -class Organizer(ZenModelRM, EventView):
31 """ 32 The base for all hierarchical organization classes. It allows Organizers 33 to be addressed and created with file system like paths like 34 /Devices/Servers. Organizers have a containment relation called children. 35 Subclasses must define the attribute: 36 37 dmdRootName - root in the dmd database for this organizer 38 """ 39 40 _properties = ( 41 {'id':'description', 'type':'string', 'mode':'w'}, 42 ) 43 44 _relations = ZenModelRM._relations 45 46 security = ClassSecurityInfo() 47 security.declareObjectProtected(ZEN_VIEW) 48
49 - def __init__(self, id, description = ''):
50 """ 51 @param id: Name of this organizer 52 @type id: string 53 @param description: A decription of this organizer 54 @type description: string 55 @rtype: Organizer 56 """ 57 ZenModelRM.__init__(self, id) 58 self.description = description
59 69 70
71 - def childMoveTargets(self):
72 """ 73 Returns a list of all organizer names 74 under the same root excluding ourselves 75 76 @return: A list of organizers excluding our self. 77 @rtype: list 78 @todo: We should be using either deviceMoveTargets or childMoveTargets 79 80 >>> dmd.Events.getOrganizerName() in dmd.Events.childMoveTargets() 81 False 82 """ 83 myname = self.getOrganizerName() 84 return filter(lambda x: x != myname, 85 self.getDmdRoot(self.dmdRootName).getOrganizerNames())
86
87 - def getChildMoveTarget(self, moveTargetName):
88 """ 89 Returns an organizer under the same root. 90 91 @param moveTargetName: Name of the organizer 92 @type moveTargetName: string 93 @rtype: Organizer 94 95 >>> dmd.Devices.getChildMoveTarget('Server') 96 <DeviceClass at /zport/dmd/Devices/Server> 97 """ 98 return self.getDmdRoot(self.dmdRootName).getOrganizer(moveTargetName)
99 100 101 security.declareProtected(ZEN_COMMON, "children")
102 - def children(self, sort=False, checkPerm=True, spec=None):
103 """ 104 Returns the immediate children of an organizer 105 106 @param sort: If True, sorts the returned children. 107 @type sort: boolean 108 @param checkPerm: If True, checks if the user has the permission 109 to view each child. 110 @type checkPerm: boolean 111 @param spec: If set, returns children of the specified meta_type. 112 @type spec: string 113 @return: A list of children of the organizer 114 @rtype: list 115 @permission: ZEN_COMMON 116 117 >>> dmd.Devices.Printer.children() 118 [<DeviceClass at /zport/dmd/Devices/Printer/Laser>, 119 <DeviceClass at /zport/dmd/Devices/Printer/InkJet>] 120 """ 121 if spec is None: 122 spec = self.meta_type 123 kids = self.objectValues(spec=spec) 124 if checkPerm: 125 kids = [ kid for kid in kids if self.checkRemotePerm(ZEN_VIEW, kid)] 126 if sort: 127 kids.sort(key=lambda x: x.primarySortKey()) 128 return kids
129 130
131 - def childIds(self, spec=None):
132 """ 133 Returns the ids of the immediate children of an organizer 134 135 @param spec: If set, returns children of the specified meta_type. 136 @type spec: string 137 @return: Ids of children within our organizer 138 @rtype: list 139 140 >>> 'Discovered' in dmd.Devices.childIds() 141 True 142 """ 143 if spec is None: 144 spec = self.meta_type 145 #spec = self.getDefaultSpecForChildren() 146 return self.objectIds(spec=spec)
147 148 149 security.declareProtected(ZEN_COMMON, "countChildren")
150 - def countChildren(self, spec=None):
151 """ 152 Returns the number of all the children underneath an organizer 153 154 @param spec: If set, returns children of the specified meta_type. 155 @type spec: string 156 @return: A count of all our contained children. 157 @rtype: integer 158 @permission: ZEN_COMMON 159 160 """ 161 if spec is None: 162 spec = self.meta_type 163 #spec = self.getDefaultSpecForChildren() 164 count = len(self.objectIds(spec=spec)) 165 for child in self.children(spec=spec): 166 count += child.countChildren(spec=spec) 167 return count
168 169 170 security.declareProtected(ZEN_ADD, 'manage_addOrganizer')
171 - def manage_addOrganizer(self, newPath, factory=None, REQUEST=None):
172 """ 173 Adds a new organizer under this organizer. if given a fully qualified 174 path it will create an organizer at that path 175 176 @param newPath: Path of the organizer to be created 177 @type newPath: string 178 @raise: ZentinelException 179 @permission: ZEN_ADD 180 181 >>> dmd.Devices.manage_addOrganizer('/Devices/DocTest') 182 """ 183 if factory is None: 184 factory = self.__class__ 185 if not newPath: return self.callZenScreen(REQUEST) 186 try: 187 if newPath.startswith("/"): 188 org = self.createOrganizer(newPath) 189 else: 190 org = factory(newPath) 191 self._setObject(org.id, org) 192 except ZentinelException, e: 193 if REQUEST: 194 messaging.IMessageSender(self).sendToBrowser( 195 'Error', e, priority=messaging.WARNING) 196 return self.callZenScreen(REQUEST) 197 if REQUEST: 198 audit(('UI', getDisplayType(org), 'Add'), org) 199 messaging.IMessageSender(self).sendToBrowser( 200 'Organizer Added', 201 '%s "%s" was created.' % (getDisplayType(self), newPath) 202 ) 203 return self.callZenScreen(REQUEST)
204 205 206 security.declareProtected(ZEN_DELETE, 'manage_deleteOrganizer') 207 @deprecated
208 - def manage_deleteOrganizer(self, orgname, REQUEST=None):
209 """ 210 Deletes an organizer underneath this organizer 211 212 @param orgname: Name of the organizer to delete 213 @type orgname: string 214 @raise: KeyError 215 @permission: ZEN_DELETE 216 217 >>> dmd.Devices.manage_deleteOrganizer('/Devices/Server/Linux') 218 """ 219 if REQUEST: 220 audit(('UI', getDisplayType(self), 'Delete'), orgname) 221 if orgname.startswith("/"): 222 try: 223 orgroot = self.getDmdRoot(self.dmdRootName) 224 organizer = orgroot.getOrganizer(orgname) 225 parent = aq_parent(organizer) 226 parent._delObject(organizer.getId()) 227 except KeyError: 228 pass # we may have already deleted a sub object 229 else: 230 self._delObject(orgname) 231 if REQUEST: 232 messaging.IMessageSender(self).sendToBrowser( 233 'Organizer Deleted', 234 '%s "%s" was deleted.' % (getDisplayType(self), orgname) 235 ) 236 return self.callZenScreen(REQUEST)
237 238 239 security.declareProtected(ZEN_DELETE, 'manage_deleteOrganizers')
240 - def manage_deleteOrganizers(self, organizerPaths=None, REQUEST=None):
241 """ 242 Delete a list of Organizers from the database using their ids. 243 244 @param organizerPaths: Names of organizer to be deleted 245 @type organizerPaths: list 246 @permission: ZEN_DELETE 247 248 >>> dmd.Devices.manage_deleteOrganizers(['/Devices/Server/Linux', 249 ... '/Devices/Server/Windows']) 250 """ 251 if not organizerPaths: 252 messaging.IMessageSender(self).sendToBrowser( 253 'Error', 254 'No organizers were specified.', 255 priority=messaging.WARNING 256 ) 257 return self.callZenScreen(REQUEST) 258 for organizerName in organizerPaths: 259 if REQUEST: 260 audit(('UI',getDisplayType(self),'Delete'), organizerName) 261 self.manage_deleteOrganizer(organizerName) 262 if REQUEST: 263 plural = '' 264 if len(organizerPaths) > 1: plural = 's' 265 messaging.IMessageSender(self).sendToBrowser( 266 'Organizers Deleted', 267 '%s%s %s were deleted.' % (getDisplayType(self), 268 plural, ', '.join(organizerPaths)) 269 ) 270 return self.callZenScreen(REQUEST)
271 272
273 - def deviceMoveTargets(self):
274 """ 275 DEPRECATED - see childMoveTargets 276 Return list of all organizers excluding our self. 277 278 @return: A sorted list of organizers excluding our self. 279 @rtype: list 280 @todo: We should be using either deviceMoveTargets or childMoveTargets 281 """ 282 targets = filter(lambda x: x != self.getOrganizerName(), 283 self.getDmdRoot(self.dmdRootName).getOrganizerNames()) 284 return sorted(targets, key=lambda x: x.lower())
285 286
287 - def moveOrganizer(self, moveTarget, organizerPaths=None, REQUEST=None):
288 """ 289 Move organizers under this organizer to another organizer 290 291 @param moveTarget: Name of the destination organizer 292 @type moveTarget: string 293 @param organizerPaths: Paths of organizers to be moved 294 @type organizerPaths: list 295 296 >>> dmd.Events.Status.moveOrganizer('/Events/Ignore', 297 ... ['Ping', 'Snmp']) 298 """ 299 if not moveTarget or not organizerPaths: return self() 300 target = self.getDmdRoot(self.dmdRootName).getOrganizer(moveTarget) 301 movedStuff = False 302 for organizerName in organizerPaths: 303 if moveTarget.find(organizerName) > -1: continue 304 obj = self._getOb(organizerName, None) 305 if obj is None: continue 306 obj._operation = 1 #move object 307 self._delObject(organizerName) 308 target._setObject(organizerName, obj) 309 movedStuff = True 310 if REQUEST: 311 if movedStuff: 312 plural = '' 313 if len(organizerPaths) > 1: plural = 's' 314 for organizerName in organizerPaths: 315 audit(('UI', getDisplayType(self), 'Move'), organizerName, data_={'from':getDisplayName(self), 'to':getDisplayName(target)}) 316 messaging.IMessageSender(self).sendToBrowser( 317 'Organizers Moved', 318 '%s%s %s were moved to %s.' % (getDisplayType(self), 319 plural, ', '.join(organizerPaths), moveTarget) 320 ) 321 else: 322 messaging.IMessageSender(self).sendToBrowser( 323 'Error', 324 'No %s were moved.' % getDisplayType(self), 325 priority=messaging.WARNING 326 ) 327 return target.callZenScreen(REQUEST)
328 329
330 - def createOrganizer(self, path):
331 """ 332 Creates an organizer with a specified path. 333 Use manage_addOrganizer instead 334 335 @param path: Path of the organizer to create 336 @type path: string 337 @return: Organizer created with the specified path 338 @rtype: Organizer 339 """ 340 return self.createHierarchyObj(self.getDmdRoot(self.dmdRootName), 341 path,self.__class__)
342 343
344 - def getOrganizer(self, path):
345 """ 346 Get an organizer by path under the same root 347 348 @param path: Path of the organizer to retrieve 349 @type path: string 350 @return: Organizer with the specified path 351 @rtype: Organizer 352 353 >>> dmd.Events.Status.getOrganizer('/Status/Snmp') 354 <EventClass at /zport/dmd/Events/Status/Snmp> 355 >>> dmd.Events.Status.getOrganizer('Status/Snmp') 356 <EventClass at /zport/dmd/Events/Status/Snmp> 357 >>> dmd.Events.Status.getOrganizer('/Events/Status/Snmp') 358 <EventClass at /zport/dmd/Events/Status/Snmp> 359 """ 360 if path.startswith("/"): path = path[1:] 361 return self.getDmdRoot(self.dmdRootName).unrestrictedTraverse(path)
362 363 364 security.declareProtected(ZEN_COMMON, "getOrganizerName")
365 - def getOrganizerName(self):
366 """ 367 Return the DMD path of an Organizer without its dmdSubRel names. 368 369 @return: Name of this organizer 370 @rtype: string 371 @permission: ZEN_COMMON 372 373 >>> dmd.Events.Status.Snmp.getOrganizerName() 374 '/Status/Snmp' 375 """ 376 return self.getPrimaryDmdId(self.dmdRootName)
377 getDmdKey = getOrganizerName 378 379 380 security.declareProtected(ZEN_COMMON, "getOrganizerNames")
381 - def getOrganizerNames(self, addblank=False, checkPerm=True):
382 """ 383 Returns a list of all organizer names under this organizer 384 385 @param addblank: If True, add a blank item in the list. 386 @type addblank: boolean 387 @return: The DMD paths of all Organizers below this instance. 388 @rtype: list 389 @permission: ZEN_COMMON 390 391 >>> dmd.Events.Security.getOrganizerNames() 392 ['/Security', '/Security/Auth', '/Security/Conn', 393 '/Security/Conn/Close', '/Security/Conn/Open', '/Security/Login', 394 '/Security/Login/BadPass', '/Security/Login/Fail', '/Security/Sudo', 395 '/Security/Virus'] 396 """ 397 groupNames = [] 398 user = getSecurityManager().getUser() 399 if user.has_permission(ZEN_VIEW, self) or not checkPerm: 400 groupNames.append(self.getOrganizerName()) 401 for subgroup in self.children(checkPerm=False): 402 groupNames.extend(subgroup.getOrganizerNames()) 403 if self.id == self.dmdRootName: 404 if addblank: groupNames.append("") 405 groupNames.sort(key=lambda x: x.lower()) 406 return groupNames
407 408
409 - def _getCatalog(self):
410 """ 411 Returns a catalog instance for this organizer. 412 413 @return: The catalog instance for this Organizer. 414 @rtype: ZCatalog 415 @note: Catalog is found using the attribute default_catalog. 416 """ 417 catalog = None 418 if hasattr(self, self.default_catalog): 419 catalog = getattr(self, self.default_catalog) 420 return catalog
421 422 423 security.declareProtected(ZEN_COMMON, "getSubOrganizers")
424 - def getSubOrganizers(self):
425 """ 426 Returns all the organizers under this organizer 427 428 @return: Organizers below this instance 429 @rtype: list 430 @permission: ZEN_COMMON 431 432 >>> dmd.Events.Security.getSubOrganizers() 433 [<EventClass at /zport/dmd/Events/Security/Login>, 434 <EventClass at /zport/dmd/Events/Security/Sudo>, 435 <EventClass at /zport/dmd/Events/Security/Conn>, 436 <EventClass at /zport/dmd/Events/Security/Virus>, 437 <EventClass at /zport/dmd/Events/Security/Auth>, 438 <EventClass at /zport/dmd/Events/Security/Login/BadPass>, 439 <EventClass at /zport/dmd/Events/Security/Login/Fail>, 440 <EventClass at /zport/dmd/Events/Security/Conn/Open>, 441 <EventClass at /zport/dmd/Events/Security/Conn/Close>] 442 """ 443 orgs = self.children() 444 for child in self.children(): 445 orgs.extend(child.getSubOrganizers()) 446 return orgs
447 448 security.declareProtected(ZEN_COMMON, "getSubInstances")
449 - def getSubInstanceIds(self, rel):
450 """ 451 Returns the object ids of all the instances of a specific relation 452 under this organizer 453 454 @param rel: The name of the relation to traverse 455 @type rel: string 456 @return: The object ids of instances under an relation of this org 457 @rtype: list 458 @raise: AttributeError 459 @permission: ZEN_COMMON 460 461 >>> dmd.Events.Security.Login.getSubInstanceIds('instances') 462 ['MSExchangeIS Mailbox Store_1009', 'MSExchangeIS Mailbox Store_1011', 463 'defaultmapping', 'dropbear', 'sshd', 'MSFTPSVC_100', 'W3SVC_100', 464 'dropbear', 'remote(pam_unix)'] 465 """ 466 relobj = getattr(self, rel, None) 467 if not relobj: 468 raise AttributeError( "%s not found on %s" % (rel, self.id) ) 469 objs = relobj.objectIds() 470 for suborg in self.children(): 471 objs.extend(suborg.getSubInstanceIds(rel)) 472 return objs
473 474 security.declareProtected(ZEN_COMMON, "getSubInstances")
475 - def getSubInstances(self, rel):
476 """ 477 Returns the object isntances of a specific relation 478 under this organizer 479 480 @param rel: The name of the relation to traverse 481 @type rel: string 482 @return: The object instances under an relation of this org 483 @rtype: list 484 @raise: AttributeError 485 @permission: ZEN_COMMON 486 487 >>> dmd.Events.Security.Login.getSubInstances('instances') 488 [<EventClassInst at /zport/dmd/Events/Security/Login/instances/MSExchangeIS Mailbox Store_1009>, 489 <EventClassInst at /zport/dmd/Events/Security/Login/instances/MSExchangeIS Mailbox Store_1011>, 490 <EventClassInst at /zport/dmd/Events/Security/Login/instances/defaultmapping>, 491 <EventClassInst at /zport/dmd/Events/Security/Login/BadPass/instances/dropbear>, 492 <EventClassInst at /zport/dmd/Events/Security/Login/BadPass/instances/sshd>, 493 <EventClassInst at /zport/dmd/Events/Security/Login/Fail/instances/MSFTPSVC_100>, 494 <EventClassInst at /zport/dmd/Events/Security/Login/Fail/instances/W3SVC_100>, 495 <EventClassInst at /zport/dmd/Events/Security/Login/Fail/instances/dropbear>, 496 <EventClassInst at /zport/dmd/Events/Security/Login/Fail/instances/remote(pam_unix)>] 497 """ 498 relobj = getattr(self, rel, None) 499 if not relobj: 500 raise AttributeError( "%s not found on %s" % (rel, self.id) ) 501 objs = relobj() 502 if not objs: objs = [] 503 for suborg in self.children(): 504 objs.extend(suborg.getSubInstances(rel)) 505 return objs
506 507 security.declareProtected(ZEN_COMMON, "getSubInstancesGen")
508 - def getSubInstancesGen(self, rel):
509 """ 510 Returns the object isntances of a specific relation 511 under this organizer 512 513 @param rel: The name of the relation to traverse 514 @type rel: string 515 @return: The object ids of instances under an relation of this org 516 @rtype: generator 517 @raise: AttributeError 518 @permission: ZEN_COMMON 519 """ 520 relobj = getattr(self, rel, None) 521 if not relobj: 522 raise AttributeError( "%s not found on %s" % (rel, self.id) ) 523 for obj in relobj.objectValuesGen(): 524 yield obj 525 for suborg in self.children(): 526 for obj in suborg.getSubInstancesGen(rel): 527 yield obj
528
529 - def exportXmlHook(self, ofile, ignorerels):
530 """ 531 Calls exportXml on the children of this organizer 532 533 @param ofile: The file to output 534 @type ofile: File 535 @param ignorerels: Relations to ignore 536 @type ignorerels: list 537 """ 538 map(lambda o: o.exportXml(ofile, ignorerels), self.children())
539 540 541 InitializeClass(Organizer) 542