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