Commit a025bcb2 authored by Tomas Hlavacek's avatar Tomas Hlavacek

Refactor BGP graph. Add IPv6 support.

Refactor bgp_graph_gen function and subfunctions.
Add sh bgp ipv6 uni command with BGP graph decorator.
Add label escaping and vertex ID transformation in order to avoid
forbidden colons in the vertex ID. The colon char is a separator of values
in the pydot interface or so.
parent 2a9884d0
......@@ -77,6 +77,7 @@ REGEX_SH_BGP_UNI_ORIGLINE_BEST = '\s*Origin\s.*\sbest.*'
regex_sh_bgp_uni_origline_best = re.compile(REGEX_SH_BGP_UNI_ORIGLINE_BEST)
COMMAND_NAME_GRAPH4 = 'Graph - show bgp ipv4 uni <IP subnet>'
COMMAND_NAME_GRAPH6 = 'Graph - show bgp ipv6 uni <IP subnet>'
def cisco_parse_sh_bgp_uni(lines,prependas):
def split_ases(ases):
......@@ -574,11 +575,11 @@ class CiscoCommandShowBgpIPv6NeighRecv(CiscoCommandShowBgpIPv46Select):
class CiscoCommandGraphShowBgpIPv46Uni(ulgmodel.TextCommand):
TABLE_HEADER_REGEXP=BGP_PREFIX_TABLE_HEADER
LASTLINE_REGEXP='^\s*Total number of prefixes [0-9]+\s*$'
PARAM_REGEXP = '.*'
def __init__(self,peers,name=None):
ulgmodel.TextCommand.__init__(self,self.COMMAND_TEXT,param_specs=[
ulgmodel.TextParameter(IPV4_SUBNET_REGEXP,name=defaults.STRING_IPSUBNET)],
ulgmodel.TextParameter(self.PARAM_REGEXP,name=defaults.STRING_IPSUBNET)],
name=name)
def decorateResult(self,session,decorator_helper=None):
......@@ -596,6 +597,12 @@ class CiscoCommandGraphShowBgpIPv46Uni(ulgmodel.TextCommand):
class CiscoCommandGraphShowBgpIPv4Uni(CiscoCommandGraphShowBgpIPv46Uni):
COMMAND_TEXT='show bgp ipv4 unicast %s'
PARAM_REGEXP = IPV4_SUBNET_REGEXP
class CiscoCommandGraphShowBgpIPv6Uni(CiscoCommandGraphShowBgpIPv46Uni):
COMMAND_TEXT='show bgp ipv6 unicast %s'
PARAM_REGEXP = IPV6_SUBNET_REGEXP
class CiscoRouter(ulgmodel.RemoteRouter):
PS_KEY_BGPV4 = '-bgpipv4'
......@@ -609,6 +616,7 @@ class CiscoRouter(ulgmodel.RemoteRouter):
_show_bgp_ipv6_uni_neigh_advertised = CiscoCommandShowBgpIPv6NeighAdv(self.getBGPIPv6Peers())
_show_bgp_ipv6_uni_neigh_received_routes = CiscoCommandShowBgpIPv6NeighRecv(self.getBGPIPv6Peers())
_graph_show_bgp_ipv4_uni = CiscoCommandGraphShowBgpIPv4Uni(self.getBGPIPv4Peers(),COMMAND_NAME_GRAPH4)
_graph_show_bgp_ipv6_uni = CiscoCommandGraphShowBgpIPv6Uni(self.getBGPIPv6Peers(),COMMAND_NAME_GRAPH6)
return [ulgmodel.TextCommand('show version'),
ulgmodel.TextCommand('show interfaces status'),
......@@ -633,6 +641,7 @@ class CiscoRouter(ulgmodel.RemoteRouter):
ulgmodel.TextCommand('show mac-address-table address %s',[ulgmodel.TextParameter(MAC_ADDRESS_REGEXP,name=defaults.STRING_MACADDRESS)]),
ulgmodel.TextCommand('show mac-address-table interface %s',[ulgmodel.TextParameter('.*',name=defaults.STRING_INTERFACE)]),
_graph_show_bgp_ipv4_uni,
_graph_show_bgp_ipv6_uni,
]
def __init__(self, host, user, password, port=22, commands=None, enable_bgp=True, asn='My ASN'):
......
......@@ -26,63 +26,84 @@ from pygraph.classes.digraph import digraph
from pygraph.readwrite.dot import write
USED_FILL_COLOR = '#DC738A'
USED_LINE_COLOR = 'red'
RECONLY_LINE_COLOR = 'gray'
REC_LINE_COLOR = 'blue'
FONT_SIZE = 10
LABEL_FONT_SIZE = 8
REC_LINE_WIDTH = 0.5
USED_LINE_WIDTH = 1.2
def bgp_graph_gen(graphdata,start=None,end=None):
gr = digraph()
def add_edge(graph,v1,v2,color='black',style='solid',penwidth=1.0,fillcolor=None,label=None):
params = [('fontsize',FONT_SIZE)]
if(fillcolor):
params = params + [('style','filled'),('fillcolor',fillcolor)]
def transform_nodename(name):
return name.replace(":", "")
if(not graph.has_node(v1)):
graph.add_node(v1,attrs=params)
if(not graph.has_node(v2)):
graph.add_node(v2,attrs=params)
def transform_label(s):
return "".join(["&#%d;"%ord(x) for x in s])
def add_node(graph,v,fillcolor=None,shape='ellipse'):
vid = transform_nodename(v)
if(not graph.has_node(vid)):
params = [('fontsize',FONT_SIZE),('shape',shape),('label',transform_label(v))]
if(fillcolor):
params = params + [('style','filled'),('fillcolor',fillcolor)]
graph.add_node(vid,attrs=params)
def add_edge(graph,v1,v2,color='black',style='solid',penwidth=REC_LINE_WIDTH,label=None):
if(v1==v2):
return
eparams = [('color',color),('style',style),('penwidth',penwidth)]
if(label):
eparams = eparams + [('fontsize',LABEL_FONT_SIZE),('label',' '+label+' ')]
vid1 = transform_nodename(v1)
vid2 = transform_nodename(v2)
if(not graph.has_edge((vid1,vid2))):
params = [('color',color),('style',style),('penwidth',penwidth)]
if(label):
params = params + [('fontsize',LABEL_FONT_SIZE),('label',transform_label(" "+label+" "))]
graph.add_edge((vid1,vid2),attrs=params)
if(not graph.has_edge((v1,v2))):
graph.add_edge((v1,v2),attrs=eparams)
for gd in graphdata:
params = {}
if(start):
add_node(gr,start,shape='box',fillcolor=USED_FILL_COLOR)
add_node(gr,gd[0][0],fillcolor=USED_FILL_COLOR)
add_edge(gr,start,gd[0][0],color=USED_LINE_COLOR,penwidth=USED_LINE_WIDTH,style='dashed')
vparams = {}
eparams = {}
if(gd[1]['recuse']):
params['color']='red'
params['penwidth']=1.2
params['fillcolor']=USED_FILL_COLOR
eparams['color']=USED_LINE_COLOR
eparams['penwidth']=USED_LINE_WIDTH
vparams['fillcolor']=USED_FILL_COLOR
elif(gd[1]['reconly']):
params['color']='gray'
params['style']='dotted'
params['penwidth']=0.5
eparams['color']=RECONLY_LINE_COLOR
eparams['style']='dotted'
eparams['penwidth']=REC_LINE_WIDTH
else:
params['penwidth']=0.5
params['color']='blue'
if(start):
if(not gr.has_node(start)):
gr.add_node(start,attrs=[('shape','box'),('style','filled'),('fillcolor',USED_FILL_COLOR),('fontsize',FONT_SIZE)])
add_edge(gr,start,gd[0][0],**{'color':'red','penwidth':1.2,'style':'dashed','fillcolor':USED_FILL_COLOR})
eparams['penwidth']=REC_LINE_WIDTH
eparams['color']=REC_LINE_COLOR
i = 0
while (i < len(gd[0])):
if(i+1 < len(gd[0])):
add_node(gr,gd[0][i],**vparams)
add_node(gr,gd[0][i+1],**vparams)
if((i==0) and ('peer' in gd[1])):
add_edge(gr,gd[0][i],gd[0][i+1],label=gd[1]['peer'],**params)
add_edge(gr,gd[0][i],gd[0][i+1],label=gd[1]['peer'],**eparams)
else:
add_edge(gr,gd[0][i],gd[0][i+1],**params)
add_edge(gr,gd[0][i],gd[0][i+1],**eparams)
i = i+1
if(not gr.has_node(end)):
gr.add_node(end,attrs=[('shape','box'),('style','filled'),('fillcolor',USED_FILL_COLOR),('fontsize',FONT_SIZE)])
add_edge(gr,gd[0][-1],end,**{'color':'red','penwidth':1.2,'style':'dashed'})
if(end):
add_node(gr,end,shape='box',fillcolor=USED_FILL_COLOR)
add_edge(gr,gd[0][-1],end,color=USED_LINE_COLOR,penwidth=USED_LINE_WIDTH,style='dashed')
dot = write(gr)
gvv = gv.readstring(dot)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment