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

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

      1  ###########################################################################
      2  #
      3  # This program is part of Zenoss Core, an open source monitoring platform.
      4  # Copyright (C) 2008, 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 logging
     15  log = logging.getLogger('zen.DiscoverService')
     16
     17  from Products.ZenUtils.IpUtil import numbip, strip
     18  from Products.ZenEvents.Event import Event
     19  from Products.ZenEvents.ZenEventClasses import Status_Ping
     20  from Products.ZenModel.Device import manage_createDevice
     21  from Products.Jobber.status import JobStatusProxy
     22  from Products.ZenHub.PBDaemon import translateError
     23  from Products.ZenModel.Exceptions import DeviceExistsError
     24
     25  import transaction
     26
     27  from twisted.spread import pb
     28  import math
     29
     30  from ModelerService import ModelerService
     31
     32  DEFAULT_PING_THRESH = 168
     33
     34
     35 -class IpNetProxy(pb.Copyable, pb.RemoteCopy):
     36      "A class that will represent a ZenModel/IpNetwork in zendisc"
     37
     38      id = ''
     39      _children = None
     40      netmask = None
     41
     42 -    def __init__(self, ipnet):
     43          self.id = ipnet.id
     44          self._children = map(IpNetProxy, ipnet.children())
     45          self.netmask = ipnet.netmask
     46          for prop in 'zAutoDiscover zDefaultNetworkTree zPingFailThresh'.split():
     47              if hasattr(ipnet, prop):
     48                  setattr(self, prop, getattr(ipnet, prop))
     49
     50 -    def children(self):
     51          return self._children
     52
     53 -    def fullIpList(self):
     54          "copied from IpNetwork"
     55          if (self.netmask == 32): return [self.id]
     56          ipnumb = numbip(self.id)
     57          maxip = math.pow(2, 32 - self.netmask)
     58          start = int(ipnumb + 1)
     59          end = int(ipnumb + maxip - 1)
     60          return map(strip, range(start,end))
     61
     62 -    def getNetworkName(self):
     63          return "%s/%d" % (self.id, self.netmask)
     64
     65  pb.setUnjellyableForClass(IpNetProxy, IpNetProxy)
     66
     67 -class DiscoverService(ModelerService):
     68
     69      @translateError
     70 -    def remote_getNetworks(self, net, includeSubNets):
     71          "Get network objects to scan networks should be in CIDR form 1.1.1.0/24"
     72          netObj = self.dmd.Networks.getNetworkRoot().findNet(net)
     73          if not netObj:
     74              return None
     75          nets = [netObj]
     76          if includeSubNets:
     77              nets += netObj.getSubNetworks()
     78          return map(IpNetProxy, nets)
     79
     80
     81      @translateError
     82 -    def remote_pingStatus(self, net, goodips, badips, resetPtr, addInactive):
     83          "Create objects based on ping results"
     84          net = self.dmd.Networks.getNetworkRoot().findNet(net.id, net.netmask)
     85          pingthresh = getattr(net, "zPingFailThresh", DEFAULT_PING_THRESH)
     86          ips = []
     87          for ip in goodips:
     88              ipobj = net.createIp(ip, net.netmask)
     89              if resetPtr:
     90                  ipobj.setPtrName()
     91              if not ipobj.device():
     92                  ips.append(ip)
     93              if ipobj.getStatus(Status_Ping) > 0:
     94                  self.sendIpStatusEvent(ipobj, sev=0)
     95          for ip in badips:
     96              ipobj = self.dmd.Networks.getNetworkRoot().findIp(ip)
     97              if not ipobj and addInactive:
     98                  ipobj = net.createIp(ip, net.netmask)
     99              if ipobj:
    100                  if resetPtr:
    101                      ipobj.setPtrName()
    102                  elif ipobj.getStatus(Status_Ping) > pingthresh:
    103                      net.ipaddresses.removeRelation(ipobj)
    104                  if ipobj:
    105                      self.sendIpStatusEvent(ipobj)
    106          transaction.commit()
    107          return ips
    108
    109
    110 -    def sendIpStatusEvent(self, ipobj, sev=2):
    111          """Send an ip down event.  These are used to cleanup unused ips.
    112          """
    113          ip = ipobj.id
    114          dev = ipobj.device()
    115          if sev == 0:
    116              msg = "ip %s is up" % ip
    117          else:
    118              msg = "ip %s is down" % ip
    119          if dev:
    120              devname = dev.id
    121              comp = ipobj.interface().id
    122          else:
    123              devname = comp = ip
    124          self.sendEvent(dict(device=devname, ipAddress=ip, eventKey=ip,
    125              component=comp, eventClass=Status_Ping, summary=msg, severity=sev,
    126              agent="Discover"))
    127
    128
    129      @translateError
    130 -    def remote_createDevice(self, ip, force=False, **kw):
    131          """Create a device.
    132
    133          @param ip: The manageIp of the device
    134          @param kw: The args to manage_createDevice.
    135          """
    136          from Products.ZenModel.Device import getNetworkRoot
    137          try:
    138              netroot = getNetworkRoot(self.dmd,
    139                  kw.get('performanceMonitor', 'localhost'))
    140              ipobj = netroot.createIp(ip)
    141              # If we're not supposed to discover this ip, return None
    142              if not force and not getattr(ipobj, 'zAutoDiscover', True):
    143                  return None, False
    144              kw['manageIp'] = ip
    145              dev = manage_createDevice(self.dmd, **kw)
    146          except DeviceExistsError, e:
    147              # Update device with latest info from zendisc
    148              e.dev.setManageIp(kw['manageIp'])
    149              e.dev.setTitle(kw['deviceName'])
    150              for key in ('manageIp', 'deviceName', 'devicePath',
    151                          'discoverProto'):
    152                  del kw[key]
    153              e.dev.manage_editDevice(**kw)
    154              # Make and return a device proxy
    155              return self.createDeviceProxy(e.dev), False
    156          except Exception, ex:
    157              raise pb.CopyableFailure(ex)
    158          transaction.commit()
    159          return self.createDeviceProxy(dev), True
    160
    161      @translateError
    162 -    def remote_getJobProperties(self, jobid):
    163          jobstatus = self.dmd.JobManager.getJob(jobid)
    164          if jobstatus:
    165              return JobStatusProxy(jobstatus)
    166
    167      @translateError
    168 -    def remote_succeedDiscovery(self, id):
    169          dev = self.dmd.Devices.findDeviceByIdOrIp(id)
    170          if dev:
    171              dev._temp_device = False
    172          transaction.commit()
    173          return True
    174
    175      @translateError
    176 -    def remote_followNextHopIps(self, device):
    177          """
    178          Return the ips that the device's indirect routes point to
    179          which aren't currently connected to devices.
    180          """
    181          dev = self.getPerformanceMonitor().findDevice(device)
    182          ips = []
    183          for r in dev.os.routes():
    184              ipobj = r.nexthop()
    185              if ipobj: ips.append(ipobj.id)
    186          return ips
    187
    188
    189      @translateError
    190 -    def remote_getSubNetworks(self):
    191          "Fetch proxies for all the networks"
    192          return map(IpNetProxy,
    193                  self.dmd.Networks.getNetworkRoot().getSubNetworks())
    194
    195
    196      @translateError
    197 -    def remote_getSnmpConfig(self, devicePath):
    198          "Get the snmp configuration defaults for scanning a device"
    199          devroot = self.dmd.Devices.createOrganizer(devicePath)
    200          return (devroot.zSnmpCommunities,
    201                  devroot.zSnmpPort,
    202                  devroot.zSnmpVer,
    203                  devroot.zSnmpTimeout,
    204                  devroot.zSnmpTries)
    205
    206
    207      @translateError
    208 -    def remote_moveDevice(self, dev, path):
    209          self.dmd.Devices.moveDevices(path, [dev])
    210          transaction.commit()
    211
    212      @translateError
    213 -    def remote_getDefaultNetworks(self):
    214          monitor = self.dmd.Monitors.Performance._getOb(self.instance)
    215          return [net for net in monitor.discoveryNetworks]
    216