Esempio n. 1
0
  def __proceed_installation (self, mapped_nffg, original_request=None):
    """
    Helper function to instantiate the NFFG mapping from different source.

    :param mapped_nffg: pre-mapped service request
    :type mapped_nffg: :class:`NFFG`
    :return: None
    """
    log.getChild('API').info("Invoke install_nffg on %s with NF-FG: %s " % (
      self.__class__.__name__, mapped_nffg))
    stats.add_measurement_start_entry(type=stats.TYPE_DEPLOY,
                                      info=LAYER_NAME)
    try:
      deploy_status = self.controller_adapter.install_nffg(mapped_nffg,
                                                           original_request)
    except Exception:
      log.error("Something went wrong during NFFG installation!")
      self.raiseEventNoErrors(InstallationFinishedEvent,
                              result=InstallationFinishedEvent.DEPLOY_ERROR)
      raise
    log.getChild('API').debug("Invoked install_nffg on %s is finished!" %
                              self.__class__.__name__)
    if not deploy_status.still_pending:
      id = mapped_nffg.id
      result = InstallationFinishedEvent.get_result_from_status(deploy_status)
      log.info("Overall installation result: %s" % result)
      self.raiseEventNoErrors(InstallationFinishedEvent, id=id, result=result)
Esempio n. 2
0
  def install_nffg (self, nffg_part):
    """
    Install :class:`NFFG` part into the domain using the specific REST-API
    function and Virtualizer format.

    :param nffg_part: domain related part of the mapped :class:`NFFG`
    :type nffg_part: :class:`NFFG`
    :return: status if the installation was success
    :rtype: bool
    """
    # if nffg_part.is_bare():
    #   self.log.info(">>> Splitted part is a bare NFFG! Skip domain deploy...")
    #   return True
    self.log.info(">>> Install %s domain part..." % self.domain_name)
    try:
      log.debug("Request and store the most recent domain topology....")
      topo = self.topoAdapter.get_config()
      if topo:
        self.__last_success_state = topo
        log.log(VERBOSE,
                "Last successful state:\n%s" % self.__last_success_state.xml())
      request_params = {"diff": self._diff,
                        "message_id": "edit-config-%s" % nffg_part.id}
      cb = None
      if self.callback_manager is not None:
        cb_url = self.callback_manager.get_url(domain=self.domain_name)
        log.debug("Set callback URL: %s" % cb_url)
        request_params["callback"] = cb_url
        cb = self._setup_callback(hook=self.edit_config_hook,
                                  req_id=nffg_part.id,
                                  msg_id=request_params.get('message_id'),
                                  type=self.CALLBACK_TYPE_INSTALL,
                                  data=nffg_part)
      response = self.topoAdapter.edit_config(nffg_part, **request_params)
      stats.add_measurement_start_entry(type=stats.TYPE_DEPLOY_REQUEST,
                                        info="%s-%s"
                                             % (self.domain_name,
                                                "with_callback" if
                                                self.callback_manager else
                                                "no_callback"))
      if not self.callback_manager:
        stats.add_measurement_end_entry(type=stats.TYPE_DEPLOY_REQUEST,
                                        info="%s-no_callback" %
                                             self.domain_name)
      else:
        stats.add_measurement_end_entry(type=stats.TYPE_DEPLOY_REQUEST,
                                        info="%s-with_callback" %
                                             self.domain_name)
      if self.callback_manager and cb:
        if response is None or response == 0:
          log.debug("Unsubscribe callback of unsuccessful request!")
          self.callback_manager.unsubscribe_callback(cb_id=cb.callback_id,
                                                     domain=self.domain_name)
          return response
      return response is not None
    except:
      self.log.exception("Got exception during NFFG installation into: %s." %
                         self.domain_name)
      return False
Esempio n. 3
0
    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__)
