Exemple #1
0
 def initialize(self):
     """
 .. seealso::
   :func:`AbstractAPI.initialize() <escape.util.api.AbstractAPI.initialize>`
 """
     log.debug("Initializing Resource Orchestration Sublayer...")
     self.orchestrator = ResourceOrchestrator(self)
     if self._nffg_file:
         try:
             service_request = self._read_data_from_file(self._nffg_file)
             service_request = NFFG.parse(service_request)
             dov = self.orchestrator.virtualizerManager.dov
             self.__proceed_instantiation(
                 nffg=service_request,
                 resource_view=dov.get_resource_info())
         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:
             log.info("Graph representation is loaded successfully!")
     # Initiate ROS REST-API if needed
     if self._agent or self._rosapi:
         self._initiate_ros_api()
     log.info("Resource Orchestration Sublayer has been initialized!")
     if self._agent:
         log.warning(
             "In AGENT mode Service Layer is not going to be initialized!")
Exemple #2
0
  def build (self, topo=None):
    """
    Initialize network.

    1. If the additional ``topology`` is given then using that for init.
    2. If TOPO is not given, search topology description in CONFIG with the \
    name 'TOPO'.
    3. If TOPO not found or an Exception was raised, search for the fallback \
    topo with the name ``FALLBACK-TOPO``.
    4. If FALLBACK-TOPO not found raise an exception or run a bare Mininet \
    object if the run_dry attribute is set


    :param topo: optional topology representation
    :type topo: :any:`NFFG` or :any:`AbstractTopology` or ``None``
    :return: object representing the emulated network
    :rtype: :any:`ESCAPENetworkBridge`
    """
    log.debug("Init emulated topology based on Mininet v%s" % MNVERSION)
    # Load topology
    try:
      if topo is None:
        log.info("Get Topology description from CONFIG...")
        self.__init_from_CONFIG()
      elif isinstance(topo, NFFG):
        log.info("Get Topology description from given NFFG...")
        self.__init_from_NFFG(nffg=topo)
      elif isinstance(topo, basestring) and topo.startswith('/'):
        log.info("Get Topology description from given file...")
        self.__init_from_file(path=topo)
      elif isinstance(topo, AbstractTopology):
        log.info("Get Topology description based on Topology class...")
        self.__init_from_AbstractTopology(topo_class=topo)
      else:
        raise TopologyBuilderException(
          "Unsupported topology format: %s - %s" % (type(topo), topo))
      return self.get_network()
    except SystemExit as e:
      quit_with_error(msg="Mininet exited unexpectedly!", logger=log,
                      exception=e)
    except TopologyBuilderException:
      if self.fallback:
        # Search for fallback topology
        fallback = CONFIG.get_fallback_topology()
        if fallback:
          log.info("Load topo from fallback topology description...")
          self.__init_from_AbstractTopology(fallback)
          return self.get_network()
      # fallback topo is not found or set
      if self.run_dry:
        # Return with the bare Mininet object
        log.warning("Topology description is not found! Running dry...")
        return self.get_network()
      else:
        # Re-raise the exception
        raise
    except KeyboardInterrupt:
      quit_with_error(
        msg="Assembly of Mininet network was interrupted by user!",
        logger=log)
Exemple #3
0
    def start_network(self):
        """
    Start network.

    :return: None
    """
        log.debug("Starting Mininet network...")
        if self.__mininet is not None:
            if not self.started:
                try:
                    self.__mininet.start()
                except SystemExit:
                    quit_with_error(
                        msg="Mininet emulation requires root privileges!",
                        logger=LAYER_NAME)
                except KeyboardInterrupt:
                    quit_with_error(
                        msg=
                        "Initiation of Mininet network was interrupted by user!",
                        logger=log)
                self.started = True
                log.debug("Mininet network has been started!")
                self.runXTerms()
            else:
                log.warning(
                    "Mininet network has already started! Skipping start task..."
                )
        else:
            log.error("Missing topology! Skipping emulation...")
