1
0
Fork 0
mirror of https://github.com/sileht/bird-lg.git synced 2024-11-22 06:54:43 +01:00

Add BGPmaps

This commit is contained in:
Mehdi Abaakouk 2012-05-27 14:30:31 +02:00
parent eb4f4f52b3
commit 2a15a0cfc3
2 changed files with 71 additions and 4 deletions

72
lg.py
View file

@ -24,10 +24,12 @@ import subprocess
import re import re
from urllib2 import urlopen from urllib2 import urlopen
from urllib import quote, unquote from urllib import quote, unquote
import json
from toolbox import mask_is_valid, ipv6_is_valid, ipv4_is_valid, resolve from toolbox import mask_is_valid, ipv6_is_valid, ipv4_is_valid, resolve
from flask import Flask, render_template, jsonify, redirect, session, request, abort import pydot
from flask import Flask, render_template, jsonify, redirect, session, request, abort, Response
app = Flask(__name__) app = Flask(__name__)
app.config.from_pyfile('lg.cfg') app.config.from_pyfile('lg.cfg')
@ -54,6 +56,15 @@ def add_links(text):
ret_text.append(line) ret_text.append(line)
return "\n".join(ret_text) return "\n".join(ret_text)
def extract_paths(text):
paths = []
for line in text:
line = line.strip()
if line.startswith("BGP.as_path:"):
paths.append(line.replace("BGP.as_path:", "").strip().split(" "))
return paths
def set_session(request_type, hosts, proto, request_args): def set_session(request_type, hosts, proto, request_args):
""" Store all data from user in the user session """ """ Store all data from user in the user session """
session.permanent = True session.permanent = True
@ -74,6 +85,9 @@ def set_session(request_type, hosts, proto, request_args):
history.insert(0, t) history.insert(0, t)
session["history"] = history[:20] session["history"] = history[:20]
def whois_command(query):
return subprocess.Popen( [ 'whois', query], stdout=subprocess.PIPE).communicate()[0].decode('utf-8', 'ignore')
def bird_command(host, proto, query): def bird_command(host, proto, query):
"""Alias to bird_proxy for bird service""" """Alias to bird_proxy for bird service"""
return bird_proxy(host, proto, "bird", query) return bird_proxy(host, proto, "bird", query)
@ -150,7 +164,7 @@ def whois(query):
except: except:
m = re.match(r"[\w\d-]*\.(?P<domain>[\d\w-]+\.[\d\w-]+)$", query) m = re.match(r"[\w\d-]*\.(?P<domain>[\d\w-]+\.[\d\w-]+)$", query)
if m: query = query.groupdict()["domain"] if m: query = query.groupdict()["domain"]
output = subprocess.Popen( [ 'whois', query], stdout=subprocess.PIPE).communicate()[0].decode('utf-8', 'ignore').replace("\n","<br>") output = whois_command(query).replace("\n","<br>")
return jsonify(output=output, title=query) return jsonify(output=output, title=query)
SUMMARY_UNWANTED_PROTOS = ["Kernel", "Static", "Device"] SUMMARY_UNWANTED_PROTOS = ["Kernel", "Static", "Device"]
@ -243,6 +257,56 @@ def show_route_for(hosts, proto):
def show_route_for_detail(hosts, proto): def show_route_for_detail(hosts, proto):
return show_route("prefix_detail", hosts, proto) return show_route("prefix_detail", hosts, proto)
ASNAME_CACHE = {}
def get_as_name(_as):
if True or not ASNAME_CACHE.has_key(_as):
whois_answer = whois_command("as%s" % _as)
as_name = re.search('as-name: (.*)', whois_answer)
if as_name:
ASNAME_CACHE[_as] = as_name.group(1).strip()
else:
ASNAME_CACHE[_as] = _as
if ASNAME_CACHE[_as] == _as:
return "AS%s" % _as
else:
return "AS%s\r%s" % (_as, ASNAME_CACHE[_as])
@app.route("/bgpmap/<data>")
def show_bgpmap(data):
data = json.loads(unquote(data))
graph = pydot.Dot('BGPMAP', graph_type='digraph')
nodes = {}
edges = {}
for host, asmaps in data.iteritems():
nodes[host] = pydot.Node(host, shape="box", style="filled", fillcolor="#F5A9A9")
graph.add_node(nodes[host])
for host, asmaps in data.iteritems():
first = True
for asmap in asmaps:
previous_as = host
for _as in asmap:
_as = get_as_name(_as)
if _as == previous_as:
continue
if not nodes.has_key(_as):
nodes[_as] = pydot.Node(_as, style="filled", fillcolor=(first and "#F5A9A9" or "white"))
graph.add_node(nodes[_as])
edge_tuple = (nodes[previous_as], nodes[_as])
if not edges.has_key(edge_tuple):
edge = pydot.Edge(*edge_tuple)
graph.add_edge(edge)
edges[edge_tuple] = edge
if edge.get_color() != "red" and first:
edge.set_color("red")
previous_as = _as
first = False
#return Response("<pre>" + graph.create_dot() + "</pre>")
return Response(graph.create_png(), mimetype='image/png')
def show_route(request_type, hosts, proto): def show_route(request_type, hosts, proto):
expression = unquote(request.args.get('q', '')) expression = unquote(request.args.get('q', ''))
if not expression.strip(): abort(400) if not expression.strip(): abort(400)
@ -275,16 +339,18 @@ def show_route(request_type, hosts, proto):
detail = {} detail = {}
error = [] error = []
bgpmap = {}
for host in hosts.split("+"): for host in hosts.split("+"):
ret, res = bird_command(host, proto, command) ret, res = bird_command(host, proto, command)
res = res.split("\n") res = res.split("\n")
if len(res) > 1 : #if ret: if len(res) > 1 : #if ret:
detail[host] = add_links(res) detail[host] = add_links(res)
bgpmap[host] = extract_paths(res)
else: else:
error.append("%s: bird command failed with error, %s" % (host,"\n".join(res))) error.append("%s: bird command failed with error, %s" % (host,"\n".join(res)))
return render_template('route.html', detail=detail, command=command, expression=expression, error="<br>".join(error) ) return render_template('route.html', detail=detail, command=command, expression=expression, bgpmap=json.dumps(bgpmap), error="<br>".join(error) )
app.secret_key = app.config["SESSION_KEY"] app.secret_key = app.config["SESSION_KEY"]
app.debug = True app.debug = True

View file

@ -8,6 +8,7 @@
<pre> <pre>
{{ detail[host]|trim|safe }} {{ detail[host]|trim|safe }}
</pre> </pre>
<br />
{% endfor %} {% endfor %}
<a href="/bgpmap/{{bgpmap}}"><img src="/bgpmap/{{bgpmap}}" /></a>
<br />
{% endblock %} {% endblock %}