Esempio n. 4
0
    def invoke_hook(self, msg_id, domain, result, body=None):
        """
    Main entry point to invoke a callback based on the extracted data from
    received message.

    :param msg_id: message id
    :type msg_id: str
    :param domain: domain name
    :type domain: str
    :param result: result of the callback
    :type result: str
    :param body: parsed callback body (optional)
    :type body: str or None
    :return: None
    """
        try:
            result = int(result)
        except ValueError:
            log.error(
                "Received response code is not valid: %s! Abort callback..." %
                result)
            return
        if (domain, msg_id) not in self.__register:
            log.warning(
                "Received unregistered callback with id: %s from domain: %s" %
                (msg_id, domain))
            return
        log.debug(
            "Received valid callback with id: %s, result: %s from domain: %s" %
            (msg_id, "TIMEOUT" if not result else result, domain))
        cb = self.__register.get((domain, msg_id))
        if cb is None:
            log.error("Missing callback: %s from register!" % msg_id)
            return
        stats.add_measurement_start_entry(type=stats.TYPE_DEPLOY_CALLBACK,
                                          info="%s-callback_received" % domain)
        cb.result_code = result
        cb.body = body
        if cb.hook is None:
            log.debug("No hook was defined!")
            self.__blocking_mutex.set()
            return
        elif callable(cb.hook):
            log.debug("Schedule callback hook: %s" % cb.short())
            cb.hook(callback=cb)
        else:
            log.warning(
                "No callable hook was defined for the received callback: %s!" %
                msg_id)
Esempio n. 5
0
    def __proceed_installation(self,
                               mapped_nffg,
                               original_request=None,
                               direct_deploy=False):
        """
    Helper function to instantiate the NFFG mapping from different source.

    :param mapped_nffg: pre-mapped service request
    :type mapped_nffg: :class:`NFFG`
    :return: None
    """
        log.getChild('API').info("Invoke install_nffg on %s with NF-FG: %s " %
                                 (self.__class__.__name__, mapped_nffg))
        stats.add_measurement_start_entry(type=stats.TYPE_DEPLOY,
                                          info=LAYER_NAME)
        try:
            deploy_status = self.controller_adapter.install_nffg(
                mapped_nffg=mapped_nffg,
                original_request=original_request,
                direct_deploy=direct_deploy)
        except Exception as e:
            log.error("Something went wrong during NFFG installation: %s" % e)
            self._process_mapping_result(nffg_id=mapped_nffg.id, fail=True)
            self.raiseEventNoErrors(
                InstallationFinishedEvent,
                id=mapped_nffg.id,
                result=InstallationFinishedEvent.DEPLOY_ERROR)
            return
        log.getChild('API').debug("Invoked install_nffg on %s is finished!" %
                                  self.__class__.__name__)
        if deploy_status is None:
            log.error("Deploy status is missing!")
            self._process_mapping_result(nffg_id=mapped_nffg.id, fail=True)
            self.raiseEventNoErrors(
                InstallationFinishedEvent,
                id=mapped_nffg.id,
                result=InstallationFinishedEvent.DEPLOY_ERROR)
        elif not deploy_status.still_pending:
            result = InstallationFinishedEvent.get_result_from_status(
                deploy_status)
            log.info("Overall installation result: %s" % result)
            is_fail = InstallationFinishedEvent.is_error(result)
            self._process_mapping_result(nffg_id=mapped_nffg.id, fail=is_fail)
            self.raiseEventNoErrors(InstallationFinishedEvent,
                                    id=mapped_nffg.id,
                                    result=result)
        elif deploy_status.standby:
            if self._dovapi:
                RequestScheduler().set_orchestration_standby()
