Neutron/ServiceInsertion

= 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) 


 * Contributors: Salvatore,Edgar Magana, 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.



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.




 * 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.



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.



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.



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 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:



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.



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.



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):



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.




 * 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//enable_service
 * /routers//disable_service
 * Option 2: List Attribute
 * Option 3: Sub-Resource      POST /routers//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 = {| 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
 * APIs for service type management
 * Undecided
 * Service types in Quantum DB
 * Normal
 * Reworking some L3 capabilities as adv svc
 * Undecided
 * Reworking some L3 capabilities as adv svc
 * Undecided