def __init__(self, single=True ): """ Initalizer @param single: collect from a single device? @type single: boolean """ ZenModeler.__init__(self, single ) self.discovered = [] # pyraw inserts IPV4_SOCKET and IPV6_SOCKET globals if IPV4_SOCKET is None: self._pinger4 = None else: protocol = Ping4(IPV4_SOCKET) self._pinger4 = PingService(protocol, timeout=self.options.timeout, defaultTries=self.options.tries) if IPV6_SOCKET is None: self._pinger6 = None else: protocol = Ping6(IPV6_SOCKET) self._pinger6 = PingService(protocol, timeout=self.options.timeout, defaultTries=self.options.tries)
def __init__(self, single=True): """ Initalizer @param single: collect from a single device? @type single: boolean """ ZenModeler.__init__(self, single) self.discovered = [] # pyraw inserts IPV4_SOCKET and IPV6_SOCKET globals if IPV4_SOCKET is None: self._pinger4 = None else: protocol = Ping4(IPV4_SOCKET) self._pinger4 = PingService(protocol, timeout=self.options.timeout, defaultTries=self.options.tries) if IPV6_SOCKET is None: self._pinger6 = None else: protocol = Ping6(IPV6_SOCKET) self._pinger6 = PingService(protocol, timeout=self.options.timeout, defaultTries=self.options.tries)
class ZenDisc(ZenModeler): """ Scan networks and routes looking for devices to add to the ZODB """ initialServices = PBDaemon.initialServices + ['DiscoverService'] name = 'zendisc' scanned = 0 def __init__(self, single=True ): """ Initalizer @param single: collect from a single device? @type single: boolean """ ZenModeler.__init__(self, single ) self.discovered = [] # pyraw inserts IPV4_SOCKET and IPV6_SOCKET globals if IPV4_SOCKET is None: self._pinger4 = None else: protocol = Ping4(IPV4_SOCKET) self._pinger4 = PingService(protocol, timeout=self.options.timeout, defaultTries=self.options.tries) if IPV6_SOCKET is None: self._pinger6 = None else: protocol = Ping6(IPV6_SOCKET) self._pinger6 = PingService(protocol, timeout=self.options.timeout, defaultTries=self.options.tries) def ping(self, ip): """ Given an IP address, return a deferred that pings the address. """ self.log.debug("Using ipaddr module to convert %s" % ip) ipObj = IPAddress(ip) if ipObj.version == 6: if self._pinger6 is None: retval = Failure() else: retval = self._pinger6.ping(ip) else: if self._pinger4 is None: retval = Failure() else: retval = self._pinger4.ping(ip) return retval def config(self): """ Get the DiscoverService @return: a DiscoverService from zenhub @rtype: function """ return self.services.get('DiscoverService', FakeRemote()) def discoverIps(self, nets): """ Ping all ips, create entries in the network if necessary. @param nets: list of networks to discover @type nets: list @return: successful result is a list of IPs that were added @rtype: Twisted deferred """ def inner(driver): """ Twisted driver class to iterate through devices @param driver: Zenoss driver @type driver: Zenoss driver @return: successful result is a list of IPs that were added @rtype: Twisted deferred """ ips = [] goodCount = 0 # it would be nice to interleave ping/discover for net in nets: if self.options.subnets and len(net.children()) > 0: continue if not getattr(net, "zAutoDiscover", False): self.log.info( "Skipping network %s because zAutoDiscover is False" % net.getNetworkName()) continue self.log.info("Discover network '%s'", net.getNetworkName()) yield NJobs(self.options.chunkSize, self.ping, net.fullIpList()).start() results = driver.next() goodips = [ v.ipaddr for v in results if not isinstance(v, Failure)] badips = [ v.value.ipaddr for v in results if isinstance(v, Failure)] goodCount += len(goodips) self.log.debug("Got %d good IPs and %d bad IPs", len(goodips), len(badips)) yield self.config().callRemote('pingStatus', net, goodips, badips, self.options.resetPtr, self.options.addInactive) ips += driver.next() self.log.info("Discovered %s active ips", goodCount) # make sure this is the return result for the driver yield succeed(ips) driver.next() d = drive(inner) return d def discoverRanges(self, driver): """ Ping all IPs in the range and create devices for the ones that come back. @param ranges: list of ranges to discover @type ranges: list """ if isinstance(self.options.range, basestring): self.options.range = [self.options.range] # in case someone uses 10.0.0.0-5,192.168.0.1-5 instead of # --range 10.0.0.0-5 --range 192.168.0.1-5 if (isinstance(self.options.range, list) and self.options.range[0].find(",") > -1): self.options.range = [n.strip() for n in self.options.range[0].split(',')] ips = [] goodCount = 0 for iprange in self.options.range: # Parse to find ips included ips.extend(parse_iprange(iprange)) yield NJobs(self.options.chunkSize, self.ping, ips).start() results = driver.next() goodips = [v.ipaddr for v in results if not isinstance(v, Failure)] badips = [v.value.ipaddr for v in results if isinstance(v, Failure)] goodCount += len(goodips) self.log.debug("Got %d good IPs and %d bad IPs", len(goodips), len(badips)) yield self.discoverDevices(goodips) yield succeed("Discovered %d active IPs" % goodCount) driver.next() def discoverRouters(self, rootdev, seenips=None): """ Discover all default routers based on DMD configuration. @param rootdev: device root in DMD @type rootdev: device class @param seenips: list of IP addresses @type seenips: list of strings @return: Twisted/Zenoss Python iterable @rtype: Python iterable """ if not seenips: seenips = [] def inner(driver): """ Twisted driver class to iterate through devices @param driver: Zenoss driver @type driver: Zenoss driver @return: successful result is a list of IPs that were added @rtype: Twisted deferred """ yield self.config().callRemote('followNextHopIps', rootdev.id) for ip in driver.next(): if ip in seenips: continue self.log.info("device '%s' next hop '%s'", rootdev.id, ip) seenips.append(ip) yield self.discoverDevice(ip, devicepath="/Network/Router") router = driver.next() if not router: continue yield self.discoverRouters(router, seenips) driver.next() return drive(inner) def sendDiscoveredEvent(self, ip, dev=None, sev=2): """ Send a 'device discovered' event through zenhub @param ip: IP addresses @type ip: strings @param dev: remote device name @type dev: device object @param sev: severity @type sev: integer """ devname = comp = ip if dev: devname = dev.id msg = "'Discovered device name '%s' for ip '%s'" % (devname, ip) evt = dict(device=devname,ipAddress=ip,eventKey=ip, component=comp,eventClass=Status_Snmp, summary=msg, severity=sev, agent="Discover") self.sendEvent(evt) def discoverDevices(self, ips, devicepath="/Discovered", prodState=1000): """ Discover devices by active ips that are not associated with a device. @param ips: list of IP addresses @type ips: list of strings @param devicepath: where in the DMD to put any discovered devices @type devicepath: string @param prodState: production state (see Admin Guide for a description) @type prodState: integer @return: Twisted/Zenoss Python iterable @rtype: Python iterable """ def discoverDevice(ip): """ Discover a particular device NB: Wrapper around self.discoverDevice() @param ip: IP address @type ip: string @return: Twisted/Zenoss Python iterable @rtype: Python iterable """ return self.discoverDevice(ip, devicepath, prodState) return NJobs(self.options.parallel, discoverDevice, ips).start() def findRemoteDeviceInfo(self, ip, devicePath, deviceSnmpCommunities=None): """ Scan a device for ways of naming it: PTR DNS record or a SNMP name @param ip: IP address @type ip: string @param devicePath: where in the DMD to put any discovered devices @type devicePath: string @param deviceSnmpCommunities: Optional list of SNMP community strings to try, overriding those set on the device class @type deviceSnmpCommunities: list @return: result is None or a tuple containing (community, port, version, snmp name) @rtype: deferred: Twisted deferred """ from pynetsnmp.twistedsnmp import AgentProxy def inner(driver): """ Twisted driver class to iterate through devices @param driver: Zenoss driver @type driver: Zenoss driver @return: successful result is a list of IPs that were added @rtype: Twisted deferred """ self.log.debug("findRemoteDeviceInfo.inner: Doing SNMP lookup on device %s", ip) yield self.config().callRemote('getSnmpConfig', devicePath) communities, ports, version, timeout, retries = driver.next() self.log.debug("findRemoteDeviceInfo.inner: override acquired community strings") # Override the device class communities with the ones set on # this device, if they exist if deviceSnmpCommunities is not None: communities = deviceSnmpCommunities # Reverse the communities so that ones earlier in the list have a # higher weight. communities.reverse() configs = [] for i, community in enumerate(communities): for port in ports: port = int(port) configs.append(SnmpV1Config( ip, weight=i, port=port, timeout=timeout, retries=retries, community=community)) configs.append(SnmpV2cConfig( ip, weight=i+100, port=port, timeout=timeout, retries=retries, community=community)) yield SnmpAgentDiscoverer().findBestConfig(configs) driver.next() self.log.debug("Finished SNMP lookup on device %s", ip) return drive(inner) def discoverDevice(self, ip, devicepath="/Discovered", prodState=1000): """ Discover a device based on its IP address. @param ip: IP address @type ip: string @param devicepath: where in the DMD to put any discovered devices @type devicepath: string @param prodState: production state (see Admin Guide for a description) @type prodState: integer @return: Twisted/Zenoss Python iterable @rtype: Python iterable """ self.scanned += 1 if self.options.maxdevices: if self.scanned >= self.options.maxdevices: self.log.info("Limit of %d devices reached" % self.options.maxdevices) return succeed(None) def inner(driver): """ Twisted driver class to iterate through devices @param driver: Zenoss driver @type driver: Zenoss driver @return: successful result is a list of IPs that were added @rtype: Twisted deferred @todo: modularize this function (130+ lines is ridiculous) """ try: kw = dict(deviceName=ip, discoverProto=None, devicePath=devicepath, performanceMonitor=self.options.monitor, productionState=prodState) # If zProperties are set via a job, get them and pass them in if self.options.job: yield self.config().callRemote('getJobProperties', self.options.job) job_props = driver.next() if job_props is not None: # grab zProperties from Job kw['zProperties'] = getattr(job_props, 'zProperties', {}) # grab other Device properties from jobs #deviceProps = job_props.get('deviceProps', {}) #kw.update(deviceProps) #@FIXME we are not getting deviceProps, check calling # chain for clues. twisted upgrade heartburn perhaps? # if we are using SNMP, lookup the device SNMP info and use the # name defined there for deviceName if not self.options.nosnmp: self.log.debug("Scanning device with address %s", ip) snmpCommunities = kw.get('zProperties', {}).get( 'zSnmpCommunities', None) yield self.findRemoteDeviceInfo(ip, devicepath, snmpCommunities) snmp_config = driver.next() if snmp_config: if snmp_config.sysName: kw['deviceName'] = snmp_config.sysName if snmp_config.version: kw['zSnmpVer'] = snmp_config.version if snmp_config.port: kw['zSnmpPort'] = snmp_config.port if snmp_config.community: kw['zSnmpCommunity'] = snmp_config.community # if we are using SNMP, did not find any snmp info, # and we are in strict discovery mode, do not # create a device elif self.options.zSnmpStrictDiscovery: self.log.info('zSnmpStrictDiscovery is True. ' + 'Not creating device for %s.' % ip ) return # RULES FOR DEVICE NAMING: # 1. If zPreferSnmpNaming is true: # If snmp name is returned, use snmp name. Otherwise, # use the passed device name. If no device name was passed, # do a dns lookup on the ip. # 2. If zPreferSnmpNaming is false: # If we are discovering a single device and a name is # passed in instead of an IP, use the passed-in name. # Otherwise, do a dns lookup on the ip. if self.options.zPreferSnmpNaming and \ not isip( kw['deviceName'] ): # In this case, we want to keep kw['deviceName'] as-is, # because it is what we got from snmp pass elif self.options.device and not isip(self.options.device): kw['deviceName'] = self.options.device else: # An IP was passed in so we do a reverse lookup on it to get # deviceName yield asyncNameLookup(ip) try: kw.update(dict(deviceName=driver.next())) except Exception, ex: self.log.debug("Failed to lookup %s (%s)" % (ip, ex)) # If it's discovering a particular device, # ignore zAutoDiscover limitations forceDiscovery = bool(self.options.device) # now create the device by calling zenhub yield self.config().callRemote('createDevice', ipunwrap(ip), force=forceDiscovery, **kw) result = driver.next() self.log.debug("ZenDisc.discoverDevice.inner: got result from remote_createDevice") if isinstance(result, Failure): raise ZentinelException(result.value) dev, created = result # if no device came back from createDevice we assume that it # was told to not auto-discover the device. This seems very # dubious to me! -EAD if not dev: self.log.info("IP '%s' on no auto-discover, skipping",ip) return else: # A device came back and it already existed. if not created and not dev.temp_device: # if we shouldn't remodel skip the device by returning # at the end of this block if not self.options.remodel: self.log.info("Found IP '%s' on device '%s';" " skipping discovery", ip, dev.id) if self.options.device: self.setExitCode(3) yield succeed(dev) driver.next() return else: # we continue on to model the device. self.log.info("IP '%s' on device '%s' remodel", ip, dev.id) self.sendDiscoveredEvent(ip, dev) # the device that we found/created or that should be remodeled # is added to the list of devices to be modeled later if not self.options.nosnmp: self.discovered.append(dev.id) yield succeed(dev) driver.next() except ZentinelException, e: self.log.exception(e) evt = dict(device=ip, component=ip, ipAddress=ip, eventKey=ip, eventClass=Status_Snmp, summary=str(e), severity=Info, agent="Discover") if self.options.snmpMissing: self.sendEvent(evt) except Exception, e: self.log.exception("Failed device discovery for '%s'", ip)
class ZenDisc(ZenModeler): """ Scan networks and routes looking for devices to add to the ZODB """ initialServices = PBDaemon.initialServices + ['DiscoverService'] name = 'zendisc' scanned = 0 def __init__(self, single=True): """ Initalizer @param single: collect from a single device? @type single: boolean """ ZenModeler.__init__(self, single) self.discovered = [] # pyraw inserts IPV4_SOCKET and IPV6_SOCKET globals if IPV4_SOCKET is None: self._pinger4 = None else: protocol = Ping4(IPV4_SOCKET) self._pinger4 = PingService(protocol, timeout=self.options.timeout, defaultTries=self.options.tries) if IPV6_SOCKET is None: self._pinger6 = None else: protocol = Ping6(IPV6_SOCKET) self._pinger6 = PingService(protocol, timeout=self.options.timeout, defaultTries=self.options.tries) def ping(self, ip): """ Given an IP address, return a deferred that pings the address. """ self.log.debug("Using ipaddr module to convert %s" % ip) ipObj = IPAddress(ip) if ipObj.version == 6: if self._pinger6 is None: retval = Failure() else: retval = self._pinger6.ping(ip) else: if self._pinger4 is None: retval = Failure() else: retval = self._pinger4.ping(ip) return retval def config(self): """ Get the DiscoverService @return: a DiscoverService from zenhub @rtype: function """ return self.services.get('DiscoverService', FakeRemote()) def discoverIps(self, nets): """ Ping all ips, create entries in the network if necessary. @param nets: list of networks to discover @type nets: list @return: successful result is a list of IPs that were added @rtype: Twisted deferred """ def inner(driver): """ Twisted driver class to iterate through devices @param driver: Zenoss driver @type driver: Zenoss driver @return: successful result is a list of IPs that were added @rtype: Twisted deferred """ ips = [] goodCount = 0 # it would be nice to interleave ping/discover for net in nets: if self.options.subnets and len(net.children()) > 0: continue if not getattr(net, "zAutoDiscover", False): self.log.info( "Skipping network %s because zAutoDiscover is False" % net.getNetworkName()) continue self.log.info("Discover network '%s'", net.getNetworkName()) yield NJobs(self.options.chunkSize, self.ping, net.fullIpList()).start() results = driver.next() goodips = [ v.ipaddr for v in results if not isinstance(v, Failure) ] badips = [ v.value.ipaddr for v in results if isinstance(v, Failure) ] goodCount += len(goodips) self.log.debug("Got %d good IPs and %d bad IPs", len(goodips), len(badips)) yield self.config().callRemote('pingStatus', net, goodips, badips, self.options.resetPtr, self.options.addInactive) ips += driver.next() self.log.info("Discovered %s active ips", goodCount) # make sure this is the return result for the driver yield succeed(ips) driver.next() d = drive(inner) return d def discoverRanges(self, driver): """ Ping all IPs in the range and create devices for the ones that come back. @param ranges: list of ranges to discover @type ranges: list """ if isinstance(self.options.range, basestring): self.options.range = [self.options.range] # in case someone uses 10.0.0.0-5,192.168.0.1-5 instead of # --range 10.0.0.0-5 --range 192.168.0.1-5 if (isinstance(self.options.range, list) and self.options.range[0].find(",") > -1): self.options.range = [ n.strip() for n in self.options.range[0].split(',') ] ips = [] goodCount = 0 for iprange in self.options.range: # Parse to find ips included ips.extend(parse_iprange(iprange)) yield NJobs(self.options.chunkSize, self.ping, ips).start() results = driver.next() goodips = [v.ipaddr for v in results if not isinstance(v, Failure)] badips = [v.value.ipaddr for v in results if isinstance(v, Failure)] goodCount += len(goodips) self.log.debug("Got %d good IPs and %d bad IPs", len(goodips), len(badips)) yield self.discoverDevices(goodips) yield succeed("Discovered %d active IPs" % goodCount) driver.next() def discoverRouters(self, rootdev, seenips=None): """ Discover all default routers based on DMD configuration. @param rootdev: device root in DMD @type rootdev: device class @param seenips: list of IP addresses @type seenips: list of strings @return: Twisted/Zenoss Python iterable @rtype: Python iterable """ if not seenips: seenips = [] def inner(driver): """ Twisted driver class to iterate through devices @param driver: Zenoss driver @type driver: Zenoss driver @return: successful result is a list of IPs that were added @rtype: Twisted deferred """ yield self.config().callRemote('followNextHopIps', rootdev.id) for ip in driver.next(): if ip in seenips: continue self.log.info("device '%s' next hop '%s'", rootdev.id, ip) seenips.append(ip) yield self.discoverDevice(ip, devicepath="/Network/Router") router = driver.next() if not router: continue yield self.discoverRouters(router, seenips) driver.next() return drive(inner) def sendDiscoveredEvent(self, ip, dev=None, sev=2): """ Send a 'device discovered' event through zenhub @param ip: IP addresses @type ip: strings @param dev: remote device name @type dev: device object @param sev: severity @type sev: integer """ devname = comp = ip if dev: devname = dev.id msg = "'Discovered device name '%s' for ip '%s'" % (devname, ip) evt = dict(device=devname, ipAddress=ip, eventKey=ip, component=comp, eventClass=Status_Snmp, summary=msg, severity=sev, agent="Discover") self.sendEvent(evt) def discoverDevices(self, ips, devicepath="/Discovered", prodState=1000): """ Discover devices by active ips that are not associated with a device. @param ips: list of IP addresses @type ips: list of strings @param devicepath: where in the DMD to put any discovered devices @type devicepath: string @param prodState: production state (see Admin Guide for a description) @type prodState: integer @return: Twisted/Zenoss Python iterable @rtype: Python iterable """ def discoverDevice(ip): """ Discover a particular device NB: Wrapper around self.discoverDevice() @param ip: IP address @type ip: string @return: Twisted/Zenoss Python iterable @rtype: Python iterable """ return self.discoverDevice(ip, devicepath, prodState) return NJobs(self.options.parallel, discoverDevice, ips).start() def findRemoteDeviceInfo(self, ip, devicePath, deviceSnmpCommunities=None): """ Scan a device for ways of naming it: PTR DNS record or a SNMP name @param ip: IP address @type ip: string @param devicePath: where in the DMD to put any discovered devices @type devicePath: string @param deviceSnmpCommunities: Optional list of SNMP community strings to try, overriding those set on the device class @type deviceSnmpCommunities: list @return: result is None or a tuple containing (community, port, version, snmp name) @rtype: deferred: Twisted deferred """ from pynetsnmp.twistedsnmp import AgentProxy def inner(driver): """ Twisted driver class to iterate through devices @param driver: Zenoss driver @type driver: Zenoss driver @return: successful result is a list of IPs that were added @rtype: Twisted deferred """ self.log.debug( "findRemoteDeviceInfo.inner: Doing SNMP lookup on device %s", ip) yield self.config().callRemote('getSnmpConfig', devicePath) communities, ports, version, timeout, retries = driver.next() self.log.debug( "findRemoteDeviceInfo.inner: override acquired community strings" ) # Override the device class communities with the ones set on # this device, if they exist if deviceSnmpCommunities is not None: communities = deviceSnmpCommunities # Reverse the communities so that ones earlier in the list have a # higher weight. communities.reverse() configs = [] for i, community in enumerate(communities): for port in ports: port = int(port) configs.append( SnmpV1Config(ip, weight=i, port=port, timeout=timeout, retries=retries, community=community)) configs.append( SnmpV2cConfig(ip, weight=i + 100, port=port, timeout=timeout, retries=retries, community=community)) yield SnmpAgentDiscoverer().findBestConfig(configs) driver.next() self.log.debug("Finished SNMP lookup on device %s", ip) return drive(inner) def discoverDevice(self, ip, devicepath="/Discovered", prodState=1000): """ Discover a device based on its IP address. @param ip: IP address @type ip: string @param devicepath: where in the DMD to put any discovered devices @type devicepath: string @param prodState: production state (see Admin Guide for a description) @type prodState: integer @return: Twisted/Zenoss Python iterable @rtype: Python iterable """ self.scanned += 1 if self.options.maxdevices: if self.scanned >= self.options.maxdevices: self.log.info("Limit of %d devices reached" % self.options.maxdevices) return succeed(None) def inner(driver): """ Twisted driver class to iterate through devices @param driver: Zenoss driver @type driver: Zenoss driver @return: successful result is a list of IPs that were added @rtype: Twisted deferred @todo: modularize this function (130+ lines is ridiculous) """ try: kw = dict(deviceName=ip, discoverProto=None, devicePath=devicepath, performanceMonitor=self.options.monitor, productionState=prodState) # If zProperties are set via a job, get them and pass them in if self.options.job: yield self.config().callRemote('getJobProperties', self.options.job) job_props = driver.next() if job_props is not None: # grab zProperties from Job kw['zProperties'] = getattr(job_props, 'zProperties', {}) # grab other Device properties from jobs #deviceProps = job_props.get('deviceProps', {}) #kw.update(deviceProps) #@FIXME we are not getting deviceProps, check calling # chain for clues. twisted upgrade heartburn perhaps? # if we are using SNMP, lookup the device SNMP info and use the # name defined there for deviceName if not self.options.nosnmp: self.log.debug("Scanning device with address %s", ip) snmpCommunities = kw.get('zProperties', {}).get('zSnmpCommunities', None) yield self.findRemoteDeviceInfo(ip, devicepath, snmpCommunities) snmp_config = driver.next() if snmp_config: if snmp_config.sysName: kw['deviceName'] = snmp_config.sysName if snmp_config.version: kw['zSnmpVer'] = snmp_config.version if snmp_config.port: kw['zSnmpPort'] = snmp_config.port if snmp_config.community: kw['zSnmpCommunity'] = snmp_config.community # if we are using SNMP, did not find any snmp info, # and we are in strict discovery mode, do not # create a device elif self.options.zSnmpStrictDiscovery: self.log.info('zSnmpStrictDiscovery is True. ' + 'Not creating device for %s.' % ip) return # RULES FOR DEVICE NAMING: # 1. If zPreferSnmpNaming is true: # If snmp name is returned, use snmp name. Otherwise, # use the passed device name. If no device name was passed, # do a dns lookup on the ip. # 2. If zPreferSnmpNaming is false: # If we are discovering a single device and a name is # passed in instead of an IP, use the passed-in name. # Otherwise, do a dns lookup on the ip. if self.options.zPreferSnmpNaming and \ not isip( kw['deviceName'] ): # In this case, we want to keep kw['deviceName'] as-is, # because it is what we got from snmp pass elif self.options.device and not isip(self.options.device): kw['deviceName'] = self.options.device else: # An IP was passed in so we do a reverse lookup on it to get # deviceName yield asyncNameLookup(ip) try: kw.update(dict(deviceName=driver.next())) except Exception, ex: self.log.debug("Failed to lookup %s (%s)" % (ip, ex)) # If it's discovering a particular device, # ignore zAutoDiscover limitations forceDiscovery = bool(self.options.device) # now create the device by calling zenhub yield self.config().callRemote('createDevice', ipunwrap(ip), force=forceDiscovery, **kw) result = driver.next() self.log.debug( "ZenDisc.discoverDevice.inner: got result from remote_createDevice" ) if isinstance(result, Failure): raise ZentinelException(result.value) dev, created = result # if no device came back from createDevice we assume that it # was told to not auto-discover the device. This seems very # dubious to me! -EAD if not dev: self.log.info("IP '%s' on no auto-discover, skipping", ip) return else: # A device came back and it already existed. if not created and not dev.temp_device: # if we shouldn't remodel skip the device by returning # at the end of this block if not self.options.remodel: self.log.info( "Found IP '%s' on device '%s';" " skipping discovery", ip, dev.id) if self.options.device: self.setExitCode(3) yield succeed(dev) driver.next() return else: # we continue on to model the device. self.log.info("IP '%s' on device '%s' remodel", ip, dev.id) self.sendDiscoveredEvent(ip, dev) # the device that we found/created or that should be remodeled # is added to the list of devices to be modeled later if not self.options.nosnmp: self.discovered.append(dev.id) yield succeed(dev) driver.next() except ZentinelException, e: self.log.exception(e) evt = dict(device=ip, component=ip, ipAddress=ip, eventKey=ip, eventClass=Status_Snmp, summary=str(e), severity=Info, agent="Discover") if self.options.snmpMissing: self.sendEvent(evt) except Exception, e: self.log.exception("Failed device discovery for '%s'", ip)