def __init__(self, url, prefix="", features=None, **kwargs): """ Init. :param url: url of RESTful API :type url: str :param prefix: URL prefix :type prefix: str :param features: limitation anf filter parameters for the Adapter class :type features: dict :return: None """ AbstractRESTAdapter.__init__(self, base_url=url, prefix=prefix, **kwargs) AbstractESCAPEAdapter.__init__(self, **kwargs) log.debug("Init %s - type: %s, domain: %s, URL: %s" % (self.__class__.__name__, self.type, self.domain_name, url)) # Converter object self.converter = NFFGConverter( unique_bb_id=CONFIG.ensure_unique_bisbis_id(), unique_nf_id=CONFIG.ensure_unique_vnf_id(), domain=self.domain_name, logger=log) self.features = features if features is not None else {} # Cache for parsed Virtualizer self.__last_virtualizer = None self.__last_request = None self.__original_virtualizer = None
def __init__ (self, url=None, rpc=None, timeout=DEFAULT_TIMEOUT, instance_id=None): """ Init. :param url: URL of the remote server :type url: str :param rpc: RPC name :type rpc: str :param timeout: connections timeout :type timeout: int :param instance_id: additional id to join to the end of the id :type instance_id: str :return: None """ super(RemoteVisualizer, self).__init__() self.log = core.getLogger("visualizer") if url is None: url = CONFIG.get_visualization_url() if rpc is None: rpc = CONFIG.get_visualization_rpc() self._url = urlparse.urljoin(url, rpc) if self._url is None: raise RuntimeError("Missing URL from %s" % self.__class__.__name__) self._timeout = timeout if instance_id is None: self.instance_id = CONFIG.get_visualization_instance_id() self.log.info("Setup remote Visualizer with URL: %s" % self._url) # Store the last request self._response = None self.converter = NFFGConverter(domain="ESCAPE", logger=log, unique_bb_id=CONFIG.ensure_unique_bisbis_id(), unique_nf_id=CONFIG.ensure_unique_vnf_id()) # Suppress low level logging self.__suppress_requests_logging()
def _initiate_rest_api(self): """ Initialize and set up REST API in a different thread. :return: None """ # set bounded layer name here to avoid circular dependency problem handler = CONFIG.get_sas_api_class() handler.bounded_layer = self._core_name params = CONFIG.get_sas_agent_params() # can override from global config if 'prefix' in params: handler.prefix = params['prefix'] if 'unify_interface' in params: handler.virtualizer_format_enabled = params['unify_interface'] address = (params.get('address'), params.get('port')) self.rest_api = RESTServer(handler, *address) self.rest_api.api_id = handler.LOGGER_NAME = "U-Sl" handler.log.info("Init REST-API for %s on %s:%s!" % (self.rest_api.api_id, address[0], address[1])) self.rest_api.start() handler.log.debug( "Enforced configuration for %s: interface: %s" % (self.rest_api.api_id, "UNIFY" if handler.virtualizer_format_enabled else "Internal-NFFG"))
def _handle_ComponentRegistered(self, event): """ Wait for controller (internal POX module) :param event: registered component event :type event: :class:`ComponentRegistered` :return: None """ # Check if our POX controller is up # ESCAPEConfig follows Singleton design pattern internal_adapters = CONFIG.get_component_params( component="INTERNAL")['adapters'] # print internal_adapters internal_controller = CONFIG.get_component(component="CONTROLLER", parent=internal_adapters) # print internal_controller if event.name == internal_controller.name and isinstance( event.component, OpenFlow_01_Task): if self.topology is not None: log.info( "Internal domain controller is up! Initiate network emulation " "now...") self.topology.start_network() else: log.error( "Mininet topology is missing! Skip network starting...")
def send_notification (self, data, url=None, unique_id=None, **kwargs): """ Send given data to a remote server for visualization. Convert given NFFG into Virtualizer format if needed. :param data: topology description need to send :type data: :class:`NFFG` or :class:`Virtualizer` :param url: additional URL (optional) :type url: str :param unique_id: use given ID as NFFG id :type unique_id: str or int :param kwargs: additional params to request :type kwargs: dict :return: response text :rtype: str """ if url is None: url = self._url if url is None: self.log.error("Missing URL for remote visualizer! Skip notification...") return if 'timeout' not in kwargs: kwargs['timeout'] = self._timeout self.log.debug("Send visualization notification to %s" % self._url) try: if data is None: self.log.warning("Missing data! Skip notifying remote visualizer.") return False elif isinstance(data, NFFG): data = self.converter.dump_to_Virtualizer(nffg=data) elif not isinstance(data, Virtualizer.Virtualizer): self.log.warning( "Unsupported data type: %s! Skip notification..." % type(data)) return if unique_id: data.id.set_value(value=unique_id) # If additional params is not empty dict -> override the basic params if 'headers' in kwargs: kwargs['headers'].update(self.basic_headers) else: kwargs['headers'] = self.basic_headers.copy() kwargs['headers'].update(CONFIG.get_visualization_headers()) if "params" in kwargs: kwargs['params'].update(CONFIG.get_visualization_params()) else: kwargs['params'] = CONFIG.get_visualization_params() self.log.debug("Sending visualization notification...") self._response = self.request(method='POST', url=url, data=data.xml(), **kwargs) self._response.raise_for_status() return self._response.text except (ConnectionError, HTTPError, KeyboardInterrupt) as e: self.log.warning( "Got exception during notifying remote Visualizer: %s!" % e) return False except Timeout: self.log.warning( "Got timeout(%ss) during notify remote Visualizer!" % kwargs['timeout']) return True
def __create_server(self): host = CONFIG.get_rest_api_host() port = CONFIG.get_rest_api_port() self.flask = Flask(__name__) self.__werkzeug = make_server(host=host if host else self.DEFAULT_HOST, port=port if port else self.DEFAULT_PORT, app=self.flask) # Suppress low level logging logging.getLogger("werkzeug").setLevel(logging.WARNING)
def _all_dependencies_met(self): """ Called when every component on which depends are initialized on POX core. Contain dependency relevant initialization. :return: None """ try: self.initialize() # With fully event-driven communication between the layers the dependency # handling takes care by listen_to_dependencies() run into a dead-lock. # The root of this problem is the bidirectional or cyclic dependency # between the components, so basically the layers will always wait to each # other to be registered on core. To avoid this situation the naming # convention of event handlers on which the dependency checking based is # not followed (a.k.a. leave _handle_<component name>_<event name>) and # the event listeners is set up manually. For automatic core registration # the components have to contain dependencies explicitly. for dep in self.dependencies: if not self._standalone: if core.core.hasComponent(dep): dep_layer = core.components[dep] # Register actual event handlers on dependent layer dep_layer.addListeners(self) # Register dependent layer's event handlers on actual layer self.addListeners(dep_layer) else: raise AttributeError( "Component is not registered on core") else: # In case of standalone mode set up a StandaloneHelper in this object # with the name of the dependency to handle raised events # automatically setattr(self, dep, SimpleStandaloneHelper(self, dep)) # Subscribe for GoingDownEvent to finalize API classes # shutdown() function will be called if POX's core going down core.addListenerByName('GoingDownEvent', self.shutdown) # Subscribe for UpEvent to call functions after everithing is up core.addListenerByName('UpEvent', self.post_up_hook) # Subscribe core event for advanced functions # Listeners' name must follow POX naming conventions core.addListeners(self) # Everything is set up an "running" so register the component on pox.core # as a final step. Other dependent component can finish initialization # now. core.core.register(self._core_name, self) # Set "running" config for convenience purposes CONFIG.set_layer_loaded(self._core_name) except KeyboardInterrupt: quit_with_error( msg="Initialization of %s was interrrupted by user!" % self.__class__.__name__) except Exception as e: quit_with_error(msg="Abort ESCAPEv2 initialization...", exception=e)
def rest_api_edit_config(self, id, data, params=None): """ Implementation of REST-API RPC: edit-config :param params: original request params :type params: dict :return: None """ self.log.info("Invoke preprocessing on %s with SG: %s " % (self.__class__.__name__, id)) if self._agent: # ESCAPE serves as a local orchestrator, probably with infrastructure # layer --> rewrite domain nffg = self.__update_nffg_domain(nffg_part=data) # Update API cache if CONFIG.get_rest_api_config(self._core_name)['unify_interface']: self.log.debug( "Virtualizer format enabled! Start conversion step...") if CONFIG.get_rest_api_config(self._core_name)['diff']: self.log.debug("Diff format enabled! Start patching step...") if self.api_mgr.last_response is None: self.log.info( "Missing cached Virtualizer! Acquiring topology now..." ) self.rest_api_get_config() stats.add_measurement_start_entry(type=stats.TYPE_PROCESSING, info="RECREATE-FULL-REQUEST") self.log.info("Patching cached topology with received diff...") full_req = self.api_mgr.last_response.yang_copy() full_req.patch(source=data) stats.add_measurement_end_entry(type=stats.TYPE_PROCESSING, info="RECREATE-FULL-REQUEST") else: full_req = data self.log.info("Converting full request data...") stats.add_measurement_start_entry(type=stats.TYPE_CONVERSION, info="VIRTUALIZER-->NFFG") nffg = self.api_mgr.converter.parse_from_Virtualizer( vdata=full_req) stats.add_measurement_end_entry(type=stats.TYPE_CONVERSION, info="VIRTUALIZER-->NFFG") else: nffg = data self.log.debug("Set NFFG id: %s" % id) if nffg.service_id is None: nffg.service_id = nffg.id nffg.id = id if params: nffg.add_metadata(name="params", value=params) self.log.info("Proceeding request: %s to instantiation..." % id) # Get resource view of the interface res = self.__get_slor_resource_view().get_resource_info() # ESCAPE serves as a global or proxy orchestrator self.__proceed_instantiation(nffg=nffg, resource_nffg=res) self.log.info("Preprocessing on %s ended!" % self.__class__.__name__)
def orchestrate (self, input_graph, resource_view): """ Abstract function for wrapping optional steps connected to orchestration. Implemented function call the mapping algorithm. If a derived class of :any:`AbstractMappingDataProcessor` is set in the global config under the name "PROCESSOR" then the this class performs pre/post mapping steps. After the pre/post-processor steps the relevant Mapping event will be raised on the main API class of the layer! :param input_graph: graph representation which need to be mapped :type input_graph: :class:`NFFG` :param resource_view: resource information :type resource_view: :any:`AbstractVirtualizer` :raise: NotImplementedError :return: mapped graph :rtype: :class:`NFFG` """ # Get resource info resource_graph = resource_view.get_resource_info() # If validator is not None call the pre function if CONFIG.get_processor_enabled(layer=self._layer_name): # Preform pre-mapping validation if self.processor is not None and self.processor.pre_mapping_exec( input_graph=input_graph, resource_graph=resource_graph): # Raise Error if processor function return with True raise ProcessorError("Pre mapping validation is failed!") # Raise event for external POX modules if core.hasComponent(self._layer_name): core.components[self._layer_name].raiseEvent( PreMapEvent, input_graph=input_graph, resource_graph=resource_graph) # Invoke mapping algorithm mapping_result = self._perform_mapping(input_graph=input_graph, resource_view=resource_view) # Perform post-mapping validation # If the mapping is threaded skip post mapping here if not self._threaded: # If validator is not None call the post function if CONFIG.get_processor_enabled(layer=self._layer_name): if self.processor is not None and self.processor.post_mapping_exec( input_graph=input_graph, resource_graph=resource_graph, result_graph=mapping_result): # Raise Error if processor function return with True raise ProcessorError("Post mapping validation is failed!") # Raise event for external POX modules if core.hasComponent(self._layer_name): core.components[self._layer_name].raiseEvent( PostMapEvent, input_graph=input_graph, resource_graph=resource_graph, result_graph=mapping_result) # Return the mapped NFFG return mapping_result
def __get_slor_resource_view(self): """ :return: Return with the Virtualizer object assigned to the Sl-Or interface. :rtype: :any:`AbstractVirtualizer` """ virt_mgr = self.orchestrator.virtualizerManager virtualizer_type = CONFIG.get_api_virtualizer(layer=self._core_name) params = CONFIG.get_virtualizer_params(layer=self._core_name) log.debug("Acquired Virtualizer type: %s, params: %s" % (virtualizer_type, params)) return virt_mgr.get_virtual_view(virtualizer_id=self._core_name, type=virtualizer_type, **params)
def initialize(self): """ .. seealso:: :func:`AbstractAPI.initialize() <escape.util.api.AbstractAPI.initialize>` """ log.debug("Initializing Infrastructure Layer...") # Set layer's LOADED value manually here to avoid issues CONFIG.set_layer_loaded(self._core_name) mn_opts = CONFIG.get_mn_network_opts() # Build the emulated topology with the NetworkBuilder optional_topo = getattr(self, '_topo', None) self.topology = ESCAPENetworkBuilder(**mn_opts).build( topo=optional_topo) log.info("Infrastructure Layer has been initialized!")
def __init__ (self, layer_API, mapper=None, strategy=None): """ Init. :param layer_API: reference os the actual layer performing the orchestration :type layer_API: :any:`AbstractAPI` :param mapper: additional mapper class (optional) :type mapper: :any:`AbstractMapper` :param strategy: override strategy class for the used Mapper (optional) :type strategy: :any:`AbstractMappingStrategy` :return: None """ layer_name = layer_API._core_name # Set Mapper if mapper is None: # Use the Mapper in CONFIG mapper = CONFIG.get_mapper(layer_name) if mapper is None and self.DEFAULT_MAPPER is not None: # Use de default Mapper if it's set self.mapper = self.DEFAULT_MAPPER if mapper is None: raise RuntimeError("Mapper class is not found!") assert issubclass(mapper, AbstractMapper), "Mapper is not subclass of " \ "AbstractMapper!" self.mapper = mapper(strategy=strategy) # Init Mapper listeners # Listeners must be weak references in order the layer API can garbage # collected # self.mapper is set by the AbstractOrchestrator's constructor self.mapper.addListeners(layer_API, weak=True) super(AbstractOrchestrator, self).__init__()
def __filter_external_domains(nffg): """ Filter out domains detected by external DomainManagers. :param nffg: filtered NFFG :return: :class:`NFFG` """ log.debug("Filtering domains detected from external DomainManagers...") # Get External DomainManager names ext_mgr = CONFIG.get_external_managers() # Copy NFFG filtered_nffg = nffg.copy() # Remove the detected domains by External DomainManagers for ext in ext_mgr: # Get all the domains domains = NFFGToolBox.detect_domains(nffg=filtered_nffg) # Get domains detected and initiated by the External DomainManager ext_domains = [d for d in domains if ext in d] # Remove collected domains from NFFG for domain in ext_domains: log.debug( "Remove domain: %s originated from external DomainManager: %s" % (domain, ext)) NFFGToolBox.remove_domain(base=filtered_nffg, domain=domain, log=log) filtered_nffg.name += "-filtered" return filtered_nffg
def collect_mappings(self, mappings, slor_topo): dov = self.virtualizerManager.dov.get_resource_info() response = mappings.full_copy() log.debug("Start checking mappings...") for mapping in response: bb, nf = detect_bb_nf_from_path(path=mapping.object.get_value(), topo=slor_topo) if not nf: # mapping.target.object.set_value("NOT_FOUND") mapping.target.domain.set_value("N/A") continue m_result = self.__collect_binding(dov=dov, nfs=[nf]) if not m_result: log.warning("Mapping is not found for NF: %s!" % nf) # mapping.target.object.set_value("NOT_FOUND") mapping.target.domain.set_value("N/A") continue try: node = m_result[0]['bisbis']['id'] domain = m_result[0]['bisbis']['domain'] except KeyError: log.warning("Missing mapping element from: %s" % m_result) # mapping.target.object.set_value("NOT_FOUND") mapping.target.domain.set_value("N/A") continue log.debug("Found mapping: %s@%s (domain: %s)" % (nf, node, domain)) mapping.target.object.set_value(NF_PATH_TEMPLATE % (node, nf)) mapping.target.domain.set_value( CONFIG.get_domain_url(domain=domain)) return response
def _handle_InstallationFinishedEvent(self, event): """ Get information from NFFG installation process. :param event: event object info :type event: :any:`InstallationFinishedEvent` :return: None """ if not InstantiationFinishedEvent.is_error(event.result): self.log.info( "NF-FG(%s) instantiation has been finished successfully " "with result: %s!" % (event.id, event.result)) else: self.log.error( "NF-FG(%s) instantiation has been finished with error " "result: %s!" % (event.id, event.result)) if InstantiationFinishedEvent.is_deploy_error(event.result): if CONFIG.get_trial_and_error(layer=LAYER_NAME): log.info( "TRIAL_AND_ERROR is enabled! Reschedule for mapping..." ) self.__proceed_trial_and_error( original_request_id=event.id) return else: log.debug("TRIAL_AND_ERROR is disabled! Proceeding...") if not event.is_pending(event.result): self.__process_mapping_result(nffg_id=event.id, fail=event.is_error(event.result)) self.raiseEventNoErrors(InstantiationFinishedEvent, id=event.id, result=event.result)
def __update_nffg_domain(nffg_part, domain_name=None): """ Update domain descriptor of infras: REMOTE -> INTERNAL :param nffg_part: NF-FG need to be updated :type nffg_part: :class:`NFFG` :return: updated NFFG :rtype: :class:`NFFG` """ rewritten = [] if domain_name is None: local_mgr = CONFIG.get_internal_manager() if local_mgr is None: log.error("No local Manager has been initiated! " "Skip domain rewriting!") elif len(local_mgr) > 1: log.warning("Multiple local Manager has been initiated: %s! " "Arbitrarily use the first..." % local_mgr) domain_name = local_mgr.pop() log.debug("Rewrite received NFFG domain to %s..." % domain_name) for infra in nffg_part.infras: infra.domain = domain_name rewritten.append(infra.id) log.debug("Rewritten infrastructure nodes: %s" % rewritten) return nffg_part
def __manage_neo4j_service(self): """ Manage neo4j service. :return: None """ if not CONFIG.get_manage_neo4j_service(): log.debug("Skip Neo4j service management...") return log.debug("Detected Neo4j service name: %s" % self.service_name) if check_service_status(self.service_name): log.debug("%s service is already running..." % self.service_name) return log.info("Starting service: %s..." % self.service_name) ret = run_cmd('sudo service %s start' % self.service_name) if "failed" in ret: log.error("Neo4j service initiation status: %s" % ret) return log.log(VERBOSE, "Neo4j service initiation status: %s" % ret) # Check if the service has been started - only 5 try if port_tester(host=self.DB_HOST, port=self.DB_PORT, interval=1, period=10, log=log): log.debug("Neo4j service has been verified!") else: log.error("Neo4j service has not started correctly!")
def initialize(self): """ .. seealso:: :func:`AbstractAPI.initialize() <escape.util.api.AbstractAPI.initialize>` """ log.debug("Initializing Service Layer...") self.__sid = CONFIG.get_service_layer_id() if self.__sid is not None: log.debug("Setup ID for Service Layer: %s" % self.__sid) else: self.__sid = self.LAYER_ID log.error( "Missing ID of Service Layer from config. Using default value: %s" % self.__sid) # Set element manager self.elementManager = ClickManager() # Init central object of Service layer self.service_orchestrator = ServiceOrchestrator(self) # Read input from file if it's given and initiate SG if self._sg_file: try: stats.init_request_measurement(request_id=self._sg_file) service_request = self._read_data_from_file(self._sg_file) log.info("Graph representation is loaded successfully!") if service_request.startswith('{'): log.debug( "Detected format: JSON - Parsing from NFFG format...") nffg = NFFG.parse(raw_data=service_request) elif service_request.startswith('<'): log.debug( "Detected format: XML - Parsing from Virtualizer format..." ) converter = NFFGConverter(domain="INTERNAL", logger=log) nffg = converter.parse_from_Virtualizer( vdata=service_request) else: log.warning("Detected unexpected format...") return if nffg.mode is not None: log.info('Detected mapping mode in NFFG: %s' % nffg.mode) else: nffg.mode = NFFG.MODE_ADD log.info("No mapping mode has been detected in NFFG! " "Set default mode: %s" % nffg.mode) log.info("Schedule service request delayed by %d seconds..." % SCHEDULED_SERVICE_REQUEST_DELAY) stats.set_request_id(request_id=nffg.id) self.api_sas_sg_request_delayed(service_nffg=nffg) except (ValueError, IOError, TypeError) as e: log.error("Can't load service request from file because of: " + str(e)) quit_with_error(msg=str(e), logger=log) else: # Init REST-API if no input file is given self._initiate_rest_api() # Init GUI if self._gui: self._initiate_gui() log.info("Service Layer has been initialized!")
def __init__(self, standalone=False, **kwargs): log.info("Starting REST-API Sublayer...") self.__server = MainApiServer() self.__entry_point_cache = {} self.mgrs = {} self.is_up = False self.prefix = CONFIG.get_rest_api_prefix() super(RestInterfaceAPI, self).__init__(standalone, **kwargs)
def finalize(self): """ Finalize function for the class. :return: None """ if CONFIG.get_manage_neo4j_service(): log.info("Stopping %s service..." % self.service_name) ret = run_cmd('sudo service %s stop' % self.service_name) log.log(VERBOSE, "Neo4j service shutdown status: %s" % ret)
def __init__ (self, layer_name, strategy=None, threaded=None): """ Initialize Mapper class. Set given strategy class and threaded value or check in `CONFIG`. If no valid value is found for arguments set the default params defined in `_default`. .. warning:: Strategy classes must be a subclass of AbstractMappingStrategy :param layer_name: name of the layer which initialize this class. This value is used to search the layer configuration in `CONFIG` :type layer_name: str :param strategy: strategy class (optional) :type strategy: :any:`AbstractMappingStrategy` :param threaded: run mapping algorithm in separate Python thread instead of in the coop microtask environment (optional) :type threaded: bool :return: None """ self._layer_name = layer_name # Set threaded self._threaded = threaded if threaded is not None else CONFIG.get_threaded( layer_name) # Set strategy if strategy is None: # Use the Strategy in CONFIG strategy = CONFIG.get_strategy(layer_name) if strategy is None and self.DEFAULT_STRATEGY is not None: # Use the default Strategy if it's set strategy = self.DEFAULT_STRATEGY if strategy is None: raise RuntimeError("Strategy class is not found!") self.strategy = strategy assert issubclass(strategy, AbstractMappingStrategy), "Mapping strategy is not " \ "subclass of " \ "AbstractMappingStrategy!" self.processor = CONFIG.get_mapping_processor(layer_name)(layer_name) super(AbstractMapper, self).__init__()
def initialize_on_demand(cls): """ Initialize the CallbackManager on demand. :return: initializer manager object :rtype: :class:`CallbackManager` """ global_cb_cfg = CONFIG.get_callback_config() callback_manager = cls(**global_cb_cfg) callback_manager.start() return callback_manager
def __init__(self, domain_name=None, path=None, diff=None, **kwargs): """ Init. :param path: file path offered as the domain topology :type path: str :return: None """ log.debug( "Init %s - type: %s, domain: %s, path: %s, diff: %s" % (self.__class__.__name__, self.type, domain_name, path, diff)) # Converter object self.converter = NFFGConverter( unique_bb_id=CONFIG.ensure_unique_bisbis_id(), unique_nf_id=CONFIG.ensure_unique_vnf_id(), domain=domain_name, logger=log) super(VirtualizerBasedStaticFileAdapter, self).__init__(domain_name=domain_name, path=path, **kwargs) self.diff = diff
def _handle_GetVirtResInfoEvent(self, event): """ Generate virtual resource info and send back to SAS. :param event: event object contains service layer id :type event: :any:`GetVirtResInfoEvent` :return: None """ self.log.debug("Received <Virtual View> request from %s layer" % str(event.source._core_name).title()) # Currently view is a Virtualizer to keep ESCAPE fast # Virtualizer type for Sl-Or API virtualizer_type = CONFIG.get_api_virtualizer(layer=event.sid) params = CONFIG.get_virtualizer_params(layer=event.sid) v = self.orchestrator.virtualizerManager.get_virtual_view( virtualizer_id=event.sid, type=virtualizer_type, **params) if v is None: self.log.error("Missing Virtualizer for id: %s!" % event.sid) return self.log.debug("Sending back <Virtual View>: %s..." % v) self.raiseEventNoErrors(VirtResInfoEvent, v)
def __init_from_CONFIG(self, format=DEFAULT_NFFG_FORMAT): """ Build a pre-defined topology from an NFFG stored in a file. The file path is searched in CONFIG with tha name ``TOPO``. :param format: NF-FG storing format (default: internal NFFG representation) :type format: str :return: None """ path = CONFIG.get_mininet_topology() if path is None: raise TopologyBuilderException("Missing Topology!") self.__init_from_file(path=path, format=format)
def register_component(self, component): component_name = component._core_name mgr_klass = CONFIG.get_rest_api_resource_class(layer=component_name) if mgr_klass is None: log.error("REST-API configuration is missing for component: %s" % component_name) return mgr = mgr_klass(layer_api=self) mgr.register_routes(app=self.__server.flask) self._register_entry_points(component=component) self.mgrs[mgr.LAYER_NAME] = mgr log.debug("Register component: %s into %s" % (component_name, self.__server))
def get_network(self): """ Return the bridge to the constructed network. :return: object representing the emulated network :rtype: :any:`ESCAPENetworkBridge` """ if self.mn_bridge is None: # Create the Interface object and set the topology description as the # original NFFG self.mn_bridge = ESCAPENetworkBridge(network=self.mn, topo_desc=self.topo_desc) # Additional settings self.mn_bridge._need_clean = CONFIG.get_clean_after_shutdown() return self.mn_bridge
def __init__(self, standalone=False, **kwargs): """ .. seealso:: :func:`AbstractAPI.__init__() <escape.util.api.AbstractAPI.__init__>` """ log.info("Starting Resource Orchestration Sublayer...") # Mandatory super() call self.orchestrator = None """:type: ResourceOrchestrator""" self.api_mgr = RESTAPIManager( unique_bb_id=False, unique_nf_id=CONFIG.ensure_unique_vnf_id(), logger=log) self.log = log.getChild('API') super(ResourceOrchestrationAPI, self).__init__(standalone, **kwargs)
def dispatch_request(self): """ :return: """ log.info("Received edit-config deploy request...") if not request.data: log.error("No data received!") return Response("Request data is missing!", httplib.BAD_REQUEST) # Get message-id unique = "ESCAPE-%s-edit-config" % self.mgr.LAYER_NAME # Trailing stats.init_request_measurement(request_id=unique) MessageDumper().dump_to_file(data=request.data, unique=unique) # Parsing log.debug("Parsing request (body_size: %s)..." % len(request.data)) if CONFIG.get_rest_api_config(self.mgr.LAYER_NAME)['unify_interface']: req = Virtualizer.parse_from_text(text=request.data) else: req = NFFG.parse(raw_data=request.data) if req.mode: log.info("Detected mapping mode in request body: %s" % req.mode) else: if request.method == 'POST': req.mode = req.MODE_ADD log.debug('Add mapping mode: %s based on HTTP verb: %s' % (req.mode, request.method)) elif request.method == 'PUT': req.mode = NFFG.MODE_DEL log.debug('Add mapping mode: %s based on HTTP verb: %s' % (req.mode, request.method)) else: log.info('No mode parameter has been defined in body!') log.debug("Request parsing ended...") # Scheduling params = request.args.to_dict(flat=True) msg_id = self.get_message_id() log.info("Acquired message-id: %s" % msg_id) params[self.MESSAGE_ID_NAME] = msg_id entry_point = self.mgr.layer_api.get_entry_point( layer=self.mgr.LAYER_NAME, rpc=self.name) self.mgr.scheduler.schedule_request(id=msg_id, layer=self.mgr.LAYER_NAME, hook=entry_point, data=req, params=params) return Response(status=httplib.ACCEPTED, headers={"message-id": msg_id})
def rest_api_get_config(self): """ Implementation of REST-API RPC: get-config. Return with the global resource as an :class:`NFFG` if it has been changed otherwise return with False. :return: global resource view (DoV) :rtype: :class:`NFFG` or False """ self.log.debug("Requesting Virtualizer for %s" % self._core_name) slor_virt = self.__get_slor_resource_view() if slor_virt is not None: # Check the topology is initialized if slor_virt.revision is None: self.log.debug("DoV has not initialized yet! " "Force to get default topology...") else: # Check if the resource is changed if self.api_mgr.topology_revision == slor_virt.revision: # If resource has not been changed return False # This causes to response with the cached topology self.log.debug( "Global resource has not changed (revision: %s)! " % slor_virt.revision) log.debug("Send topology from cache...") if self.api_mgr.last_response is None: log.error("Cached topology is missing!") return else: return self.api_mgr.last_response else: self.log.debug( "Response cache is outdated (new revision: %s)!" % slor_virt.revision) # Get topo view as NFFG res = slor_virt.get_resource_info() self.api_mgr.topology_revision = slor_virt.revision self.log.debug("Updated revision number: %s" % self.api_mgr.topology_revision) if CONFIG.get_rest_api_config(self._core_name)['unify_interface']: self.log.info("Convert internal NFFG to Virtualizer...") res = self.api_mgr.converter.dump_to_Virtualizer(nffg=res) log.debug("Cache acquired topology...") self.api_mgr.last_response = res return res else: log.error("Virtualizer assigned to %s is not found!" % self._core_name)