Exemple #4
0
    def __init__(self, layer_API, with_infr=False):
        """
    Initialize Controller adapter.

    For domain components the ControllerAdapter checks the CONFIG first.

    :param layer_API: layer API instance
    :type layer_API: :any:`ControllerAdaptationAPI`
    :param with_infr: using emulated infrastructure (default: False)
    :type with_infr: bool
    """
        log.debug("Init ControllerAdapter - with IL: %s" % with_infr)
        super(ControllerAdapter, self).__init__()
        # Set a weak reference to avoid circular dependencies
        self._layer_API = weakref.proxy(layer_API)
        self._with_infr = with_infr
        # Set virtualizer-related components
        self.DoVManager = GlobalResourceManager()
        self.domains = ComponentConfigurator(self)
        try:
            if with_infr:
                # Init internal domain manager if Infrastructure Layer is started
                self.domains.load_local_domain_mgr()
            # Init default domain managers
            self.domains.load_default_mgrs()
        except (ImportError, AttributeError, ConfigurationError) as e:
            from escape.util.misc import quit_with_error
            quit_with_error(
                msg="Shutting down ESCAPEv2 due to an unexpected error!",
                logger=log,
                exception=e)
        # Here every domainManager is up and running
        # Notify the remote visualizer about collected data if it's needed
        notify_remote_visualizer(data=self.DoVManager.dov.get_resource_info(),
                                 id=LAYER_NAME)
Exemple #5
0
 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!")
Exemple #6
0
    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)
Exemple #7
0
 def __init__ (self):
   """
   Init.
   """
   super(NFIBManager, self).__init__()
   log.debug("Init %s based on neo4j" % self.__class__.__name__)
   # Suppress low level logging
   self.__suppress_neo4j_logging()
   try:
     self.graph_db = Graph()
   except Unauthorized as e:
     quit_with_error(
       "Got Unauthorozed error on: %s from neo4j! Disable the authorization "
       "in /etc/neo4j/neoj4-server.properties!" % e)
Exemple #8
0
  def _load_cfg_file (path):
    """
    Load external configuration from file. Support JSON and YAML format.

    :param path: file path
    :type path: str
    :return: loaded configuration
    :rtype: dict
    """
    try:
      with open(path) as f:
        return yaml.safe_load(f)
    except IOError:
      quit_with_error('Default config file: %s is not found!' % path)
    except (yaml.YAMLError, Exception) as e:
      quit_with_error("An error occurred when load configuration: %s" % e)
Exemple #9
0
def launch(standalone=False, topo=None):
    """
  Launch function called by POX core when core is up.

  :param standalone: Run layer without dependency checking (optional)
  :type standalone: bool
  :param topo: Load the topology description from file (optional)
  :type topo: str
  :return: None
  """
    global init_param
    init_param.update(locals())
    if os.geteuid() != 0:
        quit_with_error(msg="Mininet emulation requires root privileges!",
                        logger=InfrastructureLayerAPI._core_name)
    # Load additional params into CONFIG if necessary
    core.addListenerByName("UpEvent", _start_layer)
Exemple #10
0
    def __init__(self, net=None, opts=None, fallback=True, run_dry=True):
        """
    Initialize NetworkBuilder.

    If the topology definition is not found, an exception will be raised or
    an empty :class:`mininet.net.Mininet` topology will be created if
    ``run_dry`` is set.

    :param net: update given Mininet object instead of creating a new one
    :type net: :class:`mininet.net.Mininet`
    :param opts: update default options with the given opts
    :type opts: dict
    :param fallback: search for fallback topology (default: True)
    :type fallback: bool
    :param run_dry: do not raise an Exception and return with bare Mininet obj.
    :type run_dry: bool
    :return: None
    """
        self.opts = dict(self.default_opts)
        if opts is not None:
            self.opts.update(opts)
        self.fallback = fallback
        self.run_dry = run_dry
        if net is not None:
            if isinstance(net, Mininet):
                # Initial settings - Create new Mininet object if necessary
                self.mn = net
            else:
                raise TopologyBuilderException(
                    "Network object's type must be a derived class of Mininet!"
                )
        else:
            # self.mn = Mininet(**self.opts)
            try:
                self.mn = MininetWithControlNet(**self.opts)
            except KeyboardInterrupt:
                quit_with_error(
                    msg="Assembly of Mininet network was interrupted by user!",
                    logger=log)
        # Basically a wrapper for mn to offer helping functions
        self.mn_bridge = None
        # Cache of the topology description as an NFFG which is parsed during
        # initialization
        self.topo_desc = None
        self.__dpid_cntr = self.dpidBase
