diff --git a/inventory_provider/snmp.py b/inventory_provider/snmp.py index 05d10c2ab402ed0d60598f94a017903923a82a45..6bd56f45d1809f95ab3da1ccb9021296ac3e6d5a 100644 --- a/inventory_provider/snmp.py +++ b/inventory_provider/snmp.py @@ -13,6 +13,7 @@ from pysnmp.error import PySnmpError RFC1213_MIB_IFDESC = '1.3.6.1.2.1.2.2.1.2' # BGP4-V2-MIB-JUNIPER::jnxBgpM2PeerState JNX_BGP_M2_PEER_STATE = '1.3.6.1.4.1.2636.5.1.1.2.1.1.1.2' +JNX_LOGICAL_SYSTEMS = ['VRR'] logger = logging.getLogger(__name__) @@ -132,16 +133,71 @@ def walk(agent_hostname, community, base_oid): # pragma: no cover f'snmp error communicating with {agent_hostname}: {e}') -def get_router_snmp_indexes(hostname, community): +def _get_router_snmp_indexes(hostname, community): for ifc in walk(hostname, community, RFC1213_MIB_IFDESC): m = re.match(r'.*\.(\d+)$', ifc['oid']) assert m, f'sanity failure parsing oid: {ifc["oid"]}' yield { 'name': ifc['value'], - 'index': int(m.group(1)) + 'index': int(m.group(1)), + 'community': community } +def _walk_util(hostname, default_community, walk_handler): + """ + Run walk_handler for default_community and + + :param hostname: + :param community: base community name + :param walk_handler: a method that takes params (hostname, community) + and yields things + :return: generator yielding whatever walk_handler yields + """ + # do the default community last, in case of duplicates + communities = [ + f'{ls}/default@{default_community}' + for ls in JNX_LOGICAL_SYSTEMS] + communities.append(default_community) + + for c in communities: + yield from walk_handler(hostname, c) + + +def get_router_snmp_indexes(hostname, community): + """ + return interface names and snmp indexes + + items are structured like: + {name: str, index: str, community: str} + + :param hostname: + :param community: base community name + :return: generator yielding dicts + """ + _walk_util(hostname, community, _get_router_snmp_indexes) + + +def get_peer_state_info(hostname, community): + """ + return peering states from all logical systems + + items are structured like: + {local: str, remote: str, oid: str, community: str} + + :param hostname: + :param community: base community name + :return: generator yielding dicts + """ + # do the default community last, in case of duplicates + communities = [f'{ls}/default@{community}' for ls in JNX_LOGICAL_SYSTEMS] + communities.append(community) + for c in communities: + for peering in _get_peer_state_info(hostname, c): + peering['community'] = c + yield peering + + def _v6bytes(int_str_list): assert len(int_str_list) == 16 return struct.pack('!16B', *map(int, int_str_list)) @@ -152,7 +208,8 @@ def _v4str(int_str_list): return '.'.join(int_str_list) -def get_peer_state_info(hostname, community): +def _get_peer_state_info(hostname, community): + oid_prefix = f'.{JNX_BGP_M2_PEER_STATE}.' for ifc in walk(hostname, community, JNX_BGP_M2_PEER_STATE): @@ -178,10 +235,24 @@ def get_peer_state_info(hostname, community): yield { 'local': local.exploded, 'remote': remote.exploded, - 'oid': ifc['oid'] + 'oid': ifc['oid'], + 'community': community } +def get_peer_state_info(hostname, community): + """ + return peering states from all logical systems + + items are structured like: + {local: str, remote: str, oid: str, community: str} + + :param hostname: + :param community: base community name + :return: generator yielding dicts + """ + _walk_util(hostname, community, _get_peer_state_info) + # if __name__ == '__main__': # #