diff --git a/inventory_provider/routes/msr.py b/inventory_provider/routes/msr.py index ac2aa9b98afff35c6ea537e8f8ccad1853769573..231112ee1c248c89e0a3be02b5bc5afb22cd0c20 100644 --- a/inventory_provider/routes/msr.py +++ b/inventory_provider/routes/msr.py @@ -104,6 +104,7 @@ import json import ipaddress import logging import re +import subprocess import threading from collections import defaultdict from typing import Dict @@ -160,7 +161,6 @@ PEERING_LIST_SCHEMA = { 'items': {'$ref': '#/definitions/peering-instance'} } - IP_ADDRESS_LIST_SCHEMA = { '$schema': 'https://json-schema.org/draft-07/schema#', 'definitions': { @@ -441,7 +441,8 @@ ASN_PEER_LIST_SCHEMA = { 'remote-asn': {'type': 'integer'}, 'local-asn': {'type': 'integer'}, 'instance': {'type': 'string'}, - 'nren': {'type': 'string'} + 'nren': {'type': 'string'}, + 'whois-info': {'type': 'string'} }, # only vrr peerings have remote-asn # only group peerings have local-asn or instance @@ -451,7 +452,8 @@ ASN_PEER_LIST_SCHEMA = { 'address', 'group', 'hostname', - 'nren'], + 'nren', + 'whois-info'], 'additionalProperties': False } }, @@ -1397,6 +1399,25 @@ def _asn_peers(asn, group, instance): """ r = common.get_current_redis() + def _whois_str(asn: int) -> str: + args = ["whois", "-h", "whois.cymru.com", f"AS{asn}"] + env = {"PATH": "/bin:/usr/bin"} + r = None + try: + r = subprocess.check_output(args, env=env) + except (subprocess.CalledProcessError, OSError): + logger.exception(f'error calling {" ".join(args)}') + return "?" + + if not r: + logger.error("no whois result returned") + return "" + result = r.splitlines() + if not result: + logger.error("error executing whois") + return "" + return result[-1].decode("utf-8") + def _get_filtered_peers_for_asn(asn, nren, group, instance): peers = json.loads(r.get(f'router-peerings:peer-asn:{asn}')) @@ -1407,10 +1428,12 @@ def _asn_peers(asn, group, instance): return False # no value exists, cannot meet condition return peer[name] == value + whois_info = _whois_str(asn) for peer in peers: if _attribute_filter(peer, "group", group) and \ _attribute_filter(peer, "instance", instance): peer['nren'] = nren + peer['whois-info'] = whois_info yield peer def _get_filtered_peers(asn_nren_map, group, instance):