def process(self, device, results, log): """Process SNMP information from this device""" log.info('Modeler %s processing data for device %s', self.name(), device.id) getdata, tabledata = results log.debug("%s tabledata = %s", device.id, tabledata) fstable = tabledata.get("fsTableOid") if fstable is None: log.error("Unable to get data for %s from fsTableOid" " -- skipping model" % device.id) return None skipfsnames = getattr(device, 'zFileSystemMapIgnoreNames', None) maps = [] rm = self.relMap() for fs in fstable.values(): if not self.checkColumns(fs, self.columns, log): continue totalBlocks = fs['totalBlocks'] # This may now be a redundant check. Candidate for removal. # http://dev.zenoss.org/trac/ticket/4556 if totalBlocks < 0: fs['totalBlocks'] = unsigned(totalBlocks) # blockSize is not used by UCD mibs. # UCD mibs display size in kilobytes. # Value has been hardcoded as 1024 to convert to bytes. fs['blockSize'] = 1024 size = fs['totalBlocks'] # UCD-SNMP-MIB does not provide filesystem type info. # Only zFileSystemMapIgnoreNames is checked. if skipfsnames and re.search(skipfsnames, fs['mount']): log.info( "Skipping %s as it matches zFileSystemMapIgnoreNames.", fs['mount']) continue om = self.objectMap(fs) om.id = self.prepId(om.mount) rm.append(om) maps.append(rm) return maps
def process(self, device, results, log): """Process SNMP information from this device""" log.info('Modeler %s processing data for device %s', self.name(), device.id) getdata, tabledata = results log.debug("%s tabledata = %s", device.id, tabledata) fstable = tabledata.get("fsTableOid") if fstable is None: log.error("Unable to get data for %s from fsTableOid" " -- skipping model" % device.id) return None skipfsnames = getattr(device, 'zFileSystemMapIgnoreNames', None) maps = [] rm = self.relMap() for fs in fstable.values(): if not self.checkColumns(fs, self.columns, log): continue totalBlocks = fs['totalBlocks'] # This may now be a redundant check. Candidate for removal. # http://dev.zenoss.org/trac/ticket/4556 if totalBlocks < 0: fs['totalBlocks'] = unsigned(totalBlocks) # blockSize is not used by UCD mibs. # UCD mibs display size in kilobytes. # Value has been hardcoded as 1024 to convert to bytes. fs['blockSize'] = 1024 size = fs['totalBlocks'] # UCD-SNMP-MIB does not provide filesystem type info. # Only zFileSystemMapIgnoreNames is checked. if skipfsnames and re.search(skipfsnames, fs['mount']): log.info("Skipping %s as it matches zFileSystemMapIgnoreNames.", fs['mount']) continue om = self.objectMap(fs) om.id = self.prepId(om.mount) rm.append(om) maps.append(rm) return maps
class InterfaceMap(SnmpPlugin): """ Map IPv4 and IPv6 network names and aliases to DMD 'interface' objects """ order = 80 compname = "os" relname = "interfaces" modname = "Products.ZenModel.IpInterface" deviceProperties = \ SnmpPlugin.deviceProperties + ('zInterfaceMapIgnoreNames', 'zInterfaceMapIgnoreTypes', 'zInterfaceMapIgnoreDescriptions') # Interface related tables likely to be used in all subclasses. baseSnmpGetTableMaps = ( GetTableMap( 'iftable', '.1.3.6.1.2.1.2.2.1', { '.1': 'ifindex', '.2': 'id', '.3': 'type', '.4': 'mtu', '.5': 'speed', '.6': 'macaddress', '.7': 'adminStatus', '.8': 'operStatus' }), # ipAddrTable is the better way to get IP addresses GetTableMap('ipAddrTable', '.1.3.6.1.2.1.4.20.1', { '.1': 'ipAddress', '.2': 'ifindex', '.3': 'netmask' }), # IP-MIB::ipAddressIfIndex can give us IPv6 addresses. GetTableMap('ipAddressIfIndex', '.1.3.6.1.2.1.4.34.1.3.2', { '.16': 'ifindex', }), # Use the ipNetToMediaTable as a backup to the ipAddrTable GetTableMap('ipNetToMediaTable', '.1.3.6.1.2.1.4.22.1', { '.1': 'ifindex', '.3': 'ipaddress', '.4': 'iptype' }), # attempt to determine if the interface supports duplex mode GetTableMap('duplex', '.1.3.6.1.2.1.10.7.2.1', {'.19': 'duplex'}), ) # Base interface tables, plus ones used locally. snmpGetTableMaps = baseSnmpGetTableMaps + ( # Extended interface information. GetTableMap( 'ifalias', '.1.3.6.1.2.1.31.1.1.1', { '.6': 'ifHCInOctets', '.7': 'ifHCInUcastPkts', '.15': 'highSpeed', '.18': 'description' }), ) def process(self, device, results, log): """ From SNMP info gathered from the device, convert them to interface objects. """ getdata, tabledata = results log.info('Modeler %s processing data for device %s', self.name(), device.id) log.debug("%s tabledata = %s", device.id, tabledata) rm = self.relMap() iptable = tabledata.get("ipAddrTable") sourceTable = 'ipAddrTable' if not iptable: iptable = tabledata.get("ipNetToMediaTable") if iptable: log.info( "Unable to use ipAddrTable -- using ipNetToMediaTable instead" ) sourceTable = 'ipNetToMediaTable' else: log.warn("Unable to get data for %s from either ipAddrTable or" " ipNetToMediaTable" % device.id) iptable = dict() # Add in IPv6 info ipv6table = tabledata.get("ipAddressIfIndex") if ipv6table: iptable.update(ipv6table) iftable = tabledata.get("iftable") if iftable is None: log.error( "Unable to get data for %s for iftable -- skipping model" % device.id) return None ifalias = tabledata.get("ifalias", {}) self.prepIfTable(log, iftable, ifalias) omtable = {} duplex = tabledata.get("duplex", {}) for key, iface in iftable.items(): if key in duplex: iftable[key]['duplex'] = duplex[key].get('duplex', 0) else: iftable[key]['duplex'] = 0 for ip, row in iptable.items(): #FIXME - not getting ifindex back from HP printer if 'ifindex' not in row: log.debug("IP entry for %s is missing ifindex" % ip) continue ip_parts = ip.split('.') # If the ipAddrTable key has five octets, that probably # means this is a classless subnet (that is, <256). Usually, # the first 4 octets will be the ipAddress we care about. # Regardless, we will be using the ip address in the row # later anyway. try: if len(ip_parts) == 5 and sourceTable == 'ipAddrTable': addr_type = IpUtil.IPV4_ADDR_TYPE ip = IpUtil.bytesToCanonIp(ip_parts[:-1]) # If we are using the ipNetToMediaTable, we use the # last 4 octets. elif len(ip_parts) == 5 and sourceTable == 'ipNetToMediaTable': addr_type = IpUtil.IPV4_ADDR_TYPE if row['iptype'] != 1: log.debug("iptype (%s) is not 1 -- skipping" % (row['iptype'])) continue ip = IpUtil.bytesToCanonIp(ip_parts[1:]) log.warn("Can't find netmask -- using /24") row['netmask'] = '255.255.255.0' elif len(ip_parts) == 16: addr_type = IpUtil.IPV6_ADDR_TYPE ip = IpUtil.bytesToCanonIp(ip_parts) except Exception: log.warn("The %s address for ifindex %s is incorrect: %s", addr_type, row['ifindex'], ip) continue strindex = str(row['ifindex']) if strindex not in omtable and strindex not in iftable: log.warn("Skipping %s as it points to missing ifindex %s", row.get('ipAddress', ""), row.get('ifindex', "")) continue if strindex not in omtable: om = self.processInt(log, device, iftable[strindex]) if not om: continue rm.append(om) omtable[strindex] = om del iftable[strindex] elif strindex in omtable: om = omtable[strindex] else: log.warn("The IP %s points to missing ifindex %s -- skipping" % (ip, strindex)) continue if not hasattr(om, 'setIpAddresses'): om.setIpAddresses = [] if 'ipAddress' in row: ip = row['ipAddress'] if 'netmask' in row: ip = ip + "/" + str(self.maskToBits(row['netmask'].strip())) # Ignore IP addresses with a 0.0.0.0 netmask. if ip.endswith("/0"): log.warn("Ignoring IP address with 0.0.0.0 netmask: %s", ip) else: om.setIpAddresses.append(ip) for iface in iftable.values(): om = self.processInt(log, device, iface) if om: rm.append(om) return rm def prepIfTable(self, log, iftable, ifalias): """ Add interface alias (Cisco description) to iftable Sanity check speed """ for ifidx, data in ifalias.items(): log.debug("ifalias %s raw data = %s" % (ifidx, data)) if ifidx not in iftable: log.debug("ifidx %s is not in iftable -- skipping" % (ifidx)) continue iftable[ifidx]['description'] = data.get('description', '') # handle 10GB interfaces using IF-MIB::ifHighSpeed speed = iftable[ifidx].get('speed', 0) if speed == 4294967295L or speed == 1410065408 or speed < 0: try: iftable[ifidx]['speed'] = data['highSpeed'] * 1e6 except KeyError: pass # Detect availability of the high-capacity counters if data.get('ifHCInOctets', None) is not None and \ data.get('ifHCInUcastPkts', None) is not None: iftable[ifidx]['hcCounters'] = True for ifidx, data in iftable.items(): try: data['speed'] = unsigned(data['speed']) except KeyError: pass
def process(self, device, results, log): """Process SNMP information from this device""" log.info('Modeler %s processing data for device %s', self.name(), device.id) getdata, tabledata = results log.debug("%s tabledata = %s", device.id, tabledata) fstable = tabledata.get("fsTableOid") if fstable is None: log.error("Unable to get data for %s from fsTableOid" " -- skipping model" % device.id) return None dskTable = tabledata.get("dskTable") hrFSEntry = tabledata.get("hrFSEntry", {}) remoteMountMap = self._createRemoteMountMap(hrFSEntry) skipfsnames = getattr(device, 'zFileSystemMapIgnoreNames', None) skipfstypes = getattr(device, 'zFileSystemMapIgnoreTypes', None) maps = [] rm = self.relMap() for fs in fstable.values(): if not self.checkColumns(fs, self.columns, log): continue # Gentoo and openSUSE report "Virtual memory" as swap. This needs # to be ignored so we can pickup the real swap later in the table. if "virtual memory" in fs['mount'].lower(): continue rmount = remoteMountMap.get(fs['snmpindex']) if rmount is not None and fs['mount'] != rmount: log.debug('Switching mount from %s to %s', fs['mount'], rmount) fs['storageDevice'] = rmount # Large file systems can report as an unsigned integer if fs['totalBlocks'] < 0: fs['totalBlocks'] = unsigned(totalBlocks) totalBlocks = fs['totalBlocks'] size = long(fs['blockSize'] * totalBlocks) if size <= 0: log.info("Skipping %s. 0 total blocks.", fs['mount']) continue fs['type'] = self.typemap.get(fs['type'], "other") size = long(fs['blockSize'] * totalBlocks) # Handle file systems that need to be mapped into other parts of # the model such as total memory or total swap. if fs['type'] == "ram": maps.append(ObjectMap({"totalMemory": size}, compname="hw")) elif fs['type'] == "virtualMemory" or fs['mount'] == 'Swap': maps.append(ObjectMap({"totalSwap": size}, compname="os")) if skipfsnames and re.search(skipfsnames, fs['mount']): log.info("Skipping %s as it matches zFileSystemMapIgnoreNames.", fs['mount']) continue if skipfstypes and fs['type'] in skipfstypes: log.info("Skipping %s (%s) as it matches zFileSystemMapIgnoreTypes.", fs['mount'], fs['type']) continue fs["snmpindex_dct"] = {HRFileSystemMap.dskTableOid: self._getDskIndex(dskTable, fs["mount"])} om = self.objectMap(fs) om.id = self.prepId(om.mount) om.title = om.mount rm.append(om) maps.append(rm) # look for any map 'm' with m.compname == 'os' and m.totalSwap > 0 if not any(getattr(m,'compname', None) == 'os' and getattr(m,'totalSwap', 0) > 0 for m in maps): # if no value set for device.os.totalSwap, set totalSwap to 0 log.info("Swap space not detected for device %s, setting to 0", device.id) maps.append(ObjectMap({'totalSwap': 0}, compname="os")) return maps
class AIXInterfaceMap(SnmpPlugin): order = 80 maptype = "InterfaceMap" compname = "os" relname = "interfaces" modname = "Products.ZenModel.IpInterface" deviceProperties = \ SnmpPlugin.deviceProperties + ('zInterfaceMapIgnoreNames', 'zInterfaceMapIgnoreTypes') snmpGetTableMaps = ( # If table GetTableMap( 'iftable', '.1.3.6.1.2.1.2.2.1', { '.1': 'ifindex', '.2': 'id', '.3': 'type', '.4': 'mtu', '.5': 'speed', '.6': 'macaddress', '.7': 'adminStatus', '.8': 'operStatus' }), # AIX If table GetTableMap( 'aixiftable', '.1.3.6.1.4.1.2.6.191.9.8.1.1', { '.1': 'id', '.2': 'ifindex', '.3': 'aixNetworkType', #'.4': 'aixNetworkInterface', # eg EN or LO or .... '.5': 'aixNetworkStatus', # 1 for available, 2 for defined state #'.6': 'aixNetworkLocation', # Slot number '.7': 'aixNetworkDescr', }), # ipAddrTable is the better way to get IP addresses GetTableMap('ipAddrTable', '.1.3.6.1.2.1.4.20.1', { '.1': 'ipAddress', '.2': 'ifindex', '.3': 'netmask' }), # Use the ipNetToMediaTable as a backup to the ipAddrTable GetTableMap('ipNetToMediaTable', '.1.3.6.1.2.1.4.22.1', { '.1': 'ifindex', '.3': 'ipaddress', '.4': 'iptype' }), # Interface Description GetTableMap('ifalias', '.1.3.6.1.2.1.31.1.1.1', { '.18': 'description', '.15': 'highSpeed', }), ) def process(self, device, results, log): """Gather SNMP information from the the standard MIB and match it with what AIX provides.""" log.info('processing %s for device %s', self.name(), device.id) getdata, tabledata = results # # Find all available AIX adapters # aixiftable = tabledata.get("aixiftable") if aixiftable is None: log.error('%s: Unable to gather data for aixiftable!', self.name()) return available_interfaces = {} for index, data in aixiftable.items(): if data.get( 'aixNetworkStatus') != 1: # ie not in 'available' state continue id = data.get('id') if_type = data.get('aixNetworkType') if_desc = data.get('aixNetworkDescr') log.debug("Found 'available' interface %s with desc= %s", id, if_desc) available_interfaces[id] = { 'description': if_desc, 'type': if_type, } # # Now match the AIX OID interfaces with the HOST-MIB OID interfaces. # This is necessary as we'll still be using the collectors for HOST-MIB, # so we'll need to keep the interface indices the same (ie all HOST-MIB indices). # iptable= tabledata.get("ipAddrTable") \ or tabledata.get("ipNetToMediaTable") iftable = tabledata.get("iftable") ifalias = tabledata.get("ifalias") if iptable is None or iftable is None: log.error('%s: Unable to gather HOST-MIB data!', self.name()) return if not ifalias: ifalias = {} # # NB: One of the issues is that the regular HOST-MIB entries find id's like # en2; Product: 10 Gigabit-SR Ethernet PCI-X Adapter Manufacturer: not available! Part Number: 16R0599 FRU Number: 16R0599 # # which is, of course, really annoying. Remove any of the tripe after # the first semi-colon in order to return to sanity. # # # add interface alias (Cisco description) to iftable # for ifidx, data in ifalias.items(): if not iftable.has_key(ifidx): continue iftable[ifidx]['description'] = data.get('description', '') # if we collect ifAlias name use it # this is in the map subclass InterfaceAliasMap id = data.get('id', None) if id: semicolon_index = id.find(';') if semicolon_index != -1: id = id[:semicolon_index] iftable[ifidx]['id'] = id iftable[ifidx]['description'] = data.get('description', '') # handle 10GB interfaces using IF-MIB::ifHighSpeed speed = iftable[ifidx].get('speed', 0) if speed == 4294967295L or speed < 0: try: iftable[ifidx]['speed'] = data['highSpeed'] * 1e6 except KeyError: pass for ifidx, data in iftable.items(): try: data['speed'] = unsigned(data['speed']) except KeyError: pass rm = self.relMap() omtable = {} for ip, row in iptable.items(): if not row.has_key("ifindex"): continue # Fix data up if it is from the ipNetToMediaTable. if len(ip.split('.')) == 5: if row['iptype'] != 1: continue ip = '.'.join(ip.split('.')[1:]) row['netmask'] = '255.255.255.0' strindex = str(row['ifindex']) if not omtable.has_key(strindex) and not iftable.has_key(strindex): log.warn("skipping %s points to missing ifindex %s", row.get('ipAddress', ""), row.get('ifindex', "")) continue if not omtable.has_key(strindex): log.debug("Examining %s", iftable[strindex]) om = self.processInt(device, iftable[strindex], available_interfaces) if not om: continue log.debug("Adding iface %s", om.id) rm.append(om) omtable[strindex] = om del iftable[strindex] elif omtable.has_key(strindex): om = omtable[strindex] else: log.warn("ip points to missing ifindex %s skipping", strindex) continue if not hasattr(om, 'setIpAddresses'): om.setIpAddresses = [] if row.has_key('ipAddress'): ip = row['ipAddress'] if row.has_key('netmask'): ip = ip + "/" + str(self.maskToBits(row['netmask'].strip())) om.setIpAddresses.append(ip) #om.ifindex = row.ifindex #FIXME ifindex is not set! for iface in iftable.values(): log.debug("Examining %s", iface['id']) om = self.processInt(device, iface, available_interfaces) if om: log.debug("Adding iface %s", om.id) rm.append(om) return rm
def process(self, device, results, log): """Process SNMP information from this device""" log.info('Modeler %s processing data for device %s', self.name(), device.id) getdata, tabledata = results log.debug("%s tabledata = %s", device.id, tabledata) fstable = tabledata.get("fsTableOid") if fstable is None: log.error("Unable to get data for %s from fsTableOid" " -- skipping model" % device.id) return None dskTable = tabledata.get("dskTable") hrFSEntry = tabledata.get("hrFSEntry", {}) remoteMountMap = self._createRemoteMountMap(hrFSEntry) skipfsnames = getattr(device, 'zFileSystemMapIgnoreNames', None) skipfstypes = getattr(device, 'zFileSystemMapIgnoreTypes', None) maps = [] rm = self.relMap() for fs in fstable.values(): if not self.checkColumns(fs, self.columns, log): continue # Gentoo and openSUSE report "Virtual memory" as swap. This needs # to be ignored so we can pickup the real swap later in the table. if "virtual memory" in fs['mount'].lower(): continue rmount = remoteMountMap.get(fs['snmpindex']) if rmount is not None and fs['mount'] != rmount: log.debug('Switching mount from %s to %s', fs['mount'], rmount) fs['storageDevice'] = rmount # Large file systems can report as an unsigned integer if fs['totalBlocks'] < 0: fs['totalBlocks'] = unsigned(totalBlocks) totalBlocks = fs['totalBlocks'] size = long(fs['blockSize'] * totalBlocks) if size <= 0: log.info("Skipping %s. 0 total blocks.", fs['mount']) continue fs['type'] = self.typemap.get(fs['type'], "other") size = long(fs['blockSize'] * totalBlocks) # Handle file systems that need to be mapped into other parts of # the model such as total memory or total swap. if fs['type'] == "ram": maps.append(ObjectMap({"totalMemory": size}, compname="hw")) elif fs['type'] == "virtualMemory" or fs['mount'] == 'Swap': maps.append(ObjectMap({"totalSwap": size}, compname="os")) if skipfsnames and re.search(skipfsnames, fs['mount']): log.info( "Skipping %s as it matches zFileSystemMapIgnoreNames.", fs['mount']) continue if skipfstypes and fs['type'] in skipfstypes: log.info( "Skipping %s (%s) as it matches zFileSystemMapIgnoreTypes.", fs['mount'], fs['type']) continue fs["snmpindex_dct"] = { HRFileSystemMap.dskTableOid: self._getDskIndex(dskTable, fs["mount"]) } om = self.objectMap(fs) om.id = self.prepId(om.mount) om.title = om.mount rm.append(om) maps.append(rm) # look for any map 'm' with m.compname == 'os' and m.totalSwap > 0 if not any( getattr(m, 'compname', None) == 'os' and getattr(m, 'totalSwap', 0) > 0 for m in maps): # if no value set for device.os.totalSwap, set totalSwap to 0 log.info("Swap space not detected for device %s, setting to 0", device.id) maps.append(ObjectMap({'totalSwap': 0}, compname="os")) return maps