def get_bgp_table(host): """Return the contents of the cbgpPeer2Table table.""" obj = ObjectIdentity('CISCO-BGP4-MIB', 'cbgpPeer2Table') target = UdpTransportTarget((host, SNMP['port'])) results = defaultdict(dict) for (errorIndication, errorStatus, errorIndex, varBinds) in bulkCmd(snmp, usm, target, context, 0, 25, ObjectType(obj), lexicographicMode=False, lookupMib=True): if errorIndication: raise RuntimeError(errorIndication) elif errorStatus: raise RuntimeError('%s at %s' % (errorStatus.prettyPrint(), errorIndex and varBinds[-1][int(errorIndex)-1] or '?')) else: for (key, val) in varBinds: if not isinstance(val, EndOfMibView): (mib, name, index) = \ key.loadMibs('BGP4-MIB').getMibSymbol() a = index[1].prettyPrint() results[a]['cbgpPeer2Type'] = index[0] results[a][name] = val for address in results: if results[address]['cbgpPeer2Type'] == 1: results[address]['cbgpPeer2RemoteAddr'] = \ ipaddress.IPv4Address(int(address, 16)) elif results[address]['cbgpPeer2Type'] == 2: results[address]['cbgpPeer2RemoteAddr'] = \ ipaddress.IPv6Address(int(address, 16)) return results
def _get_fdb_dot1q(self): """Fetch the forwarding database via SNMP using the Q-BRIDGE-MIB Returns: Dict[List[str]]: ports and their values """ from pysnmp import hlapi ports = {} for (errorIndication, errorStatus, errorIndex, varBindTable) in hlapi.bulkCmd( hlapi.SnmpEngine(), hlapi.CommunityData('public'), hlapi.UdpTransportTarget((self.hostname, 161)), hlapi.ContextData(), 0, 50, hlapi.ObjectType( hlapi.ObjectIdentity('Q-BRIDGE-MIB', 'dot1qTpFdbPort')), lexicographicMode=False): if errorIndication: Exception("snmp error {}".format(errorIndication)) elif errorStatus: Exception("snmp error {}".format(errorStatus)) else: for varBinds in varBindTable: key, val = varBinds if not val: continue mac = key.getMibSymbol()[-1][1].prettyPrint() interface = str(int(val)) ports.setdefault(interface, []).append(mac) return ports
def get_bulk(self, target, oids, community, count, version=1, timeout=1, retries=3, start_from=0, port=161, engine=hlapi.SnmpEngine(), context=hlapi.ContextData()): try: handler = hlapi.bulkCmd( engine, hlapi.CommunityData(community, mpModel=version), hlapi.UdpTransportTarget((target, port), timeout=timeout, retries=retries), context, start_from, count, *self._construct_object_types(oids)) except Exception as e: print('> get_bulk : ', e) traceback.print_exc(file=sys.stdout) return None return self._fetch(handler, count)
def snmpgetbulk(target, oids, credentials, count, start_from=0, port=161, engine=hlapi.SnmpEngine(), context=hlapi.ContextData()): handler = hlapi.bulkCmd( engine, credentials, hlapi.UdpTransportTarget((target, port)), context, start_from, count, *construct_object_types(oids), lexicographicMode=False ) return fetch(handler, count)
def get_bulk2(self, oids, count, start_from=0): handler = hlapi.bulkCmd( hlapi.SnmpEngine(), hlapi.UsmUserData(userName=self.username, authKey=self.authKey, privKey=self.privKey, authProtocol=self.authProtocol, privProtocol=self.privProtocol), hlapi.UdpTransportTarget((self.host, 161)), hlapi.ContextData(), start_from, count, *self.__construct_object_types(oids)) return self.__fetchBulk(handler, count)
def get_bulk(target, oids, credentials, count, start_from=0, port=161, engine=hlapi.SnmpEngine(), context=hlapi.ContextData()): handler = hlapi.bulkCmd( engine, credentials, hlapi.UdpTransportTarget((target, port)), context, start_from, count, *__class__.construct_object_types(oids) ) return __class__.fetch(handler, count)
def bulk_cmd(self, oid, non_repeaters=0, max_repeaters=1): ''' bulk get router info by oid ''' self.snmp_ret = bulkCmd(SnmpEngine(), CommunityData(self.community), UdpTransportTarget( (self.router_ip, self.snmp_port)), ContextData(), non_repeaters, max_repeaters, ObjectType(ObjectIdentity(oid)), maxCalls=10) return self._to_list(oid)
def _get_ports(self): """Fetch ports and their values via SNMP Returns: Dict[Dict[]]: ports and their values """ from pysnmp import hlapi vars = [ (hlapi.ObjectType(hlapi.ObjectIdentity('IF-MIB', 'ifIndex')), 'index'), (hlapi.ObjectType(hlapi.ObjectIdentity('IF-MIB', 'ifDescr')), 'descr'), (hlapi.ObjectType(hlapi.ObjectIdentity('IF-MIB', 'ifSpeed')), 'speed'), (hlapi.ObjectType(hlapi.ObjectIdentity('IF-MIB', 'ifOperStatus')), 'status'), (hlapi.ObjectType(hlapi.ObjectIdentity('IF-MIB', 'ifInErrors')), 'inErrors'), (hlapi.ObjectType(hlapi.ObjectIdentity('IF-MIB', 'ifHCInOctets')), 'inOctets'), (hlapi.ObjectType(hlapi.ObjectIdentity('IF-MIB', 'ifHCOutOctets')), 'outOctets'), ] ports = {} for (errorIndication, errorStatus, errorIndex, varBindTable) in hlapi.bulkCmd(hlapi.SnmpEngine(), hlapi.CommunityData('public'), hlapi.UdpTransportTarget( (self.hostname, 161)), hlapi.ContextData(), 0, 20, *[x[0] for x in vars], lexicographicMode=False): if errorIndication: Exception("snmp error {}".format(errorIndication)) elif errorStatus: Exception("snmp error {}".format(errorStatus)) else: port = {} for (key, val), (base, label) in zip(varBindTable, vars): index = key.getMibSymbol()[-1][0].prettyPrint() val = val.prettyPrint() if label == 'status': val = val.strip("'") port[label] = val ports[port.pop('index')] = port return ports
def get_bulk(self, oids, count, start_from=0, engine=hlapi.SnmpEngine(), context=hlapi.ContextData()): handler = hlapi.bulkCmd(engine, self.credentials, hlapi.UdpTransportTarget( (self.target, self.port)), context, start_from, count, *construct_object_types(oids), lexicographicMode=False) return self.fetch(handler, count)
def get_bulk_snmp(template_oid, ip, snmp_config_data, timeout=1, retries=0, lexicographicMode=False): """[Get bulk Snmp] Arguments: template_oid {[string]} -- [OID] ip {[string]} -- [ip of server(ex: 192.168.88.88)] snmp_config_data {[type]} -- [snmp config get from config file] Keyword Arguments: timeout {int} -- [timeout in seconds] (default: {1}) retries {int} -- [Maximum number of request retries, 0 retries means just a single request.] (default: {0}) lexicographicMode {bool} -- [walk SNMP agent’s MIB till the end (if True), otherwise (if False) stop iteration when all response MIB variables leave the scope of initial MIB variables in varBinds] (default: {False}) Raises: KeyError: [snmp_version input wrong format. Not match in map_snmp_version] KeyError: [property is not exist in snmp_config_data] Returns: [generator] -- [result generator data get by snmp] """ try: snmp_version = snmp_config_data['snmp_version'] port = snmp_config_data['port'] if snmp_version == "v1" or snmp_version == "v2c": snmp_community = snmp_config_data['snmp_community'] snmp_iter = bulkCmd(SnmpEngine(), CommunityData( snmp_community, mpModel=map_snmp_version[snmp_version]), UdpTransportTarget((ip, port), timeout=timeout, retries=retries), ContextData(), 0, 10, ObjectType(ObjectIdentity(template_oid)), lexicographicMode=lexicographicMode) elif snmp_version == "v3": user_name = snmp_config_data['user_name'] auth_key = process_password.decrypt_password( empty_to_none(snmp_config_data['authen_password'])) priv_key = process_password.decrypt_password( empty_to_none(snmp_config_data['priv_password'])) auth_protocol = AUTH_PROTOCOL[empty_to_none( snmp_config_data['authen_protocol'])] priv_protocol = PRIV_PROTOCOL[empty_to_none( snmp_config_data['priv_protocol'])] snmp_iter = bulkCmd(SnmpEngine(), UsmUserData(user_name, authKey=auth_key, privKey=priv_key, authProtocol=auth_protocol, privProtocol=priv_protocol), UdpTransportTarget((ip, port), timeout=timeout, retries=retries), ContextData(), 0, 10, ObjectType(ObjectIdentity(template_oid)), lexicographicMode=lexicographicMode) else: raise KeyError( "'{}' wrong format snmp_version".format(snmp_version)) except KeyError as key_error: raise KeyError("Can not find {} in snmp_config_data".format(key_error)) except Exception as ex: raise ex return snmp_iter
def get_bgp_state(host): # noqa """Get the BGP session state.""" peer_table = ObjectIdentity('CISCO-BGP4-MIB', 'cbgpPeer2Table') af_table = ObjectIdentity('CISCO-BGP4-MIB', 'cbgpPeer2AddrFamilyTable') prefix_table = ObjectIdentity('CISCO-BGP4-MIB', 'cbgpPeer2AddrFamilyPrefixTable') target = UdpTransportTarget((host, SNMP['port'])) results = defaultdict(dict) for (errorIndication, errorStatus, errorIndex, varBinds) in bulkCmd(snmp, usm, target, context, 0, 25, ObjectType(peer_table), lexicographicMode=False, lookupMib=True): if errorIndication: raise RuntimeError(errorIndication) elif errorStatus: raise RuntimeError('%s at %s' % (errorStatus.prettyPrint(), errorIndex and varBinds[-1][int(errorIndex)-1] or '?')) else: for (key, val) in varBinds: if not isinstance(val, EndOfMibView): (mib, name, index) = \ key.loadMibs('BGP4-MIB').getMibSymbol() address = index[1].prettyPrint() results[address]['cbgpPeer2Type'] = index[0] results[address][name] = val for address in results: results[address]['address_families'] = defaultdict(dict) for (errorIndication, errorStatus, errorIndex, varBinds) in bulkCmd(snmp, usm, target, context, 0, 25, ObjectType(af_table), lexicographicMode=False, lookupMib=True): if errorIndication: raise RuntimeError(errorIndication) elif errorStatus: raise RuntimeError('%s at %s' % (errorStatus.prettyPrint(), errorIndex and varBinds[-1][int(errorIndex)-1] or '?')) else: for (key, val) in varBinds: if not isinstance(val, EndOfMibView): (mib, name, index) = \ key.loadMibs('BGP4-MIB').getMibSymbol() address = index[1].prettyPrint() afi = index[2] safi = index[3] results[address]['address_families'][afi][safi] = \ {name: val} for (errorIndication, errorStatus, errorIndex, varBinds) in bulkCmd(snmp, usm, target, context, 0, 25, ObjectType(prefix_table), lexicographicMode=False, lookupMib=True): if errorIndication: raise RuntimeError(errorIndication) elif errorStatus: raise RuntimeError('%s at %s' % (errorStatus.prettyPrint(), errorIndex and varBinds[-1][int(errorIndex)-1] or '?')) else: for (key, val) in varBinds: if not isinstance(val, EndOfMibView): (mib, name, index) = \ key.loadMibs('BGP4-MIB').getMibSymbol() address = index[1].prettyPrint() afi = index[2] safi = index[3] results[address]['address_families'][afi][safi][name] = \ val for address in results: if results[address]['cbgpPeer2Type'] == 1: results[address]['cbgpPeer2RemoteAddr'] = \ ipaddress.IPv4Address(int(address, 16)) elif results[address]['cbgpPeer2Type'] == 2: results[address]['cbgpPeer2RemoteAddr'] = \ ipaddress.IPv6Address(int(address, 16)) results[address]['TotalAcceptedPrefixes'] = 0 for afi in results[address]['address_families']: for safi in results[address]['address_families'][afi]: results[address]['TotalAcceptedPrefixes'] += \ results[address]['address_families'][afi][safi]['cbgpPeer2AcceptedPrefixes'] # noqa return results
def do_work( self, ir: InventoryRecord, walk: bool = False, profiles: List[str] = None, walked_first_time=True, ): retry = False address = transform_address_to_key(ir.address, ir.port) if time.time() - self.last_modified > PROFILES_RELOAD_DELAY: self.profiles = load_profiles() self.last_modified = time.time() logger.debug("Profiles reloaded") varbinds_get, get_mapping, varbinds_bulk, bulk_mapping = self.get_var_binds( address, walk=walk, profiles=profiles, walked_first_time=walked_first_time) authData = GetAuth(logger, ir, self.snmpEngine) contextData = get_context_data() transport = UdpTransportTarget((ir.address, ir.port), timeout=UDP_CONNECTION_TIMEOUT) metrics: Dict[str, Any] = {} if not varbinds_get and not varbinds_bulk: logger.info(f"No work to do for {address}") return False, {} if varbinds_bulk: for ( errorIndication, errorStatus, errorIndex, varBindTable, ) in bulkCmd( self.snmpEngine, authData, transport, contextData, 1, 10, *varbinds_bulk, lexicographicMode=False, ignoreNonIncreasingOid=is_increasing_oids_ignored( ir.address, ir.port), ): if not _any_failure_happened( errorIndication, errorStatus, errorIndex, varBindTable, ir.address, walk, ): tmp_retry, tmp_mibs, _ = self.process_snmp_data( varBindTable, metrics, address, bulk_mapping) if tmp_mibs: self.load_mibs(tmp_mibs) self.process_snmp_data(varBindTable, metrics, address, bulk_mapping) if varbinds_get: for ( errorIndication, errorStatus, errorIndex, varBindTable, ) in getCmd(self.snmpEngine, authData, transport, contextData, *varbinds_get): if not _any_failure_happened( errorIndication, errorStatus, errorIndex, varBindTable, ir.address, walk, ): self.process_snmp_data(varBindTable, metrics, address, get_mapping) for group_key, metric in metrics.items(): if "profiles" in metrics[group_key]: metrics[group_key]["profiles"] = ",".join( metrics[group_key]["profiles"]) return retry, metrics