From 332a377868dbc8aca3a86439ca6e2a3c60f7faa9 Mon Sep 17 00:00:00 2001 From: Karl Newell Date: Wed, 5 Feb 2020 14:57:25 -0500 Subject: [PATCH] Update main.py, ui.js Add connection error logging in main.py Change absolute API calls in ui.js to relative --- main.py | 561 +++++++++++++++++++++++++++++-------------------------- ui/ui.js | 12 +- 2 files changed, 301 insertions(+), 272 deletions(-) diff --git a/main.py b/main.py index e6cbe6a..2c9df21 100644 --- a/main.py +++ b/main.py @@ -29,7 +29,7 @@ from jinja2 import Environment, FileSystemLoader from jnpr.junos.utils.config import Config from jnpr.junos import Device -from jnpr.junos.exception import ConfigLoadError, CommitError +from jnpr.junos.exception import ConfigLoadError, CommitError, ConnectRefusedError, ConnectTimeoutError from data.fr import FlowRoutesTable, FlowFilterTable # set up logging for the main program @@ -40,7 +40,7 @@ # suppressing the INFO logging from ncclient module logging.getLogger('ncclient').setLevel(logging.WARNING) # suppressing the INFO logging from cherrypy module -#logging.getLogger('cherrypy').setLevel(logging.WARNING) +logging.getLogger('cherrypy').setLevel(logging.WARNING) class MyDev(object): @@ -71,9 +71,8 @@ def addNewFlowRoute(self, flowRouteData=None): if 'rr' in value['type']: my_router = [value['ip']] - with Device(host=my_router[0], user=self.dev_user, password=self.dev_pw) as dev: - - try: + try: + with Device(host=my_router[0], user=self.dev_user, password=self.dev_pw) as dev: cu = Config(dev) cu.lock() @@ -83,9 +82,12 @@ def addNewFlowRoute(self, flowRouteData=None): cu.unlock() logger.info('Flow Route added ' + str(flowRouteData)) - except ConfigLoadError as cle: - logger.warning(cle.message) - return False, cle.message + except ConfigLoadError as cle: + logger.warning(cle.message) + return False, cle.message + except (ConnectRefusedError, ConnectTimeoutError) as cre: + logger.warning('NETCONF connection error: {}'.format(cre)) + return False # self.flow_config[flowRouteData['flowRouteName']] = { # 'dstPrefix': flowRouteData['dstPrefix'] if 'dstPrefix' in flowRouteData else None, @@ -113,9 +115,9 @@ def modFlowRoute(self, flowRouteData=None): if 'rr' in value['type']: my_router = [value['ip']] - with Device(host=my_router[0], user=self.dev_user, password=self.dev_pw) as dev: + try: + with Device(host=my_router[0], user=self.dev_user, password=self.dev_pw) as dev: - try: cu = Config(dev) cu.lock() cu.load(template_path='template/set-flow-route.conf', template_vars=flowRouteData) @@ -123,9 +125,12 @@ def modFlowRoute(self, flowRouteData=None): cu.unlock() logger.info('Flow Route modified ' + str(flowRouteData)) - except CommitError as ce: - logger.warning(ce.message) - return False, ce.message + except CommitError as ce: + logger.warning(ce.message) + return False, ce.message + except (ConnectRefusedError, ConnectTimeoutError) as cre: + logger.warning('NETCONF connection error: {}'.format(cre)) + return False # self.flow_config[flowRouteData['flowRouteName']] = { # 'dstPrefix': flowRouteData['dstPrefix'] if 'dstPrefix' in flowRouteData else None, @@ -151,9 +156,8 @@ def delFlowRoute(self, flowRouteData=None): flowRouteData.update({'flowRouteName': flowRouteData['name']}) - with Device(host=my_router[0], user=self.dev_user, password=self.dev_pw) as dev: - - try: + try: + with Device(host=my_router[0], user=self.dev_user, password=self.dev_pw) as dev: cu = Config(dev) cu.lock() @@ -162,9 +166,12 @@ def delFlowRoute(self, flowRouteData=None): cu.unlock() logger.info('Flow Route deleted ' + str(flowRouteData)) - except ConfigLoadError as cle: - logger.warning(cle.message) - return False, cle.message + except ConfigLoadError as cle: + logger.warning(cle.message) + return False, cle.message + except (ConnectRefusedError, ConnectTimeoutError) as cre: + logger.warning('NETCONF connection error: {}'.format(cre)) + return False self.flow_config.pop(flowRouteData['flowRouteName'], None) @@ -179,137 +186,142 @@ def getActiveFlowRoutes(self): for name, value in router.items(): - with Device(host=value['ip'], user=self.dev_user, password=self.dev_pw) as dev: - - # data = dev.rpc.get_config(filter_xml='routing-options/flow/route/name') - frt = FlowRoutesTable(dev) - flowtables = list() - for vrf in self.vrfs: - if vrf == 'default': - flowtables.extend(['inetflow.0', 'inet6flow.0']) - else: - flowtables.extend(['{}.inetflow.0'.format(vrf), '{}.inet6flow.0'.format(vrf)]) -# for flowtable in ['inetflow.0', 'inet6flow.0', 'trcps.inetflow.0', 'trcps.inet6flow.0']: - for flowtable in flowtables: - frt.get(table=flowtable) + try: + with Device(host=value['ip'], user=self.dev_user, password=self.dev_pw) as dev: - _flowtable = flowtable.split('.') - vrf = '' - family = '' - _vrf = ['',''] - if len(_flowtable) == 2: - vrf = 'default' - if _flowtable[0] == 'inetflow': - family = 'v4' - if _flowtable[0] == 'inet6flow': - family = 'v6' - if len(_flowtable) > 2: - vrf = _flowtable[0] - if _flowtable[1] == 'inetflow': - family = 'v4' - if _flowtable[1] == 'inet6flow': - family = 'v6' - - for flow in frt: - - destination = self.parseFlow(flow.destination) - - # for index, item in enumerate(destination): - # _item = item.split('=') - # destination[index] = _item[1] if len(_item) > 1 else _item[0] - - hash_object = hashlib.sha512('{0}{1}'.format(str(destination), str(value['ip'])).encode('utf-8')) - hex_dig = hash_object.hexdigest() - _age = dict() - - if len(flow.age) <= 2: - _age['current'] = datetime.timedelta(seconds=int(flow.age)) - elif len(flow.age) == 4 or len(flow.age) == 5: - ms = flow.age.split(':') - _age['current'] = datetime.timedelta(minutes=int(ms[0]), seconds=int(ms[1])) - elif len(flow.age) == 7 or len(flow.age) == 8: - ms = flow.age.split(':') - _age['current'] = datetime.timedelta(hours=int(ms[0]), minutes=int(ms[1]), - seconds=int(ms[2])) + # data = dev.rpc.get_config(filter_xml='routing-options/flow/route/name') + frt = FlowRoutesTable(dev) + flowtables = list() + for vrf in self.vrfs: + if vrf == 'default': + flowtables.extend(['inetflow.0', 'inet6flow.0']) else: - pattern = r'(.*w)?(.*)\s(.*?):(.*?):(.*)' + flowtables.extend(['{}.inetflow.0'.format(vrf), '{}.inet6flow.0'.format(vrf)]) + # for flowtable in ['inetflow.0', 'inet6flow.0', 'trcps.inetflow.0', 'trcps.inet6flow.0']: + for flowtable in flowtables: + frt.get(table=flowtable) + + _flowtable = flowtable.split('.') + vrf = '' + family = '' + _vrf = ['',''] + if len(_flowtable) == 2: + vrf = 'default' + if _flowtable[0] == 'inetflow': + family = 'v4' + if _flowtable[0] == 'inet6flow': + family = 'v6' + if len(_flowtable) > 2: + vrf = _flowtable[0] + if _flowtable[1] == 'inetflow': + family = 'v4' + if _flowtable[1] == 'inet6flow': + family = 'v6' + + for flow in frt: + + destination = self.parseFlow(flow.destination) + + # for index, item in enumerate(destination): + # _item = item.split('=') + # destination[index] = _item[1] if len(_item) > 1 else _item[0] + + hash_object = hashlib.sha512('{0}{1}'.format(str(destination), str(value['ip'])).encode('utf-8')) + hex_dig = hash_object.hexdigest() + _age = dict() + + if len(flow.age) <= 2: + _age['current'] = datetime.timedelta(seconds=int(flow.age)) + elif len(flow.age) == 4 or len(flow.age) == 5: + ms = flow.age.split(':') + _age['current'] = datetime.timedelta(minutes=int(ms[0]), seconds=int(ms[1])) + elif len(flow.age) == 7 or len(flow.age) == 8: + ms = flow.age.split(':') + _age['current'] = datetime.timedelta(hours=int(ms[0]), minutes=int(ms[1]), + seconds=int(ms[2])) + else: + pattern = r'(.*w)?(.*)\s(.*?):(.*?):(.*)' + regex = re.compile(pattern) + age = re.findall(regex, flow.age) + if age[0][0][:-1] is '': + weeks = 0 + else: + weeks = int(age[0][0][:-1]) + _age['current'] = datetime.timedelta( + weeks=weeks, + days=int(age[0][1][:-1]), + hours=int(age[0][2]), + minutes=int(age[0][3]), + seconds=int(age[0][4])) + + pattern = r'([^\s]+)' regex = re.compile(pattern) - age = re.findall(regex, flow.age) - if age[0][0][:-1] is '': - weeks = 0 + _krt_actions = re.findall(regex, flow.tsi) + + if len(_krt_actions) <= 4: + krt_actions = _krt_actions else: - weeks = int(age[0][0][:-1]) - _age['current'] = datetime.timedelta( - weeks=weeks, - days=int(age[0][1][:-1]), - hours=int(age[0][2]), - minutes=int(age[0][3]), - seconds=int(age[0][4])) - - pattern = r'([^\s]+)' - regex = re.compile(pattern) - _krt_actions = re.findall(regex, flow.tsi) - - if len(_krt_actions) <= 4: - krt_actions = _krt_actions - else: - krt_actions = _krt_actions[4] + krt_actions = _krt_actions[4] + + # Junos 14.1RX different XPATH for BGP communities + version = dev.facts['version'].split('R')[0].split('.') - # Junos 14.1RX different XPATH for BGP communities - version = dev.facts['version'].split('R')[0].split('.') + if int(version[0]) <= 14 and int(version[1]) <= 1: - if int(version[0]) <= 14 and int(version[1]) <= 1: + if isinstance(flow.action_141, str): + if 'traffic-action' in flow.action_141: + commAction = flow.action_141.split(":")[1].lstrip().strip() + else: + commAction = flow.action_141 - if isinstance(flow.action_141, str): - if 'traffic-action' in flow.action_141: - commAction = flow.action_141.split(":")[1].lstrip().strip() + elif isinstance(flow.action_141, list): + commAction = flow.action_141[1].split(':')[1].lstrip().strip() else: commAction = flow.action_141 - elif isinstance(flow.action_141, list): - commAction = flow.action_141[1].split(':')[1].lstrip().strip() else: - commAction = flow.action_141 - else: + if isinstance(flow.action, str): + if 'traffic-action' in flow.action: + commAction = flow.action.split(":")[1].lstrip().strip() + else: + commAction = flow.action - if isinstance(flow.action, str): - if 'traffic-action' in flow.action: - commAction = flow.action.split(":")[1].lstrip().strip() + elif isinstance(flow.action, list): + commAction = flow.action[1].split(':')[1].lstrip().strip() else: commAction = flow.action - elif isinstance(flow.action, list): - commAction = flow.action[1].split(':')[1].lstrip().strip() - else: - commAction = flow.action + if hex_dig not in self.flow_active: - if hex_dig not in self.flow_active: + 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'} + else: - 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'} - else: + if 'term:N/A' in flow['term']: + self.flow_active.pop(hex_dig, None) - if 'term:N/A' in flow['term']: - self.flow_active.pop(hex_dig, None) + if _age['current']: - if _age['current']: + if _age['current'] > datetime.timedelta(hours=t.hour, minutes=t.minute, + seconds=t.second): + self.flow_active[hex_dig]['status'] = 'old' - if _age['current'] > datetime.timedelta(hours=t.hour, minutes=t.minute, - seconds=t.second): - self.flow_active[hex_dig]['status'] = 'old' + try: + if hex_dig in self.flow_active: + self.flow_active[hex_dig].update({'term': flow.term, 'destination': destination, + 'commAction': commAction, + 'krtAction': krt_actions, + 'age': str(_age['current'])}) - try: - if hex_dig in self.flow_active: - self.flow_active[hex_dig].update({'term': flow.term, 'destination': destination, - 'commAction': commAction, - 'krtAction': krt_actions, - 'age': str(_age['current'])}) + except KeyError as ke: + return False, ke - except KeyError as ke: - return False, ke + except (ConnectRefusedError, ConnectTimeoutError) as cre: + logger.warning('NETCONF connection error: {}'.format(cre)) + return False return True, self.flow_active @@ -322,36 +334,41 @@ def getActiveFlowRouteFilter(self): for name, value in router.items(): self.filter_active[name] = list() - with Device(host=value['ip'], user=self.dev_user, password=self.dev_pw) as dev: + try: + with Device(host=value['ip'], user=self.dev_user, password=self.dev_pw) as dev: - frft = FlowFilterTable(dev) - flowfilters = list() - for vrf in self.vrfs: - flowfilters.extend(['__flowspec_{}_inet__'.format(vrf), '__flowspec_{}_inet6__'.format(vrf)]) + frft = FlowFilterTable(dev) + flowfilters = list() + for vrf in self.vrfs: + flowfilters.extend(['__flowspec_{}_inet__'.format(vrf), '__flowspec_{}_inet6__'.format(vrf)]) - for table in flowfilters: -# for table in ['__flowspec_default_inet__', '__flowspec_default_inet6__', '__flowspec_trcps_inet__', '__flowspec_trcps_inet6__']: + for table in flowfilters: + # for table in ['__flowspec_default_inet__', '__flowspec_default_inet6__', '__flowspec_trcps_inet__', '__flowspec_trcps_inet6__']: - frft.get(filtername=table) + frft.get(filtername=table) - for filter in frft: + for filter in frft: - data = self.parseFlow(filter.name) + data = self.parseFlow(filter.name) - # for didx, item in enumerate(data): - # _item = item.split('=') - # data[didx] = _item[1] if len(_item) > 1 else _item[0] + # for didx, item in enumerate(data): + # _item = item.split('=') + # data[didx] = _item[1] if len(_item) > 1 else _item[0] - _vrf = table.split('_') - family = '' - if _vrf[4] == 'inet': - family = 'v4' - if _vrf[4] == 'inet6': - family = 'v6' - vrf = '{}'.format(_vrf[3]) - - self.filter_active[name].append({'vrf': vrf, 'family': family, 'data': data, 'packet_count': filter.packet_count, - 'byte_count': filter.byte_count}) + _vrf = table.split('_') + family = '' + if _vrf[4] == 'inet': + family = 'v4' + if _vrf[4] == 'inet6': + family = 'v6' + vrf = '{}'.format(_vrf[3]) + + self.filter_active[name].append({'vrf': vrf, 'family': family, 'data': data, 'packet_count': filter.packet_count, + 'byte_count': filter.byte_count}) + + except (ConnectRefusedError, ConnectTimeoutError) as cre: + logger.warning('NETCONF connection error: {}'.format(cre)) + return False return True, self.filter_active @@ -366,132 +383,144 @@ def loadFlowRouteConfig(self): if 'rr' in value['type']: dev_ip.append(value['ip']) - with Device(host=dev_ip[0], user=self.dev_user, password=self.dev_pw, normalize=True) as dev: - version = dev.facts['version'].split('R')[0].split('.') + try: + with Device(host=dev_ip[0], user=self.dev_user, password=self.dev_pw, normalize=True) as dev: - # Junos 14.1RX does not support json so let's go with XML here + version = dev.facts['version'].split('R')[0].split('.') - if int(version[0]) <= 14 and int(version[1]) <= 1: + # Junos 14.1RX does not support json so let's go with XML here - # Retrieving all routing-options so we can get both v4 and v6. Might also work for VRFs - data = dev.rpc.get_config(options={'format': 'xml'}, filter_xml='routing-options') - # Retrieving all routing-instances. Should figure out how to limit to specified VRFs - data_trcps = dev.rpc.get_config(options={'format': 'xml'}, filter_xml='routing-instances') - - data.append(data_trcps) + if int(version[0]) <= 14 and int(version[1]) <= 1: - # iterate only over children. Appears to enter into multiple levels implicitly - for routes in data.iter('flow'): - for route in routes.iter('route'): - my_list = list() + # Retrieving all routing-options so we can get both v4 and v6. Might also work for VRFs + data = dev.rpc.get_config(options={'format': 'xml'}, filter_xml='routing-options') + # Retrieving all routing-instances. Should figure out how to limit to specified VRFs + data_trcps = dev.rpc.get_config(options={'format': 'xml'}, filter_xml='routing-instances') + + data.append(data_trcps) - for item in route: + # iterate only over children. Appears to enter into multiple levels implicitly + for routes in data.iter('flow'): + for route in routes.iter('route'): + my_list = list() - if 'name' in item.tag: - my_list.append(item.text) - self.flow_config[item.text] = {} + for item in route: - elif 'match' in item.tag: - tag = None + if 'name' in item.tag: + my_list.append(item.text) + self.flow_config[item.text] = {} - for child in item.iterchildren(): + elif 'match' in item.tag: + tag = None - if 'destination-port' in child.tag: - tag = 'dstPort' - elif 'source-port' in child.tag: - tag = 'srcPort' - elif 'destination' in child.tag: - tag = 'dstPrefix' - elif 'source' in child.tag: - tag = 'srcPrefix' - elif 'protocol' in child.tag: - tag = 'protocol' - - # v6 flow routes have a child inside src and dst items - # this grabs the value and puts it in child.txt - if tag in ['srcPrefix', 'dstPrefix']: - for grandchild in child.iterchildren(): - if 'prefix' in grandchild.tag: - child.text = grandchild.text - - self.flow_config[my_list[0]][tag] = child.text - - elif 'then' in item.tag: - - _action = dict() - - for child in item.iterchildren(): - - for value in child.iter(): - _action[child.tag] = {'value': value.text} - - self.flow_config[my_list[0]]['action'] = _action - - return True, self.flow_config - - else: - for vrf in self.vrfs: - _vrf_data = dict() - _data = dict() - family = '' - if vrf == 'default': - try: - options = dev.rpc.get_config(options={'format': 'json'}, filter_xml='routing-options') - except IndexError as error: - print(error) - _vrf_data = options['configuration']['routing-options'] - else: - try: - instances = dev.rpc.get_config(options={'format': 'json'}, filter_xml='routing-instances') - except IndexError as error: - print(error) - for instance in instances['configuration']['routing-instances']['instance']: - if instance['name'] == vrf: - _vrf_data = instance['routing-options'] - - for table in ['inet', 'inet6']: - if table == 'inet6': - if 'rib' in _vrf_data: - if 'flow' in _vrf_data['rib'][0]: - _data = _vrf_data['rib'][0]['flow'] - family = 'v6' + for child in item.iterchildren(): + + if 'destination-port' in child.tag: + tag = 'dstPort' + elif 'source-port' in child.tag: + tag = 'srcPort' + elif 'destination' in child.tag: + tag = 'dstPrefix' + elif 'source' in child.tag: + tag = 'srcPrefix' + elif 'protocol' in child.tag: + tag = 'protocol' + + # v6 flow routes have a child inside src and dst items + # this grabs the value and puts it in child.txt + if tag in ['srcPrefix', 'dstPrefix']: + for grandchild in child.iterchildren(): + if 'prefix' in grandchild.tag: + child.text = grandchild.text + + self.flow_config[my_list[0]][tag] = child.text + + elif 'then' in item.tag: + + _action = dict() + + for child in item.iterchildren(): + + for value in child.iter(): + _action[child.tag] = {'value': value.text} + + self.flow_config[my_list[0]]['action'] = _action + + return True, self.flow_config + + else: + for vrf in self.vrfs: + _vrf_data = dict() + _data = dict() + family = '' + if vrf == 'default': + try: + options = dev.rpc.get_config(options={'format': 'json'}, filter_xml='routing-options') + except IndexError as error: + logger.warn(error) + except (ConnectRefusedError, ConnectTimeoutError) as cre: + logger.warning('NETCONF connection error: {}'.format(cre)) + return False + _vrf_data = options['configuration']['routing-options'] else: - 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'].items(): - - if value[0]: - _action[key] = {'value': value} + try: + instances = dev.rpc.get_config(options={'format': 'json'}, filter_xml='routing-instances') + except IndexError as error: + logger.warn(error) + except (ConnectRefusedError, ConnectTimeoutError) as cre: + logger.warning('NETCONF connection error: {}'.format(cre)) + return False + for instance in instances['configuration']['routing-instances']['instance']: + if instance['name'] == vrf: + _vrf_data = instance['routing-options'] + + for table in ['inet', 'inet6']: + if table == 'inet6': + if 'rib' in _vrf_data: + if 'flow' in _vrf_data['rib'][0]: + _data = _vrf_data['rib'][0]['flow'] + family = 'v6' + else: + 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'].items(): + + 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': 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: - 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, self.vrfs - return True, self.flow_config, self.vrfs + except (ConnectRefusedError, ConnectTimeoutError) as cre: + logger.warning('NETCONF connection error: {}'.format(cre)) + return False def parseFlow(self, flow=None): _flow = flow.split(',') @@ -647,11 +676,11 @@ def POST(self): webapp.api.frt = Frt(my_dev=my_dev) webapp.api.frct = Frtc(my_dev=my_dev) webapp.api.frft = Frft(my_dev=my_dev) - cherrypy.config.update({'log.screen': True, + cherrypy.config.update({'log.screen': False, 'server.socket_host': '0.0.0.0', 'server.socket_port': 8080, }) # suppressing the logging from cherrypy module if log.screen == False - cherrypy.log.error_log.propagate = False + cherrypy.log.error_log.propagate = True cherrypy.log.access_log.propagate = False cherrypy.quickstart(webapp, '/', conf) diff --git a/ui/ui.js b/ui/ui.js index 0c56fb3..3d7aaaf 100644 --- a/ui/ui.js +++ b/ui/ui.js @@ -36,7 +36,7 @@ $(document).ready(function () { var t_flow_config = $('#t_flow_config').DataTable({ 'ajax' : { "type" : "POST", - "url" : "/api/frct", + "url" : "api/frct", "contentType": "application/json", "processData": true, "dataType": "json", @@ -133,7 +133,7 @@ $(document).ready(function () { 'ajax' : { "type" : "POST", - "url" : "/api/frt", + "url" : "api/frt", "contentType": "application/json", "processData": true, "dataType": "json", @@ -225,7 +225,7 @@ $(document).ready(function () { 'ajax' : { "type" : "POST", - "url" : "/api/frft", + "url" : "api/frft", "contentType": "application/json", "processData": true, "dataType": "json", @@ -524,7 +524,7 @@ function flowRouteDelBtnEventHandler(){ function addNewFlowRouteConfig(flowRouteData) { $.ajax({ - url: '/api?action=add', + url: 'api?action=add', type: 'POST', data: JSON.stringify(flowRouteData), cache: false, @@ -559,7 +559,7 @@ function addNewFlowRouteConfig(flowRouteData) { function modFlowRouteConfig(flowRouteData) { $.ajax({ - url: '/api?action=mod', + url: 'api?action=mod', type: 'POST', data: JSON.stringify(flowRouteData), cache: false, @@ -587,7 +587,7 @@ function modFlowRouteConfig(flowRouteData) { function delFlowRouteConfig(flowRouteData){ $.ajax({ - url: '/api?action=del', + url: 'api?action=del', type: 'POST', data: JSON.stringify(flowRouteData), cache: false,