Esempio n. 6
0
    def _proceed_API_call(self, request):
        """
    Fail-safe method to call API function.
    The cooperative micro-task context is handled by actual APIs.
    Should call this with params, not directly the function of actual API.

    :param request: scheduled request container object
    :type request: APIRequest
    :return: None
    """
        self.log.info("Start request processing in coop-task: %s" % request)
        stats.add_measurement_start_entry(stats.TYPE_SCHEDULED, request.id)
        if callable(request.hook):
            return request.hook(id=request.id,
                                data=request.data,
                                **request.kwargs)
        else:
            raise RESTError(
                msg='Error: No component has registered with name: %s, '
                'ABORT function call!' % request.layer)
Esempio n. 7
0
    def call_mapping_algorithm(cls,
                               request,
                               topology,
                               profiling=False,
                               stats_type=stats.TYPE_ORCHESTRATION_MAPPING,
                               stat_level=None,
                               **params):
        """
    Template function to call the main algorithm.
    Provide an easy way to change the algorithm easily in child classes.

    Contains profiling to measure basic performance of the algorithm.

    :param request: request graph
    :type request: :class:`NFFG`
    :param topology: topology graph
    :type topology: :class:`NFFG`
    :param profiling: enables cProfile for mapping which bring big overhead
    :type profiling: bool
    :param stats_type: use explicit identifier for statistic
    :type stats_type: int
    :param stat_level: use explicit level for statistic
    :type stat_level: str
    :param params: additional mapping parameters
    :type params: dict
    :return: mapping result
    :rtype: :class:`NFFG`
    """
        log.debug("Call mapping algorithm with parameters:\n%s" %
                  pprint.pformat(params))
        stat_level = stat_level if stat_level else cls.__name__
        stats.add_measurement_start_entry(type=stats_type, info=stat_level)
        try:
            if profiling:
                ret = cls.cprofiler_decorator(MAP, request, topology, **params)
            else:
                ret = cls.timer_decorator(MAP, request, topology, **params)
        finally:
            stats.add_measurement_end_entry(type=stats_type, info=stat_level)
        return ret
Esempio n. 8
0
    def _proceed_API_call(self, request):
        """
    Fail-safe method to call API function.
    The cooperative micro-task context is handled by actual APIs.
    Should call this with params, not directly the function of actual API.

    :param request: scheduled request container object
    :type request: APIRequest
    :return: None
    """
        self.log.info("Start request processing in coop-task: %s" % request)
        stats.add_measurement_start_entry(stats.TYPE_SCHEDULED, request.id)
        if core.core.hasComponent(request.layer):
            layer = core.components[request.layer]
            if hasattr(layer, request.function):
                return getattr(layer, request.function)(**request.kwargs)
            else:
                raise RESTError(
                    msg='Mistyped or not implemented API function call: %s ' %
                    request.function)
        else:
            raise RESTError(
                msg='Error: No component has registered with name: %s, '
                'ABORT function call!' % request.layer)
