Jump to: navigation, search

Difference between revisions of "Neutron/EmbraneNeutronPlugin"

(Use Cases)
Line 3: Line 3:
 
==Scope==
 
==Scope==
  
The present blueprint aims at the implementation of a Neutron plugins which allows users to interface Neutron with the Embrane heleos platform.
+
The current blueprint includes the implementation of an Embrane Neutron plugin which enables users to interface Neutron with the Embrane heleos platform.
  
 
==Use Cases==
 
==Use Cases==
  
Cloud service providers who choose to adopt [[OpenStack]] and [[Neutron]] for their cloud orchestration, will also be able to use the Embrane heleos platform with the API and workflows they are comfortable with. <br />
+
Cloud service providers who choose to adopt OpenStack and Neutron for their cloud orchestration will also be able to use Embrane heleos via Neutron.
 +
Using the Embrane Neutron plugin, users can achieve any level of L2 isolation using existing plugins and build L3 connectivity through Embrane Distributed Virtual Appliances (DVAs) created by the Embrane Elastic Services Manager (ESM), the provisioning system used in the Embrane heleos platform.  The ESM can rapidly provide per-tenant "core routers" within a pool of virtualized hosts. These routers are configurable through both Neutron itself or their own REST APIs.  
  
Using the Embrane heleos plugin, the users can achieve any level of L2 isolation using the existing plugins (when supported), while leveraging L3 connectivity through the Embrane Elastic Services Manager, hereafter ESM, the provisioning system used in the Embrane heleos platform, which can rapidly provide per tenant "core routers" in a pool of dedicated/shared physical hosts. These routers are configurable through both Neutron itself or their own REST APIs.
 
  
 
== Implementation==
 
== Implementation==
  
This session discusses the plugin implementation, with special focus to the plugin specific features and configurations.<br />
+
This section discusses the plugin implementation, with special focus to the plugin specific features and configurations.
 
+
The plugin file list is shown below:  
The plugin file list is the following:
 
 
 
<pre><nowiki>
 
 
neutron/plugins/embrane/EmbraneInit.py
 
neutron/plugins/embrane/EmbraneInit.py
 
neutron/plugins/embrane/__init__.py
 
neutron/plugins/embrane/__init__.py
Line 30: Line 27:
 
neutron/plugins/embrane/l2base/support_exceptions.py
 
neutron/plugins/embrane/l2base/support_exceptions.py
 
neutron/plugins/embrane/plugin.py
 
neutron/plugins/embrane/plugin.py
</nowiki></pre>
+
Additionally, more Embrane specific packages are included:  
 
 
Additionally, more packages are defined:
 
 
 
