Jump to: navigation, search

Difference between revisions of "Neutron/ServiceInsertion"

m (ThierryCarrez moved page Quantum/ServiceInsertion to Neutron/ServiceInsertion)
 
(35 intermediate revisions by 6 users not shown)
Line 1: Line 1:
__NOTOC__
 
----
 
This page contains the design spec for the service insertion blueprint.
 
Despite being quite fleshed out the spec is not finalised yet, as some details are still subject to change, especially as far as the implementation plan is concerned.
 
Please subscribe to this page to get every update, or check it as often as necessary.
 
The blueprint itself can be found at this address:
 
----
 
  
= High level description =
+
= WORK IN PROGRESS =
 +
We are integrating all the information related to Services Insertion in only one wiki page
  
The ''service insertion'' feature aims at defining a framework for running L4/L7 network services on Quantum Logical Networks.
+
= Services Insertion Model in Quantum =
 +
* '''Launchpad Entries''':
 +
 
 +
''''' [https://blueprints.launchpad.net/quantum/+spec/quantum-service-type services-type] '''''
 +
 
 +
''''' [https://blueprints.launchpad.net/quantum/+spec/services-insertion-wrapper services-insertion-wrapper (folsom)] '''''
 +
 
 +
* '''Contributors''': [https://launchpad.net/~salvatore-orlando Salvatore],[https://launchpad.net/~emagana Edgar Magana], [https://launchpad.net/~enikanorov Eugene], Ram Durairaj, Mani Ramasamy and Quantum Community.
 +
 
 +
== Description ==
 +
This page contains the design spec for the service insertion blueprint. Despite being quite fleshed out the spec is not finalised yet, as some details are still subject to change, especially as far as the implementation plan is concerned. Please subscribe to this page to get every update, or check it as often as necessary.  The blueprint itself can be found at this address:
 +
 
 +
This specification does not fully respects the blueprint template set for Quantum. This is because we are giving much more space to the design discussion. We will have another wiki page using the blueprint template once the design discussion is Finalized.
 +
 
 +
== High level description ==
 +
The ''service insertion'' feature aims at defining a framework for running L4/L7 network services on Quantum Logical Topologies. This framework will be immediately leveraged by the LBaaS effort; and in the near future by other advanced services which will be plugged into Quantum (for instance, VPN, and edge firewalls).
 +
 
 +
== Defining Service Insertion ==
 +
Before going in depth into design and implementation discussion, it might be worth to define in a detailed way what an advanced service is, and how it could be inserted in the Quantum logical topology. The diagram below show Quantum's basic network topology, with a logica router interconnecting internal and external networks; ports, which are used for VIF, DHCP server, router, and floating IP attachments are also shown in the diagram.
 +
 
 +
[[Image:basic-topology.png]]
  
 
From previous discussions it emerged that services can be inserted in the following modes:
 
From previous discussions it emerged that services can be inserted in the following modes:
# Routed mode - Where the service is applied
 
  
Defining which services might be inserted, and how they should be presented to tenants is beyond the scope of this blueprint, which focuses on:
+
* Routed mode - Where the service is attached to a logical router, which then becomes a multi-service appliance.
* providing a set of API calls (as well supporting logic and data model) for defining which, where, and how services might be attached on the logical topology defined by the fundamental Quantum resources (ports, networks, routers);
 
* providing authorization policies for discriminating access to the above mentioned API calls, in accordance wit the Quantum policy engine;
 
* providing the infrastructure for allowing implementations of these services to serve API requests; multiple implementations for each class of service should be allowed to coexist at the same time in a Quantum deployment.
 
  
''Further notes:''
+
[[Image:routed-si.png]]
  
= API =
+
* Floating Mode (In-path) - Where service runs in a standalone way. Please note that the "Floating" insertion is not automatically a network level insertion, as L3 routing might still occur. This mode has also been referred as "in-path or bump-in-the-wire" insertion.
  
Service insertion support will require the following changes in the Quantum API
+
[[Image:in-path-si.png]]
  
== [[ServiceType]] Definition ==
+
With reference to the diagram above, is is worth noting that an advanced service, even when inserted in floating mode, should still 'plug' into networks. In the example above, the service plugs into the external network and into an internal network. This should be reflected by ports on the relevant Quantum networks ''owned'' by the advanced service itself.
  
This is an entirely new resource, which defines a list of services (and their providers) which can be offered to tenants.
+
* Re-directed Mode (Out-of-path) - Where the service also runs in a standalone way but in this case the traffic is first sent to the Router entity and then redirected to the Advanced Service, finally send it back to the routed with specific configuration. In particular, this model could be reduced to the first assuming that a standalone service is regarded as a peculiar case of router capable of providing only a specific service. This mode needs specific changes at the routing entity and may not be implemented in Grizzly release.
Note: [[ServiceDefinition]] might translate either to a 1st class resource or to an element of the ''service_definition'' attribute of the '''[[ServiceType]]''' resource.
+
 
While the former approach might seem conceptually more correct, the latter approach will probably lead to a leaner, more efficient, and easier to use API interface.
+
[[Image:out-of-path-si.png]]
 +
 
 +
All these three modes are not mutually exclusive. The diagram below shows how they can be combined. With reference to the diagram below, it is worth noting that the services inserted in routing and floating modes could have different implementations. This means for instance, that instances on the same Quantum networks could be load balanced using two different solutions.
 +
 
 +
[[Image:mixnmatch-si.png]]
 +
 
 +
== The Service Type concept ==
 +
Just like the Quantum plugins allow for using several technologies for implementing the basic logical topologies, advanced services will use a similar mechanism. However, for advanced services, multiple different implementations of the same kind of service might co-exist in the same deployment. There are a number of reasons for this, most importantly the ability of giving tenants a choice among solutions. The '''Service Type''' concept tries to address the need for multiple, co-existing, service providers.
 +
 
 +
A '''Service Type''' definitions might be regarded as list of services (and their providers) which can be offered to tenants. Each advanced service, regardless of its insertion mode, should be either directly or indirectly associated with a single service type.
 +
 
 +
The Service Type resource might be described as follows:
  
  
Line 46: Line 67:
 
   name: string,
 
   name: string,
 
   type: enum(LB, VPN, FW) # or whatever you think is right
 
   type: enum(LB, VPN, FW) # or whatever you think is right
   provider: string # This ultimately must map to a python class
+
   provider: string # This ultimately must map to a python class (perhaps through a configuration variable)
 
   capabilities: list of API extensions which are enabled for this specify service provider
 
   capabilities: list of API extensions which are enabled for this specify service provider
 
}
 
}
 +
