Allo to show route as JSON value

Example : https://[[LG_MASTER]]/api/[[LG_NODES_LIST]]/ipv4?q=8.8.8.8

Return :

{

    "[[LG_NODES_LIST]]": {
        "result": [
            {
                "origin": "IGP",
                "med": 0,
                "via": "1.1.1.2",
                "last": "2018-07-10",
                "network": "8.8.8.0",
                "localPref": 350,
                "asPath": "15169",
                "originatorId": {
                    "addr": "4.4.4.4",
                    "reverse": "router.fr.eu"
                },
                "community": [
                    "65000:65000"
                ],
                "clusterList": [
                    "9.89.6.6",
                    "9.89.8.8"
                ],
                "netmask": "24",
                "fromPeer": "bird",
                "from": "4.4.4.4",
                "nextHop": {
                    "addr": "1.1.1.2",
                    "reverse": "google.fr.eu"
                },
                "ipType": "IPv4"
            }
        ]
    }

}
This commit is contained in:
Fabien VINCENT 2018-07-16 14:37:17 +02:00
parent 01ec638435
commit 9df351a4fb
1 changed files with 111 additions and 0 deletions

111
lg.py
View File

@ -52,6 +52,13 @@ memcache_server = app.config.get("MEMCACHE_SERVER", "127.0.0.1:11211")
memcache_expiration = int(app.config.get("MEMCACHE_EXPIRATION", "1296000")) # 15 days by default
mc = memcache.Client([memcache_server])
def reverse(ip):
try:
name, alias, addresslist = socket.gethostbyaddr(ip)
return name
except socket.herror:
return ""
def get_asn_from_as(n):
asn_zone = app.config.get("ASN_ZONE", "asn.cymru.com")
try:
@ -64,16 +71,31 @@ def get_asn_from_as(n):
def add_links(text):
"""Browser a string and replace ipv4, ipv6, as number, with a
whois link """
ipv4_re = re.compile('(BGP.next_hop|BGP.originator_id):\s+(\d+\.\d+\.\d+\.\d+).*')
ipv6_re = re.compile('(BGP.next_hop|BGP.originator_id):\s+(([0-9a-fA-F]{1,4}:)*:?(?:([0-9a-fA-F]{1,4}))).*')
if type(text) in [str, unicode]:
text = text.split("\n")
ret_text = []
for line in text:
reverse = None
mipv4 = ipv4_re.match(line.strip())
mipv6 = ipv6_re.match(line.strip())
# Some heuristic to create link
if line.strip().startswith("BGP.as_path:") or \
line.strip().startswith("Neighbor AS:"):
ret_text.append(re.sub(r'(\d+)', r'<a href="/whois?q=\1" class="whois">\1</a>', line))
elif mipv4:
ipv4 = mipv4.group(2)
reverse = dns(ipv4)
line = re.sub(ipv4,r'<a href="/whois?q='+ipv4+'" class="whois">'+ipv4+'</a> '+reverse+'', line)
ret_text.append(line)
elif mipv6:
ipv6 = mipv6.group(2)
reverse = dns(ipv6)
line = re.sub(ipv6,r'<a href="/whois?q='+ipv6+'" class="whois">'+ipv6+'</a> '+reverse+'', line)
ret_text.append(line)
else:
line = re.sub(r'([a-zA-Z0-9\-]*\.([a-zA-Z]{2,3}){1,2})(\s|$)', r'<a href="/whois?q=\1" class="whois">\1</a>\3', line)
line = re.sub(r'AS(\d+)', r'<a href="/whois?q=\1" class="whois">AS\1</a>', line)
@ -87,6 +109,94 @@ def add_links(text):
ret_text.append(line)
return "\n".join(ret_text)
def add_json(text):
"""Browser a string and replace ipv4, ipv6, as number, with a
whois link """
ipv4_re = re.compile('^(\d+\.\d+\.\d+\.\d+).*')
ipv6_re = re.compile('^(([0-9a-fA-F]{1,4}:)*:?(?:([0-9a-fA-F]{1,4}))).*')
if type(text) in [str, unicode]:
text = text.split("\n")
q = {}
data = []
current = {}
current['asPath'] = ""
current['med'] = 0
peer = ""
for line in text:
reverse = None
mipv4 = ipv4_re.match(line.strip())
mipv6 = ipv6_re.match(line.strip())
# Some heuristic to create link
m = re.search(r'^((?:\d+\.\d+\.\d+\.\d+)|(?:[0-9a-fA-F]{1,4}:)*:?(?:(?:[0-9a-fA-F]{1,4})?))?\/?(\d+)?\s+via\s+((?:\d+\.\d+\.\d+\.\d+)|(?:[0-9a-fA-F]{1
,4}:)*:?(?:(?:[0-9a-fA-F]{1,4})?))\son\seth\d+\s\[([a-z0-9_]+)\s(\d+-\d+-\d+)\sfrom\s((?:\d+\.\d+\.\d+\.\d+)|(?:[0-9a-fA-F]{1,4}:)*:?(?:(?:[0-9a-fA-F]{1,4})?)
)\].*$', line.strip())
if m is not None:
if peer != m.group(4):
data.append(current)
if m.group(1):
current['network'] = m.group(1)
current['netmask'] = m.group(2)
peer = m.group(4)
current['fromPeer'] = m.group(4)
current['last'] = m.group(5)
current['via'] = m.group(3)
current['from'] = m.group(6)
if re.match(r"\d+\.\d+\.\d+\.\d+", current['network']):
current["ipType"] = "IPv4"
elif re.match(r"(?:[0-9a-fA-F]{1,4}:)*:?(?:(?:[0-9a-fA-F]{1,4})?)", current['network']):
current["ipType"] = "IPv6"
if line.strip().startswith("BGP.as_path:"):
m = re.search(r"BGP.as_path: (?P<asPath>\d+\s*)*", line.strip())
if m is not None:
current['asPath'] = m.group('asPath')
elif line.strip().startswith("BGP.origin:"):
m = re.search(r"BGP.origin: (?P<origin>\w+\s*)*", line.strip())
if m is not None:
current['origin'] = m.group('origin')
else:
current['origin'] = ""
elif line.strip().startswith("BGP.next_hop:"):
m = re.search(r"BGP.next_hop: (?P<nextHop>((([a-f\d]{0,4}:){3,10}[a-f\d]{0,4})|(\d+\.\d+\.\d+\.\d+))\s*)*", line.strip())
if m is not None:
current['nextHop'] = {'addr': m.group('nextHop'), "reverse": reverse(m.group('nextHop'))}
else:
current['nextHop'] = {'addr': "", "reverse": ""}
elif line.strip().startswith("BGP.med:"):
m = re.search(r"BGP.med: (?P<med>\d+\s*)*", line.strip())
if m is not None:
current['med'] = int(m.group('med'))
else:
current['med'] = 0
elif line.strip().startswith("BGP.local_pref:"):
m = re.search(r"BGP.local_pref: (?P<localPref>\d+\s*)*", line.strip())
if m is not None:
current['localPref'] = int(m.group('localPref'))
else:
current['localPref'] = 0
elif line.strip().startswith("BGP.originator_id:"):
m = re.search(r"BGP.originator_id: (?P<origin>((([a-f\d]{0,4}:){3,10}[a-f\d]{0,4})|(\d+\.\d+\.\d+\.\d+))\s*)*", line.strip())
if m is not None:
current['originatorId'] = {'addr': m.group('origin'), "reverse": reverse(m.group('origin'))}
else:
current['originator'] = {'addr': "", "reverse": ""}
elif line.strip().startswith("BGP.community:"):
current['community'] = []
for m in re.findall(r"(\d+,\d+)", line.strip()):
if m is not None:
community = m
current['community'].append(community.replace(',',':'))
else:
current['community'] = ""
elif line.strip().startswith("BGP.cluster_list:"):
current['clusterList'] = []
for m in re.findall(r"(\d+\.\d+\.\d+\.\d+)", line.strip()):
if m is not None:
current['clusterList'].append(m)
data.append(current)
return {'result':data}
def set_session(request_type, hosts, proto, request_args):
""" Store all data from user in the user session """
@ -656,6 +766,7 @@ def show_route(request_type, hosts, proto):
return render_template((bgpmap and 'bgpmap.html' or 'route.html'), detail=detail, command=command, expression=expression, errors=errors)
def show_route_api(request_type, hosts, proto):
expression = get_query()
if not expression: