diff --git a/main.py b/main.py index 4fb528e..fd9289e 100644 --- a/main.py +++ b/main.py @@ -51,7 +51,9 @@ def addNewFlowRoute(self, flowRouteData=None): loader=FileSystemLoader('./template'), trim_blocks=False, lstrip_blocks=False) template = env.get_template('set-flow-route.conf') - # print template.render(flowRouteData) + if flowRouteData['vrf'] == 'default': + flowRouteData.pop('vrf', None) + #print template.render(flowRouteData) my_router = None for router in self.routers: @@ -74,13 +76,13 @@ def addNewFlowRoute(self, flowRouteData=None): except ConfigLoadError as cle: return False, cle.message - self.flow_config[flowRouteData['flowRouteName']] = { - 'dstPrefix': flowRouteData['dstPrefix'] if 'dstPrefix' in flowRouteData else None, - 'srcPrefix': flowRouteData['srcPrefix'] if 'srcPrefix' in flowRouteData else None, - 'protocol': flowRouteData['protocol'] if 'protocol' in flowRouteData else None, - 'dstPort': flowRouteData['dstPort'] if 'dstPort' in flowRouteData else None, - 'srcPort': flowRouteData['srcPort'] if 'srcPort' in flowRouteData else None, - 'action': flowRouteData['action']} + # self.flow_config[flowRouteData['flowRouteName']] = { + # 'dstPrefix': flowRouteData['dstPrefix'] if 'dstPrefix' in flowRouteData else None, + # 'srcPrefix': flowRouteData['srcPrefix'] if 'srcPrefix' in flowRouteData else None, + # 'protocol': flowRouteData['protocol'] if 'protocol' in flowRouteData else None, + # 'dstPort': flowRouteData['dstPort'] if 'dstPort' in flowRouteData else None, + # 'srcPort': flowRouteData['srcPort'] if 'srcPort' in flowRouteData else None, + # 'action': flowRouteData['action']} return True, 'Successfully added new flow route' def modFlowRoute(self, flowRouteData=None): @@ -104,13 +106,13 @@ def modFlowRoute(self, flowRouteData=None): except CommitError as ce: return False, ce.message - self.flow_config[flowRouteData['flowRouteName']] = { - 'dstPrefix': flowRouteData['dstPrefix'] if 'dstPrefix' in flowRouteData else None, - 'srcPrefix': flowRouteData['srcPrefix'] if 'srcPrefix' in flowRouteData else None, - 'protocol': flowRouteData['protocol'] if 'protocol' in flowRouteData else None, - 'dstPort': flowRouteData['dstPort'] if 'dstPort' in flowRouteData else None, - 'srcPort': flowRouteData['srcPort'] if 'srcPort' in flowRouteData else None, - 'action': flowRouteData['action']} + # self.flow_config[flowRouteData['flowRouteName']] = { + # 'dstPrefix': flowRouteData['dstPrefix'] if 'dstPrefix' in flowRouteData else None, + # 'srcPrefix': flowRouteData['srcPrefix'] if 'srcPrefix' in flowRouteData else None, + # 'protocol': flowRouteData['protocol'] if 'protocol' in flowRouteData else None, + # 'dstPort': flowRouteData['dstPort'] if 'dstPort' in flowRouteData else None, + # 'srcPort': flowRouteData['srcPort'] if 'srcPort' in flowRouteData else None, + # 'action': flowRouteData['action']} return True, 'Successfully modified flow route' @@ -122,6 +124,11 @@ def delFlowRoute(self, flowRouteData=None): for name, value in router.iteritems(): if 'rr' in value['type']: my_router = [value['ip']] + + if 'default' in flowRouteData['vrf']: + flowRouteData.pop('vrf', None) + + flowRouteData.update({'flowRouteName': flowRouteData['name']}) with Device(host=my_router[0], user=self.dev_user, password=self.dev_pw) as dev: @@ -164,20 +171,21 @@ def getActiveFlowRoutes(self): frt.get(table=flowtable) _flowtable = flowtable.split('.') + vrf = '' + family = '' _vrf = ['',''] if len(_flowtable) == 2: - _vrf[0] = 'default' + vrf = 'default' if _flowtable[0] == 'inetflow': - _vrf[1] = 'v4' + family = 'v4' if _flowtable[0] == 'inet6flow': - _vrf[1] = 'v6' + family = 'v6' if len(_flowtable) > 2: - _vrf[0] = _flowtable[0] + vrf = _flowtable[0] if _flowtable[1] == 'inetflow': - _vrf[1] = 'v4' + family = 'v4' if _flowtable[1] == 'inet6flow': - _vrf[1] = 'v6' - vrf = '{} ({})'.format(_vrf[0], _vrf[1]) + family = 'v6' for flow in frt: @@ -247,7 +255,7 @@ def getActiveFlowRoutes(self): if hex_dig not in self.flow_active: - self.flow_active[hex_dig] = {'router': name, 'vrf': vrf, 'term': flow.term, 'destination': destination, + self.flow_active[hex_dig] = {'router': name, 'vrf': vrf, 'family': family, 'term': flow.term, 'destination': destination, 'commAction': commAction, 'krtAction': krt_actions, 'age': str(_age['current']), 'hash': hex_dig, 'status': 'new'} @@ -304,13 +312,14 @@ def getActiveFlowRouteFilter(self): data[didx] = _item[1] if len(_item) > 1 else _item[0] _vrf = table.split('_') + family = '' if _vrf[4] == 'inet': - _vrf[4] = 'v4' + family = 'v4' if _vrf[4] == 'inet6': - _vrf[4] = 'v6' - vrf = '{} ({})'.format(_vrf[3], _vrf[4]) + family = 'v6' + vrf = '{}'.format(_vrf[3]) - self.filter_active[name].append({'vrf': vrf, 'data': data, 'packet_count': filter.packet_count, + self.filter_active[name].append({'vrf': vrf, 'family': family, 'data': data, 'packet_count': filter.packet_count, 'byte_count': filter.byte_count}) return True, self.filter_active @@ -392,11 +401,12 @@ def loadFlowRouteConfig(self): else: options = dev.rpc.get_config(options={'format': 'json'}, filter_xml='routing-options') instances = dev.rpc.get_config(options={'format': 'json'}, filter_xml='routing-instances') - + data = options['configuration'] data.update(instances['configuration']) for vrf in self.vrfs: + family = '' if vrf == 'default': _vrf_data = data['routing-options'] else: @@ -406,40 +416,44 @@ def loadFlowRouteConfig(self): for table in ['inet', 'inet6']: if table == 'inet6': - _data = _vrf_data['rib'][0]['flow'] - vrf_table = '(v6)' + if 'flow' in _vrf_data['rib'][0]: + _data = _vrf_data['rib'][0]['flow'] + family = 'v6' else: - _data = _vrf_data['flow'] - vrf_table = '(v4)' - - for route in _data['route']: - _action = dict() + if 'flow' in _vrf_data: + _data = _vrf_data['flow'] + family = 'v4' + + if 'route' in _data: + for route in _data['route']: + _action = dict() - for key, value in route['then'].iteritems(): + for key, value in route['then'].iteritems(): - if value[0]: - _action[key] = {'value': value} + if value[0]: + _action[key] = {'value': value} + else: + _action[key] = {'value': None} + + self.flow_config[route['name']] = { + 'vrf': vrf, + 'family': family, + 'protocol': route['match']['protocol'] if 'protocol' in route['match'] else None, + 'dstPort': route['match']['destination-port'] if 'destination-port' in route[ + 'match'] else None, + 'srcPort': route['match']['source-port'] if 'source-port' in route['match'] else None, + 'action': _action + } + if family == 'v6': + self.flow_config[route['name']].update({ + 'dstPrefix': route['match']['destination']['prefix'] if 'destination' in route['match'] else None, + 'srcPrefix': route['match']['source']['prefix'] if 'source' in route['match'] else None + }) else: - _action[key] = {'value': None} - - self.flow_config[route['name']] = { - 'vrf': '{} {}'.format(vrf, vrf_table), - 'protocol': route['match']['protocol'] if 'protocol' in route['match'] else None, - 'dstPort': route['match']['destination-port'] if 'destination-port' in route[ - 'match'] else None, - 'srcPort': route['match']['source-port'] if 'source-port' in route['match'] else None, - 'action': _action - } - if table == 'inet6': - self.flow_config[route['name']].update({ - 'dstPrefix': route['match']['destination']['prefix'] if 'destination' in route['match'] else None, - 'srcPrefix': route['match']['source']['prefix'] if 'source' in route['match'] else None - }) - else: - self.flow_config[route['name']].update({ - 'dstPrefix': route['match']['destination'] if 'destination' in route['match'] else None, - 'srcPrefix': route['match']['source'] if 'source' in route['match'] else None - }) + self.flow_config[route['name']].update({ + 'dstPrefix': route['match']['destination'] if 'destination' in route['match'] else None, + 'srcPrefix': route['match']['source'] if 'source' in route['match'] else None + }) return True, self.flow_config diff --git a/template/delete-flow-route.conf b/template/delete-flow-route.conf index 71f6e6b..4c725af 100644 --- a/template/delete-flow-route.conf +++ b/template/delete-flow-route.conf @@ -1,6 +1,24 @@ -routing-options { - flow { - delete: - route {{ flowRouteName }}; - } +{%- if vrf is defined %} +routing-instances { + {{vrf}} { +{%- endif %} + routing-options { + {%- if family == 'v6' %} + {%- if vrf is defined %} + rib {{vrf}}.inet6.0 { + {%- else %} + rib inet6.0 { + {% endif %} + {% endif %} + flow { + delete: + route {{ flowRouteName }}; + } + {%- if family == 'v6' %} + } + {%- endif %} + } +{%- if vrf is defined %} + } } +{%- endif %} diff --git a/template/mod-flow-route.conf b/template/mod-flow-route.conf index ee01bf8..1ac0b7c 100644 --- a/template/mod-flow-route.conf +++ b/template/mod-flow-route.conf @@ -1,49 +1,67 @@ -routing-options { - flow { - route {{ flowRouteName }} { - replace: - match { - {%- if dstPrefix is defined and dstPrefix !=None %} - destination {{dstPrefix}}; - {%- endif %} - {%- if dstPort is defined and dstPort !=None %} - destination-port {{ dstPort }}; - {%- endif %} - {%- if dscp is defined and dscp !=None %} - dscp {{dscp}}; - {%- endif %} - {%- if fragment is defined and fragment !=None %} - fragment {{fragment}}; - {%- endif %} - {%- if icmp_code is defined and icmp_code !=None %} - icmp-code {{icmp_code}}; - {%- endif %} - {%- if icmp_type is defined and icmp_type !=None %} - icmp-type {{icmp_type}}; - {%- endif %} - {%- if packet_length is defined and packet_length !=None %} - packet-length {{packet_length}}; - {%- endif %} - {%- if port is defined and port !=None %} - port {{port}}; - {%- endif %} - {%- if protocol is defined and protocol !=None %} - protocol {{protocol}}; - {%- endif %} - {%- if srcPrefix is defined and srcPrefix !=None %} - source {{srcPrefix}}; - {%- endif %} - {%- if srcPort is defined and srcPortt !=None %} - source-port {{srcPort}}; - {%- endif %} - {%- if tcp_flags is defined and tcp_flags !=None %} - tcp-flags {{tcp_flags}}; - {%- endif %} +{%- if vrf is defined %} +routing-instances { + {{vrf}} { +{%- endif %} + routing-options { + {%- if family == 'v6' %} + {%- if vrf is defined %} + rib {{vrf}}.inet6.0 { + {%- else %} + rib inet6.0 { + {% endif %} + {% endif %} + flow { + route {{ flowRouteName }} { + replace: + match { + {%- if dstPrefix is defined and dstPrefix !=None %} + destination {{dstPrefix}}; + {%- endif %} + {%- if dstPort is defined and dstPort !=None %} + destination-port {{ dstPort }}; + {%- endif %} + {%- if dscp is defined and dscp !=None %} + dscp {{dscp}}; + {%- endif %} + {%- if fragment is defined and fragment !=None %} + fragment {{fragment}}; + {%- endif %} + {%- if icmp_code is defined and icmp_code !=None %} + icmp-code {{icmp_code}}; + {%- endif %} + {%- if icmp_type is defined and icmp_type !=None %} + icmp-type {{icmp_type}}; + {%- endif %} + {%- if packet_length is defined and packet_length !=None %} + packet-length {{packet_length}}; + {%- endif %} + {%- if port is defined and port !=None %} + port {{port}}; + {%- endif %} + {%- if protocol is defined and protocol !=None %} + protocol {{protocol}}; + {%- endif %} + {%- if srcPrefix is defined and srcPrefix !=None %} + source {{srcPrefix}}; + {%- endif %} + {%- if srcPort is defined and srcPortt !=None %} + source-port {{srcPort}}; + {%- endif %} + {%- if tcp_flags is defined and tcp_flags !=None %} + tcp-flags {{tcp_flags}}; + {%- endif %} + } + replace: + then { + {{action}}; + } + } } - replace: - then { - {{action}}; + {%- if family == 'v6' %} } + {%- endif %} } +{%- if vrf is defined %} } -} \ No newline at end of file +} +{%- endif %} diff --git a/template/set-flow-route.conf b/template/set-flow-route.conf index faaa760..f913d88 100644 --- a/template/set-flow-route.conf +++ b/template/set-flow-route.conf @@ -3,6 +3,13 @@ routing-instances { {{vrf}} { {%- endif %} routing-options { + {%- if family == 'v6' %} + {%- if vrf is defined %} + rib {{vrf}}.inet6.0 { + {%- else %} + rib inet6.0 { + {% endif %} + {% endif %} flow { route {{ flowRouteName }} { match { @@ -44,8 +51,13 @@ routing-instances { {%- endif %} } then { - {{action}}; + {{action}}; + } + } + } + {%- if family == 'v6' %} } + {%- endif %} } {%- if vrf is defined %} } diff --git a/ui/index.html b/ui/index.html index fd15d95..be8311c 100644 --- a/ui/index.html +++ b/ui/index.html @@ -79,6 +79,7 @@

