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