Exemple #11
0
 def initialize (self):
   """
   .. seealso::
     :func:`AbstractAPI.initialize() <escape.util.api.AbstractAPI.initialize>`
   """
   log.debug("Initializing Controller Adaptation Sublayer...")
   self.controller_adapter = ControllerAdapter(self, with_infr=self._with_infr)
   if self._mapped_nffg:
     try:
       mapped_request = self._read_data_from_file(self._mapped_nffg)
       mapped_request = NFFG.parse(mapped_request)
       self.__proceed_installation(mapped_nffg=mapped_request)
     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:
       log.debug("Graph representation is loaded successfully!")
   log.info("Controller Adaptation Sublayer has been initialized!")
Exemple #12
0
 def initialize(self):
     """
 Initialize NFIB with test data.
 """
     try:
         try:
             host, port = CONFIG.get_neo4j_host_port()
             host = host if host else self.DB_HOST
             port = port if port else self.DB_PORT
             log.debug("Initiating Graph database connection[%s:%s]..." %
                       (host, port))
             self.graph_db = Graph(host=host, http_port=port)
         except Unauthorized as e:
             quit_with_error(
                 "Got Unauthorized error on: %s from neo4j! Disable the authorization "
                 "in /etc/neo4j/neoj4-server.properties!" % e)
             return self
         except SocketError:
             log.warning(
                 "NFIBManager has not been initialized! Only cause problem "
                 "if ESCAPE is used as a Local Orchestrator!")
             return self
         self.__initialize()
     except SocketError as e:
         log.error(
             "NFIB is not reachable due to failed neo4j service! Cause: " +
             str(e))
     except KeyboardInterrupt:
         log.warning("NFIB was interrupted by user!")
     except Unauthorized:
         log.error(
             "neo4j responded with Unauthorized error! Maybe you forgot disabling "
             "authentication in '/etc/neo4j/neo4j.conf' ?")
     except IOError as e:
         if ".neo4j/known_hosts" in str(e):
             # Skip Permission denied in case of accessing neo4j cache file (v3.0.2)
             pass
         else:
             raise
     except:
         log.exception("Got unexpected error during NFIB initialization!")
     return self
Exemple #13
0
    def _load_cfg_file(path):
        """
    Load external configuration from file. Support JSON and YAML format.

    :param path: file path
    :type path: str
    :return: loaded configuration
    :rtype: dict
    """
        try:
            with open(path) as f:
                if path.endswith('yml'):
                    import yaml
                    return yaml.safe_load(f)
                elif path.endswith('json') or path.endswith('config'):
                    return json.load(f, object_hook=unicode_to_str)
                else:
                    raise ConfigurationError(
                        "Unsupported configuration extension: %s" % path)
        except IOError:
            quit_with_error('Default config file: %s is not found!' % path)
        except Exception as e:
            quit_with_error("An error occurred when load configuration: %s" %
                            e)
