def create_sff(sffname): """ This function creates a SFF on-the-fly when it receives a PUT request from ODL. The SFF runs on a separate thread. If a SFF thread with same name already exist it is killed before a new one is created. This happens when a SFF is modified or recreated :param sffname: SFF name :type sffname: str """ if not flask.request.json: flask.abort(400) local_sff_threads = sfc_globals.get_sff_threads() if sffname in local_sff_threads.keys(): stop_sff(sffname) r_json = flask.request.get_json() local_sff_topo = sfc_globals.get_sff_topo() local_sff_topo[sffname] = r_json['service-function-forwarder'][0] sff_port = (local_sff_topo[sffname]['sff-data-plane-locator'][0] ['data-plane-locator']['port']) start_sff(sffname, "0.0.0.0", sff_port) return flask.jsonify({'sff': sfc_globals.get_sff_topo()}), 201
def get_sff_sf_locator(odl_ip_port, sff_name, sf_name): """ #TODO: add description #TODO: add arguments description and type """ try: logger.info("Getting SFF information from ODL ...") url = common.sfc_globals.SFF_SF_DATA_PLANE_LOCATOR_URL odl_dataplane_url = url.format(odl_ip_port, sff_name, sf_name) s = requests.Session() r = s.get(odl_dataplane_url, auth=sfc_globals.get_odl_credentials(), stream=False) except (requests.exceptions.ConnectionError, requests.exceptions.RequestException) as exc: logger.exception('Can\'t get SFF {} data plane from ODL. Error: {}', exc) return if r.ok: r_json = r.json() sff_json = r_json['service-function-forwarders'] local_sff_topo = sfc_globals.get_sff_topo() for sff in sff_json['service-function-forwarder']: local_sff_topo[sff['name']] = sff else: logger.warning("=>Failed to GET SFF from ODL \n")
def delete_sff(sffname): """ Deletes SFF from topology, kills associated thread and if necessary remove all SFPs that depend on it :param sffname: SFF name :type sffname: str """ status_code = 204 local_sff_topo = sfc_globals.get_sff_topo() local_sff_threads = sfc_globals.get_sff_threads() try: if sffname in local_sff_threads.keys(): stop_sff(sffname) if sffname == sfc_globals.get_my_sff_name(): sfc_globals.reset_path() sfc_globals.reset_data_plane_path() local_sff_topo.pop(sffname) except KeyError: logger.warning('SFF name %s not found', sffname) status_code = 404 return '', status_code
def delete_sffs(): """ Delete all SFFs, SFPs, RSPs """ # We always use accessors sfc_globals.reset_sff_topo() sfc_globals.reset_path() sfc_globals.reset_data_plane_path() return flask.jsonify({'sff': sfc_globals.get_sff_topo()}), 201
def get_sffs_from_odl(odl_ip_port): """ Retrieves the list of configured SFFs from ODL and update global dictionary of SFFs :param odl_ip_port: ODL IP and port :type odl_ip_port: str :return Nothing """ try: logger.info("Getting SFFs configured in ODL ...") url = common.sfc_globals.SFF_PARAMETER_URL odl_sff_url = url.format(odl_ip_port) s = requests.Session() r = s.get(odl_sff_url, auth=sfc_globals.get_odl_credentials(), stream=False) except requests.exceptions.ConnectionError as e: logger.exception('Can\'t get SFFs from ODL. Error: {}'.format(e)) return except requests.exceptions.RequestException as e: logger.exception('Can\'t get SFFs from ODL. Error: {}'.format(e)) return if r.ok: r_json = r.json() sff_json = r_json['service-function-forwarders'] sfc_globals.reset_sff_topo() local_sff_topo = sfc_globals.get_sff_topo() try: for sff in sff_json['service-function-forwarder']: local_sff_topo[sff['name']] = sff except KeyError: logger.info("=>No configured SFFs in ODL \n") else: logger.warning("=>Failed to GET SFFs from ODL \n")
def find_sff_locator(sff_name): """ For a given SFF name, look into local SFF topology for a match and returns the corresponding data plane locator. If SFF is not known tries to retrieve it from ODL. :param sff_name: SFF name :type sff_name: str :return sff_locator: A dictionary with keys 'ip' and 'port' """ sff_locator = {} local_sff_topo = sfc_globals.get_sff_topo() if not _sff_present(sff_name, local_sff_topo): return sff_locator _sff_locator = local_sff_topo[sff_name]['sff-data-plane-locator'][0] sff_locator['ip'] = _sff_locator['data-plane-locator']['ip'] sff_locator['port'] = _sff_locator['data-plane-locator']['port'] return sff_locator
def get_sff_from_odl(odl_ip_port, sff_name): """ Retrieves a single configured SFF from ODL and update global dictionary of SFFs :param odl_ip_port: ODL IP and port :type odl_ip_port: str :param sff_name: SFF name :type sff_name: str :return int or None """ try: logger.info('Contacting ODL about information for SFF: %s' % sff_name) url = common.sfc_globals.SFF_NAME_PARAMETER_URL odl_sff_url = url.format(odl_ip_port, sff_name) s = requests.Session() r = s.get(odl_sff_url, auth=sfc_globals.get_odl_credentials(), stream=False) except (requests.exceptions.ConnectionError, requests.exceptions.RequestException) as exc: logger.exception('Can\'t get SFF "{}" from ODL. Error: {}', sff_name, exc) return -1 if r.ok: r_json = r.json() local_sff_topo = sfc_globals.get_sff_topo() local_sff_topo[sff_name] = r_json['service-function-forwarder'][0] return 0 else: logger.warning("=>Failed to GET SFF {} from ODL \n".format(sff_name)) return -1
def find_sf_locator(sf_name, sff_name): """ Looks for the SF name within the service function dictionary of sff_name. If SFF is not present in local SFF topology it is requested from ODL. Return the corresponding SF data plane locator or None if not found. :param sf_name: SF name :type sf_name: str :param sff_name: SFF name :type sff_name: str :return sf_locator: A dictionary with keys 'ip' and 'port' """ sf_locator = {} local_sff_topo = sfc_globals.get_sff_topo() if not _sff_present(sff_name, local_sff_topo): return sf_locator service_dict = local_sff_topo[sff_name]['service-function-dictionary'] for service_function in service_dict: if sf_name == service_function['name']: _sf_locator = service_function['sff-sf-data-plane-locator'] # A locator might use something other than IP if 'ip' in _sf_locator: sf_locator['ip'] = _sf_locator['ip'] sf_locator['port'] = _sf_locator['port'] return sf_locator if not sf_locator: logger.error("Failed to find data plane locator for SF: %s", sf_name) return sf_locator
def find_sff_locator_by_ip(addr): """ For a given IP address iterate over all SFFs looking for which one has a the same data plane locator IP :param addr: IP address :type addr: str :return str or None """ local_sff_topo = sfc_globals.get_sff_topo() for sff_name, sff_value in local_sff_topo.items(): try: for locator_value in sff_value['sff-data-plane-locator']: if locator_value['data-plane-locator']['ip'] == addr: return sff_name else: continue except KeyError: continue return None
def get_sffs(): return flask.jsonify(sfc_globals.get_sff_topo())