<pre><nowiki>
 
 
neutron/plugins/embrane/api/*
 
neutron/plugins/embrane/api/*
 
neutron/plugins/embrane/embranerest/*
 
neutron/plugins/embrane/embranerest/*
</nowiki></pre>
 
 
The files inside these packages are backend-specific, and represent the set of tools used to interact with the Embrane's platform. They are a dependency for the plugin and may be distributed separately at first.
 
  
 
===Supported feature===
 
===Supported feature===
Line 50: Line 40:
  
 
=== Using existing plugins for L2 connectivity ===
 
=== Using existing plugins for L2 connectivity ===
The Embrane Neutron Plugin main goal is of course to interface OpenStack (specifically Neutron) with heleos, which provides L3-7 network services for cloud environments.
+
The main goal of the Embrane plugin is to interface OpenStack (specifically Neutron) with Embrane heleos providing L3-7 network services for cloud environments. For this reason, the Embrane heleos plugin leverages L2 connectivity to an existing plugin chosen at configuration time. The Embrane heleos plugin and the L2 plugin share information about the network implementation, which is used to implement L3. So any time a request is sent to Neutron, it will be directed to Embrane heleos where applicable.
For this reason, the Embrane Plugin lends the leveraging of L2 connectivity to an existing Plugin chosen at configuration time.  
+
To achieve this, there are 2 main techniques that are used:  
The Embrane Plugin and the L2 plugin share information about the network implementation, which will be used to implement L3.
 
So any time a request is sent to Neutron, it will be directed to the Embrane Plugin if is part of the API set showed in the previous section, to the L2 plugin otherwise.
 
 
 
To achieve this, there are 2 main techniques that have been used:
 
  
 
'''Plugin Inheritance'''<br />
 
'''Plugin Inheritance'''<br />
  
In 'neutron/plugins/embrane/plugins/*' (where the actual plugins resides) each plugin class (i.e. EmbraneOvsPlugin) is created using the base Embrane plugin (neutron/plugins/embrane/plugin.py.EmbranePlugin) and the specific L2 plugin as bases. This will ensure, provided that everything is done correctly, that the L2 networks will be provided by an existing L2 plugin, while L3 connectivity will be managed by Embrane's plugin. More details on how to create a specific Embrane plugin are provided below.
+
In 'neutron/plugins/embrane/plugins/*' where the actual plugins resides, each plugin class (i.e. EmbraneOvsPlugin) is created using the base Embrane plugin (neutron/plugins/embrane/plugin.py.EmbranePlugin) and the specific L2 plugin as bases. This will ensure, provided that everything is done correctly, that the L2 networks will be provided by an existing L2 plugin, while L3 connectivity will be managed by the Embrane heleos plugin. More details on how to create a specific Embrane plugin are provided below.  
  
 
'''Plugin-in-Plugin'''<br />
 
'''Plugin-in-Plugin'''<br />
  
In order to get all this to work, the 2 plugins (Embrane's and L2) need to share some information about the actual network implementation. At the present state, only plugins which implement network isolation through VLANs can be used together with Embrane's plugin. Support for different L2 isolation will be added in the future.
+
In order for this to work, the 2 plugins, Embrane heleos plugin and chosen L2 plugin, need to share some information about the actual network implementation. At the present state, only plugins which implement network isolation through VLANs can be used together with the Embrane heleos plugin. Support for different L2 isolation methods will be added in the future. The information sharing is implemented through a plugin inside the plugin, which means that for each L2 plugin that is supported, it's mandatory to create a new package inside 'neutron/plugins/embrane/l2base/' and a class that inherits from 'neutron/plugins/embrane/l2base/support_base.py'. This abstract class only defines one simple method, which shall be implemented by the support class in order to fulfill the contract.
This "information sharing" is implemented through a plugin "inside the plugin", which means that for each L2 plugin that is to be supported, it's mandatory to create a new package inside 'neutron/plugins/embrane/l2base/' and a class that inherits from 'neutron/plugins/embrane/l2base/support_base.py'.
 
This abstract class only defines one simple method, which shall be implemented by the support class in order to fulfill the contract.
 
  
'''-Instructions to build a new Embrane plugin from a different base-'''
+
'''Instructions to build a new Embrane plugin from a different base'''
 
 
see examples from:
+
See examples from:  
 
 
<pre><nowiki>
 
 
neutron.plugins.embrane.plugins.embrane_fake_plugin.EmbraneFakePlugin
 
neutron.plugins.embrane.plugins.embrane_fake_plugin.EmbraneFakePlugin
 
neutron.plugins.embrane.plugins.embrane_ovs_plugin.EmbraneOvsPlugin
 
neutron.plugins.embrane.plugins.embrane_ovs_plugin.EmbraneOvsPlugin
</nowiki></pre>
+
To build a new L2 support for the Embrane heleos Neutron plugin, one must first implement the specific l2base.
 
+
Create a new package under:  
To build a new L2 support for the Embrane's Neutron plugin, you must first implement the specific l2base.<br />
 
 
 
Create a new package under:
 
 
 
<pre><nowiki>
 
 
neutron.plugins.embrane.l2base
 
neutron.plugins.embrane.l2base
</nowiki></pre>
+
And name it with the specific plugin technology. Create a python module and a class which extends support_base.SupportBase, implementing all its abstract methods.  
 
 
And name it with the specific plugin technology. Create a python module, and a class which extends support_base.SupportBase, implementing all its abstract methods.
 
 
 
<pre><nowiki>
 
 
@abstractmethod
 
@abstractmethod
 
def retrieve_utif_info(self, context, neutron_port=None, network=None):
 
def retrieve_utif_info(self, context, neutron_port=None, network=None):
</nowiki></pre>
+
An example of support class can be found in 'neutron/plugins/embrane/l2base/openvswitch/openvswitch_support.py'.
 
+
Once the contract is fulfilled (see examples and comments in the code for more info) create a new module under:  
An example of support class can be found in 'neutron/plugins/embrane/l2base/openvswitch/openvswitch_support.py'.<br />
 
 
 
Once the contract is fulfilled (see examples and comments in the code for more info) create a new module under:
 
 
 
<pre><nowiki>
 
 
neutron.plugins.embrane.plugins
 
neutron.plugins.embrane.plugins
</nowiki></pre>
+
Referencing specific plugin technology (see existing examples)
 
+
Inside the module define a class built as follows:  
Named referencing the specific plugin technology (see existing examples). Inside the module define a class built as follows:
 
of the plugin following the example below:
 
 
 
<pre><nowiki>
 
 
class EmbraneNewPlugin(base.EmbranePlugin, l2.NewL2Plugin):
 
class EmbraneNewPlugin(base.EmbranePlugin, l2.NewL2Plugin):
 
     _plugin_support = support.NewPluginSupport
 
     _plugin_support = support.NewPluginSupport
 
     def __init__(self):
 
     def __init__(self):
 
         '''First run plugin specific initialization, then Embrane's.'''
 
         '''First run plugin specific initialization, then Embrane's.'''
         self.supported_extension_aliases += ["extraroute", "router"] #IF NEEDED
+
         self.supported_extension_aliases += ["extraroute", "router"]
 +
#IF NEEDED
 +
 
 
         l2.NewL2Plugin.__init__(self)
 
         l2.NewL2Plugin.__init__(self)
 
         self._run_embrane_config()
 
         self._run_embrane_config()
</nowiki></pre>
+
NOTE: The base order is very important. EmbranePlugin shall always be the first base of the built plugin, so the L3 requests can be correctly resolved (MRO)
  
NOTE: The base order is very important!!! EmbranePlugin shall always be the first base of the built plugin, so the L3 requests can be correctly resolved (MRO)<br />
+
NOTE: The plugin needs certain bases and extensions:
NOTE2: The plugin needs certain bases and extensions:<br />
+
REQUIRED_EXTENSIONS = ["extraroute", "router"]  
*REQUIRED_EXTENSIONS = ["extraroute", "router"]
+
REQUIRED_BASES = (ExtraRoute_db_mixin,)  
*REQUIRED_BASES = (ExtraRoute_db_mixin,)
+
Add them if needed (i.e. the L2 plugin doesn't natively support them).  
Add them if needed (i.e. the L2 plugin doesn't natively support them).
 
  
 
=== Asynchronous Calls===
 
=== Asynchronous Calls===
  
To avoid too much wait time on long operations, the calls to the Embrane plugin will be executed asynchronously and by a different thread "per Router". This means that each request will be sent to the dispatcher ('neutron/plugins/embrane/agent/dispatcher.py') which will serve each Router using a different thread, in which all the operations will be queued and executed sequentially, while the available database information on the specific resource will be returned to the user ([[Nova]] style). Moreover, the router state attribute is used to tell the user when a router is busy with an operation:
+
To avoid excessive wait time on long operations, the calls to the Embrane heleos plugin are executed asynchronously and by a different thread per router. This means that each request will be sent to the dispatcher ('neutron/plugins/embrane/agent/dispatcher.py') which will serve each router using a different thread.  All operations will be queued and executed sequentially, while the available database information on the specific resource will be returned to the user (Nova style). Moreover, the router state attribute is used to tell the user when a router is busy with an operation:  
  
 
'''Table 1. Status Values '''
 
'''Table 1. Status Values '''
Line 140: Line 105:
  
  
So when the model is changed (via POST, PUT or DELETE for example) the call may return before the actual operation is executed on the virtual system, putting the router in a 'PENDING_*' state. Subsequent GETs shall always reflect the current status of the virtual appliance itself.
+
So when the model is changed (via POST, PUT or DELETE for example) the call may return before the actual operation is executed on the virtual system, putting the router in a 'PENDING_*' state. Subsequent GETs shall always reflect the current status of the virtual appliance itself. When a router is in a given state, only a subset of operations can be executed on it.  
When a router is in a given state, only a subset of operations can be executed on it.
 
  
 
==Configuration==
 
==Configuration==

Revision as of 19:04, 18 November 2013

Embrane Neutron Plugin

Scope

The current blueprint includes the implementation of an Embrane Neutron plugin which enables users to interface Neutron with the Embrane heleos platform.

Use Cases

Cloud service providers who choose to adopt OpenStack and Neutron for their cloud orchestration will also be able to use Embrane heleos via Neutron. Using the Embrane Neutron plugin, users can achieve any level of L2 isolation using existing plugins and build L3 connectivity through Embrane Distributed Virtual Appliances (DVAs) created by the Embrane Elastic Services Manager (ESM), the provisioning system used in the Embrane heleos platform. The ESM can rapidly provide per-tenant "core routers" within a pool of virtualized hosts. These routers are configurable through both Neutron itself or their own REST APIs.


Implementation

This section discusses the plugin implementation, with special focus to the plugin specific features and configurations. The plugin file list is shown below: neutron/plugins/embrane/EmbraneInit.py neutron/plugins/embrane/__init__.py neutron/plugins/embrane/agent/__init__.py neutron/plugins/embrane/agent/dispatcher.py neutron/plugins/embrane/agent/operations/__init__.py neutron/plugins/embrane/agent/operations/routerOperations.py neutron/plugins/embrane/l2base/__init__.py neutron/plugins/embrane/l2base/openvswitch/__init__.py neutron/plugins/embrane/l2base/openvswitch/openvswitch_support.py neutron/plugins/embrane/l2base/support_base.py neutron/plugins/embrane/l2base/support_exceptions.py neutron/plugins/embrane/plugin.py Additionally, more Embrane specific packages are included: neutron/plugins/embrane/api/* neutron/plugins/embrane/embranerest/*

Supported feature

The plugin supports the following features:


Using existing plugins for L2 connectivity

The main goal of the Embrane plugin is to interface OpenStack (specifically Neutron) with Embrane heleos providing L3-7 network services for cloud environments. For this reason, the Embrane heleos plugin leverages L2 connectivity to an existing plugin chosen at configuration time. The Embrane heleos plugin and the L2 plugin share information about the network implementation, which is used to implement L3. So any time a request is sent to Neutron, it will be directed to Embrane heleos where applicable. To achieve this, there are 2 main techniques that are used:

Plugin Inheritance

In 'neutron/plugins/embrane/plugins/*' where the actual plugins resides, each plugin class (i.e. EmbraneOvsPlugin) is created using the base Embrane plugin (neutron/plugins/embrane/plugin.py.EmbranePlugin) and the specific L2 plugin as bases. This will ensure, provided that everything is done correctly, that the L2 networks will be provided by an existing L2 plugin, while L3 connectivity will be managed by the Embrane heleos plugin. More details on how to create a specific Embrane plugin are provided below.

Plugin-in-Plugin

In order for this to work, the 2 plugins, Embrane heleos plugin and chosen L2 plugin, need to share some information about the actual network implementation. At the present state, only plugins which implement network isolation through VLANs can be used together with the Embrane heleos plugin. Support for different L2 isolation methods will be added in the future. The information sharing is implemented through a plugin inside the plugin, which means that for each L2 plugin that is supported, it's mandatory to create a new package inside 'neutron/plugins/embrane/l2base/' and a class that inherits from 'neutron/plugins/embrane/l2base/support_base.py'. This abstract class only defines one simple method, which shall be implemented by the support class in order to fulfill the contract.

Instructions to build a new Embrane plugin from a different base

See examples from: neutron.plugins.embrane.plugins.embrane_fake_plugin.EmbraneFakePlugin neutron.plugins.embrane.plugins.embrane_ovs_plugin.EmbraneOvsPlugin To build a new L2 support for the Embrane heleos Neutron plugin, one must first implement the specific l2base. Create a new package under: neutron.plugins.embrane.l2base And name it with the specific plugin technology. Create a python module and a class which extends support_base.SupportBase, implementing all its abstract methods. @abstractmethod def retrieve_utif_info(self, context, neutron_port=None, network=None): An example of support class can be found in 'neutron/plugins/embrane/l2base/openvswitch/openvswitch_support.py'. Once the contract is fulfilled (see examples and comments in the code for more info) create a new module under: neutron.plugins.embrane.plugins Referencing specific plugin technology (see existing examples) Inside the module define a class built as follows: class EmbraneNewPlugin(base.EmbranePlugin, l2.NewL2Plugin):

   _plugin_support = support.NewPluginSupport
   def __init__(self):
       First run plugin specific initialization, then Embrane's.
       self.supported_extension_aliases += ["extraroute", "router"]

#IF NEEDED

       l2.NewL2Plugin.__init__(self)
       self._run_embrane_config()

NOTE: The base order is very important. EmbranePlugin shall always be the first base of the built plugin, so the L3 requests can be correctly resolved (MRO)

NOTE: The plugin needs certain bases and extensions: • REQUIRED_EXTENSIONS = ["extraroute", "router"] • REQUIRED_BASES = (ExtraRoute_db_mixin,) Add them if needed (i.e. the L2 plugin doesn't natively support them).

Asynchronous Calls

To avoid excessive wait time on long operations, the calls to the Embrane heleos plugin are executed asynchronously and by a different thread per router. This means that each request will be sent to the dispatcher ('neutron/plugins/embrane/agent/dispatcher.py') which will serve each router using a different thread. All operations will be queued and executed sequentially, while the available database information on the specific resource will be returned to the user (Nova style). Moreover, the router state attribute is used to tell the user when a router is busy with an operation:

Table 1. Status Values

Name
ACTIVE
PENDING_CREATE
PENDING_UPDATE
PENDING_DELETE
INACTIVE
ERROR


So when the model is changed (via POST, PUT or DELETE for example) the call may return before the actual operation is executed on the virtual system, putting the router in a 'PENDING_*' state. Subsequent GETs shall always reflect the current status of the virtual appliance itself. When a router is in a given state, only a subset of operations can be executed on it.

Configuration

The configuration file is stored in 'etc/neutron/plugins/embrane/heleos_conf.ini', this section explains the meaning of each field (example are provided in the configuration class itself).

  • esm_mgmt: management address of the ESM, the Embrane heleos module that is installed separately and which will actually provision the routers inside the cloud environment;
  • admin_username: admin username for authenticating against the ESM api;
  • admin_password: admin password for authenticating against the ESM api;
  • router_image: ID of the router image stored inside the ESM, which will be used to create the routers;
  • *_id: a series of product specific resources that can be specified inside the plugin, or alternatively, from the product itself.


etc/neutron/neutron.conf example:

  • core_plugin = neutron.plugins.embrane.plugins.embrane_ovs_plugin.EmbraneOvsPlugin