</nowiki></pre>
 +
 +
Please note that the ''ServiceDefinition'' object might be regarded either as a resource of its own, or as a child resource of ''ServiceType''. The association between a service and a service type can happen in two ways, according to the insertion mode of the service.
 +
 +
* ''Routed'' Insertion mode: The advanced service will be associated with Quantum logical router, which in turn is associated with a service_type resource;
 +
 +
In order to ensure backward compatibility a default service type must be specified. This implies that all the services which will be inserted on a router will share the same service type.
 +
 +
* ''Floating'' Insertion mode: The service type should be explicitly specified on the advanced service being created; if not, the default service type will be used.
 +
 +
When an advanced service is created at the API layer one of the following two should be specified:
 +
 +
# service_type_id # floating or out-of-path insertion
 +
# router_id # routed or in-path insertion
 +
 +
It should not be allowed to specify both parameters.
  
</nowiki></pre>
+
The logical model for service insertion, augmented with the service type concept, is depicted in the following diagram:
 +
 
 +
[[Image:svc-type.png]]
 +
 
 +
The diagram shows a set of services deployed in routed mode (light blue), and a service deployed in floating mode (purple). Light blue and purple services are associated with different service types, which then can map to distinct implementations of the same services.
 +
 
 +
== Dispatching calls to the plugins ==
 +
The concept of service type implicitly allows for different paths for an API call, as it allows multiple providers to serve the same request. Eugene Nikanorov also addresses this topic in this wiki page: http://wiki.openstack.org/Quantum/ServiceIntegration
 +
 
 +
There are two design alternatives to be considered:
 +
 
 +
# A single plugin, augmented with the capability of serving requests for advanced services; call will then be redirected to provider-specific drivers.
 +
# Multiple, self-contained plugins. Each plugin is specific to a given service provider and might implement one or more advanced service interfaces.
  
 +
For both design alternatives, it is pretty clear that each advanced service should have a 'service plugin interface', which is the plugin-side dual of the tenant-facing APIs. The core Quantum plugin similarly, defines a plugin interface that all plugins must implement.
  
CRUD operations should be available on a [[ServiceType]] object. Regular tenants typically should be allowed to read only, whereas administrators would have right to create, modify, and delete those object. Also, the provider attribute might be hidden in response returned to regular tenants.
+
=== Single Plugin Approach ===
Please note however, that default policy settings might always be overridden as they're specified in ''etc/policy.json''
+
The diagram below show a Quantum Plugin which implements both core and advanced services interface. The plugin is capable of interpreting the service_type attribute, and dispatching the call to the appropriate, provider-specific driver.
  
== Router ==
+
[[Image:single-plugin.png]]
  
