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

Source Code for Module 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 evt = Event(device=devname, ipAddress=ip, eventKey=ip, 125 component=comp, eventClass=Status_Ping, 126 summary=msg, severity=sev, 127 agent="Discover") 128 self.dmd.ZenEventManager.sendEvent(evt)
129 130 131 @translateError
132 - def remote_createDevice(self, ip, force=False, **kw):
133 """Create a device. 134 135 @param ip: The manageIp of the device 136 @param kw: The args to manage_createDevice. 137 """ 138 from Products.ZenModel.Device import getNetworkRoot 139 try: 140 netroot = getNetworkRoot(self.dmd, 141 kw.get('performanceMonitor', 'localhost')) 142 ipobj = netroot.createIp(ip) 143 # If we're not supposed to discover this ip, return None 144 if not force and not getattr(ipobj, 'zAutoDiscover', True): 145 return None, False 146 kw['manageIp'] = ip 147 dev = manage_createDevice(self.dmd, **kw) 148 except DeviceExistsError, e: 149 # Update device with latest info from zendisc 150 e.dev.setManageIp(kw['manageIp']) 151 for key in ('manageIp', 'deviceName', 'devicePath', 152 'discoverProto'): 153 del kw[key] 154 e.dev.manage_editDevice(**kw) 155 # Make and return a device proxy 156 return self.createDeviceProxy(e.dev), False 157 except Exception, ex: 158 raise pb.CopyableFailure(ex) 159 transaction.commit() 160 return self.createDeviceProxy(dev), True
161 162 @translateError
163 - def remote_getJobProperties(self, jobid):
164 jobstatus = self.dmd.JobManager.getJob(jobid) 165 if jobstatus: 166 return JobStatusProxy(jobstatus)
167 168 @translateError
169 - def remote_succeedDiscovery(self, id):
170 dev = self.dmd.Devices.findDevice(id) 171 if dev: 172 dev._temp_device = False 173 transaction.commit() 174 return True
175 176 @translateError
177 - def remote_followNextHopIps(self, device):
178 """ 179 Return the ips that the device's indirect routes point to 180 which aren't currently connected to devices. 181 """ 182 dev = self.getPerformanceMonitor().findDevice(device) 183 ips = [] 184 for r in dev.os.routes(): 185 ipobj = r.nexthop() 186 if ipobj: ips.append(ipobj.id) 187 return ips
188 189 190 @translateError
191 - def remote_getSubNetworks(self):
192 "Fetch proxies for all the networks" 193 return map(IpNetProxy, 194 self.dmd.Networks.getNetworkRoot().getSubNetworks())
195 196 197 @translateError
198 - def remote_getSnmpConfig(self, devicePath):
199 "Get the snmp configuration defaults for scanning a device" 200 devroot = self.dmd.Devices.createOrganizer(devicePath) 201 return (devroot.zSnmpCommunities, 202 devroot.zSnmpPort, 203 devroot.zSnmpVer, 204 devroot.zSnmpTimeout, 205 devroot.zSnmpTries)
206 207 208 @translateError
209 - def remote_moveDevice(self, dev, path):
210 self.dmd.Devices.moveDevices(path, [dev]) 211 transaction.commit()
212 213 @translateError
215 monitor = self.dmd.Monitors.Performance._getOb(self.instance) 216 return [net for net in monitor.discoveryNetworks]
217