Esempio n. 9
0
    def edit_config(self,
                    data,
                    diff=False,
                    message_id=None,
                    callback=None,
                    full_conversion=False):
        """
    Send the requested configuration with a netconf-like "edit-config" command.

    Remote domains always expect diff of mapping changes.

    :param data: whole domain view
    :type data: :class:`NFFG`
    :param diff: send the diff of the mapping request (default: False)
    :param diff: bool
    :param message_id: optional message id
    :type message_id: str
    :param callback: callback URL
    :type callback: str
    :param full_conversion: do full conversion instead of adapt (default: False)
    :type full_conversion: bool
    :return: response data / empty str if request was successful else None
    :rtype: str
    """
        log.debug("Prepare edit-config request for remote agent at: %s" %
                  self._base_url)
        if isinstance(data, Virtualizer):
            # Nothing to do
            vdata = data
        elif isinstance(data, NFFG):
            log.debug("Convert NFFG to XML/Virtualizer format...")
            if self.last_virtualizer is None:
                log.debug("Missing last received Virtualizer! "
                          "Updating last topology view now...")
                self.get_config()
                if self.last_virtualizer is None:
                    return False
            stats.add_measurement_start_entry(type=stats.TYPE_CONVERSION,
                                              info="%s-deploy" %
                                              self.domain_name)
            if full_conversion:
                vdata = self.converter.dump_to_Virtualizer(nffg=data)
            else:
                vdata = self.converter.adapt_mapping_into_Virtualizer(
                    virtualizer=self.last_virtualizer,
                    nffg=data,
                    reinstall=diff)
            stats.add_measurement_end_entry(type=stats.TYPE_CONVERSION,
                                            info="%s-deploy" %
                                            self.domain_name)
            log.log(VERBOSE, "Adapted Virtualizer:\n%s" % vdata.xml())
        else:
            raise RuntimeError(
                "Not supported config format: %s for 'edit-config'!" %
                type(data))
        self.__cache_request(data=vdata)
        if diff:
            log.debug(
                "DIFF is enabled. Calculating difference of mapping changes..."
            )
            stats.add_measurement_start_entry(type=stats.TYPE_PROCESSING,
                                              info="%s-DIFF" %
                                              self.domain_name)
            vdata = self.__calculate_diff(vdata)
            stats.add_measurement_end_entry(type=stats.TYPE_PROCESSING,
                                            info="%s-DIFF" % self.domain_name)
        else:
            log.debug("Using given Virtualizer as full mapping request")
        plain_data = vdata.xml()
        log.log(VERBOSE, "Generated Virtualizer:\n%s" % plain_data)
        if is_empty(virtualizer=vdata):
            log.info("Generated edit-config request is empty! Skip sending...")
            return self.SKIPPED_REQUEST
        log.debug("Send request to %s domain agent at %s..." %
                  (self.domain_name, self._base_url))
        params = {}
        if message_id is not None:
            params[self.MESSAGE_ID_NAME] = message_id
            log.debug("Using explicit message-id: %s" % message_id)
        if callback is not None:
            params[self.CALLBACK_NAME] = callback
            log.debug("Using explicit callback: %s" % callback)
        MessageDumper().dump_to_file(data=plain_data,
                                     unique="%s-edit-config" %
                                     self.domain_name)
        try:
            response = self.send_with_timeout(method=self.POST,
                                              url='edit-config',
                                              body=plain_data,
                                              params=params)
        except Timeout:
            log.warning(
                "Reached timeout(%ss) while waiting for 'edit-config' response!"
                " Ignore exception..." % self.CONNECTION_TIMEOUT)
            # Ignore exception - assume the request was successful -> return True
            return True
        if response is not None:
            log.debug("Deploy request has been sent successfully!")
        return response