Monitoring BGP Flow Name VRF + Family Destination Prefix Source Prefix Protocol @@ -104,6 +105,7 @@

Monitoring BGP Flow Router VRF + Family Name Destination Prefix Source Prefix @@ -132,6 +134,7 @@

Monitoring BGP Flow Router VRF + Family Destination Prefix Source Prefix Protocol @@ -206,6 +209,24 @@

placeholder="My New Flow Route"> +
+ +
+ +
+
+
+ +
+ +
+
@@ -251,14 +272,6 @@
-
- -
- -
+
+ +
+ +
+
+
+ +
+ +
+
diff --git a/ui/ui.js b/ui/ui.js index a1a2b96..c444527 100644 --- a/ui/ui.js +++ b/ui/ui.js @@ -62,6 +62,7 @@ $(document).ready(function () { return_data.push({ 'name': name, 'vrf': flow.vrf, + 'family': flow.family, 'dstPrefix': flow.dstPrefix, 'dstPort': flow.dstPort, 'srcPrefix': flow.srcPrefix, @@ -82,6 +83,10 @@ $(document).ready(function () { "data": "vrf", "defaultContent": "" }, + { + "data": "family", + "defaultContent": "" + }, { "data": "dstPrefix", "defaultContent": "" @@ -125,6 +130,7 @@ $(document).ready(function () { return_data.push({ 'router': flow.router, 'vrf': flow.vrf, + 'family': flow.family, 'term': flow.term, 'dstPrefix': flow.destination[0], 'dstPort': flow.destination[3], @@ -157,6 +163,10 @@ $(document).ready(function () { "data": "vrf", "defaultContent": "" }, + { + "data": "family", + "defaultContent": "" + }, { "data": "term", "defaultContent": "" @@ -213,6 +223,7 @@ $(document).ready(function () { return_data.push({ 'name': rname, 'vrf': filter.vrf, + 'family': filter.family, 'dstPrefix': filter.data[0], 'dstPort': filter.data[3], 'srcPrefix': filter.data[1], @@ -238,6 +249,10 @@ $(document).ready(function () { "data": "vrf", "defaultContent": "" }, + { + "data": "family", + "defaultContent": "" + }, { "data": "dstPrefix", "defaultContent": "" @@ -381,8 +396,12 @@ function flowRouteAddNewConfigEventHandler(){ if ($('#selectProtocol').val()) { data.protocol = $('#selectProtocol').val(); } - - data.vrf = $('#selectVrf').val(); + if ($('#selectVrf').val()) { + data.vrf = $('#selectVrf').val(); + } + if ($('#selectFamily').val()) { + data.family = $('#selectFamily').val(); + } data.action = $('#selectAddNewFlowAction').val(); @@ -415,6 +434,12 @@ function flowRouteModBtnEventHandler(){ if ($('#selectModProtocol').val()) { data.protocol = $('#selectModProtocol').val(); } + if ($('#selectModVrf').val()) { + data.vrf = $('#selectModVrf').val(); + } + if ($('#selectModFamily').val()) { + data.family = $('#selectModFamily').val(); + } if ($('#selectModFlowAction').val()) { data.action = $('#selectModFlowAction').val(); } @@ -437,6 +462,8 @@ function flowRouteModModalBtnEventHandler(){ $("#inputModDstPrefix").val(rowData.dstPrefix); $("#inputModSrcPrefix").val(rowData.srcPrefix); $("#selectModProtocol").val(rowData.protocol); + $("#selectModVrf").val(rowData.vrf); + $("#selectModFamily").val(rowData.family); $("#inputModDstPort").val(rowData.dstPort); $("#inputModSrcPort").val(rowData.srcPort); @@ -474,7 +501,7 @@ function flowRouteDelBtnEventHandler(){ $('#flowDelBtn').click( function () { var table = $('#t_flow_config').DataTable(); var rowData = table.row( '.selected' ).data(); - delFlowRouteConfig(rowData.name); + delFlowRouteConfig(rowData); }); } @@ -541,12 +568,12 @@ function modFlowRouteConfig(flowRouteData) { }); } -function delFlowRouteConfig(flowRouteName){ +function delFlowRouteConfig(flowRouteData){ $.ajax({ url: '/api?action=del', type: 'POST', - data: JSON.stringify({"flowRouteName": flowRouteName}), + data: JSON.stringify(flowRouteData), cache: false, processData: true, dataType: 'json',