Jump to: navigation, search

Difference between revisions of "L3 mixin to plugin"

Line 1: Line 1:
 
__NOTOC__
 
__NOTOC__
Some questions for discussion regarding the[https://blueprints.launchpad.net/quantum/+spec/quantum-l3-routing-plugin L3 mixin to plugin blueprint] (further described [https://docs.google.com/presentation/d/1lEMKNZQlXfuTOIAyoNwctr8H6mZqWoYL4iSzWCzS0hM/edit here]):
+
Details regarding the[https://blueprints.launchpad.net/quantum/+spec/quantum-l3-routing-plugin L3 mixin to plugin blueprint]:
  
'''1) '''Today the L3 database functionality resides in the L3_NAT_db_mixin class, which along with QuantumDBPluginV2, are inherited by the plugins.
+
== Scope ==
 +
Refactor current implementation so that L3 routing functionality (i.e., routing/NAT/floatingip) can be provided by a separate service plugin. Traditional Quantum plugins will still be able to provide the L3 functionality integrated as today for those that prefer that.
  
For the case when the L3 functionality is separated out from the core plugin to its own L3 plugin, the L3_NAT_db_mixin no longer needs to be mixed into the core plugin. It is only needed in the L3 plugin. However, there are a number of calls to functions in QuantumDBPluginV2 from L3_NAT_db_mixin, e.g.,  self.get_ports(…), self.delete_port(…), self._get_port(…), etc, which are referenced via 'self'. Thus, if L3_NAT_db_mixin is not mixed into the same class as QuantumDBPluginV2 those references will not work.
+
This blueprint does not migrate L3 API into core, it will still be an extension. It does not provide a new L3 routing implementation, nor does it touch the L3 agent.
  
A way around this would be to replace 'self' with 'self.corePlugin' in L3_NAT_db_mixin, where 'corePlugin' is a variable set to reference the core plugin. Would this be an acceptable approach?
+
== Use cases ==
 +
When L3 functionality is provided as separate plugin, multiple such implementations can made available, just as there exists a wide variety of traditional Quantum plugins.
  
'''2)''' The other area that requires modification to support a separate L3 plugin is the plugin method dispatching in response to REST API calls. Today the controller for "core" resources : network, port, subnet (and for Grizzly router and floatingip) all point to the core plugin as per code in '''router.py'''. When some of the resources are handled by a separate plugin then that plugin must be associated with the controllers of those resources. I.e., for resource X use plugin Y.
+
The cloud provider can decide at deployment time which combination of L2 and L3 implementations/strategies to use by making appropriate configuration file settings to load the wanted plugins.
  
One way of doing this is the following: The RESOURCES dict is extended so that each item includes a service type identifier that specifies which type plugin implements the resource. Something like:
+
== Implementation overview ==
 +
The router:external attribute part of the existing l3 extension is broken out into its own ‘external-net’ extension. The functions associated with this attributed are migrated to an ‘Ext_net_db_mixin’ class but are otherwise untouched. This means that the only change to plugins is to add the ‘external-net’ extension to the list of extensions they implement and inherit the ‘Ext_net_db_mixin’.
 +
 
 +
Plugins that continue to provide the L3 routing functionality integrated, will keep the ‘router’ extension as well as keep inheriting the ‘L3_NAT_db_mixin' (and their RPCCallback class will keep inheriting the '[[L3RpcCallbackMixin]]').
 +
 
 +
Those plugins that delegate L3 routing functionality to a separate L3 router service plugin will remove the ‘router’ extension and the L3 mixin classes. The 'delete_port(…)' function of the plugin must be slightly modified to use a reference to the l3 plugin for the port check and floatingip cleanup.
 +
 
 +
The 'L3_NAT_db_mixin' is changed so that calls to functions in the '[[QuantumDbPluginV2]]' class uses a reference to the core plugin instead of ‘self’. This way, the calls will work both when the 'L3_NAT_db_mixin' is inherited by the same plugin class that inherits '[[QuantumDbPluginV2]]' and when this is not the case, i.e., with a separate L3 router plugin.
 +
 
 +
A new service type constant ‘L3_ROUTER_NAT’ is added to /quantum/plugins/common/constants.py.
 +
 
 +
A new ‘[[L3RouterPlugin]]’ class implementing the L3 router service plugin using the L3 extension (with 'L3_NAT_db_mixin' and '[[L3RpcCallbackMixin]]') is introduced. The service type that the new service plugin reports is ‘L3_ROUTER_NAT’.
 +
 
 +
The plugin loading in '[[QuantumManager]]' is slightly modified so that a plugin for service type L3_ROUTER_NAT is correctly added to the 'service_plugins' list. If a traditional plugin implementing the L3 extension and the new L3 router service plugin are both specified to be used the loading step will throw an exception.
 +
 
 +
== Data model changes ==
 +
None.
 +
 
 +
== Configuration variables ==
 +
No new configurations variables. The L3 service plugin is specified using the ‘service_plugins’ setting in ‘quantum.conf’ in accordance with the service insertion framework.
 +
 
 +
== API's ==
 +
No new APIs.
 +
 
 +
== Plugin interface ==
 +
No, but comments are made in the code about possible enhancements.
 +
 
 +
These concerns port usage, how plugins can reference each other and state dependency.
 +
 
 +
== Required Plugin support ==
 +
For a traditional plugin to "delegate" to the separate L3 routing service plugins the following steps are required:
 +
 
 +
* Do not inherit 'l3_db.L3_NAT_db_mixin' anymore.
 +
* Remove "router" from 'supported_extension_aliases'.
 +
* Modify any 'self' references to members in L3_NAT_db_mixin to instead use
 +
** 'manager.[[QuantumManager]].get_service_plugins()[constants.L3_ROUTER_NAT]' For example,
  
  
 
<pre><nowiki>
 
<pre><nowiki>
RESOURCES = {'network': {'coll': 'networks', 'type': constants.CORE},
+
      self.prevent_l3_port_deletion(...)
            'subnet': {'coll': 'subnets', 'type': constants.CORE},
 
            'port': {'coll': 'ports', 'type': constants.CORE},
 
            'router': {'coll': 'routers', 'type': constants.L3_ROUTER_NAT},
 
            'floatingip': {'coll': 'floatingips', 'type': constants.L3_ROUTER_NAT}}
 
 
</nowiki></pre>
 
</nowiki></pre>
  
The APIRouter class (essentially the _map_resource method) is modified so that a plugin implementing the resource's service type is used when creating a controller for that resource. [[QuantumManager]]'s get_plugin method could be modified to take a (constants.CORE defaulted) service type argument and return the plugin that implements that service type. Another required change (for core plugins to still be able to implement resources with type != 'CORE') is that core plugins have a function that reports which service types the core plugin implements. Something like get_service_types() returning ['CORE', 'L3-ROUTER-NAT'] or whatever is supported.
+
* becomes something like
  
I believe the above would allow the L3 router/floatingip resources (or any other resource) to be implemented by a separate L3 plugin or remain implemented by a core plugin.
 
  
I'd appreciate your feedback on this proposal.
+
<pre><nowiki>
 +
      plugin = manager.QuantumManager.get_service_plugins()[
 +
        constants.L3_ROUTER_NAT]
 +
      plugin.prevent_l3_port_deletion(...)
 +
</nowiki></pre>
 +
 
 +
* Do not inherit 'l3_rpc_base.[[L3RpcCallbackMixin]]' in any '*[[RpcCallbacks]]' class.
 +
 
 +
''' '''
 +
 
 +
== Dependencies: ==
 +
No new dependencies.
 +
 
 +
== CLI Requirements: ==
 +
None.
 +
 
 +
== Usage Example: ==
 +
The code patch for this blueprint contains a L3 router service plugin that provides the L3 routing functionality that is otherwise provided by the traditional plugins. The Openvswitch and Linuxbridge plugins have been modified so that they do not provide L3 functionality. For these two plugins the L3 routing functionality is delegated to the L3 routing service plugin.
 +
 
 +
The L3 plugin is specified by the ‘service_plugins’ setting in ‘quantum.conf’ and the l3 agent is configured in the usual way in the ‘l3agent.ini’ file.
 +
 
 +
Excerpt from quantum.conf:
 +
 
 +
 
 +
<pre><nowiki>
 +
core_plugin =
 +
quantum.plugins.openvswitch.ovs_quantum_plugin.OVSQuantumPluginV2
 +
service_plugins =
 +
quantum.plugins.services.l3_router.l3_router_plugin.L3RouterPlugin
 +
</nowiki></pre>
 +
 
 +
== Test Cases: ==
 +
Unit tests will be extended to also cover the case where the L3 routing functionality is handled by a routing service plugin separate from the traditional plugin. Tests for the external network attribute are put in a separate file for that extension.

Revision as of 20:04, 27 January 2013

Details regarding theL3 mixin to plugin blueprint:

Scope

Refactor current implementation so that L3 routing functionality (i.e., routing/NAT/floatingip) can be provided by a separate service plugin. Traditional Quantum plugins will still be able to provide the L3 functionality integrated as today for those that prefer that.

This blueprint does not migrate L3 API into core, it will still be an extension. It does not provide a new L3 routing implementation, nor does it touch the L3 agent.

Use cases

When L3 functionality is provided as separate plugin, multiple such implementations can made available, just as there exists a wide variety of traditional Quantum plugins.

The cloud provider can decide at deployment time which combination of L2 and L3 implementations/strategies to use by making appropriate configuration file settings to load the wanted plugins.

Implementation overview

The router:external attribute part of the existing l3 extension is broken out into its own ‘external-net’ extension. The functions associated with this attributed are migrated to an ‘Ext_net_db_mixin’ class but are otherwise untouched. This means that the only change to plugins is to add the ‘external-net’ extension to the list of extensions they implement and inherit the ‘Ext_net_db_mixin’.

Plugins that continue to provide the L3 routing functionality integrated, will keep the ‘router’ extension as well as keep inheriting the ‘L3_NAT_db_mixin' (and their RPCCallback class will keep inheriting the 'L3RpcCallbackMixin').

Those plugins that delegate L3 routing functionality to a separate L3 router service plugin will remove the ‘router’ extension and the L3 mixin classes. The 'delete_port(…)' function of the plugin must be slightly modified to use a reference to the l3 plugin for the port check and floatingip cleanup.

The 'L3_NAT_db_mixin' is changed so that calls to functions in the 'QuantumDbPluginV2' class uses a reference to the core plugin instead of ‘self’. This way, the calls will work both when the 'L3_NAT_db_mixin' is inherited by the same plugin class that inherits 'QuantumDbPluginV2' and when this is not the case, i.e., with a separate L3 router plugin.

A new service type constant ‘L3_ROUTER_NAT’ is added to /quantum/plugins/common/constants.py.

A new ‘L3RouterPlugin’ class implementing the L3 router service plugin using the L3 extension (with 'L3_NAT_db_mixin' and 'L3RpcCallbackMixin') is introduced. The service type that the new service plugin reports is ‘L3_ROUTER_NAT’.

The plugin loading in 'QuantumManager' is slightly modified so that a plugin for service type L3_ROUTER_NAT is correctly added to the 'service_plugins' list. If a traditional plugin implementing the L3 extension and the new L3 router service plugin are both specified to be used the loading step will throw an exception.

Data model changes

None.

Configuration variables

No new configurations variables. The L3 service plugin is specified using the ‘service_plugins’ setting in ‘quantum.conf’ in accordance with the service insertion framework.

API's

No new APIs.

Plugin interface

No, but comments are made in the code about possible enhancements.

These concerns port usage, how plugins can reference each other and state dependency.

Required Plugin support

For a traditional plugin to "delegate" to the separate L3 routing service plugins the following steps are required:

  • Do not inherit 'l3_db.L3_NAT_db_mixin' anymore.
  • Remove "router" from 'supported_extension_aliases'.
  • Modify any 'self' references to members in L3_NAT_db_mixin to instead use
    • 'manager.QuantumManager.get_service_plugins()[constants.L3_ROUTER_NAT]' For example,


      self.prevent_l3_port_deletion(...)
  • becomes something like


      plugin = manager.QuantumManager.get_service_plugins()[
         constants.L3_ROUTER_NAT]
      plugin.prevent_l3_port_deletion(...)

Dependencies:

No new dependencies.

CLI Requirements:

None.

Usage Example:

The code patch for this blueprint contains a L3 router service plugin that provides the L3 routing functionality that is otherwise provided by the traditional plugins. The Openvswitch and Linuxbridge plugins have been modified so that they do not provide L3 functionality. For these two plugins the L3 routing functionality is delegated to the L3 routing service plugin.

The L3 plugin is specified by the ‘service_plugins’ setting in ‘quantum.conf’ and the l3 agent is configured in the usual way in the ‘l3agent.ini’ file.

Excerpt from quantum.conf:


core_plugin =
quantum.plugins.openvswitch.ovs_quantum_plugin.OVSQuantumPluginV2
service_plugins =
quantum.plugins.services.l3_router.l3_router_plugin.L3RouterPlugin

Test Cases:

Unit tests will be extended to also cover the case where the L3 routing functionality is handled by a routing service plugin separate from the traditional plugin. Tests for the external network attribute are put in a separate file for that extension.