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

# Source Code for Module Products.ZenModel.Organizer

      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  __doc__ = """Organizer
     15  Base class for all Zenoss organizers
     16  """
     17
     18  from Globals import InitializeClass
     19  from Acquisition import aq_parent
     20  from AccessControl import ClassSecurityInfo, getSecurityManager
     21
     22  from Products.ZenRelations.RelSchema import *
     23  from Products.ZenUtils.Exceptions import ZentinelException
     24  from Products.ZenWidgets import messaging
     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
     60 -    def urlLink(self, text=None, url=None, attrs={}):
     61          """
     62          Override urlLink to return a link with the full path of the organizer.
     63
     64          >>> dmd.Devices.Server.urlLink()
     65          '<a href="/zport/dmd/Devices/Server">/Server</a>'
     66          """
     67          if text is None: text = self.getOrganizerName()
     68          return ZenModelRM.urlLink(self, text=text, url=url, attrs=attrs)
     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: kids.sort(lambda x,y: cmp(x.primarySortKey(),
    127                                             y.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                  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              messaging.IMessageSender(self).sendToBrowser(
    199                  'Organizer Added',
    200                  '%s "%s" was created.' % (self.__class__.__name__, newPath)
    201              )
    202              return self.callZenScreen(REQUEST)
    203
    204
    205      security.declareProtected(ZEN_DELETE, 'manage_deleteOrganizer')
    206 -    def manage_deleteOrganizer(self, orgname, REQUEST=None):
    207          """
    208          Deletes an organizer underneath this organizer
    209
    210          @param orgname: Name of the organizer to delete
    211          @type orgname: string
    212          @raise: KeyError
    213          @permission: ZEN_DELETE
    214
    215          >>> dmd.Devices.manage_deleteOrganizer('/Devices/Server/Linux')
    216          """
    217          if orgname.startswith("/"):
    218              try:
    219                  orgroot = self.getDmdRoot(self.dmdRootName)
    220                  organizer = orgroot.getOrganizer(orgname)
    221                  parent = aq_parent(organizer)
    222                  parent._delObject(organizer.getId())
    223              except KeyError:
    224                  pass  # we may have already deleted a sub object
    225          else:
    226              self._delObject(orgname)
    227          if REQUEST:
    228              messaging.IMessageSender(self).sendToBrowser(
    229                  'Organizer Deleted',
    230                  '%s "%s" was deleted.' % (self.__class__.__name__, orgname)
    231              )
    232              return self.callZenScreen(REQUEST)
    233
    234
    235      security.declareProtected(ZEN_DELETE, 'manage_deleteOrganizers')
    236 -    def manage_deleteOrganizers(self, organizerPaths=None, REQUEST=None):
    237          """
    238          Delete a list of Organizers from the database using their ids.
    239
    240          @param organizerPaths: Names of organizer to be deleted
    241          @type organizerPaths: list
    242          @permission: ZEN_DELETE
    243
    244          >>> dmd.Devices.manage_deleteOrganizers(['/Devices/Server/Linux',
    245          ... '/Devices/Server/Windows'])
    246          """
    247          if not organizerPaths:
    248              messaging.IMessageSender(self).sendToBrowser(
    249                  'Error',
    250                  'No organizers were specified.',
    251                  priority=messaging.WARNING
    252              )
    253              return self.callZenScreen(REQUEST)
    254          for organizerName in organizerPaths:
    255              self.manage_deleteOrganizer(organizerName)
    256          if REQUEST:
    257              plural = ''
    258              if len(organizerPaths) > 1: plural = 's'
    259              messaging.IMessageSender(self).sendToBrowser(
    260                  'Organizers Deleted',
    261                  '%s%s %s were deleted.' % (self.__class__.__name__,
    262                                      plural, ', '.join(organizerPaths))
    263              )
    264              return self.callZenScreen(REQUEST)
    265
    266
    267 -    def deviceMoveTargets(self):
    268          """
    269          DEPRECATED - see childMoveTargets
    270          Return list of all organizers excluding our self.
    271
    272          @return: A sorted list of organizers excluding our self.
    273          @rtype: list
    274          @todo: We should be using either deviceMoveTargets or childMoveTargets
    275          """
    276          targets = filter(lambda x: x != self.getOrganizerName(),
    277              self.getDmdRoot(self.dmdRootName).getOrganizerNames())
    278          targets.sort(lambda x,y: cmp(x.lower(), y.lower()))
    279          return targets
    280
    281
    282 -    def moveOrganizer(self, moveTarget, organizerPaths=None, REQUEST=None):
    283          """
    284          Move organizers under this organizer to another organizer
    285
    286          @param moveTarget: Name of the destination organizer
    287          @type moveTarget: string
    288          @param organizerPaths: Paths of organizers to be moved
    289          @type organizerPaths: list
    290
    291          >>> dmd.Events.Status.moveOrganizer('/Events/Ignore',
    292          ... ['Ping', 'Snmp'])
    293          """
    294          if not moveTarget or not organizerPaths: return self()
    295          target = self.getDmdRoot(self.dmdRootName).getOrganizer(moveTarget)
    296          movedStuff = False
    297          for organizerName in organizerPaths:
    298              if moveTarget.find(organizerName) > -1: continue
    299              obj = self._getOb(organizerName, None)
    300              if obj is None: continue
    301              obj._operation = 1 #move object
    302              self._delObject(organizerName)
    303              target._setObject(organizerName, obj)
    304              movedStuff = True
    305          if REQUEST:
    306              if movedStuff:
    307                  plural = ''
    308                  if len(organizerPaths) > 1: plural = 's'
    309                  messaging.IMessageSender(self).sendToBrowser(
    310                      'Organizers Moved',
    311                      '%s%s %s were moved to %s.' % (self.__class__.__name__,
    312                                  plural, ', '.join(organizerPaths), moveTarget)
    313                  )
    314              else:
    315                  messaging.IMessageSender(self).sendToBrowser(
    316                      'Error',
    317                      'No %s were moved.' % self.__class__.__name__,
    318                      priority=messaging.WARNING
    319                  )
    320              return target.callZenScreen(REQUEST)
    321
    322
    323 -    def createOrganizer(self, path):
    324          """
    325          Creates an organizer with a specified path.
    326          Use manage_addOrganizer instead
    327
    328          @param path: Path of the organizer to create
    329          @type path: string
    330          @return: Organizer created with the specified path
    331          @rtype: Organizer
    332          """
    333          return self.createHierarchyObj(self.getDmdRoot(self.dmdRootName),
    334                                             path,self.__class__)
    335
    336
    337 -    def getOrganizer(self, path):
    338          """
    339          Get an organizer by path under the same root
    340
    341          @param path: Path of the organizer to retrieve
    342          @type path: string
    343          @return: Organizer with the specified path
    344          @rtype: Organizer
    345
    346          >>> dmd.Events.Status.getOrganizer('/Status/Snmp')
    347          <EventClass at /zport/dmd/Events/Status/Snmp>
    348          >>> dmd.Events.Status.getOrganizer('Status/Snmp')
    349          <EventClass at /zport/dmd/Events/Status/Snmp>
    350          >>> dmd.Events.Status.getOrganizer('/Events/Status/Snmp')
    351          <EventClass at /zport/dmd/Events/Status/Snmp>
    352          """
    353          if path.startswith("/"): path = path[1:]
    354          return self.getDmdRoot(self.dmdRootName).getObjByPath(path)
    355
    356
    357      security.declareProtected(ZEN_COMMON, "getOrganizerName")
    358 -    def getOrganizerName(self):
    359          """
    360          Return the DMD path of an Organizer without its dmdSubRel names.
    361
    362          @return: Name of this organizer
    363          @rtype: string
    364          @permission: ZEN_COMMON
    365
    366          >>> dmd.Events.Status.Snmp.getOrganizerName()
    367          '/Status/Snmp'
    368          """
    369          return self.getPrimaryDmdId(self.dmdRootName)
    370      getDmdKey = getOrganizerName
    371
    372
    373      security.declareProtected(ZEN_COMMON, "getOrganizerNames")
    374 -    def getOrganizerNames(self, addblank=False, checkPerm=True):
    375          """
    376          Returns a list of all organizer names under this organizer
    377
    378          @param addblank: If True, add a blank item in the list.
    379          @type addblank: boolean
    380          @return: The DMD paths of all Organizers below this instance.
    381          @rtype: list
    382          @permission: ZEN_COMMON
    383
    384          >>> dmd.Events.Security.getOrganizerNames()
    385          ['/Security', '/Security/Auth', '/Security/Conn',
    386          '/Security/Conn/Close', '/Security/Conn/Open', '/Security/Login',
    387          '/Security/Login/BadPass', '/Security/Login/Fail', '/Security/Sudo',
    388          '/Security/Virus']
    389          """
    390          groupNames = []
    391          user = getSecurityManager().getUser()
    392          if user.has_permission(ZEN_VIEW, self) or not checkPerm:
    393              groupNames.append(self.getOrganizerName())
    394          for subgroup in self.children(checkPerm=False):
    395              groupNames.extend(subgroup.getOrganizerNames())
    396          if self.id == self.dmdRootName:
    397              if addblank: groupNames.append("")
    398          groupNames.sort(lambda x,y: cmp(x.lower(), y.lower()))
    399          return groupNames
    400
    401
    402 -    def _getCatalog(self):
    403          """
    404          Returns a catalog instance for this organizer.
    405
    406          @return: The catalog instance for this Organizer.
    407          @rtype: ZCatalog
    408          @note: Catalog is found using the attribute default_catalog.
    409          """
    410          catalog = None
    411          if hasattr(self, self.default_catalog):
    412              catalog = getattr(self, self.default_catalog)
    413          return catalog
    414
    415
    416      security.declareProtected(ZEN_COMMON, "getSubOrganizers")
    417 -    def getSubOrganizers(self):
    418          """
    419          Returns all the organizers under this organizer
    420
    421          @return: Organizers below this instance
    422          @rtype: list
    423          @permission: ZEN_COMMON
    424
    425          >>> dmd.Events.Security.getSubOrganizers()
    426          [<EventClass at /zport/dmd/Events/Security/Login>,
    427          <EventClass at /zport/dmd/Events/Security/Sudo>,
    428          <EventClass at /zport/dmd/Events/Security/Conn>,
    429          <EventClass at /zport/dmd/Events/Security/Virus>,
    430          <EventClass at /zport/dmd/Events/Security/Auth>,
    431          <EventClass at /zport/dmd/Events/Security/Login/BadPass>,
    432          <EventClass at /zport/dmd/Events/Security/Login/Fail>,
    433          <EventClass at /zport/dmd/Events/Security/Conn/Open>,
    434          <EventClass at /zport/dmd/Events/Security/Conn/Close>]
    435          """
    436          orgs = self.children()
    437          for child in self.children():
    438              orgs.extend(child.getSubOrganizers())
    439          return orgs
    440
    441      security.declareProtected(ZEN_COMMON, "getSubInstances")
    442 -    def getSubInstanceIds(self, rel):
    443          """
    444          Returns the object ids of all the instances of a specific relation
    445          under this organizer
    446
    447          @param rel: The name of the relation to traverse
    448          @type rel: string
    449          @return: The object ids of instances under an relation of this org
    450          @rtype: list
    451          @raise: AttributeError
    452          @permission: ZEN_COMMON
    453
    454          >>> dmd.Events.Security.Login.getSubInstanceIds('instances')
    455          ['MSExchangeIS Mailbox Store_1009', 'MSExchangeIS Mailbox Store_1011',
    456          'defaultmapping', 'dropbear', 'sshd', 'MSFTPSVC_100', 'W3SVC_100',
    457          'dropbear', 'remote(pam_unix)']
    458          """
    459          relobj = getattr(self, rel, None)
    460          if not relobj:
    461              raise AttributeError( "%s not found on %s" % (rel, self.id) )
    462          objs = relobj.objectIds()
    463          for suborg in self.children():
    464              objs.extend(suborg.getSubInstanceIds(rel))
    465          return objs
    466
    467      security.declareProtected(ZEN_COMMON, "getSubInstances")
    468 -    def getSubInstances(self, rel):
    469          """
    470          Returns the object isntances of a specific relation
    471          under this organizer
    472
    473          @param rel: The name of the relation to traverse
    474          @type rel: string
    475          @return: The object instances under an relation of this org
    476          @rtype: list
    477          @raise: AttributeError
    478          @permission: ZEN_COMMON
    479
    480          >>> dmd.Events.Security.Login.getSubInstances('instances')
    481          [<EventClassInst at /zport/dmd/Events/Security/Login/instances/MSExchangeIS Mailbox Store_1009>,
    482          <EventClassInst at /zport/dmd/Events/Security/Login/instances/MSExchangeIS Mailbox Store_1011>,
    483          <EventClassInst at /zport/dmd/Events/Security/Login/instances/defaultmapping>,
    484          <EventClassInst at /zport/dmd/Events/Security/Login/BadPass/instances/dropbear>,
    485          <EventClassInst at /zport/dmd/Events/Security/Login/BadPass/instances/sshd>,
    486          <EventClassInst at /zport/dmd/Events/Security/Login/Fail/instances/MSFTPSVC_100>,
    487          <EventClassInst at /zport/dmd/Events/Security/Login/Fail/instances/W3SVC_100>,
    488          <EventClassInst at /zport/dmd/Events/Security/Login/Fail/instances/dropbear>,
    489          <EventClassInst at /zport/dmd/Events/Security/Login/Fail/instances/remote(pam_unix)>]
    490          """
    491          relobj = getattr(self, rel, None)
    492          if not relobj:
    493              raise AttributeError( "%s not found on %s" % (rel, self.id) )
    494          objs = relobj()
    495          if not objs: objs = []
    496          for suborg in self.children():
    497              objs.extend(suborg.getSubInstances(rel))
    498          return objs
    499
    500      security.declareProtected(ZEN_COMMON, "getSubInstancesGen")
    501 -    def getSubInstancesGen(self, rel):
    502          """
    503          Returns the object isntances of a specific relation
    504          under this organizer
    505
    506          @param rel: The name of the relation to traverse
    507          @type rel: string
    508          @return: The object ids of instances under an relation of this org
    509          @rtype: generator
    510          @raise: AttributeError
    511          @permission: ZEN_COMMON
    512          """
    513          relobj = getattr(self, rel, None)
    514          if not relobj:
    515              raise AttributeError( "%s not found on %s" % (rel, self.id) )
    516          for obj in relobj.objectValuesGen():
    517              yield obj
    518          for suborg in self.children():
    519              for obj in suborg.getSubInstancesGen(rel):
    520                  yield obj
    521
    522 -    def exportXmlHook(self, ofile, ignorerels):
    523          """
    524          Calls exportXml on the children of this organizer
    525
    526          @param ofile: The file to output
    527          @type ofile: File
    528          @param ignorerels: Relations to ignore
    529          @type ignorerels: list
    530          """
    531          map(lambda o: o.exportXml(ofile, ignorerels), self.children())
    532
    533
    534  InitializeClass(Organizer)
    535