Package Products :: Package ZenHub :: Package services :: Module PerformanceConfig |
[hide private]
[frames] | no frames]

# Source Code for Module Products.ZenHub.services.PerformanceConfig

      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  import Globals
     12  from Products.ZenEvents.ZenEventClasses import Status_Snmp
     13  from zope import component
     14
     15  from Products.ZenHub.HubService import HubService
     16  from Products.ZenHub.PBDaemon import translateError
     17
     18  from Products.ZenModel.Device import Device
     19  from Products.ZenModel.ZenPack import ZenPack
     20  from Products.ZenModel.PerformanceConf import PerformanceConf
     21  from Products.ZenHub.zodb import onUpdate, onDelete
     22  from Products.ZenHub.interfaces import IBatchNotifier
     23  from Acquisition import aq_parent
     24
     25  from twisted.internet import defer
     26
     27  from Procrastinator import Procrastinate
     28  from ThresholdMixin import ThresholdMixin
     29
     30  ATTRIBUTES = (
     31      'id',
     32      'manageIp',
     33      'zMaxOIDPerRequest',
     34      'zSnmpMonitorIgnore',
     35      'zSnmpAuthPassword',
     36      'zSnmpAuthType',
     37      'zSnmpCommunity',
     38      'zSnmpCommunities',
     39      'zSnmpPort',
     40      'zSnmpPrivPassword',
     41      'zSnmpPrivType',
     42      'zSnmpSecurityName',
     43      'zSnmpTimeout',
     44      'zSnmpTries',
     45      'zSnmpVer',
     46      )
     47
     48  from twisted.spread import pb
     49 -class SnmpConnInfo(pb.Copyable, pb.RemoteCopy):
     50      "A class to transfer the many SNMP values to clients"
     51
     52      changed = False
     53
     54 -    def __init__(self, device):
     55          "Store the properties from the device"
     56          for propertyName in ATTRIBUTES:
     57              setattr(self, propertyName, getattr(device, propertyName, None))
     58              self.id = device.id
     59
     60 -    def __cmp__(self, other):
     61          for propertyName in ATTRIBUTES:
     62              c = cmp(getattr(self, propertyName), getattr(other, propertyName))
     63              if c != 0:
     64                  return c
     65          return 0
     66
     67 -    def summary(self):
     68          result = 'SNMP info for %s at %s:%s' % (
     69              self.id, self.manageIp, self.zSnmpPort)
     70          result += ' timeout: %s tries: %d' % (
     71              self.zSnmpTimeout, self.zSnmpTries)
     72          result += ' version: %s ' % (self.zSnmpVer)
     73          if '3' not in self.zSnmpVer:
     74              result += ' community: %s' % self.zSnmpCommunity
     75          else:
     76              result += ' securityName: %s' % self.zSnmpSecurityName
     77              result += ' authType: %s' % self.zSnmpAuthType
     78              result += ' privType: %s' % self.zSnmpPrivType
     79          return result
     80
     81 -    def createSession(self, protocol=None, allowCache=False):
     82          "Create a session based on the properties"
     83          from pynetsnmp.twistedsnmp import AgentProxy
     84          cmdLineArgs=[]
     85          if '3' in self.zSnmpVer:
     86              if self.zSnmpPrivType:
     87                  cmdLineArgs += ['-l', 'authPriv']
     88                  cmdLineArgs += ['-x', self.zSnmpPrivType]
     89                  cmdLineArgs += ['-X', self.zSnmpPrivPassword]
     90              elif self.zSnmpAuthType:
     91                  cmdLineArgs += ['-l', 'authNoPriv']
     92              else:
     93                  cmdLineArgs += ['-l', 'noAuthNoPriv']
     94              if self.zSnmpAuthType:
     95                  cmdLineArgs += ['-a', self.zSnmpAuthType]
     96                  cmdLineArgs += ['-A', self.zSnmpAuthPassword]
     97              cmdLineArgs += ['-u', self.zSnmpSecurityName]
     98          #the parameter tries seems to really be retries so take one off
     99          retries = max(self.zSnmpTries - 1, 0)
    100          p = AgentProxy(ip=self.manageIp,
    101                         port=self.zSnmpPort,
    102                         timeout=self.zSnmpTimeout,
    103                         tries=retries,
    104                         snmpVersion=self.zSnmpVer,
    105                         community=self.zSnmpCommunity,
    106                         cmdLineArgs=cmdLineArgs,
    107                         protocol=protocol,
    108                         allowCache=allowCache)
    109          p.snmpConnInfo = self
    110          return p
    111
    112 -    def __repr__(self):
    113          return '<%s for %s>' % (self.__class__, self.id)
    114
    115  pb.setUnjellyableForClass(SnmpConnInfo, SnmpConnInfo)
    116
    117
    118 -class PerformanceConfig(HubService, ThresholdMixin):
    119
    120 -    def __init__(self, dmd, instance):
    121          HubService.__init__(self, dmd, instance)
    122          self.config = self.dmd.Monitors.Performance._getOb(self.instance)
    123          self.procrastinator = Procrastinate(self.pushConfig)
    124          self._collectorMap = {}
    125          self._notifier = component.getUtility(IBatchNotifier)
    126
    127      @translateError
    128 -    def remote_propertyItems(self):
    129          return self.config.propertyItems()
    130
    131
    132 -    def remote_getDefaultRRDCreateCommand(self, *args, **kwargs):
    133          return self.config.getDefaultRRDCreateCommand(*args, **kwargs)
    134
    135
    136 -    def notifyAll(self, device):
    137          self.procrastinator.doLater(device)
    138
    139
    140 -    def pushConfig(self, device):
    141          deferreds = []
    142          cfg = None
    143
    144          cur_collector = device.perfServer.getRelatedId()
    145          prev_collector = self._collectorMap.get(device.id, None)
    146          self._collectorMap[device.id] = cur_collector
    147
    148          # Always push config to currently assigned collector.
    149          if cur_collector == self.instance:
    150              cfg = self.getDeviceConfig(device)
    151
    152          # Push a deleteDevice call if the device was previously assigned to
    153          # this collector.
    154          elif prev_collector and prev_collector == self.instance:
    155              cfg = None
    156
    157          # Don't do anything if this collector is not, and has not been involved
    158          # with the device
    159          else:
    160              return defer.DeferredList(deferreds)
    161
    162          for listener in self.listeners:
    163              if cfg is None:
    164                  deferreds.append(listener.callRemote('deleteDevice', device.id))
    165              else:
    166                  deferreds.append(self.sendDeviceConfig(listener, cfg))
    167          return defer.DeferredList(deferreds)
    168
    169
    170 -    def getDeviceConfig(self, device):
    171          "How to get the config for a device"
    172          return None
    173
    174
    175 -    def sendDeviceConfig(self, listener, config):
    176          "How to send the config to a device, probably via callRemote"
    177          pass
    178
    179
    180      @onUpdate(PerformanceConf)
    181 -    def perfConfUpdated(self, object, event):
    182          if object.id == self.instance:
    183              for listener in self.listeners:
    184                  listener.callRemote('setPropertyItems', object.propertyItems())
    185
    186      @onUpdate(ZenPack)
    187 -    def zenPackUpdated(self, object, event):
    188          for listener in self.listeners:
    189              try:
    190                  listener.callRemote('updateThresholdClasses',
    191                                      self.remote_getThresholdClasses())
    192              except Exception, ex:
    193                  self.log.warning("Error notifying a listener of new classes")
    194
    195      @onUpdate(Device)
    196 -    def deviceUpdated(self, object, event):
    197          self.notifyAll(object)
    198
    199      @onUpdate(None) # Matches all
    200 -    def notifyAffectedDevices(self, object, event):
    201          if isinstance(object, Device):
    202              return
    203
    204          # something else... mark the devices as out-of-date
    205          from Products.ZenModel.DeviceClass import DeviceClass
    206
    207          while object:
    208              # walk up until you hit an organizer or a device
    209              if isinstance(object, DeviceClass):
    210                  uid = (self.__class__.__name__, self.instance)
    211                  self._notifier.notify_subdevices(object, uid, self.notifyAll)
    212                  break
    213
    214              if isinstance(object, Device):
    215                  self.notifyAll(object)
    216                  break
    217
    218              object = aq_parent(object)
    219
    220      @onDelete(Device)
    221 -    def deviceDeleted(self, object, event):
    222          devid = object.id
    223          for listener in self.listeners:
    224              listener.callRemote('deleteDevice', devid)
    225