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