def connect(self): if self._ipAddr and not isip(self._ipAddr): return client.lookupAddress(self._ipAddr).addCallbacks( self._lookupProxyIp, self._lookupProxyIpErr) if self._hostname and not isip(self._hostname): return client.lookupAddress(self._hostname).addCallbacks( self._getIp, self._lookupErr) return self.request()
def connect(self): if self._ipAddr and not isip(self._ipAddr): return client.lookupAddress(self._ipAddr).addCallbacks( self._lookupProxyIp, self._lookupProxyIpErr ) if self._hostname and not isip(self._hostname): return client.lookupAddress(self._hostname).addCallbacks( self._getIp, self._lookupErr ) return self.request()
def _doDbWork(): """ return device object (either new or existing), and flag indicating whether device was newly created, or just updated """ try: netroot = getNetworkRoot(self.dmd, kw.get('performanceMonitor', 'localhost')) netobj = netroot.getNet(ip) netmask = 24 if netobj is not None: netmask = netobj.netmask else: defaultNetmasks = getattr(netroot, 'zDefaultNetworkTree', []) if defaultNetmasks: netmask = defaultNetmasks[0] autoDiscover = getattr(netobj, 'zAutoDiscover', True) # If we're not supposed to discover this IP, return None if not force and not autoDiscover: return None, False kw['manageIp'] = ipunwrap(ip) dev = manage_createDevice(self.dmd, **kw) netroot.createIp(ip, netmask) return dev, True except DeviceExistsError as e: # Update device with latest info from zendisc # (if necessary) if not e.dev.getManageIp(): e.dev.setManageIp(kw['manageIp']) # only overwrite title if it has not been set if not e.dev.title or isip(e.dev.title): if not isip(kw.get('deviceName')): e.dev.setTitle(kw['deviceName']) # copy kw->updateAttributes, to keep kw intact in case # we need to retry transaction updateAttributes = {} for k,v in kw.items(): if k not in ('manageIp', 'deviceName', 'devicePath', 'discoverProto', 'performanceMonitor', 'productionState'): updateAttributes[k] = v # use updateDevice so we don't clobber existing device properties. e.dev.updateDevice(**updateAttributes) return e.dev, False except Exception as ex: log.exception("IP address %s (kw = %s) encountered error", ipunwrap(ip), kw) raise pb.CopyableFailure(ex)
def parseHEADER(self, evt, msg): """ Parse RFC-3164 HEADER part of syslog message. TIMESTAMP format is: MMM HH:MM:SS and host is next token without the characters '[' or ':'. @param evt: dictionary of event properties @type evt: dictionary @param msg: message from host @type msg: string @return: tuple of dictionary of event properties and the message @type: (dictionary, string) """ slog.debug(msg) m = re.sub("Kiwi_Syslog_Daemon \d+: \d+: " "\S{3} [\d ]{2} [\d ]{2}:[\d ]{2}:[^:]+: ", "", msg) m = self.timeParse(msg) if m: slog.debug("parseHEADER timestamp=%s", m.group(1)) evt['originalTime'] = m.group(1) msg = m.group(2).strip() msglist = msg.split() if self.parsehost and not self.notHostSearch(msglist[0]): device = msglist[0] if device.find('@') >= 0: device = device.split('@', 1)[1] slog.debug("parseHEADER hostname=%s", evt['device']) msg = " ".join(msglist[1:]) evt['device'] = device if isip(device): evt['ipAddress'] = device else: if 'ipAddress' in evt: del(evt['ipAddress']) return evt, msg
def createDevice(self): """ Add a device to the system by name or IP. """ deviceName = self.options.device self.log.info("Looking for %s", deviceName) ip = ipunwrap(deviceName) if not isip(ip): try: ip = yield getHostByName(deviceName) except socket.error as ex: self.log.warn( "Hostname lookup failed for %s: %s", deviceName, ex ) raise NoIPAddress("No IP found for name %s" % deviceName) self.log.info("Found IP %s for device %s", ip, deviceName) configs = yield self.config().callRemote( 'getDeviceConfig', [deviceName] ) config = configs[0] if configs else None if not config or config.temp_device or self.options.remodel: device = yield self.discoverDevice( ip, devicepath=self.options.deviceclass, prodState=self.options.productionState, deviceConfig=config ) if device: self.log.info("Discovered device %s.", device.id) else: self.log.info("Device '%s' not found", deviceName) defer.returnValue(device) else: self.log.info("Device '%s' already found", deviceName)
def parse(self, device, results, log): log.info('Collecting routes for device %s' % device.id) indirectOnly = getattr(device, 'zRouteMapCollectOnlyIndirect', False) rm = self.newRelationshipMap("routes", "os") rlines = results.split("\n") for line in rlines: aline = line.split() if len(aline) != 8 or not isip(aline[0]): continue route = self.newObjectMap("Products.ZenModel.IpRouteEntry") route['routemask'] = maskToBits(aline[NETMASK]) if route['routemask'] == 32: continue if "G" in aline[FLAGS]: route['routetype'] = 'indirect' else: route['routetype'] = 'direct' if indirectOnly and route['routetype'] != 'indirect': continue route['id'] = aline[TARGET] route['setTarget'] = route['id'] + "/" + str(route['routemask']) route['id'] = route['id'] + "_" + str(route['routemask']) route['setInterfaceName'] = aline[INTERFACE] route['setNextHopIp'] = aline[GATEWAY] rm.append(route) return rm
def createDevice(self): """ Add a device to the system by name or IP. """ deviceName = self.options.device self.log.info("Looking for %s", deviceName) ip = ipunwrap(deviceName) if not isip(ip): try: ip = yield getHostByName(deviceName) except socket.error as ex: self.log.warn("Hostname lookup failed for %s: %s", deviceName, ex) raise NoIPAddress("No IP found for name %s" % deviceName) self.log.info("Found IP %s for device %s", ip, deviceName) configs = yield self.config().callRemote('getDeviceConfig', [deviceName]) config = configs[0] if configs else None if not config or config.temp_device or self.options.remodel: device = yield self.discoverDevice( ip, devicepath=self.options.deviceclass, prodState=self.options.productionState) if device: self.log.info("Discovered device %s.", device.id) else: self.log.info("Device '%s' not found", deviceName) defer.returnValue(device) else: self.log.info("Device '%s' already found", deviceName)
def idx_lastDecimalIp(self): last_decimal_ip = None if isip(self.id): net = IPNetwork(ipunwrap(self.id)) first_decimal_ip = long(int(net.network)) last_decimal_ip = str(long(first_decimal_ip + math.pow(2, net.max_prefixlen - self.netmask) - 1)) return last_decimal_ip
def createDevice(self, driver): """ Add a device to the system by name or IP. @param driver: driver object @type driver: Twisted/Zenoss object @return: Twisted deferred @rtype: Twisted deferred """ deviceName = self.options.device self.log.info("Looking for %s" % deviceName) ip = None if isip(ipunwrap(deviceName)): ip = ipunwrap(deviceName) else: try: # FIXME ZenUtils.IpUtil.asyncIpLookup is probably a better tool # for this, but it hasn't been tested, so it's for another day self.log.debug("getHostByName") ip = getHostByName(deviceName) except socket.error: ip = "" if not ip: raise NoIPAddress("No IP found for name %s" % deviceName) else: self.log.debug("Found IP %s for device %s" % (ip, deviceName)) yield self.config().callRemote('getDeviceConfig', [deviceName]) me, = driver.next() or [None] if not me or me.temp_device or self.options.remodel: yield self.discoverDevice(ip, devicepath=self.options.deviceclass, prodState=self.options.productionState) yield succeed("Discovered device %s." % deviceName) driver.next()
def createDevice(self, driver): """ Add a device to the system by name or IP. @param driver: driver object @type driver: Twisted/Zenoss object @return: Twisted deferred @rtype: Twisted deferred """ deviceName = self.options.device self.log.info("Looking for %s" % deviceName) ip = None if isip(ipunwrap(deviceName)): ip = ipunwrap(deviceName) else: try: # FIXME ZenUtils.IpUtil.asyncIpLookup is probably a better tool # for this, but it hasn't been tested, so it's for another day self.log.debug("getHostByName") ip = getHostByName(deviceName) except socket.error: ip = "" if not ip: raise NoIPAddress("No IP found for name %s" % deviceName) else: self.log.debug("Found IP %s for device %s" % (ip, deviceName)) yield self.config().callRemote('getDeviceConfig', [deviceName]) me, = driver.next() or [None] if not me or me.temp_device or self.options.remodel: yield self.discoverDevice( ip, devicepath=self.options.deviceclass, prodState=self.options.productionState) yield succeed("Discovered device %s." % deviceName) driver.next()
def _doDbWork(): """ return device object (either new or existing), and flag indicating whether device was newly created, or just updated """ try: netroot = getNetworkRoot(self.dmd, kw.get('performanceMonitor', 'localhost')) netobj = netroot.getNet(ip) netmask = 24 if netobj is not None: netmask = netobj.netmask else: defaultNetmasks = getattr(netroot, 'zDefaultNetworkTree', []) if defaultNetmasks: netmask = defaultNetmasks[0] autoDiscover = getattr(netobj, 'zAutoDiscover', True) # If we're not supposed to discover this IP, return None if not force and not autoDiscover: return None, False kw['manageIp'] = ipunwrap(ip) dev = manage_createDevice(self.dmd, **kw) netroot.createIp(ip, netmask) return dev, True except DeviceExistsError, e: # Update device with latest info from zendisc # (if necessary) if not e.dev.getManageIp(): e.dev.setManageIp(kw['manageIp']) # only overwrite title if it has not been set if not e.dev.title or isip(e.dev.title): if not isip(kw.get('deviceName')): e.dev.setTitle(kw['deviceName']) # copy kw->updateAttributes, to keep kw intact in case # we need to retry transaction updateAttributes = {} for k,v in kw.items(): if k not in ('manageIp', 'deviceName', 'devicePath', 'discoverProto', 'performanceMonitor', 'productionState'): updateAttributes[k] = v # use updateDevice so we don't clobber existing device properties. e.dev.updateDevice(**updateAttributes) return e.dev, False
def getDeviceName(self, event): # See RFC3164: # * The preferred value is the hostname, and fallback to IP address. # * The Domain Name MUST NOT be included in the HOSTNAME field. # However, lots of clients do it anyway. Fall back to that field. hostname = event.actor.element_title if not isip(hostname): hostname = hostname.split('.')[0].strip() return hostname
def validDeviceSpec(self, processed, device_specs): if 'deviceName' not in device_specs: return False if self.options.must_be_resolvable and \ 'setManageIp' not in device_specs and \ not isip(device_specs['deviceName']): try: socket.gethostbyname(device_specs['deviceName']) except socket.error: processed['no_IP'] += 1 return False return True
def setManageIp(self, manageIp): """ Manually set the management IP address to check the service status. @parameter manageIp: IP address to check the service health @type manageIp: string """ if not manageIp: return bare_ip = manageIp.split('/', 1)[0] if not isip(bare_ip): return self.manageIp = bare_ip
def _findDevices(self, identifier, ipAddress, limit=None): """ Returns a tuple ([device brains], [devices]) searching manage IP and interface IPs. limit is the maximum total number in both lists. """ dev_cat = IModelCatalogTool(self._devices) try: ip_address = next(i for i in (ipAddress, identifier) if isip(i)) ip_decimal = ipToDecimal(ip_address) except Exception: ip_address = None ip_decimal = None quoted_id = quote_and_escape(identifier) query_set = Or(Eq('id', quoted_id), Eq('name', quoted_id)) if ip_decimal is not None: query_set.addSubquery(Eq('decimal_ipAddress', str(ip_decimal))) device_brains = list( dev_cat.search(types=Device, query=query_set, limit=limit, filterPermissions=False, fields=["uid", "uuid"])) if device_brains: return device_brains, [] if ip_decimal is not None: # don't search interfaces for 127.x.x.x IPv4 addresses if ipToDecimal('126.255.255.255') < ip_decimal < ipToDecimal( '128.0.0.0'): ip_decimal = None # don't search interfaces for the ::1 IPv6 address elif ipToDecimal('::1') == ip_decimal: ip_decimal = None if ip_decimal is None: return [], [] net_cat = IModelCatalogTool(self._networks) results = net_cat.search(types=IpAddress, query=(Eq('name', ip_address)), limit=limit, filterPermissions=False) devices = [brain.getObject().device() for brain in results] return device_brains, devices
def _findDevices(self, identifier, ipAddress, limit=None): """ Returns a tuple ([device brains], [devices]) searching manage IP and interface IPs. limit is the maximum total number in both lists. """ dev_cat = IModelCatalogTool(self._devices) try: ip_address = next(i for i in (ipAddress, identifier) if isip(i)) ip_decimal = ipToDecimal(ip_address) except Exception: ip_address = None ip_decimal = None quoted_id = quote_and_escape(identifier) query_set = Or(Eq('id', quoted_id), Eq('name', quoted_id)) if ip_decimal is not None: query_set.addSubquery(Eq('decimal_ipAddress', str(ip_decimal))) device_brains = list(dev_cat.search(types=Device, query=query_set, limit=limit, filterPermissions=False, fields=["uid", "uuid"])) if device_brains: return device_brains, [] if ip_decimal is not None: # don't search interfaces for 127.x.x.x IPv4 addresses if ipToDecimal('126.255.255.255') < ip_decimal < ipToDecimal('128.0.0.0'): ip_decimal = None # don't search interfaces for the ::1 IPv6 address elif ipToDecimal('::1') == ip_decimal: ip_decimal = None if ip_decimal is None: return [], [] net_cat = IModelCatalogTool(self._networks) results = net_cat.search(types=IpAddress, query=(Eq('name', ip_address)), limit = limit, filterPermissions = False) devices = [brain.getObject().device() for brain in results] return device_brains, devices
def _getManageIp(self): """ Pick an IP out of available choices. @return: IP address to contact the service on @rtype: string """ if self.manageIp and isip(self.manageIp): return self.manageIp manage_ip = Service.getManageIp(self) bare_ip = manage_ip.split('/', 1)[0] if bare_ip in self.ipaddresses: return bare_ip for ip in self.ipaddresses: if ip != '0.0.0.0' and ip != '127.0.0.1' and ip != '::1': return ip return bare_ip
def getDeviceByIpAddress(self, deviceName, collector="localhost", ipAddress=""): # convert device name to an ip address if not ipAddress: if isip(deviceName): ipAddress = deviceName else: try: ipAddress = getHostByName(deviceName) except socket.error: # look for duplicate name return self.context.Devices.findDeviceByIdExact(deviceName) # find a device with the same ip on the same collector query = Eq('getDeviceIp', ipAddress) cat = self.context.Devices.deviceSearch brains = cat.evalAdvancedQuery(query) for brain in brains: if brain.getObject().getPerformanceServerName() == collector: return brain.getObject()
def setManageIp(self, manageIp): """ Manually set the management IP address to check the service status. @parameter manageIp: IP address to check the service health @type manageIp: string """ if not manageIp: return bare_ip = manageIp.split('/',1)[0] if not isip(bare_ip): return ips = self.getIpAddresses() if '0.0.0.0' in self.ipaddresses and bare_ip in ips: self.manageIp = bare_ip if bare_ip in self.ipaddresses: self.manageIp = bare_ip
def getDeviceByIpAddress(self, deviceName, collector="localhost", ipAddress=""): # convert device name to an ip address if not ipAddress: if isip(deviceName): ipAddress = deviceName else: try: ipAddress = getHostByName(deviceName) except socket.error: # look for duplicate name return self.context.Devices.findDeviceByIdExact(deviceName) # find a device with the same ip on the same collector cat = IModelCatalogTool(self.context.Devices) query = And(Eq('text_ipAddress', ipAddress), Eq('objectImplements', 'Products.ZenModel.Device.Device')) search_results = cat.search(query=query) for brain in search_results.results: if brain.getObject().getPerformanceServerName() == collector: return brain.getObject()
result = yield neutron_client.floatingips() results["floatingips"] = result["floatingips"] # Do some DNS lookups as well. hostnames = set([x["host"] for x in results["services"]]) hostnames.update([x["host"] for x in results["agents"]]) hostnames.update(device.zOpenStackExtraHosts) hostnames.update(device.zOpenStackNovaApiHosts) try: hostnames.add(urlparse(results["nova_url"]).hostname) except Exception, e: log.warning("Unable to determine nova URL for nova-api component discovery: %s" % e) results["resolved_hostnames"] = {} for hostname in sorted(hostnames): if isip(hostname): results["resolved_hostnames"][hostname] = hostname continue for i in range(1, 4): try: host_ip = yield asyncIpLookup(hostname) results["resolved_hostnames"][hostname] = host_ip break except socket.gaierror, e: # temporary dns issue- try again. log.error("resolve %s: (attempt %d/3): %s" % (hostname, i, e)) yield sleep(2) except Exception, e: log.error("resolve %s: %s" % (hostname, e))
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()
def idx_firstDecimalIp(self): first_decimal_ip = None if isip(self.id): net = IPNetwork(ipunwrap(self.id)) first_decimal_ip = str(int(net.network)) return first_decimal_ip
def discoverDevice(self, ip, devicepath=None, prodState=None): """ Discover the device at the given 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 """ if devicepath is None: devicepath = self.options.deviceclass if prodState is None: prodState = self.options.productionState self.scanned += 1 if self.options.maxdevices: if self.scanned >= self.options.maxdevices: self.log.info("Limit of %d devices reached", self.options.maxdevices) defer.returnValue(None) 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: job_props = yield self.config().callRemote( 'getJobProperties', self.options.job) 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) snmp_config = yield self.findRemoteDeviceInfo( ip, devicepath, snmpCommunities) 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 # Since we 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) defer.returnValue(None) # 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 try: kw["deviceName"] = yield asyncNameLookup(ip) except Exception as 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 result = None try: result = yield self.config().callRemote('createDevice', ipunwrap(ip), force=forceDiscovery, **kw) except Exception as ex: raise ZentinelException(ex) self.log.debug("Got result from remote_createDevice: %s", result) 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) defer.returnValue(None) # 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) defer.returnValue(dev) 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 self.config().callRemote('succeedDiscovery', dev.id) defer.returnValue(dev) except ZentinelException as e: self.log.exception(e) if self.options.snmpMissing: self.sendEvent( dict(device=ip, component=ip, ipAddress=ip, eventKey=ip, eventClass=Status_Snmp, summary=str(e), severity=Info, agent="Discover")) except Exception as e: self.log.exception("Failed device discovery for '%s'", ip) finally: self.log.info("Finished scanning device with address %s", ip)
def connect(self): if not isip(self._hostname): return client.lookupAddress(self._hostname).addCallbacks( self._getIp, self._lookupErr) return self.request()
def discoverDevice(self, ip, devicepath=None, prodState=None, deviceConfig=None): """ Discover the device at the given 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 """ if devicepath is None: devicepath = self.options.deviceclass if prodState is None: prodState = self.options.productionState self.scanned += 1 if self.options.maxdevices: if self.scanned >= self.options.maxdevices: self.log.info("Limit of %d devices reached", self.options.maxdevices) defer.returnValue(None) try: kw = dict( deviceName=ip, discoverProto=None, devicePath=devicepath, performanceMonitor=self.options.monitor, locationPath=self.options.location, groupPaths=self.options.groups, systemPaths=self.options.systems, productionState=prodState ) # If zProperties are set via a job, get them and pass them in if self.options.job: job_props = yield self.config().callRemote( 'getJobProperties', self.options.job ) 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) zProps = kw.get('zProperties', {}) deviceSnmpCommunities = zProps.get('zSnmpCommunities', None) if not deviceSnmpCommunities and deviceConfig: deviceSnmpCommunities = getattr( deviceConfig, 'zSnmpCommunities', None) snmp_config = yield self.findRemoteDeviceInfo( ip, devicepath, deviceSnmpCommunities ) 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 # Since we 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 ) defer.returnValue(None) # 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 try: kw["deviceName"] = yield asyncNameLookup(ip) except Exception as 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 result = None try: result = yield self.config().callRemote( 'createDevice', ipunwrap(ip), force=forceDiscovery, **kw ) except Exception as ex: raise ZentinelException(ex) self.log.debug("Got result from remote_createDevice: %s", result) 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) defer.returnValue(None) # 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) defer.returnValue(dev) 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 self.config().callRemote('succeedDiscovery', dev.id) defer.returnValue(dev) except ZentinelException as e: self.log.exception(e) if self.options.snmpMissing: self.sendEvent(dict( device=ip, component=ip, ipAddress=ip, eventKey=ip, eventClass=Status_Snmp, summary=str(e), severity=Info, agent="Discover" )) except Exception as e: self.log.exception("Failed device discovery for '%s'", ip) finally: self.log.info("Finished scanning device with address %s", ip)
def addDevice(self, deviceName, deviceClass, *args, **kwargs): from Products.ZenModel.PerformanceConf import PerformanceConf from Products.ZenUtils.IpUtil import isip # y: kwargs; x: key; z: default g = lambda x, y, z: y[x] if x in y else z original_kwargs = inspect.getcallargs(original, self, deviceName, deviceClass, *args, **kwargs) deviceName = g('deviceName', original_kwargs, '') deviceClass = g('deviceClass', original_kwargs, '') title = g('title', original_kwargs, '') snmpCommunity = g('snmpCommunity', original_kwargs, '') snmpPort = g('snmpPort', original_kwargs, 161) manageIp = g('manageIp', original_kwargs, '') model = g('model', original_kwargs, False) collector = g('collector', original_kwargs, 'localhost') rackSlot = g('rackSlot', original_kwargs, 0) productionState = g('productionState', original_kwargs, 1000) comments = g('comments', original_kwargs, '') hwManufacturer = g('hwManufacturer', original_kwargs, '') hwProductName = g('hwProductName', original_kwargs, '') osManufacturer = g('osManufacturer', original_kwargs, '') osProductName = g('osProductName', original_kwargs, '') priority = g('priority', original_kwargs, 3) tag = g('tag', original_kwargs, '') serialNumber = g('serialNumber', original_kwargs, '') locationPath = g('locationPath', original_kwargs, '') zCommandUsername = g('zCommandUsername', original_kwargs, '') zCommandPassword = g('zCommandPassword', original_kwargs, '') zWinUser = g('zWinUser', original_kwargs, '') zWinPassword = g('zWinPassword', original_kwargs, '') systemPaths = g('systemPaths', original_kwargs, []) groupPaths = g('groupPaths', original_kwargs, []) zProperties = g('zProperties', original_kwargs, {}) cProperties = g('cProperties', original_kwargs, {}) # Make sure this patch only applies to OpenvSwitch device if deviceClass != '/Network/OpenvSwitch': return original(self, deviceName, deviceClass, *args, **kwargs) # 5.x.x uses username, password, but 4.2.x does not if 'zCommandUsername' in original_kwargs and \ 'zCommandPassword' in original_kwargs and \ 'zWinUser' in original_kwargs and \ 'zWinPassword' in original_kwargs: zProps = dict( zSnmpCommunity=snmpCommunity, zSnmpPort=snmpPort, zCommandUsername=zCommandUsername, zCommandPassword=zCommandPassword, zWinUser=zWinUser, zWinPassword=zWinPassword, ) else: zProps = dict( zSnmpCommunity=snmpCommunity, zSnmpPort=snmpPort ) zProps.update(zProperties) model = model and "Auto" or "none" perfConf = self._dmd.Monitors.getPerformanceMonitor(collector) # this is why we need this patch. # we want device name to be the device title entered via GUI # it would be the host IP address without patch if title and isip(deviceName): manageIp = deviceName deviceName = title new_kwargs = {} new_kwargs['deviceName'] = deviceName new_kwargs['devicePath'] = deviceClass new_kwargs['performanceMonitor'] = collector new_kwargs['discoverProto'] = model new_kwargs['manageIp'] = manageIp new_kwargs['zProperties'] = zProps new_kwargs['rackSlot'] = rackSlot new_kwargs['productionState'] = productionState new_kwargs['comments'] = comments new_kwargs['hwManufacturer'] = hwManufacturer new_kwargs['hwProductName'] = hwProductName new_kwargs['osManufacturer'] = osManufacturer new_kwargs['osProductName'] = osProductName new_kwargs['priority'] = priority new_kwargs['tag'] = tag new_kwargs['serialNumber'] = serialNumber new_kwargs['locationPath'] = locationPath new_kwargs['systemPaths'] = systemPaths new_kwargs['groupPaths'] = groupPaths new_kwargs['title'] = title if 'cProperties' in inspect.getargspec(PerformanceConf.addDeviceCreationJob).args: new_kwargs['cProperties'] = cProperties return perfConf.addDeviceCreationJob(**new_kwargs)
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()