Esempio n. 10
0
    def __proceed_instantiation(self, nffg, resource_nffg):
        """
    Helper function to instantiate the NFFG mapping from different source.

    :param nffg: pre-mapped service request
    :type nffg: :class:`NFFG`
    :return: None
    """
        self.log.info("Invoke instantiation on %s with NF-FG: %s" %
                      (self.__class__.__name__, nffg.name))
        stats.add_measurement_start_entry(type=stats.TYPE_ORCHESTRATION,
                                          info=LAYER_NAME)
        # Get shown topology view
        if resource_nffg is None:
            log.error("Missing resource for difference calculation!")
            return
        log.debug("Got resource view for difference calculation: %s" %
                  resource_nffg)
        self.log.debug("Store received NFFG request info...")
        msg_id = self.api_mgr.request_cache.cache_request_by_nffg(nffg=nffg)
        if msg_id is not None:
            self.api_mgr.request_cache.set_in_progress(id=msg_id)
            self.log.debug("Request is stored with id: %s" % msg_id)
        else:
            self.log.debug("No request info detected.")
        # Check if mapping mode is set globally in CONFIG
        mapper_params = CONFIG.get_mapping_config(layer=LAYER_NAME)
        if 'mode' in mapper_params and mapper_params['mode'] is not None:
            mapping_mode = mapper_params['mode']
            log.info("Detected mapping mode from configuration: %s" %
                     mapping_mode)
        elif nffg.mode is not None:
            mapping_mode = nffg.mode
            log.info("Detected mapping mode from NFFG: %s" % mapping_mode)
        else:
            mapping_mode = None
            log.info("No mapping mode was defined explicitly!")
        if not CONFIG.get_mapping_enabled(layer=LAYER_NAME):
            log.warning("Mapping is disabled! Skip difference calculation...")
        elif nffg.status == NFFG.MAP_STATUS_SKIPPED:
            log.debug("Detected NFFG map status: %s! "
                      "Skip difference calculation and "
                      "proceed with original request..." % nffg.status)
        elif mapping_mode != NFFG.MODE_REMAP:
            # Calculated ADD-DELETE difference
            log.debug("Calculate ADD - DELETE difference with mapping mode...")
            # Recreate SG-hops for diff calc.
            log.debug("Recreate SG hops for difference calculation...")
            NFFGToolBox.recreate_all_sghops(nffg=nffg)
            NFFGToolBox.recreate_all_sghops(nffg=resource_nffg)
            log.log(VERBOSE, "New NFFG:\n%s" % nffg.dump())
            log.log(VERBOSE, "Resource NFFG:\n%s" % resource_nffg.dump())
            # Calculate difference
            add_nffg, del_nffg = NFFGToolBox.generate_difference_of_nffgs(
                old=resource_nffg, new=nffg, ignore_infras=True)
            log.log(VERBOSE, "Calculated ADD NFFG:\n%s" % add_nffg.dump())
            log.log(VERBOSE, "Calculated DEL NFFG:\n%s" % del_nffg.dump())
            if not add_nffg.is_bare() and del_nffg.is_bare():
                nffg = add_nffg
                log.info("DEL NFFG is bare! Calculated mapping mode: %s" %
                         nffg.mode)
            elif add_nffg.is_bare() and not del_nffg.is_bare():
                nffg = del_nffg
                log.info("ADD NFFG is bare! Calculated mapping mode: %s" %
                         nffg.mode)
            elif not add_nffg.is_bare() and not del_nffg.is_bare():
                log.warning("Both ADD / DEL mode is not supported currently")
                self.__process_mapping_result(nffg_id=nffg.id, fail=True)
                stats.add_measurement_end_entry(type=stats.TYPE_ORCHESTRATION,
                                                info=LAYER_NAME + "-FAILED")
                self.raiseEventNoErrors(
                    InstantiationFinishedEvent,
                    id=nffg.id,
                    result=InstantiationFinishedEvent.ABORTED)
                return
            else:
                log.debug("Difference calculation resulted empty subNFFGs!")
                log.warning(
                    "No change has been detected in request! Skip mapping...")
                self.log.debug("Invoked instantiation on %s is finished!" %
                               self.__class__.__name__)
                self.__process_mapping_result(nffg_id=nffg.id, fail=False)
                stats.add_measurement_end_entry(type=stats.TYPE_ORCHESTRATION,
                                                info=LAYER_NAME + "-SKIPPED")
                return
        else:
            log.debug(
                "Mode: %s detected from config! Skip difference calculation..."
                % mapping_mode)
        try:
            if CONFIG.get_mapping_enabled(layer=LAYER_NAME):
                # Initiate request mapping
                mapped_nffg = self.orchestrator.instantiate_nffg(nffg=nffg)
            else:
                log.warning("Mapping is disabled! Skip instantiation step...")
                mapped_nffg = nffg
                mapped_nffg.status = NFFG.MAP_STATUS_SKIPPED
                log.debug("Mark NFFG status: %s!" % mapped_nffg.status)
            # Rewrite REMAP mode for backward compatibility
            if mapped_nffg is not None and mapping_mode == NFFG.MODE_REMAP:
                mapped_nffg.mode = mapping_mode
                log.debug("Rewrite mapping mode: %s into mapped NFFG..." %
                          mapped_nffg.mode)
            else:
                log.debug("Skip mapping mode rewriting! Mode remained: %s" %
                          mapping_mode)
                self.log.debug("Invoked instantiate_nffg on %s is finished!" %
                               self.__class__.__name__)
            # If mapping is not threaded and finished with OK
            if mapped_nffg is not None and not self.orchestrator.mapper.threaded:
                self._proceed_to_install_NFFG(mapped_nffg=mapped_nffg,
                                              original_request=nffg)
            else:
                log.warning(
                    "Something went wrong in service request instantiation: "
                    "mapped service request is missing!")
                self.__process_mapping_result(nffg_id=nffg.id, fail=True)
                stats.add_measurement_end_entry(type=stats.TYPE_ORCHESTRATION,
                                                info=LAYER_NAME + "-FAILED")
                self.raiseEventNoErrors(
                    InstantiationFinishedEvent,
                    id=nffg.id,
                    result=InstantiationFinishedEvent.MAPPING_ERROR)
        except ProcessorError as e:
            self.__process_mapping_result(nffg_id=nffg.id, fail=True)
            stats.add_measurement_end_entry(type=stats.TYPE_ORCHESTRATION,
                                            info=LAYER_NAME + "-DENIED")
            self.raiseEventNoErrors(
                InstantiationFinishedEvent,
                id=nffg.id,
                result=InstantiationFinishedEvent.REFUSED_BY_VERIFICATION,
                error=e)
