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

# Source Code for Module Products.ZenModel.RRDDataSource

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