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

# Source Code for Module Products.ZenModel.RRDDataSource

      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  from Products.ZenUtils.Utils import binPath
     12
     13  __doc__="""RRDDataSource
     14
     15  Base class for DataSources
     16  """
     17
     18  import os
     19  import zope.component
     20
     21  from DateTime import DateTime
     22  from AccessControl import ClassSecurityInfo, Permissions
     23  from Products.ZenModel.ZenossSecurity import ZEN_MANAGE_DMD
     24
     25  from Products.PageTemplates.Expressions import getEngine
     26
     27  from Products.ZenUtils.ZenTales import talesCompile
     28  from Products.ZenRelations.RelSchema import *
     29  from Products.ZenWidgets import messaging
     30
     31  from ZenModelRM import ZenModelRM
     32  from ZenPackable import ZenPackable
     33
     34
     35 -class RRDDataSource(ZenModelRM, ZenPackable):
     36
     37      meta_type = 'RRDDataSource'
     38
     39      paramtypes = ('integer', 'string', 'float')
     40      sourcetypes = ()
     41
     42      sourcetype = None
     43      enabled = True
     44      component = ''
     45      eventClass = ''
     46      eventKey = ''
     47      severity = 3
     48      commandTemplate = ""
     49      cycletime = 300
     50
     51      _properties = (
     52          {'id':'sourcetype', 'type':'selection',
     53          'select_variable' : 'sourcetypes', 'mode':'w'},
     54          {'id':'enabled', 'type':'boolean', 'mode':'w'},
     55          {'id':'component', 'type':'string', 'mode':'w'},
     56          {'id':'eventClass', 'type':'string', 'mode':'w'},
     57          {'id':'eventKey', 'type':'string', 'mode':'w'},
     58          {'id':'severity', 'type':'int', 'mode':'w'},
     59          {'id':'commandTemplate', 'type':'string', 'mode':'w'},
     60          {'id':'cycletime', 'type':'int', 'mode':'w'},
     61          )
     62
     63      _relations = ZenPackable._relations + (
     64          ("rrdTemplate", ToOne(ToManyCont,"Products.ZenModel.RRDTemplate","datasources")),
     65          ("datapoints", ToManyCont(ToOne,"Products.ZenModel.RRDDataPoint","datasource")),
     66          )
     67
     68      # Screen action bindings (and tab definitions)
     69      factory_type_information = (
     70      {
     71          'immediate_view' : 'editRRDDataSource',
     72          'actions'        :
     73          (
     74              { 'id'            : 'edit'
     75              , 'name'          : 'Data Source'
     76              , 'action'        : 'editRRDDataSource'
     77              , 'permissions'   : ( Permissions.view, )
     78              },
     79          )
     80      },
     81      )
     82
     83      security = ClassSecurityInfo()
     84
     85
     86 -    def breadCrumbs(self, terminator='dmd'):
     87          """Return the breadcrumb links for this object add ActionRules list.
     88          [('url','id'), ...]
     89          """
     90          from RRDTemplate import crumbspath
     91          crumbs = super(RRDDataSource, self).breadCrumbs(terminator)
     92          return crumbspath(self.rrdTemplate(), crumbs, -2)
     93
     94
     95 -    def getDescription(self):
     96          return None
     97
     98
     99 -    def getRRDDataPoints(self):
    100          return self.datapoints()
    101
    102
    103 -    def useZenCommand(self):
    104          return False
    105
    106 -    def addDataPoints(self):
    107          """Abstract hook method, to be overridden in derived classes."""
    108          pass
    109
    110      security.declareProtected(ZEN_MANAGE_DMD, 'manage_addRRDDataPoint')
    111 -    def manage_addRRDDataPoint(self, id, REQUEST = None):
    112          """make a RRDDataPoint"""
    113          if not id:
    114              return self.callZenScreen(REQUEST)
    115          from Products.ZenModel.RRDDataPoint import RRDDataPoint
    116          dp = RRDDataPoint(id)
    117          self.datapoints._setObject(dp.id, dp)
    118          dp = self.datapoints._getOb(dp.id)
    119          if REQUEST:
    120              if dp:
    121                  url = '%s/datapoints/%s' % (self.getPrimaryUrlPath(), dp.id)
    122                  REQUEST['RESPONSE'].redirect(url)
    123              return self.callZenScreen(REQUEST)
    124          return dp
    125
    126
    127      security.declareProtected(ZEN_MANAGE_DMD, 'manage_deleteRRDDataPoints')
    128 -    def manage_deleteRRDDataPoints(self, ids=(), REQUEST=None):
    129          """Delete RRDDataPoints from this RRDDataSource"""
    130
    131          def clean(rel, id):
    132              for obj in rel():
    133                  if id in obj.dsnames:
    134                      obj.dsnames.remove(id)
    135                      if not obj.dsnames:
    136                          rel._delObject(obj.id)
    137
    138          if not ids: return self.callZenScreen(REQUEST)
    139          for id in ids:
    140              dp = getattr(self.datapoints,id,False)
    141              if dp:
    142                  if getattr(self, 'device', False):
    143                      perfConf = self.device().getPerformanceServer()
    144                      perfConf.deleteRRDFiles(device=self.device().id, datapoint=dp.name())
    145                  else:
    146                      for d in self.deviceClass.obj.getSubDevicesGen():
    147                          perfConf = d.getPerformanceServer()
    148                          perfConf.deleteRRDFiles(device=d.id, datapoint=dp.name())
    149
    150                  clean(self.graphs, dp.name())
    151                  clean(self.thresholds, dp.name())
    152                  self.datapoints._delObject(dp.id)
    153
    154          if REQUEST:
    155              return self.callZenScreen(REQUEST)
    156
    157
    158      security.declareProtected(ZEN_MANAGE_DMD, 'manage_addDataPointsToGraphs')
    159 -    def manage_addDataPointsToGraphs(self, ids=(), graphIds=(), REQUEST=None):
    160          """
    161          Create GraphPoints for all datapoints given datapoints (ids)
    162          in each of the graphDefs (graphIds.)
    163          If a graphpoint already exists for a datapoint in a graphDef then
    164          don't create a 2nd one.
    165          """
    166          newGps = []
    167          for graphDefId in graphIds:
    168              graphDef = self.rrdTemplate.graphDefs._getOb(graphDefId, None)
    169              if graphDef:
    170                  for dpId in ids:
    171                      dp = self.datapoints._getOb(dpId, None)
    172                      if dp and not graphDef.isDataPointGraphed(dp.name()):
    173                          newGps += graphDef.manage_addDataPointGraphPoints(
    174                                                                  [dp.name()])
    175          if REQUEST:
    176              numNew = len(newGps)
    177              messaging.IMessageSender(self).sendToBrowser(
    178                  'Graph Points Added',
    179                  '%s GraphPoint%s added' % (numNew, numNew != 1 and 's' or '')
    180              )
    181              return self.callZenScreen(REQUEST)
    182          return newGps
    183
    184
    185 -    def getCommand(self, context, cmd=None):
    186          """Return localized command target.
    187          """
    188          # Perform a TALES eval on the expression using self
    189          if cmd is None:
    190              cmd = self.commandTemplate
    191          if not cmd.startswith('string:') and not cmd.startswith('python:'):
    192              cmd = 'string:%s' % cmd
    193          compiled = talesCompile(cmd)
    194          d = context.device()
    195          environ = {'dev' : d,
    196                     'device': d,
    197                     'devname': d.id,
    198                     'ds': self,
    199                     'datasource': self,
    200                     'here' : context,
    201                     'zCommandPath' : context.zCommandPath,
    202                     'nothing' : None,
    203                     'now' : DateTime() }
    204          res = compiled(getEngine().getContext(environ))
    205          if isinstance(res, Exception):
    206              raise res
    207          res = self.checkCommandPrefix(context, res)
    208          return res
    209
    210
    211 -    def getComponent(self, context, component=None):
    212          """Return localized component.
    213          """
    214          if component is None:
    215              component = self.component
    216          if not component.startswith('string:') and \
    217                  not component.startswith('python:'):
    218              component = 'string:%s' % component
    219          compiled = talesCompile(component)
    220          d = context.device()
    221          environ = {'dev' : d,
    222                     'device': d,
    223                     'devname': d.id,
    224                     'here' : context,
    225                     'nothing' : None,
    226                     'now' : DateTime() }
    227          res = compiled(getEngine().getContext(environ))
    228          if isinstance(res, Exception):
    229              raise res
    230          return res
    231
    232 -    def checkCommandPrefix(self, context, cmd):
    233          if not cmd.startswith('/') and not cmd.startswith('$'):
    234              if context.zCommandPath and not cmd.startswith(context.zCommandPath):
    235                  cmd = os.path.join(context.zCommandPath, cmd)
    236              elif binPath(cmd.split(" ",1)[0]):
    237                  #if we get here it is because cmd is not absolute, doesn't
    238                  #start with $, zCommandPath is not set and we found cmd in
    239                  #one of the zenoss bin dirs
    240                  cmdList = cmd.split(" ",1) #split into command and args
    241                  cmd = binPath(cmdList[0])
    242                  if len(cmdList) > 1:
    243                      cmd = "%s %s" % (cmd, cmdList[1])
    244
    245          return cmd
    246
    247 -    def getSeverityString(self):
    248          return self.ZenEventManager.getSeverityString(self.severity)
    249
    250
    251 -    def zmanage_editProperties(self, REQUEST=None, ignored=None):
    252          return ZenModelRM.zmanage_editProperties(self, REQUEST)
    253
    254
    255 -class SimpleRRDDataSource(RRDDataSource):
    256      """
    257      A SimpleRRDDataSource has a single datapoint that shares the name of the
    258      data source.
    259      """
    260      security = ClassSecurityInfo()
    261
    262
    263 -    def addDataPoints(self):
    264          """
    265          Make sure there is exactly one datapoint and that it has the same name
    266          as the datasource.
    267          """
    268          dpid = self.prepId(self.id)
    269          remove = [d for d in self.datapoints() if d.id != dpid]
    270          for dp in remove:
    271              self.datapoints._delObject(dp.id)
    272          if not self.datapoints._getOb(dpid, None):
    273              self.manage_addRRDDataPoint(dpid)
    274
    275      security.declareProtected(ZEN_MANAGE_DMD, 'zmanage_editProperties')
    276 -    def zmanage_editProperties(self, REQUEST=None):
    277          """
    278          Overrides the method defined in RRDDataSource. Called when user clicks
    279          the Save button on the Data Source editor page.
    280          """
    281          self.addDataPoints()
    282
    283          if REQUEST and self.datapoints():
    284
    285              datapoint = self.soleDataPoint()
    286
    287              if REQUEST.has_key('rrdtype'):
    288                  if REQUEST['rrdtype'] in datapoint.rrdtypes:
    289                      datapoint.rrdtype = REQUEST['rrdtype']
    290                  else:
    291                      messaging.IMessageSender(self).sendToBrowser(
    292                          'Error',
    293                          "%s is an invalid Type" % rrdtype,
    294                          priority=messaging.WARNING
    295                      )
    296                      return self.callZenScreen(REQUEST)
    297
    298              if REQUEST.has_key('rrdmin'):
    299                  value = REQUEST['rrdmin']
    300                  if value != '':
    301                      try:
    302                          value = long(value)
    303                      except ValueError:
    304                          messaging.IMessageSender(self).sendToBrowser(
    305                              'Error',
    306                              "%s is an invalid RRD Min" % value,
    307                              priority=messaging.WARNING
    308                          )
    309                          return self.callZenScreen(REQUEST)
    310                  datapoint.rrdmin = value
    311
    312              if REQUEST.has_key('rrdmax'):
    313                  value = REQUEST['rrdmax']
    314                  if value != '':
    315                      try:
    316                          value = long(value)
    317                      except ValueError:
    318                          messaging.IMessageSender(self).sendToBrowser(
    319                              'Error',
    320                              "%s is an invalid RRD Max" % value,
    321                              priority=messaging.WARNING
    322                          )
    323                          return self.callZenScreen(REQUEST)
    324                  datapoint.rrdmax = value
    325
    326              if REQUEST.has_key('createCmd'):
    327                  datapoint.createCmd = REQUEST['createCmd']
    328
    329          return RRDDataSource.zmanage_editProperties(self, REQUEST)
    330
    331 -    def soleDataPoint(self):
    332          """
    333          Return the datasource's only datapoint
    334          """
    335          dps = self.datapoints()
    336          if dps:
    337              return dps[0]
    338
    339 -    def aliases(self):
    340          """
    341          Return the datapoint aliases that belong to the datasource's only
    342          datapoint
    343          """
    344          dp = self.soleDataPoint()
    345          if dp:
    346              return dp.aliases()
    347
    348      security.declareProtected(ZEN_MANAGE_DMD, 'manage_addDataPointsToGraphs')
    349 -    def manage_addDataPointsToGraphs(self, ids=(), graphIds=(), REQUEST=None):
    350          """
    351          Override method in super class.  ids will always be an empty tuple, so
    352          call the super class's method with the single datapoint as the ids.
    353          """
    354          return RRDDataSource.manage_addDataPointsToGraphs(self,
    355                  (self.soleDataPoint().id,), graphIds, REQUEST)
    356
    357      security.declareProtected(ZEN_MANAGE_DMD, 'manage_addDataPointAlias')
    358 -    def manage_addDataPointAlias(self, id, formula, REQUEST=None):
    359          """
    360          Add a datapoint alias to the datasource's only datapoint
    361          """
    362          alias = self.soleDataPoint().manage_addDataPointAlias( id, formula )
    363          if REQUEST:
    364              return self.callZenScreen( REQUEST )
    365          return alias
    366
    367      security.declareProtected(ZEN_MANAGE_DMD, 'manage_removeDataPointAliases')
    368 -    def manage_removeDataPointAliases(self, ids=(), REQUEST=None):
    369          """
    370          Remove the passed aliases from the datasource's only datapoint
    371          """
    372          self.soleDataPoint().manage_removeDataPointAliases( ids )
    373          if REQUEST:
    374              return self.callZenScreen(REQUEST)
    375
    376  from Products.ZenModel.interfaces import IZenDocProvider
    377  from Products.ZenModel.ZenModelBase import ZenModelZenDocProvider
    378
    379 -class SimpleRRDDataSourceZenDocProvider(ZenModelZenDocProvider):
    380      zope.component.adapts(SimpleRRDDataSource)
    381
    382 -    def datapoints(self):
    383          return self._underlyingObject.datapoints()
    384
    385 -    def soleDataPoint(self):
    386          return self._underlyingObject.soleDataPoint()
    387
    388 -    def getZendoc(self):
    389          if len( self.datapoints() ) == 1:
    390              dataPointAdapter = zope.component.queryAdapter( self.soleDataPoint(),
    391                                                              IZenDocProvider )
    392              return dataPointAdapter.getZendoc()
    393          else:
    394              return super( SimpleRRDDataSourceZenDocProvider, self ).getZendoc()
    395
    396 -    def setZendoc(self, zendocText):
    397          """Set zendoc text"""
    398          if len( self.datapoints() ) == 1:
    399              dataPointAdapter = zope.component.queryAdapter( self.soleDataPoint(),
    400                                                              IZenDocProvider )
    401              dataPointAdapter.setZendoc( zendocText )
    402          else:
    403              return super( SimpleRRDDataSourceZenDocProvider, self ).setZendoc( zendocText )
    404