Esempio n. 11
0
    def __proceed_sg_request(self, id, data, params=None):
        """
    Initiate a Service Graph (UNIFY U-Sl API).

    :return: None
    """
        log.info("Invoke preprocessing on %s with SG: %s " %
                 (self.__class__.__name__, id))
        stats.add_measurement_start_entry(type=stats.TYPE_SERVICE,
                                          info=LAYER_NAME)
        if CONFIG.get_rest_api_config(self._core_name)['unify_interface']:
            log.debug("Virtualizer format enabled! Start conversion step...")
            if CONFIG.get_rest_api_config(self._core_name)['diff']:
                log.debug("Diff format enabled! Start patching step...")
                if self.api_mgr.last_response is None:
                    log.info(
                        "Missing cached Virtualizer! Acquiring topology now..."
                    )
                    self.rest_api_topology()
                stats.add_measurement_start_entry(type=stats.TYPE_PROCESSING,
                                                  info="RECREATE-FULL-REQUEST")
                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
            log.info("Converting full request data...")
            stats.add_measurement_start_entry(type=stats.TYPE_CONVERSION,
                                              info="VIRTUALIZER-->NFFG")
            service_nffg = self.api_mgr.converter.parse_from_Virtualizer(
                vdata=full_req)
            stats.add_measurement_end_entry(type=stats.TYPE_CONVERSION,
                                            info="VIRTUALIZER-->NFFG")
        else:
            service_nffg = data
        log.debug("Set NFFG id: %s" % id)
        if service_nffg.service_id is None:
            service_nffg.service_id = service_nffg.id
        service_nffg.id = id
        service_nffg.add_metadata(name="params", value=params)
        # Check if mapping mode is set globally in CONFIG
        mapper_params = CONFIG.get_mapping_config(layer=LAYER_NAME)
        if 'mode' in mapper_params and mapper_params['mode'] is not None:
            mapping_mode = mapper_params['mode']
            log.info("Detected mapping mode from configuration: %s" %
                     mapping_mode)
        elif service_nffg.mode is not None:
            mapping_mode = service_nffg.mode
            log.info("Detected mapping mode from NFFG: %s" % mapping_mode)
        else:
            mapping_mode = None
            log.info("No mapping mode was detected!")
        self.__sg_preprocessing(nffg=service_nffg)
        # Store request if it is received on REST-API
        log.getChild('API').debug("Store received NFFG request info...")
        msg_id = self.api_mgr.request_cache.cache_request_by_nffg(
            nffg=service_nffg)
        if msg_id is not None:
            self.api_mgr.request_cache.set_in_progress(id=msg_id)
            log.getChild('API').debug("Request is stored with id: %s" % msg_id)
        else:
            log.getChild('API').debug("No request info detected.")
        try:
            if CONFIG.get_mapping_enabled(layer=LAYER_NAME):
                # Initiate service request mapping
                mapped_nffg = self.service_orchestrator.initiate_service_graph(
                    service_nffg)
            else:
                log.warning("Mapping is disabled! Skip instantiation step...")
                mapped_nffg = service_nffg
                mapped_nffg.status = NFFG.MAP_STATUS_SKIPPED
                log.debug("Mark NFFG status: %s!" % mapped_nffg.status)
            # Rewrite REMAP mode for backward compatibility
            if mapped_nffg is not None and mapping_mode == NFFG.MODE_REMAP:
                mapped_nffg.mode = mapping_mode
                log.debug("Rewrite mapping mode: %s into mapped NFFG..." %
                          mapped_nffg.mode)
            else:
                log.debug("Skip mapping mode rewriting! Mode remained: %s" %
                          mapping_mode)
            log.getChild('API').debug(
                "Invoked request_service on %s is finished" %
                self.__class__.__name__)
            # If mapping is not threaded and finished with OK
            if mapped_nffg is not None and not \
               self.service_orchestrator.mapper.threaded:
                self._proceed_to_instantiate_NFFG(mapped_nffg)
                self.last_sg = mapped_nffg
            else:
                log.warning(
                    "Something went wrong in service request initiation: "
                    "mapped service data is missing!")
                self.__handle_mapping_result(nffg_id=service_nffg.id,
                                             fail=True)
                stats.add_measurement_end_entry(type=stats.TYPE_SERVICE,
                                                info=LAYER_NAME + "-FAILED")
                self._handle_InstantiationFinishedEvent(
                    event=InstantiationFinishedEvent(
                        id=service_nffg.id,
                        result=InstantiationFinishedEvent.MAPPING_ERROR))
        except ProcessorError as e:
            self.__handle_mapping_result(nffg_id=service_nffg.id, fail=True)
            stats.add_measurement_end_entry(type=stats.TYPE_SERVICE,
                                            info=LAYER_NAME + "-DENIED")
            self._handle_InstantiationFinishedEvent(
                event=InstantiationFinishedEvent(
                    id=service_nffg.id,
                    result=InstantiationFinishedEvent.REFUSED_BY_VERIFICATION,
                    error=e))