In order to associate services with Quantum logical router, thus
+
For this approach it should be possible to leverage the "mixin" mechanism which proved successful when integrating DHCP and L3 services. The possibility of augmenting the Quantum plugin with the capability of handling advanced services should definitely be allowed. In this case there will still be a single Quantum plugin; Appropriate ''service drivers'' should be specified in the configuration file. For each service multiple drivers might be specified; The service driver should not be seen as a driver for a specific appliance implementing the service. It is rather a driver managing the service for a given provider.
--> extend with attribute: services:service_type_id # which refers to service_type object
 
  
NOTE: We need to understand whether we want to model also a network_level service insertion capability.
+
=== Multiple Plugins Approach ===
the insertion point is purely logical, and determines the scope of the advanced service being plugged in - no changes are expected in back-end implementation.
+
The diagram below show how service type are mapped to multiple plugins when adopting this approach. Each plugin implements an interface which is specific for the kind of service it implements. The API layer has a dispatcher component which forwards the call to the appropriate plugin, according to the service type associated with the advanced service specified at the API layer.
This could achieved by assigning a service_type_id to networks too; however we might need to describe in the service_type definition, which insertion_modes are allowed for each service_definition.
 
Good food for thought, but not necessarily something we want to address immediately. Please note that the "Floating" insertion is not necessarily a network level insertion, as routing might still occur (see examples in slides).
 
Network level insertion might be an interesting concepts for services such as L2 VPNs, or if we want to move the DHCP service we already run in the service insertion scheme.
 
  
== Enabling or Disabling services on a router ==
+
[[Image:multi-plugin.png]]
  
Option 1: Resource action /routers/<router_id>/enable_service
+
It is a Quantum principle that plugins are required only to implement the plugin interface. Hence they are not required to adopt the mixin mechanism; hence another aspect to consider is that there could be multiplie plugins at the same type, and the intelligence of dispatching a call to one plugin or another should reside in the API layer.
/routers/<router_id>/disable_service
 
  
Option 2: List Attribute
+
In this case several plugins might be configured at the same time. The API layer will need to figure out, for each router and/or advanced service, to which plugin the API call should be dispatched. It is also worth noting that a plugin should not be constrained to implement a single advanced services. It might well be that plugins implement a set of services; this is particularly the case of plugins which will be interfaced with integrated services appliances or application delivery controllers.
Option 3: Sub-Resource POST /routers/<router_id>/enabled_services
 
  
== Load Balancer, or other entities which allow tenants to define higher layer services ==
+
In this case the diagram above could be generalised as follow (the reference to the configuration file is an implementation detail at this stage):
  
---> extend with attribute: services:service_type_id # standalone, one-arm, or whatever we call it
+
[[Image:multi-plugin-2.png]]
---> specify router_id # insertion in routed mode
 
  
[ALTERNATIVE] Consider attaching services to routers or networks with interfaces, as we do for the DHCP service
+
=== Evaluation of pro and cons of both Approaches ===
The DHCP service is a sort of half-hidden in the logical topology - one can see its port, but not retrieve it from the API.
+
The diagrams below depicts, at a very high level, the different flows of the single versus multiple plugins approaches. The single plugin approach is reported on the right, whereas the multiple plugin approach is reported on the left.
Something similar happens with advanced services (think about the source IP address on a LB, exactly the same thing as a router interface).
 
  
== Service insertion framework API ==
+
[[Image:single-vs-multi.png]]
  
Propose it as an extension. This would be a required extension for eventual service API extensions - such as LB. This might imply the rework of the extension API framework should be complete before
+
* multiple plugins will require the API to manipulate data from different sources. Even if each plugin will return data in the same format, we will still need logic to handle collecting data from multiple sources on GET requests, and dispatching commands to the appropriate destination on POST/PUT/DELETE.
 +
* currently all plugins already implement the "mixin" approach for augmenting the L2 feature with L3 and DHCP features. This mechanism could be extended.
 +
* compatibility between plugins (not something we need to worry from day 1, but still an interesting problem)
 +
* interactions among plugins; with a single plugin, the data model has all the information it needs. With multiple plugins will have to interact with the "base" plugin (or in some cases even among them); this could be achieved throughout the plugin interfaces.
 +
* the single plugin, multiple drivers, model works very well when the Quantum database holds all the required information necessary to operate. This implies that items such as device management, resource allocation, and similars, are described using a model shared by all plugins. Although this might be mitigated by either introducing driver-specific extensions, or moving such capabilities in the driver, this is clearly a case in which the multiple plugins approach is preferred.
  
'''Configuration variables:''' [List and explanation of the    new configuration variables (if they exist)]
+
== A few notes on the scope of this blueprint ==
 +
This blueprint which focuses on:
  
'''Algorithm: '''[Provide an overview of any algorithms that will be used]
+
* Providing the infrastructure for allowing implementations of these services to serve API requests; multiple implementations for each class of service should be allowed to coexist at the same time in a Quantum deployment.
 +
* Defining a set of API calls (as well supporting logic and data model) for defining which, where, and how services might be attached on the logical topology defined by the basic Quantum topology;
 +
* Allowing providers of such services to expose implementation-specific service extensions and advertising them to API users.
  
'''Data Model Changes: '''[Are you introducing new model classes, or extending existing ones?]
+
Defining which services might be inserted, and how they should be presented to tenants is beyond the scope of this blueprint. Activity is already ongoing for the Load Balancing service; for more information please refer to lbaas-* blueprints in the Quantum framework.
  
