/
BGP-LS Topology Grapher
148 lines (109 loc) · 5.39 KB
/
BGP-LS Topology Grapher
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
__author__ = 'dipsingh'
import urllib
import json
import re
import networkx as nx
import matplotlib.pyplot as plt
# Function to extract Router-ID
def extract_routerid (str):
unicode_strlist = str.split("&")
strlist = [x.encode('UTF8') for x in unicode_strlist]
rg = re.compile(".*(router).*",re.IGNORECASE|re.DOTALL)
router_id_list = filter(rg.match , strlist)
router_id_string = router_id_list[0]
final_router_id_list = router_id_string.split("=")
router_id = final_router_id_list[1]
return router_id
#Function to extract IS-IS Level details
def extract_isis_level(str):
unicode_strlist = str.split("/")
strlist = [x.encode('UTF8') for x in unicode_strlist ]
rg = re.compile(".*(ISISLEVEL).*",re.IGNORECASE|re.DOTALL)
isis_level_list = filter(rg.match , strlist)
isis_level_string = isis_level_list[0]
isis_level_list = isis_level_string.split(":")
isis_level= isis_level_list[0]
return isis_level
#Function for drawing the graph
def draw_graph(graph,labels=None, graph_layout='spectral', node_size=1600, node_color='blue', node_alpha=0.3,node_text_size=12,edge_color='red', edge_alpha=0.2, edge_tickness=1,
edge_text_pos=0.4,text_font='sans-serif'):
nodes = set ([n1 for n1,n2 in graph]+[n2 for n1, n2 in graph]) # Do i need this
G = nx.MultiDiGraph()
for node in nodes:
for nodeattr in Node._instance_track:
if nodeattr.router_id == node :
G.add_node(node,nodeattr.prefix_metric)
for edge in graph:
G.add_edge(edge[0],edge[1],weight = 0.2)
if graph_layout == 'spring':
graph_pos=nx.spring_layout(G)
elif graph_layout == 'spectral':
graph_pos=nx.spectral_layout(G)
else:
graph_pos= nx.shell_layout(G)
nx.draw_networkx_nodes(G,graph_pos,node_size=node_size, alpha=node_alpha, node_color=node_color)
nx.draw_networkx_edges(G,graph_pos,width=edge_tickness,alpha=edge_alpha,edge_color=edge_color,arrows=True)
nx.draw_networkx_labels(G, graph_pos,font_size=node_text_size,font_family=text_font)
edge_labels = labels
print ("Edge Labels", edge_labels)
nx.draw_networkx_edge_labels(G, graph_pos, edge_labels=edge_labels,label_pos=edge_text_pos)
plt.axis('off')
plt.show()
class Node:
_instance_track = []
def __init__(self,node_name,iso_system_id,router_id):
self.node_name = node_name
self.iso_system_id = iso_system_id
self.router_id = router_id
self.prefix_metric = {}
self._instance_track.append(self)
def add_prefix_metric(self,prefix,metric):
self.prefix_metric[prefix] = metric
@classmethod
def get_instance(cls):
return cls._instance_track
class Link:
_link_instance_track = []
def __init__(self,source_router_id,destination_router_id,igp_metric,isis_level):
self.source_router_id = source_router_id
self.destination_router_id = destination_router_id
self.igp_metric = igp_metric
self.isis_level = isis_level
self._link_instance_track.append(self)
@classmethod
def get_instance(cls):
return cls._link_instance_track
# The url contains details to extract BGP-LS info from the ODL
result = urllib.urlopen('http://admin:admin@192.168.24.128:8181/restconf/operational/network-topology:network-topology/')
r= json.load(result.fp)
result.close()
# For loop to go over the Node Attributes and write that info in Json format
for n in r['network-topology']['topology'][2]['node']:
if len(n['l3-unicast-igp-topology:igp-node-attributes']) == 0 :
pass
else:
if (n['l3-unicast-igp-topology:igp-node-attributes'].has_key('prefix')) & (n['l3-unicast-igp-topology:igp-node-attributes'].has_key('name')):
i = Node(n['l3-unicast-igp-topology:igp-node-attributes']['name'],n['l3-unicast-igp-topology:igp-node-attributes']['router-id'][0],n['l3-unicast-igp-topology:igp-node-attributes']['isis-topology:isis-node-attributes']['iso']['iso-system-id'])
for p in n['l3-unicast-igp-topology:igp-node-attributes']['prefix']:
i.add_prefix_metric(str(p['prefix']),str(p['metric']))
with open('node_attributes.json','a') as fh:
json.dump(i.__dict__,fh,indent = 4)
node_list = []
igp_cost_dict = {}
#For loop to go over the link attributes and pass that info to draw the graph
for n in r['network-topology']['topology'][2]['link']:
source_router_id = extract_routerid (n['source']['source-node'])
destination_router_id = extract_routerid(n['destination']['dest-node'])
igp_metric = n['l3-unicast-igp-topology:igp-link-attributes']['metric']
isis_level = extract_isis_level(n['link-id'])
node_pair = (source_router_id,destination_router_id)
node_list.append(node_pair)
igp_cost = node_pair,igp_metric
igp_cost_dict [node_pair] = igp_metric
l = Link(source_router_id,destination_router_id,igp_metric,isis_level)
# Both For loops Print the Node and Link Details
for node in Node._instance_track:
print ("Node Attributes for {0} is IS-IS Id {1}, Router-ID {2}, Prefix and there Metric {3}".format(node.node_name,node.iso_system_id,node.router_id,node.prefix_metric))
for l in Link._link_instance_track:
print ("Source Router is {0} Destination Router is {1}, IGP Metric between them is {2} and IS-IS Level is {3}".format(l.source_router_id,l.destination_router_id,l.igp_metric,l.isis_level))
draw_graph(node_list,igp_cost_dict)