Esempio n. 12
0
    def __proceed_sg_request(self, service_nffg):
        """
    Initiate a Service Graph (UNIFY U-Sl API).

    :param service_nffg: service graph instance
    :type service_nffg: :class:`NFFG`
    :return: None
    """
        log.getChild('API').info("Invoke request_service on %s with SG: %s " %
                                 (self.__class__.__name__, service_nffg))
        stats.add_measurement_start_entry(type=stats.TYPE_SERVICE,
                                          info=LAYER_NAME)
        # Check if mapping mode is set globally in CONFIG
        mapper_params = CONFIG.get_mapping_config(layer=LAYER_NAME)
        if 'mode' in mapper_params and mapper_params['mode'] is not None:
            mapping_mode = mapper_params['mode']
            log.info("Detected mapping mode from configuration: %s" %
                     mapping_mode)
        elif service_nffg.mode is not None:
            mapping_mode = service_nffg.mode
            log.info("Detected mapping mode from NFFG: %s" % mapping_mode)
        else:
            mapping_mode = None
            log.info("No mapping mode was detected!")
        self.__sg_preprocessing(nffg=service_nffg)
        # Store request if it is received on REST-API
        if hasattr(self, 'rest_api') and self.rest_api:
            log.getChild('API').debug("Store received NFFG request info...")
            msg_id = self.rest_api.request_cache.cache_request_by_nffg(
                nffg=service_nffg)
            if msg_id is not None:
                self.rest_api.request_cache.set_in_progress(id=msg_id)
                log.getChild('API').debug("Request is stored with id: %s" %
                                          msg_id)
            else:
                log.getChild('API').debug("No request info detected.")
        try:
            # Initiate service request mapping
            mapped_nffg = self.service_orchestrator.initiate_service_graph(
                service_nffg)
            # Rewrite REMAP mode for backward compatibility
            if mapped_nffg is not None and mapping_mode == NFFG.MODE_REMAP:
                mapped_nffg.mode = mapping_mode
                log.debug("Rewrite mapping mode: %s into mapped NFFG..." %
                          mapped_nffg.mode)
            else:
                log.debug("Skip mapping mode rewriting! Mode remained: %s" %
                          mapping_mode)
            log.getChild('API').debug(
                "Invoked request_service on %s is finished" %
                self.__class__.__name__)
            # If mapping is not threaded and finished with OK
            if mapped_nffg is not None and not \
               self.service_orchestrator.mapper.threaded:
                self._proceed_to_instantiate_NFFG(mapped_nffg)
                self.last_sg = mapped_nffg
            else:
                log.warning(
                    "Something went wrong in service request initiation: "
                    "mapped service data is missing!")
                self.__handle_mapping_result(nffg_id=service_nffg.id,
                                             fail=True)
                self._handle_InstantiationFinishedEvent(
                    event=InstantiationFinishedEvent(
                        id=service_nffg.id,
                        result=InstantiationFinishedEvent.MAPPING_ERROR))
        except ProcessorError as e:
            self.__handle_mapping_result(nffg_id=service_nffg.id, fail=True)
            self._handle_InstantiationFinishedEvent(
                event=InstantiationFinishedEvent(
                    id=service_nffg.id,
                    result=InstantiationFinishedEvent.REFUSED_BY_VERIFICATION,
                    error=e))