Exemple #14
0
  def __init_from_NFFG (self, nffg):
    """
    Initialize topology from an :any:`NFFG` representation.

    :param nffg: topology object structure
    :type nffg: :any:`NFFG`
    :return: None
    """
    # pprint(nffg.network.__dict__)
    log.info("Start topology creation from NFFG(name: %s)..." % nffg.name)
    created_mn_nodes = {}  # created nodes as 'NFFG-id': <node>
    created_mn_links = {}  # created links as 'NFFG-id': <link>
    # If not set then cache the given NFFG as the topology description
    self.topo_desc = nffg
    # Create a Controller which will be the default internal POX controller
    try:
      self.create_Controller("ESCAPE")
    except SystemExit:
      raise TopologyBuilderException("Controller creations was unsuccessful!")
    # Convert INFRAs
    for infra in nffg.infras:
      # Create EE
      if infra.infra_type == NodeInfra.TYPE_EE:
        if infra.domain == "INTERNAL":
          ee_type = self.TYPE_EE_LOCAL
        else:
          log.warning(
            "Detected domain of infra: %s is not INTERNAL! Remote EE creation "
            "for domains other than INTERNAL is not supported yet!" % infra)
          # ee_type = self.TYPE_EE_REMOTE
          ee_type = self.TYPE_EE_LOCAL
          # FIXME - set resource info in MN EE if can - cpu,mem,delay,bandwidth?
        agt, sw = self.create_NETCONF_EE(name=infra.id, type=ee_type)
        created_mn_nodes[infra.id] = sw
      # Create Switch
      elif infra.infra_type == NodeInfra.TYPE_SDN_SWITCH:
        switch = self.create_Switch(name=infra.id)
        created_mn_nodes[infra.id] = switch
      elif infra.infra_type == NodeInfra.TYPE_STATIC_EE:
        static_ee = self.create_static_EE(name=infra.id)
        created_mn_nodes[infra.id] = static_ee
      else:
        quit_with_error(
          msg="Type: %s in %s is not supported by the topology creation "
              "process in %s!" % (
                infra.infra_type, infra, self.__class__.__name__), logger=log)
    # Create SAPs - skip the temporary, inter-domain SAPs
    for sap in {s for s in nffg.saps if not s.binding}:
      # Create SAP
      sap_host = self.create_SAP(name=sap.id)
      created_mn_nodes[sap.id] = sap_host
    # Convert VNFs
    # TODO - implement --> currently the default Mininet topology does not
    # TODO contain NFs but it could be possible
    # Convert connections - copy link ref in a list and iter over it
    for edge in [l for l in nffg.links]:
      # Skip initiation of links which connected to an inter-domain SAP
      if (edge.src.node.type == NFFG.TYPE_SAP and
              edge.src.node.binding is not None) or (
             edge.dst.node.type == NFFG.TYPE_SAP and
             edge.dst.node.binding is not None):
        continue
      # Create Links
      mn_src_node = created_mn_nodes.get(edge.src.node.id)
      mn_dst_node = created_mn_nodes.get(edge.dst.node.id)
      if mn_src_node is None or mn_dst_node is None:
        raise TopologyBuilderException(
          "Created topology node is missing! Something really went wrong!")
      src_port = int(edge.src.id) if int(edge.src.id) < 65535 else None
      if src_port is None:
        log.warning(
          "Source port id of Link: %s is generated dynamically! Using "
          "automatic port assignment based on internal Mininet "
          "implementation!" % edge)
      dst_port = int(edge.dst.id) if int(edge.dst.id) < 65535 else None
      if dst_port is None:
        log.warning(
          "Destination port id of Link: %s is generated dynamically! Using "
          "automatic port assignment based on internal Mininet "
          "implementation!" % edge)
      link = self.create_Link(src=mn_src_node, src_port=src_port,
                              dst=mn_dst_node, dst_port=dst_port,
                              bw=edge.bandwidth, delay=str(edge.delay) + 'ms')
      created_mn_links[edge.id] = link

    # Set port properties of SAP nodes.
    #  A possible excerpt from a escape-mn-topo.nffg file:
    #  "ports": [{ "id": 1,
    #              "property": ["ip:10.0.10.1/24"] }]
    #
    for n in {s for s in nffg.saps if not s.binding}:
      mn_node = self.mn.getNodeByName(n.id)
      for port in n.ports:
        # ip should be something like '10.0.123.1/24'.
        if len(port.l3):
          if len(port.l3) == 1:
            ip = port.l3.container[0].provided
          else:
            log.warning(
              "Multiple L3 address is detected! Skip explicit IP address "
              "definition...")
            ip = None
        else:
          # or None
          ip = port.get_property('ip')
        if port.l2:
          mac = port.l2
        else:
          mac = port.get_property('mac')
        intf = mn_node.intfs.get(port.id)
        if intf is None:
          log.warn(("Port %s of node %s is not connected,"
                    "it will remain unconfigured!") % (port.id, n.name))
          continue
        if intf == mn_node.defaultIntf():
          # Workaround a bug in Mininet
          mn_node.params.update({'ip': ip})
          mn_node.params.update({'mac': mac})
        if ip is not None:
          mn_node.setIP(ip, intf=intf)
          log.debug("Use explicit IP: %s for node: %s" % (ip, n))
        if mac is not None:
          mn_node.setMAC(mac, intf=intf)
          log.debug("Use explicit MAC: %s for node: %s" % (mac, n))

    # For inter-domain SAPs no need to create host/xterm just add the SAP as
    # a port to the border Node
    # Iterate inter-domain SAPs
    self.bind_inter_domain_SAPs(nffg=nffg)
    log.info("Topology creation from NFFG has been finished!")