'''Plugin Interface: '''[Does this feature introduce any change?]
+
Most of the concepts expressed in this blueprint are not new to the Quantum community and can be found in this wiki page authored by Edgar Magana from Cisco: http://wiki.openstack.org/QuantumServicesInsertion
  
'''Required Plugin support: '''[What should the plugins do to support this new feature? (If applicable)]
+
''Further notes (or what this design specification is not about):''
= API Changes =
 
  
== Policy Engine ==
+
* There might be scenarios where service insertion happens at network level, as shown in Sasha Ratkovic's presentation. For the scope of this blueprint we will consider only router-level insertion, assuming that network-level insertion could be reduced to a case in which the service is inserted on a router connected to a single network only.
 +
* There are also definitely scenarios where service insertion happens at the port level; in this case the insertion might be simply represented by attributes applied to the port itself. For an example please refer to the proposed https://review.openstack.org/#/c/14262/.
 +
* The concept of port group, presented by Sasha Ratkovic at the Openstack Design Summit is also outside of the scope of this blueprint.
 +
* Whether advanced services will be realized as new resource (as described in the LBaaS proposal) or as policies (as described by Sasha Ratkovic proposal), is also beyond the scope of this blueprint.
  
The default behaviour should be:
+
At this stage the careful reader might be wondering whether this blueprint is actually about anything. With all due honesty by defining a (small) set of items we want to address, and a (very large) of items that we definitely do not want to address, it might be argued that this blueprint is actually pretty well scoped, leaving a very thin, blurred, area of items which might or might not be addressed by it.
  
service_type operations: admin_only
+
= Work Tasks =
tenants should be allowed to specify a service_type for their routers and or "advanced services"
+
== API ==
 +
The service insertion API might be implemented as a Quantum extension for the Grizzly release cycle, or be part of the core if there is a total agreement on it. Service insertion support will require the following changes in the Quantum API:
  
= DB Changes =
+
* Service Type management. CRUD operations should be available on a ServiceType object.
 +
* Regular tenants typically should be allowed to read only
 +
* Administrators would have right to create, modify, and delete those object. Also, the provider attribute might be hidden in response returned to regular tenants.
  
[[ServiceType]] definition will require two model classes.
+
''Note'': default policy settings might always be overridden as they're specified in ''etc/policy.json''
The [[ServiceType]] class will have a 1:n relationship with the [[ServiceDefinition]] class. This class will have an attribute for defining the type of the advanced services provider. This could either be another class in the model or extracted from the Quantum configuration file.
 
  
[[ServiceProvider]] definition could as well be either another model class or information extracted from the configuration file (see next section on plugin integration)
+
The Router resource should therefore be extended with the following attribute:
  
Every time a router is created, an instance of service_type should be created. Even if this could be part of the router object, it might come handy having it as a standalone model class.
 
  
ROUTER - 1 ---- 1 - SERVICE_TYPE_INSTANCE - n ---- 1 - SERVICE_TYPE
+
<pre><nowiki>
        /
+
  services:service_type_id # which refers to service_type object
          LB - 1 ---- 1 --/  
+
</nowiki></pre>
  
If the service_type_instance model class is not used, model classes for LB, and other type of services will directly refer a service_type, which is however acceptable.
+
Each advanced service should allow for specifying either a service type id (for floating mode insertion) or a router_id (for routed mode insertion).
  
= Plugin Integration =
+
If a router supports multiple services, the tenant might be given the ability of enabling or  disabling specific services on a router, in accordance with the service_type associated with the router. This feature might be used by tenants to keep advanced service usage within quota limits.
  
The concept of service type implicitly allows for different paths for an API call.
+
* Option 1: Resource action    /routers/<router_id>/enable_service
Ideally one would reuse the "mixin" mechanism which proved successful when integrating DHCP and L3 services. The possibility of augmenting the core_plugin with the capability of handling advanced services should definitely be allowed. In this case there will still be a 'core_plugin" only.
+
** /routers/<router_id>/disable_service
However, it is a principle of Quantum that plugins are required only to implement the plugin interface. Hence they are not required to adopt the mixin mechanism; hence another aspect to consider is that there could be multiplie plugins at the same type, and the intelligence of dispatching a call to one plugin or another should reside in the API layer.
+
* Option 2: List Attribute
 +
* Option 3: Sub-Resource      POST /routers/<router_id>/enabled_services
  
It seems that the following situations are therefore to be considered:
+
Option 1 is currently the preferred one, as it is consistent with "the Openstack way" of defining APIs executing actions on resources beyond the ones that can be expressed as HTTP methods.
1) Single plugin with the same provider for all advanced services (think about current implementation). In this case no service provider definition should be needed.
 
2) Single plugin with distinct "drivers" for each service provider. This implies that all services implement the same db model. The mixin classes for advanced services will have a driver interface which will be invoked for performing actual configuration.
 