Esempio n. 13
0
    def rest_api_edit_config(self, id, data, params=None):
        """
    Implement edit-config call for CAS layer. Receive edit-config request from
    external component and directly forward data for deployment.

    :param params: request params
    :type params: dict
    :return: None
    """
        log.getChild('[DOV-API]').info(
            "Invoke instantiation on %s with NF-FG: "
            "%s " % (self.__class__.__name__, id))
        if CONFIG.get_rest_api_config(self._core_name)['unify_interface']:
            log.debug("Virtualizer format enabled! Start conversion step...")
            if CONFIG.get_rest_api_config(self._core_name)['diff']:
                log.debug("Diff format enabled! Start patching step...")
                if self.api_mgr.last_response is None:
                    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")
                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
            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
        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)
        log.info("Proceeding request: %s to instantiation..." % id)
        if CONFIG.get_vnfm_enabled():
            deploy_status = self.controller_adapter.status_mgr.get_last_status(
            )
            if deploy_status is None:
                log.warning(
                    "Received direct DoV rewrite request from external "
                    "component without any preliminary deploy request!")
            else:
                if deploy_status.id != nffg.id:
                    log.error(
                        "Received direct deploy request id: %s is different from "
                        "service request under deploy: %s" %
                        (nffg.id, deploy_status.id))
                    return
                else:
                    self.controller_adapter.cancel_vnfm_timer()
        log.getChild('API').debug("Store received DoV request...")
        msg_id = self.api_mgr.request_cache.cache_request_by_nffg(nffg=nffg)
        if msg_id is not None:
            self.api_mgr.request_cache.set_in_progress(id=msg_id)
            log.getChild('API').debug("Request is stored with id: %s" % msg_id)
        else:
            log.getChild('API').warning("No request info detected.")
        self.__proceed_installation(mapped_nffg=nffg, direct_deploy=True)