Commit 4883ca7f authored by Tomas Hlavacek's avatar Tomas Hlavacek

Merge branch 'master' of https://github.com/tmshlvck/ulg

parents 0138cf10 f9c4bcd2
......@@ -20,6 +20,14 @@
var rs=document.getElementById("routerselect");
var cs=document.getElementById("commandselect");
<py:for each="cp in commonparams.keys()">
var commondict_${cp} = ' \
<py:for each="paridx,partuple in enumerate(commonparams[cp].getOptions())">
<option value="${partuple[0]}"> ${partuple[1]} </option> \
</py:for>
';
</py:for>
<py:for each="ridx,router in enumerate(routers)">
<py:for each="cidx,cmd in enumerate(routers[ridx].listCommands())">
<![CDATA[ if((rs.options[rs.selectedIndex].value==$ridx) && (cs.options[cs.selectedIndex].value==$cidx)) { ]]>
......@@ -31,26 +39,17 @@
${pidx+3}. ${param.getName()}: \
</label> \
<py:choose>
<py:when test="param.getType() == 'commonselect'">
<select name="param${pidx}" id="param${pidx}"> \
' + commondict_${param.getID()} + ' \
</select> \
</py:when>
<py:when test="param.getType() == 'select'">
<select name="param${pidx}" id="param${pidx}"> \
<py:for each="paridx,partuple in enumerate(param.getOptions())">
<py:choose>
<py:when test="default_routerid == ridx and default_commandid == cidx and defined('default_params') and partuple[0] == default_params[pidx]">
<option value="${partuple[0]}" selected="selected"> \
${partuple[1]} \
</option> \
</py:when>
<py:when test="partuple[0] == param.getDefault()">
<option value="${partuple[0]}" selected="selected"> \
${partuple[1]} \
</option> \
</py:when>
<py:otherwise>
<option value="${partuple[0]}"> \
${partuple[1]} \
</option> \
</py:otherwise>
</py:choose>
</py:for>
</select> \
</py:when>
......@@ -67,6 +66,23 @@
</py:choose>
</fieldset> \
</py:for>';
<py:for each="pidx,param in enumerate(routers[ridx].listCommands()[cidx].getParamSpecs())">
<py:choose>
<py:when test="(param.getType() == 'select') or (param.getType() == 'commonselect')">
<py:for each="paridx,partuple in enumerate(param.getOptions())">
<py:choose>
<py:when test="default_routerid == ridx and default_commandid == cidx and defined('default_params') and partuple[0] == default_params[pidx]">
document.getElementById("param${pidx}").selectedIndex=${paridx};
</py:when>
<py:when test="partuple[0] == param.getDefault()">
document.getElementById("param${pidx}").selectedIndex=${paridx};
</py:when>
</py:choose>
</py:for>
</py:when>
</py:choose>
</py:for>
}
</py:for>
</py:for>
......
......@@ -38,8 +38,8 @@ config = ulgmodel.import_config()
def testRouterCommand(router=0,command=0,params=[]):
r = config.routers[router]
try:
if(not r.runCommand(r.listCommands()[command],params,ulg.DecoratorHelper())):
print "WARN: Outpit of test running command "+str(command)+" on router "+str(router)+" with parameters:"+str(params)+" is empty."
if(not r.runSyncCommand(r.listCommands()[command],params)):
print "WARN: Output of test running command "+str(command)+" on router "+str(router)+" with parameters:"+str(params)+" is empty."
return False
except Exception as e:
......@@ -143,7 +143,7 @@ def testULGLock():
def testULGRunParameter(router=0,command=4,params=['91.210.16.1']):
r = config.routers[router]
try:
if(not r.runCommand(r.listCommands()[command],params,ulg.DecoratorHelper())):
if(not r.runSyncCommand(r.listCommands()[command],params)):
print "WARN: Output of test running command "+str(command)+" on router "+str(router)+" with parameters:"+str(params)+" is empty."
return False
......
......@@ -28,7 +28,7 @@ import re
import fcntl
import traceback
import urllib
import md5
import hashlib
import time
import random
......@@ -90,7 +90,7 @@ class Session(object):
self.save()
def __genSessionId__(self):
return md5.new(str(time.time())+str(random.randint(1,1000000))).hexdigest()
return hashlib.md5(str(time.time())+str(random.randint(1,1000000))).hexdigest()
def save(self):
try:
......@@ -462,6 +462,16 @@ class ULGCgi:
else:
return defaults.refresh_interval
def getCommonParams(self):
res = {}
for r in config.routers:
for c in r.listCommands():
for ps in c.getParamSpecs():
if(ps.getType() == 'commonselect'):
res[ps.getID()] = ps
return res
def HTTPRedirect(self,url):
return """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
......@@ -531,6 +541,7 @@ class ULGCgi:
return template.generate(defaults=defaults,
routers=config.routers,
commonparams=self.getCommonParams(),
default_routerid=routerid,
default_commandid=commandid,
default_sessionid=sessionid,
......@@ -617,6 +628,7 @@ class ULGCgi:
template = self.loader.load(defaults.index_template_file)
return template.generate(defaults=defaults,
routers=config.routers,
commonparams=self.getCommonParams(),
default_routerid=session.getRouterId(),
default_commandid=session.getCommandId(),
default_params=session.getParameters(),
......@@ -639,6 +651,7 @@ class ULGCgi:
return template.generate(defaults=defaults,
routers=config.routers,
commonparams=self.getCommonParams(),
default_routerid=0,
default_commandid=0,
default_sessionid=None,
......@@ -657,6 +670,7 @@ class ULGCgi:
return template.generate(defaults=defaults,
routers=config.routers,
commonparams=self.getCommonParams(),
default_routerid=0,
default_commandid=0,
default_sessionid=None,
......
......@@ -22,6 +22,7 @@ import os
import socket
import re
import pexpect
import hashlib
import defaults
......@@ -105,7 +106,7 @@ def bird_reduce_paths(paths):
return sorted(paths,key=assign_value)
def parseBirdShowProtocols(text,resrange=None):
def parseBirdShowProtocols(text):
def parseShowProtocolsLine(line):
m = bird_show_proto_line_regexp.match(line)
if(m):
......@@ -137,9 +138,6 @@ def parseBirdShowProtocols(text,resrange=None):
# else:
# ulgmodel.log("ulgbird.parseBirdShowProtocols skipping unparsable line: "+l)
if(resrange):
return (header,table[resrange:resrange+defaults.range_step],len(table))
else:
return (header,table,len(table))
# classes
......@@ -199,7 +197,7 @@ class BirdShowProtocolsCommand(ulgmodel.TextCommand):
if((not session.getRouter()) or (not decorator_helper)):
return "<pre>\n%s\n</pre>" % session.getResult()
else:
pr = parseBirdShowProtocols(session.getResult(),session.getRange())
pr = parseBirdShowProtocols(session.getResult())
table_header = pr[0]
table = []
......@@ -212,32 +210,21 @@ class BirdShowProtocolsCommand(ulgmodel.TextCommand):
return (ulgmodel.TableDecorator(table,table_header).decorate(),pr[2])
class BirdBGPPeerSelectCommand(ulgmodel.TextCommand):
class AbstractBGPPeerSelectCommand(ulgmodel.TextCommand):
""" Abstract class for all BIRD BGP peer-specific commands """
def __init__(self,peers,name=None):
peer_param = ulgmodel.SelectionParameter([tuple((p,p,)) for p in peers],
name=defaults.STRING_PEERID)
ulgmodel.TextCommand.__init__(self,self.COMMAND_TEXT,param_specs=[peer_param],name=name)
def __init__(self,router,name=None):
ulgmodel.TextCommand.__init__(self,self.COMMAND_TEXT,param_specs=[router.getBGPPeerSelect()],name=name)
class BirdShowProtocolsAllCommand(BirdBGPPeerSelectCommand):
class BirdShowProtocolsAllCommand(AbstractBGPPeerSelectCommand):
COMMAND_TEXT = 'show protocols all %s'
class BirdShowRouteExportCommand(BirdBGPPeerSelectCommand):
COMMAND_TEXT = 'show route export %s'
class BirdShowRouteCommand(ulgmodel.TextCommand):
COMMAND_TEXT = 'show route table %s for %s'
def __init__(self,tables,name=None):
table_param = ulgmodel.SelectionParameter([tuple((t,t,)) for t in tables],
name=defaults.STRING_RTABLE)
ulgmodel.TextCommand.__init__(self,self.COMMAND_TEXT,param_specs=[
table_param,
ulgmodel.TextParameter(pattern=IPV46_SUBNET_REGEXP,name=defaults.STRING_IPSUBNET),
],name=name)
class AbstractRouteTableCommand(ulgmodel.TextCommand):
def _decorateOriginAS(self,asfield,decorator_helper):
# expected input is "[AS28171i]"
......@@ -299,27 +286,35 @@ class BirdShowRouteCommand(ulgmodel.TextCommand):
return (ulgmodel.TableDecorator(table,table_header).decorate(),result_len)
class BirdShowRouteExportCommand(AbstractBGPPeerSelectCommand,AbstractRouteTableCommand):
COMMAND_TEXT = 'show route export %s'
class BirdShowRouteCommand(AbstractRouteTableCommand):
COMMAND_TEXT = 'show route table %s for %s'
def __init__(self,router,name=None):
ulgmodel.TextCommand.__init__(self,self.COMMAND_TEXT,param_specs=[
router.getRoutingTableSelect(),
ulgmodel.TextParameter(pattern=IPV46_SUBNET_REGEXP,name=defaults.STRING_IPSUBNET),
],name=name)
class BirdShowRouteProtocolCommand(BirdShowRouteCommand):
COMMAND_TEXT = 'show route table %s protocol %s'
def __init__(self,peers,tables,name=None):
peer_param = ulgmodel.SelectionParameter([tuple((p,p,)) for p in peers],
name=defaults.STRING_PEERID)
table_param = ulgmodel.SelectionParameter([tuple((t,t,)) for t in tables],
name=defaults.STRING_RTABLE)
ulgmodel.TextCommand.__init__(self,self.COMMAND_TEXT,param_specs=[table_param, peer_param],name=name)
def __init__(self,router,name=None):
ulgmodel.TextCommand.__init__(self,self.COMMAND_TEXT,param_specs=[router.getRoutingTableSelect(),router.getBGPPeerSelect()],name=name)
class BirdShowRouteAllCommand(ulgmodel.TextCommand):
COMMAND_TEXT = 'show route table %s all for %s'
def __init__(self,tables,name=None):
table_param = ulgmodel.SelectionParameter([tuple((t,t,)) for t in tables],
name=defaults.STRING_RTABLE)
def __init__(self,router,name=None):
ulgmodel.TextCommand.__init__(self,self.COMMAND_TEXT,param_specs=[
table_param,
router.getRoutingTableSelect(),
ulgmodel.TextParameter(pattern=IPV46_SUBNET_REGEXP,name=defaults.STRING_IPSUBNET),
],
name=name)
......@@ -351,12 +346,9 @@ class BirdShowRouteAllCommand(ulgmodel.TextCommand):
class BirdGraphShowRouteAll(ulgmodel.TextCommand):
COMMAND_TEXT = 'show route table %s all for %s'
def __init__(self,tables,name=BIRD_GRAPH_SH_ROUTE_ALL):
table_param = ulgmodel.SelectionParameter([tuple((t,t,)) for t in tables],
name=defaults.STRING_RTABLE)
def __init__(self,router,name=BIRD_GRAPH_SH_ROUTE_ALL):
ulgmodel.TextCommand.__init__(self,self.COMMAND_TEXT,param_specs=[
table_param,
router.getRoutingTableSelect(),
ulgmodel.TextParameter(pattern=IPV46_SUBNET_REGEXP,name=defaults.STRING_IPSUBNET),
],
name=name)
......@@ -383,28 +375,95 @@ class BirdGraphShowRouteAll(ulgmodel.TextCommand):
return False
class BirdRouter(ulgmodel.Router):
""" Abstract class representing common base for BIRD router objects. """
RESCAN_PEERS_COMMAND = 'show protocols'
RESCAN_TABLES_COMMAND = 'show symbols'
DEFAULT_PROTOCOL_FLTR = '^BGP.*$'
def __init__(self):
self.bgp_peers = None
self.routing_tables = None
self.bgp_peer_select = None
self.rt_select = None
def _getDefaultCommands(self):
sh_proto_all = BirdShowProtocolsAllCommand(self.getBGPPeers())
sh_proto_route = BirdShowRouteProtocolCommand(self.getBGPPeers(),self.getRoutingTables())
sh_proto_export = BirdShowRouteExportCommand(self.getBGPPeers())
sh_proto_all = BirdShowProtocolsAllCommand(self)
sh_proto_route = BirdShowRouteProtocolCommand(self)
sh_proto_export = BirdShowRouteExportCommand(self)
return [BirdShowProtocolsCommand(show_proto_all_command=sh_proto_all, proto_filter = self.proto_fltr),
BirdShowRouteCommand(self.getRoutingTables()),
BirdShowRouteCommand(self),
sh_proto_all,
sh_proto_route,
sh_proto_export,
BirdShowRouteAllCommand(self.getRoutingTables()),
BirdGraphShowRouteAll(self.getRoutingTables()),
ulgmodel.TextCommand('show status'),
ulgmodel.TextCommand('show memory')
BirdShowRouteAllCommand(self),
BirdGraphShowRouteAll(self),
# ulgmodel.TextCommand('show status'),
# ulgmodel.TextCommand('show memory')
]
def rescanPeers(self):
res = self.runRawSyncCommand(self.RESCAN_PEERS_COMMAND)
psp = parseBirdShowProtocols(res)
peers = []
for pspl in psp[1]:
if(re.match(self.proto_fltr,pspl[1])):
peers.append(pspl[0])
self.bgp_peers = sorted(peers)
def rescanRoutingTables(self):
res = self.runRawSyncCommand(self.RESCAN_TABLES_COMMAND)
tables = []
for l in str.splitlines(res):
m = bird_show_symbols_line_regexp.match(l)
if(m and m.group(2).lstrip().rstrip() == STRING_SYMBOL_ROUTING_TABLE):
tables.append(m.group(1))
self.routing_tables = sorted(tables)
def getBGPPeers(self):
if(not self.bgp_peers):
self.rescanPeers()
return self.bgp_peers
def getRoutingTables(self):
if(not self.routing_tables):
self.rescanRoutingTables()
return self.routing_tables
def initBGPPeerSelect(self,peers):
rid = hashlib.md5(self.getName()).hexdigest()
self.bgp_peer_select = ulgmodel.CommonSelectionParameter(rid+"bgp",[tuple((p,p,)) for p in peers],
name=defaults.STRING_PEERID)
def initRoutingTableSelect(self,rt):
rid = hashlib.md5(self.getName()).hexdigest()
self.rt_select = ulgmodel.CommonSelectionParameter(rid+"rt",[tuple((p,p,)) for p in rt],
name=defaults.STRING_RTABLE)
def getBGPPeerSelect(self):
if(not self.bgp_peer_select):
self.initBGPPeerSelect(self.getBGPPeers())
return self.bgp_peer_select
def getRoutingTableSelect(self):
if(not self.rt_select):
self.initRoutingTableSelect(self.getRoutingTables())
return self.rt_select
class BirdRouterLocal(ulgmodel.LocalRouter,BirdRouter):
def __init__(self,sock=defaults.default_bird_sock,commands=None,proto_fltr=None,asn='My ASN',name='localhost'):
ulgmodel.LocalRouter.__init__(self)
BirdRouter.__init__(self)
self.sock = sock
self.setName(name)
self.setASN(asn)
......@@ -413,6 +472,9 @@ class BirdRouterLocal(ulgmodel.LocalRouter,BirdRouter):
else:
self.proto_fltr = self.DEFAULT_PROTOCOL_FLTR
self.rescanPeers()
self.rescanRoutingTables()
# command autoconfiguration might run only after other parameters are set
if(commands):
self.setCommands(commands)
......@@ -508,41 +570,14 @@ class BirdRouterLocal(ulgmodel.LocalRouter,BirdRouter):
return False
def rescanPeers(self):
res = self.runRawSyncCommand(self.RESCAN_PEERS_COMMAND)
psp = parseBirdShowProtocols(res)
peers = []
for pspl in psp[1]:
if(re.match(self.proto_fltr,pspl[1])):
peers.append(pspl[0])
return peers
def rescanRoutingTables(self):
res = self.runRawSyncCommand(self.RESCAN_TABLES_COMMAND)
tables = []
for l in str.splitlines(res):
m = bird_show_symbols_line_regexp.match(l)
if(m and m.group(2).lstrip().rstrip() == STRING_SYMBOL_ROUTING_TABLE):
tables.append(m.group(1))
return tables
def getBGPPeers(self):
return self.rescanPeers()
def getRoutingTables(self):
return self.rescanRoutingTables()
class BirdRouterRemote(ulgmodel.RemoteRouter,BirdRouter):
PS_KEY_BGP = '-bgppeers'
PS_KEY_RT = '-routetab'
def __init__(self,host,user,password='',port=22,commands=None,proto_fltr=None,asn='My ASN',name=None,bin_birdc=None,bin_ssh=None):
ulgmodel.RemoteRouter.__init__(self)
BirdRouter.__init__(self)
self.setHost(host)
self.setUser(user)
self.setPassword(password)
......@@ -561,7 +596,7 @@ class BirdRouterRemote(ulgmodel.RemoteRouter,BirdRouter):
else:
self.bin_birdc = defaults.default_bin_birdc
if(bin_birdc):
if(bin_ssh):
self.bin_ssh = bin_ssh
else:
self.bin_ssh = defaults.bin_ssh
......@@ -621,34 +656,6 @@ class BirdRouterRemote(ulgmodel.RemoteRouter,BirdRouter):
raise Exception("pexpect session failed: Unknown error. last output: "+s.before)
def rescanPeers(self):
res = self.runRawSyncCommand(self.RESCAN_PEERS_COMMAND)
psp = parseBirdShowProtocols(res)
peers = []
for pspl in psp[1]:
if(re.match(self.proto_fltr,pspl[1])):
peers.append(pspl[0])
self.bgp_peers = peers
def rescanRoutingTables(self):
res = self.runRawSyncCommand(self.RESCAN_TABLES_COMMAND)
tables = []
for l in str.splitlines(res):
m = bird_show_symbols_line_regexp.match(l)
if(m and m.group(2).lstrip().rstrip() == STRING_SYMBOL_ROUTING_TABLE):
tables.append(m.group(1))
self.routing_tables = tables
def getBGPPeers(self):
return self.bgp_peers
def getRoutingTables(self):
return self.routing_tables
def savePersistentInfo(self):
key_bgp = self.getHost() + self.getName() + self.PS_KEY_BGP
key_rt = self.getHost() + self.getName() + self.PS_KEY_RT
......
......@@ -23,6 +23,7 @@ import pexpect
import re
import sys
import string
import hashlib
import defaults
......@@ -34,11 +35,13 @@ STRING_EXPECT_SSH_NEWKEY='Are you sure you want to continue connecting'
STRING_EXPECT_PASSWORD='(P|p)assword:'
STRING_EXPECT_SHELL_PROMPT_REGEXP = '\n[a-zA-Z0-9\._-]+(>|#)'
BGP_IPV6_SUM_TABLE_SPLITLINE_REGEXP='^\s*[0-9a-fA-F:]+\s*$'
IPV46_ADDR_REGEXP = '^[0-9a-fA-F:\.]+$'
BGP_IPV6_TABLE_HEADER_REGEXP='^\s*(Neighbor)\s+(V)\s+(AS)\s+(MsgRcvd)\s+(MsgSent)\s+(TblVer)\s+(InQ)\s+(OutQ)\s+(Up/Down)\s+(State/PfxRcd)\s*$'
BGP_IPV6_TABLE_LINE_REGEXP='^\s*([0-9a-fA-F:]+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+([a-zA-Z0-9:]+)\s+([a-zA-Z0-9\(\)]+|[a-zA-Z0-9]+\s\(Admin\))\s*$'
BGP_IPV46_TABLE_LINE_REGEXP='^\s*([0-9a-fA-F:\.]+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+([a-zA-Z0-9:]+)\s+([a-zA-Z0-9\(\)]+|[a-zA-Z0-9]+\s\(Admin\))\s*$'
#BGP_IPV6_TABLE_LINE_REGEXP='^\s*([0-9a-fA-F:]+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+([a-zA-Z0-9:]+)\s+([a-zA-Z0-9\(\)]+|[a-zA-Z0-9]+\s\(Admin\))\s*$'
BGP_IPV4_TABLE_HEADER_REGEXP='^\s*(Neighbor)\s+(V)\s+(AS)\s+(MsgRcvd)\s+(MsgSent)\s+(TblVer)\s+(InQ)\s+(OutQ)\s+(Up/Down)\s+(State/PfxRcd)\s*$'
BGP_IPV4_TABLE_LINE_REGEXP='^\s*([0-9\.]+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+([a-zA-Z0-9:]+)\s+([a-zA-Z0-9\(\)]+|[a-zA-Z0-9]+\s\(Admin\))\s*$'
#BGP_IPV4_TABLE_LINE_REGEXP='^\s*([0-9\.]+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+([a-zA-Z0-9:]+)\s+([a-zA-Z0-9\(\)]+|[a-zA-Z0-9]+\s\(Admin\))\s*$'
BGP_PREFIX_TABLE_HEADER='^(\s)\s+(Network)\s+(Next Hop)\s+(Metric)\s+(LocPrf)\s+(Weight)\s+(Path)\s*$'
......@@ -50,7 +53,7 @@ MAC_ADDRESS_REGEXP = '^[0-9a-fA-F]{4}\.[0-9a-fA-F]{4}\.[0-9a-fA-F]{4}$'
BGP_RED_STATES = ['Idle', 'Active', '(NoNeg)']
BGP_YELLOW_STATES = ['Idle (Admin)',]
REGEX_SH_BGP_UNI_ASLINE = '^(\s*)([0-9\s]+)(|,.*)\s*$'
REGEX_SH_BGP_UNI_ASLINE = '^(\s*)([0-9\s]+|Local)(|,.*)\s*$'
regex_sh_bgp_uni_asline = re.compile(REGEX_SH_BGP_UNI_ASLINE)
REGEX_SH_BGP_UNI_AGGR = '\s*\(aggregated by ([0-9]+) [0-9a-fA-F:\.]+\).*'
......@@ -62,7 +65,7 @@ regex_sh_bgp_uni_recuse = re.compile(REGEX_SH_BGP_UNI_RECUSE)
REGEX_SH_BGP_UNI_RECONLY = '\s*\(received-only\).*'
regex_sh_bgp_uni_reconly = re.compile(REGEX_SH_BGP_UNI_RECONLY)
REGEX_SH_BGP_UNI_TABLE_START = '\s*Advertised\s+to\s+update-groups.*'
REGEX_SH_BGP_UNI_TABLE_START = '\s*(Advertised\s+to\s+update-groups|Not\s+advertised\s+to\s+any\s+peer).*'
regex_sh_bgp_uni_table_start = re.compile(REGEX_SH_BGP_UNI_TABLE_START)
REGEX_SH_BGP_UNI_PEERLINE = '\s*([0-9a-fA-F:\.]+)\s.*from\s.*'
......@@ -78,6 +81,9 @@ STRING_COMMAND_LOGOUT = 'logout'
def cisco_parse_sh_bgp_uni(lines,prependas):
def split_ases(ases):
if ases == 'Local':
return []
else:
return str.split(ases)
def get_info(info):
......@@ -99,7 +105,19 @@ def cisco_parse_sh_bgp_uni(lines,prependas):
table_prestarted = False
table_started = False
for l in str.splitlines(lines):
if(table_started):
if not table_started:
if table_prestarted:
# if prestarted and a line not containing only numbers of
# update groups, start immediately
if not re.match('^[0-9\s]+$',l):
table_started = True
# if not prestarted and match occures, wait for next line
if(regex_sh_bgp_uni_table_start.match(l)):
table_prestarted = True
if table_started:
m = regex_sh_bgp_uni_asline.match(l)
if(m):
ases = [ulgmodel.annotateAS("AS"+str(asn)) for asn in [prependas] + split_ases(m.group(2))]
......@@ -118,11 +136,6 @@ def cisco_parse_sh_bgp_uni(lines,prependas):
m = regex_sh_bgp_uni_origline_best.match(l)
if(m):
paths[-1][1]['recuse'] = True
else:
if(table_prestarted):
table_started = True
if(regex_sh_bgp_uni_table_start.match(l)):
table_prestarted = True
return paths
......@@ -178,16 +191,20 @@ def matchCiscoBGPLines(header,lines):
# ?1 hat happens when last element is line-wrapped? It looks like it does
# not happen in my settings.
def divideGroups(line,max_index_start=sys.maxint,table_line=False):
def divideGroups(line,max_index_start=sys.maxint,table_line=False,first_group_length=3):
# divide groups starting before max_index_start
result = []
# when parsing table_line (not the header and not the continuation line)
# cut off first four charactes and use them as a group
if(table_line and
(not re.match('^\s*$',line[0:4]))):
result.append([0,4])
line = ' '+line[4:]
# cut off first N charactes and use them as the first group (flags) when there is
# some non-blank characters in the first two groups (therefore the line is the leading)
if(table_line):
if(re.match('[^\s]+',line[0:(first_group_length+2)])):
result.append([0,first_group_length])
line = ' '*first_group_length + line[first_group_length:]
else:
# parsing header, add virtual Status group to the header
line = 'S'+line[1:]
last_group = False
for r in re.compile('[^\s]+').finditer(line):
......@@ -203,10 +220,17 @@ def matchCiscoBGPLines(header,lines):
# add tail to last groups
result[-1][1] = len(line)
# in header force the first group to spann till the end of the next group
if(not table_line):
result[0][1] = result[1][0]-1
return result
def matchGroup(header_groups_indexes,line_group_indexes,last_element):
ulgmodel.debug('matchGroup header_group_indexes='+str(header_groups_indexes)+' line_group_indexes='+str(line_group_indexes))
if(len(header_groups_indexes) == 1):
return 0
......@@ -249,7 +273,8 @@ def matchCiscoBGPLines(header,lines):
for l in lines:
# divide groups (leave the last group in one part)
lgps = divideGroups(l,hgidxs[-1][0],True)
# define boundary of the first group by the first letter of the second group beginning
lgps = divideGroups(l,hgidxs[-1][0],True,hgidxs[1][0]-1)
if(lgps==None):
continue
......@@ -269,7 +294,7 @@ def matchCiscoBGPLines(header,lines):
result[-1].append(normalize(l[lgp[0]:lgp[1]]))
ulgmodel.debug("DEBUG bgpmatchlines:"+str(result))
ulgmodel.debug('bgpmatchlines:'+str(result))
return result
......@@ -420,7 +445,7 @@ class CiscoCommandBgpIPv46Sum(ulgmodel.TextCommand):
class CiscoCommandBgpIPv4Sum(CiscoCommandBgpIPv46Sum):
COMMAND_TEXT='show bgp ipv4 unicast summary'
TABLE_LINE_REGEXP=BGP_IPV4_TABLE_LINE_REGEXP
TABLE_LINE_REGEXP=BGP_IPV46_TABLE_LINE_REGEXP
TABLE_HEADER_REGEXP=BGP_IPV4_TABLE_HEADER_REGEXP
def __init__(self,name=None,peer_address_command=None,peer_received_command=None):
......@@ -429,7 +454,7 @@ class CiscoCommandBgpIPv4Sum(CiscoCommandBgpIPv46Sum):
class CiscoCommandBgpIPv6Sum(CiscoCommandBgpIPv46Sum):
COMMAND_TEXT='show bgp ipv6 unicast summary'
TABLE_LINE_REGEXP=BGP_IPV6_TABLE_LINE_REGEXP
TABLE_LINE_REGEXP=BGP_IPV46_TABLE_LINE_REGEXP
TABLE_HEADER_REGEXP=BGP_IPV6_TABLE_HEADER_REGEXP
def __init__(self,name=None,peer_address_command=None,peer_received_command=None):
......@@ -451,27 +476,21 @@ class CiscoCommandBgpIPv6Sum(CiscoCommandBgpIPv46Sum):
class CiscoCommandShowBgpIPv4Neigh(ulgmodel.TextCommand):
COMMAND_TEXT='show bgp ipv4 unicast neighbor %s'
def __init__(self,peers,name=None):
peer_param = ulgmodel.SelectionParameter([tuple((p,p,)) for p in peers],
name=defaults.STRING_IPADDRESS)
ulgmodel.TextCommand.__init__(self,self.COMMAND_TEXT,param_specs=[peer_param],name=name)
def __init__(self,router,name=None):
ulgmodel.TextCommand.__init__(self,self.COMMAND_TEXT,param_specs=[router.getBGPIPv4Select()],name=name)
class CiscoCommandShowBgpIPv6Neigh(ulgmodel.TextCommand):
COMMAND_TEXT='show bgp ipv6 unicast neighbor %s'
def __init__(self,peers,name=None):
peer_param = ulgmodel.SelectionParameter([tuple((p,p,)) for p in peers],
name=defaults.STRING_IPADDRESS)
ulgmodel.TextCommand.__init__(self,self.COMMAND_TEXT,param_specs=[peer_param],name=name)
def __init__(self,router,name=None):
ulgmodel.TextCommand.__init__(self,self.COMMAND_TEXT,param_specs=[router.getBGPIPv6Select()],name=name)
class CiscoCommandShowBgpIPv46Select(ulgmodel.TextCommand):
TABLE_HEADER_REGEXP=BGP_PREFIX_TABLE_HEADER
LASTLINE_REGEXP='^\s*Total number of prefixes [0-9]+\s*$'
def __init__(self,peers,name=None):
peer_param = ulgmodel.SelectionParameter([tuple((p,p,)) for p in peers],
name=defaults.STRING_IPADDRESS)
ulgmodel.TextCommand.__init__(self,self.COMMAND_TEXT,param_specs=[peer_param],name=name)
def __init__(self,peer_select_param,name=None):
ulgmodel.TextCommand.__init__(self,self.COMMAND_TEXT,param_specs=[peer_select_param],name=name)
def _decorateASPath(self,path,decorator_helper):
result = ''
......@@ -587,19 +606,31 @@ class CiscoCommandShowBgpIPv46Select(ulgmodel.TextCommand):
class CiscoCommandShowBgpIPv4NeighAdv(CiscoCommandShowBgpIPv46Select):
COMMAND_TEXT='show bgp ipv4 unicast neighbor %s advertised'
def __init__(self,router,name=None):
ulgmodel.TextCommand.__init__(self,self.COMMAND_TEXT,[router.getBGPIPv4Select()],name=name)
class CiscoCommandShowBgpIPv6NeighAdv(CiscoCommandShowBgpIPv46Select):
COMMAND_TEXT='show bgp ipv6 unicast neighbor %s advertised'
def __init__(self,router,name=None):
ulgmodel.TextCommand.__init__(self,self.COMMAND_TEXT,[router.getBGPIPv6Select()],name=name)
class CiscoCommandShowBgpIPv4NeighRecv(CiscoCommandShowBgpIPv46Select):
COMMAND_TEXT='show bgp ipv4 unicast neighbor %s received-routes'
def __init__(self,router,name=None):
ulgmodel.TextCommand.__init__(self,self.COMMAND_TEXT,[router.getBGPIPv4Select()],name=name)
class CiscoCommandShowBgpIPv6NeighRecv(CiscoCommandShowBgpIPv46Select):
COMMAND_TEXT='show bgp ipv6 unicast neighbor %s received-routes'
def __init__(self,router,name=None):
ulgmodel.TextCommand.__init__(self,self.COMMAND_TEXT,[router.getBGPIPv6Select()],name=name)
class CiscoCommandGraphShowBgpIPv46Uni(ulgmodel.TextCommand):
TABLE_HEADER_REGEXP=BGP_PREFIX_TABLE_HEADER
def __init__(self,peers,name=None,param=None):
def __init__(self,name=None,param=None):
ulgmodel.TextCommand.__init__(self,self.COMMAND_TEXT,
param_specs=[param],
name=name)
......@@ -629,17 +660,15 @@ class CiscoCommandGraphShowBgpIPv46Uni(ulgmodel.TextCommand):
class CiscoCommandGraphShowBgpIPv4Uni(CiscoCommandGraphShowBgpIPv46Uni):
COMMAND_TEXT='show bgp ipv4 unicast %s'
def __init__(self,peers,name=None):
CiscoCommandGraphShowBgpIPv46Uni.__init__(self,peers,name,
param=ulgmodel.IPv4SubnetParameter())
def __init__(self,router,name=None):
CiscoCommandGraphShowBgpIPv46Uni.__init__(self,name,param=ulgmodel.IPv4SubnetParameter())
class CiscoCommandGraphShowBgpIPv6Uni(CiscoCommandGraphShowBgpIPv46Uni):
COMMAND_TEXT='show bgp ipv6 unicast %s'
def __init__(self,peers,name=None):
CiscoCommandGraphShowBgpIPv46Uni.__init__(self,peers,name,
param=ulgmodel.IPv6SubnetParameter())
def __init__(self,router,name=None):