In this case service drivers should be specified in the configuration file. For each service multiple drivers should be allowed (consider using multivalued options); The service driver should not be seen as a driver for a specific appliance implementing the service. It is rather a driver managing the service for a given provider. As an example, it might manage a pool of physical load balancers, or handle the provisioning of integrated services virtual appliances.
 
3) Multiple independent plugins. In this case several plugins might be configured at the same time. The API layer will need to figure out, for each router and/or advanced service, to which plugin the API call should be dispatched.
 
4) An arbitrary mix of scenarios #2 and #3,
 
  
Scenarios #3 and #4 appear more complex than #1 and #2 (are they?). This is for the following reasons:
+
== Service Configuration ==
- multiple plugins will require the API to manipulate data from different sources. Even if each plugin will return data in the same format, we will still need logic to handle collecting data from multiple sources on GET requests, and dispatching commands to the appropriate destination on POST/PUT/DELETE.
+
The configuration file should contains references to the drivers/plugins corresponding to the various advanced services. These information will be used by the plugin manager.
- currently all plugins already implement the "mixin" approach
 
- compatibility between plugins (not something we need to worry from day 1, but still an interesting problem)
 
- interactions among plugins. In scenarios #1 and #2, having a single plugin, the data model has all the information it needs. With scenarios #3 and #4 the "additional" plugins will have to interact with the "base" plugin (or in some cases even among them); this could be achieved throughout he REST interfaces or by creating appropriate RPC interfaces
 
  
Grizzly plan: provide support for #1 and #2 (actually #1 is just a particular case of #2)
+
The configuration file might also contain service type definitions, which could alternatively be stored in the Quantum 'core' database (see section on Data Model Changes).
  
= Changes to the current implementation =
+
== Plugin Manager ==
 +
A mechanism for loading multiple plugins will be required for the multi-plugin approach. The PluginAwareExtensionManager does not manage plugin loading, but some work will be required on it for handling plugin-specific API extensions, as it currently assumes that there's only a single plugin.
  
--> Define a driver interface for L3 and Floating IP functionalities
+
== Data Model Changes ==
--> Implement drivers for the l3_agent (they will probably empty as the l3 agent polls quantum server)
+
ServiceType definition, if modeled into the Quantum DB will require two model classes. The ServiceType class will have a 1:n relationship with the ServiceDefinition class. This class will have an attribute for defining the type of the advanced services provider. This could either be another class in the model or extracted from the Quantum configuration file.
--> Allow multiple external gateways per router (thus enabling PBR)? [Probably not for Grizzly]
 
--> Allow multiple routers per external network? [Probably yes for Grizzly]
 
  
Items worth being considered:
+
ServiceProvider definition could as well be either another model class or information extracted from the configuration file.
  
Think about the current Floating IP API and whether it fits the service insertions model (as it plugs into an external network and derives the router from the context)
+
== Changes to the basic plugin Interface ==
--> allow for router_id or service_type_id specification (or restricted floating ip to be applicable to routers only)?
+
The service insertion feature will add a new interface which might be implemented as a new mixin to be inherited by the "core" plugin (a completely standalone class is a viable alternative, albeit less straightforward)
  
Think about how the DHCP service we implement today through the agent fits in this model. We are not exposing specifically any DHCP API, creating implicitly an instance of this service for each subnet for which dhcp_enable=True.
+
== Managing API dispatching ==
We can either leave DHCP as it is, or include it in the service insertion model. If we go the second route, we need to think about network-level insertion, and devise a way for doing this in a backward compatible way.
+
This task is about implementing the single plugin/multiple drivers or multi-plugin approaches, as discussed earlier in this spec document.
  
= POC implementation (with APIs already available in Quantum - namely L3 and Floating IPs) =
+
= Potential changes to the current implementation =
 +
# Floating IPs: despite being shipped with Folsom, this feature might actually be regarded as an 'advanced service', and should probably fit in the service insertion framework.
 +
# External Gateway: This might be possibly be regarded as an advanced service too. For instance, a SNAT service.
 +
# DHCP:  think about how the DHCP service we implement today through the agent fits in the service insertion model. We are not exposing specifically any DHCP API, creating implicitly an instance of this service for each subnet for which ''dhcp_enable=True''. We can either leave DHCP as it is, or include it in the service insertion model.
  
Integrated services VMs - provides same services as L3 agent, but all within a "router VM".
+
NOTE: For the cases listed above it is very important to preserve backward compatibility.
  
Choice of service type definition:
+
= POC Proposal =
1) [[ServiceType1]]:
+
A POC of the service insertion model could be offered regardless of actual advanced services being implemented on top of Quantum. This POC might use 'dummy' advanced services plugins. Another options would be reworking the Floating IP and possibly also the external gateway concepts as advanced services and use them for the PoC.
routing, floating_ips: l3_agent
 
2) [[ServiceType2]]:
 
