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

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

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