routing, floating_ips: integrated_services_vm
 
  
Provisioning of Back end resource: this should probably always be a driver-specific task.
+
= Mapping tasks to Grizzly milestones =
 +
{| border="1" cellpadding="2" cellspacing="0"
 +
| '''Task'''
 +
| '''Importance'''
 +
|-
 +
| Service Type definition
 +
| Essential
 +
|-
 +
| Plugin/Driver management
 +
| Essential
 +
|-
 +
| API Call Dispatching
 +
| Essential
 +
|-
 +
| PoC with dummy plugins
 +
| High
 +
|-
 +
| PoC with LBaaS
 +
| Essential
 +
|-
 +
| APIs for service type management
 +
| Undecided
 +
|-
 +
| Service types in Quantum DB
 +
| Normal
 +
|-
 +
| Reworking some L3 capabilities as adv svc
 +
| Undecided

Latest revision as of 15:54, 21 June 2013

WORK IN PROGRESS

We are integrating all the information related to Services Insertion in only one wiki page

Services Insertion Model in Quantum

  • Launchpad Entries:

services-type

services-insertion-wrapper (folsom)

Description

This page contains the design spec for the service insertion blueprint. Despite being quite fleshed out the spec is not finalised yet, as some details are still subject to change, especially as far as the implementation plan is concerned. Please subscribe to this page to get every update, or check it as often as necessary. The blueprint itself can be found at this address:

This specification does not fully respects the blueprint template set for Quantum. This is because we are giving much more space to the design discussion. We will have another wiki page using the blueprint template once the design discussion is Finalized.

High level description

The service insertion feature aims at defining a framework for running L4/L7 network services on Quantum Logical Topologies. This framework will be immediately leveraged by the LBaaS effort; and in the near future by other advanced services which will be plugged into Quantum (for instance, VPN, and edge firewalls).

Defining Service Insertion

Before going in depth into design and implementation discussion, it might be worth to define in a detailed way what an advanced service is, and how it could be inserted in the Quantum logical topology. The diagram below show Quantum's basic network topology, with a logica router interconnecting internal and external networks; ports, which are used for VIF, DHCP server, router, and floating IP attachments are also shown in the diagram.

Basic-topology.png

From previous discussions it emerged that services can be inserted in the following modes:

  • Routed mode - Where the service is attached to a logical router, which then becomes a multi-service appliance.

Routed-si.png

  • Floating Mode (In-path) - Where service runs in a standalone way. Please note that the "Floating" insertion is not automatically a network level insertion, as L3 routing might still occur. This mode has also been referred as "in-path or bump-in-the-wire" insertion.

In-path-si.png

With reference to the diagram above, is is worth noting that an advanced service, even when inserted in floating mode, should still 'plug' into networks. In the example above, the service plugs into the external network and into an internal network. This should be reflected by ports on the relevant Quantum networks owned by the advanced service itself.

  • Re-directed Mode (Out-of-path) - Where the service also runs in a standalone way but in this case the traffic is first sent to the Router entity and then redirected to the Advanced Service, finally send it back to the routed with specific configuration. In particular, this model could be reduced to the first assuming that a standalone service is regarded as a peculiar case of router capable of providing only a specific service. This mode needs specific changes at the routing entity and may not be implemented in Grizzly release.

Out-of-path-si.png

All these three modes are not mutually exclusive. The diagram below shows how they can be combined. With reference to the diagram below, it is worth noting that the services inserted in routing and floating modes could have different implementations. This means for instance, that instances on the same Quantum networks could be load balanced using two different solutions.

Mixnmatch-si.png

The Service Type concept

Just like the Quantum plugins allow for using several technologies for implementing the basic logical topologies, advanced services will use a similar mechanism. However, for advanced services, multiple different implementations of the same kind of service might co-exist in the same deployment. There are a number of reasons for this, most importantly the ability of giving tenants a choice among solutions. The Service Type concept tries to address the need for multiple, co-existing, service providers.

A Service Type definitions might be regarded as list of services (and their providers) which can be offered to tenants. Each advanced service, regardless of its insertion mode, should be either directly or indirectly associated with a single service type.

The Service Type resource might be described as follows:


ServiceType:
{
  id: uuid,
  name: string,
  service_definitions: list<ServiceDefinition>
  default: {True¦False} # Only one service_type could be the default one. This is the service type which should be picked if none is specified in the API (think backward compatibility)
}

ServiceDefinition:
{
  id: uuid,
  name: string,
  type: enum(LB, VPN, FW) # or whatever you think is right
  provider: string # This ultimately must map to a python class (perhaps through a configuration variable)
  capabilities: list of API extensions which are enabled for this specify service provider
}

Please note that the ServiceDefinition object might be regarded either as a resource of its own, or as a child resource of ServiceType. The association between a service and a service type can happen in two ways, according to the insertion mode of the service.

  • Routed Insertion mode: The advanced service will be associated with Quantum logical router, which in turn is associated with a service_type resource;

In order to ensure backward compatibility a default service type must be specified. This implies that all the services which will be inserted on a router will share the same service type.

  • Floating Insertion mode: The service type should be explicitly specified on the advanced service being created; if not, the default service type will be used.

When an advanced service is created at the API layer one of the following two should be specified:

  1. service_type_id # floating or out-of-path insertion
  2. router_id # routed or in-path insertion

It should not be allowed to specify both parameters.

The logical model for service insertion, augmented with the service type concept, is depicted in the following diagram:

Svc-type.png

The diagram shows a set of services deployed in routed mode (light blue), and a service deployed in floating mode (purple). Light blue and purple services are associated with different service types, which then can map to distinct implementations of the same services.

Dispatching calls to the plugins

The concept of service type implicitly allows for different paths for an API call, as it allows multiple providers to serve the same request. Eugene Nikanorov also addresses this topic in this wiki page: http://wiki.openstack.org/Quantum/ServiceIntegration

There are two design alternatives to be considered:

  1. A single plugin, augmented with the capability of serving requests for advanced services; call will then be redirected to provider-specific drivers.
  2. Multiple, self-contained plugins. Each plugin is specific to a given service provider and might implement one or more advanced service interfaces.

For both design alternatives, it is pretty clear that each advanced service should have a 'service plugin interface', which is the plugin-side dual of the tenant-facing APIs. The core Quantum plugin similarly, defines a plugin interface that all plugins must implement.

Single Plugin Approach

The diagram below show a Quantum Plugin which implements both core and advanced services interface. The plugin is capable of interpreting the service_type attribute, and dispatching the call to the appropriate, provider-specific driver.

Single-plugin.png

For this approach it should be possible to leverage the "mixin" mechanism which proved successful when integrating DHCP and L3 services. The possibility of augmenting the Quantum plugin with the capability of handling advanced services should definitely be allowed. In this case there will still be a single Quantum plugin; Appropriate service drivers should be specified in the configuration file. For each service multiple drivers might be specified; The service driver should not be seen as a driver for a specific appliance implementing the service. It is rather a driver managing the service for a given provider.

Multiple Plugins Approach

The diagram below show how service type are mapped to multiple plugins when adopting this approach. Each plugin implements an interface which is specific for the kind of service it implements. The API layer has a dispatcher component which forwards the call to the appropriate plugin, according to the service type associated with the advanced service specified at the API layer.

Multi-plugin.png

It is a Quantum principle that plugins are required only to implement the plugin interface. Hence they are not required to adopt the mixin mechanism; hence another aspect to consider is that there could be multiplie plugins at the same type, and the intelligence of dispatching a call to one plugin or another should reside in the API layer.

In this case several plugins might be configured at the same time. The API layer will need to figure out, for each router and/or advanced service, to which plugin the API call should be dispatched. It is also worth noting that a plugin should not be constrained to implement a single advanced services. It might well be that plugins implement a set of services; this is particularly the case of plugins which will be interfaced with integrated services appliances or application delivery controllers.

In this case the diagram above could be generalised as follow (the reference to the configuration file is an implementation detail at this stage):

Multi-plugin-2.png

Evaluation of pro and cons of both Approaches

The diagrams below depicts, at a very high level, the different flows of the single versus multiple plugins approaches. The single plugin approach is reported on the right, whereas the multiple plugin approach is reported on the left.

Single-vs-multi.png

  • multiple plugins will require the API to manipulate data from different sources. Even if each plugin will return data in the same format, we will still need logic to handle collecting data from multiple sources on GET requests, and dispatching commands to the appropriate destination on POST/PUT/DELETE.
  • currently all plugins already implement the "mixin" approach for augmenting the L2 feature with L3 and DHCP features. This mechanism could be extended.
  • compatibility between plugins (not something we need to worry from day 1, but still an interesting problem)
  • interactions among plugins; with a single plugin, the data model has all the information it needs. With multiple plugins will have to interact with the "base" plugin (or in some cases even among them); this could be achieved throughout the plugin interfaces.
  • the single plugin, multiple drivers, model works very well when the Quantum database holds all the required information necessary to operate. This implies that items such as device management, resource allocation, and similars, are described using a model shared by all plugins. Although this might be mitigated by either introducing driver-specific extensions, or moving such capabilities in the driver, this is clearly a case in which the multiple plugins approach is preferred.

A few notes on the scope of this blueprint

This blueprint which focuses on:

  • Providing the infrastructure for allowing implementations of these services to serve API requests; multiple implementations for each class of service should be allowed to coexist at the same time in a Quantum deployment.
  • Defining a set of API calls (as well supporting logic and data model) for defining which, where, and how services might be attached on the logical topology defined by the basic Quantum topology;
  • Allowing providers of such services to expose implementation-specific service extensions and advertising them to API users.

Defining which services might be inserted, and how they should be presented to tenants is beyond the scope of this blueprint. Activity is already ongoing for the Load Balancing service; for more information please refer to lbaas-* blueprints in the Quantum framework.

Most of the concepts expressed in this blueprint are not new to the Quantum community and can be found in this wiki page authored by Edgar Magana from Cisco: http://wiki.openstack.org/QuantumServicesInsertion

Further notes (or what this design specification is not about):

  • There might be scenarios where service insertion happens at network level, as shown in Sasha Ratkovic's presentation. For the scope of this blueprint we will consider only router-level insertion, assuming that network-level insertion could be reduced to a case in which the service is inserted on a router connected to a single network only.
  • There are also definitely scenarios where service insertion happens at the port level; in this case the insertion might be simply represented by attributes applied to the port itself. For an example please refer to the proposed https://review.openstack.org/#/c/14262/.
  • The concept of port group, presented by Sasha Ratkovic at the Openstack Design Summit is also outside of the scope of this blueprint.
  • Whether advanced services will be realized as new resource (as described in the LBaaS proposal) or as policies (as described by Sasha Ratkovic proposal), is also beyond the scope of this blueprint.

At this stage the careful reader might be wondering whether this blueprint is actually about anything. With all due honesty by defining a (small) set of items we want to address, and a (very large) of items that we definitely do not want to address, it might be argued that this blueprint is actually pretty well scoped, leaving a very thin, blurred, area of items which might or might not be addressed by it.

Work Tasks

API

The service insertion API might be implemented as a Quantum extension for the Grizzly release cycle, or be part of the core if there is a total agreement on it. Service insertion support will require the following changes in the Quantum API:

  • Service Type management. CRUD operations should be available on a ServiceType object.
  • Regular tenants typically should be allowed to read only
  • Administrators would have right to create, modify, and delete those object. Also, the provider attribute might be hidden in response returned to regular tenants.

Note: default policy settings might always be overridden as they're specified in etc/policy.json

The Router resource should therefore be extended with the following attribute:


  services:service_type_id # which refers to service_type object

Each advanced service should allow for specifying either a service type id (for floating mode insertion) or a router_id (for routed mode insertion).

If a router supports multiple services, the tenant might be given the ability of enabling or disabling specific services on a router, in accordance with the service_type associated with the router. This feature might be used by tenants to keep advanced service usage within quota limits.

  • Option 1: Resource action /routers/<router_id>/enable_service
    • /routers/<router_id>/disable_service
  • Option 2: List Attribute
  • Option 3: Sub-Resource POST /routers/<router_id>/enabled_services

Option 1 is currently the preferred one, as it is consistent with "the Openstack way" of defining APIs executing actions on resources beyond the ones that can be expressed as HTTP methods.

Service Configuration

The configuration file should contains references to the drivers/plugins corresponding to the various advanced services. These information will be used by the plugin manager.

The configuration file might also contain service type definitions, which could alternatively be stored in the Quantum 'core' database (see section on Data Model Changes).

Plugin Manager

A mechanism for loading multiple plugins will be required for the multi-plugin approach. The PluginAwareExtensionManager does not manage plugin loading, but some work will be required on it for handling plugin-specific API extensions, as it currently assumes that there's only a single plugin.

Data Model Changes

ServiceType definition, if modeled into the Quantum DB will require two model classes. The ServiceType class will have a 1:n relationship with the ServiceDefinition class. This class will have an attribute for defining the type of the advanced services provider. This could either be another class in the model or extracted from the Quantum configuration file.

ServiceProvider definition could as well be either another model class or information extracted from the configuration file.

Changes to the basic plugin Interface

The service insertion feature will add a new interface which might be implemented as a new mixin to be inherited by the "core" plugin (a completely standalone class is a viable alternative, albeit less straightforward)

Managing API dispatching

This task is about implementing the single plugin/multiple drivers or multi-plugin approaches, as discussed earlier in this spec document.

Potential changes to the current implementation

  1. Floating IPs: despite being shipped with Folsom, this feature might actually be regarded as an 'advanced service', and should probably fit in the service insertion framework.
  2. External Gateway: This might be possibly be regarded as an advanced service too. For instance, a SNAT service.
  3. DHCP: think about how the DHCP service we implement today through the agent fits in the service insertion model. We are not exposing specifically any DHCP API, creating implicitly an instance of this service for each subnet for which dhcp_enable=True. We can either leave DHCP as it is, or include it in the service insertion model.

NOTE: For the cases listed above it is very important to preserve backward compatibility.

POC Proposal

A POC of the service insertion model could be offered regardless of actual advanced services being implemented on top of Quantum. This POC might use 'dummy' advanced services plugins. Another options would be reworking the Floating IP and possibly also the external gateway concepts as advanced services and use them for the PoC.

Mapping tasks to Grizzly milestones

Task Importance
Service Type definition Essential
Plugin/Driver management Essential
API Call Dispatching Essential
PoC with dummy plugins High
PoC with LBaaS Essential
APIs for service type management Undecided
Service types in Quantum DB Normal
Reworking some L3 capabilities as adv svc Undecided