diff --git a/doc/source/devref/plugin_wrapper.rst b/doc/source/devref/plugin_wrapper.rst new file mode 100644 index 0000000..b7efb41 --- /dev/null +++ b/doc/source/devref/plugin_wrapper.rst @@ -0,0 +1,293 @@ + +Gluon Plugin Wrapper Design +============================ + +**Original Gluon Architecture** + +In the original design of Gluon, the Gluon Server was placed in the +communication path between Nova and the networking backends. Its main purpose +was to maintain a mapping of ports to networking backends and to route +port-related requests to the correct backend. See diagram below. + +:: + + +-------------------------+ + | | + | Nova | + | | + | +---------------+ | + | | Gluon | | + | | Plugin | | + +----+---------------+----+ + | + | Port Requests + | + v + +-------------------------+ + | | + | Gluon | + Register Port | Server | Register Port + +------------------>| |<-------------------+ + | | +---------+---------+ | | + | | | Neutron | Proton | | | + | +--+---------+---------+--+ | + | | | | + | Neutron Port Requests | | Gluon Port Requests | + | +-----------+ +------------+ | + | | | | + | | | | + | v v | + | +-------------------------+ +-------------------------+ | + | | | | | | + | | Neutron | | Proton | | + +--| Server | | Server |--+ + | | | | + +-------------------------+ +-------------------------+ + +The set of networking backends could be the Neutron Server plus one or more +Proton Servers. In the original design, each networking backend would register +a new port with the Gluon Server in order to populate the mapping. When the +Gluon Server received a port-related request, it would look up the port and +then forward the request to the correct backend by calling its associated +client driver. This required the Gluon Server to import and manage drivers +for the different types of networking backends. Another important aspect of +the original design is that the port objects and associated networking service +objects were maintained in each networking backend database. Hence, the +Neutron Server had no visibility to the ports defined in the Proton Server(s). + +In order to get the port-related requests directed to the Gluon Server, the +original design of Gluon replaced the Networking API plugin in Nova with a +modified version of the code that would provide a port-centric model of +networking and forward all requests to the Gluon Server. In the Mitaka +release, the Networking API plugin in Nova was deprecated allowing Nova to only +communicate with Neutron. This requires a significant change to the Gluon +design. + +**New Gluon Architecture** + +This document describes a way to loosely integrate the Gluon Server +functionality into Neutron while minimizing changes to the existing Proton +Server design. In this proposed design, the Proton Server will remain an API +endpoint and maintain a separate database from the Neutron Server. Since we +can no longer replace the plugin in Nova, the integration point for Gluon can +be done in the Neutron Server using the Core plugin interface. + +The Gluon Wrapper Plugin will subclass off of the ML2 core plugin class (or +any other Core Plugin class) and override just the port-related methods. If +the method call is for a Gluon port, the Gluon Wrapper Plugin code will forward +the request to the Proton Server for processing. Otherwise, the superclass +method will be called. The goal is to introduce the Gluon networking +functionality without breaking the existing ML2 networking. The following +diagram provides an overview of this design. + +:: + + +-------------------------+ + | | + | Nova | + | | + | +---------------+ | + | | Neutron | | + | | API Plugin | | + +----+---------------+----+ + | + | Port Requests + | + v + +--------------------------------+ + | Neutron | + | Server | + | | + | +-------------------+ | + | |+-----------------+| | + | || ML2 Plugin || | + | |+-----------------+| | + | | Gluon Wrapper | | + | | Plugin | | + | | +-------------+| | + | | |Proton Driver|| | + +------+----+-------------++-----+ + ^ | + | | + Check Gluon Port | | Gluon Port Requests + +-----------+ +-----------+ + | | + | | + v v + +---------+ +-------------------------+ + | etcd | | | + | | | Proton | + +---------+ | Server | + ^ | | + | | | + | | | + | | | + | +-------------------------+ + | | + | | + +---------------------------------+ + Register Port + + +The Gluon Wrapper Plugin will determine if a port belongs to Gluon by examining +(looking up the UUID) the etcd database. The port registration code in the +Proton Server will be changed to update the etcd database when a new port is +created or deleted. When a port is registered in the etcd database, the +following backend information is stored: tenant identifier, networking service +identifier and Proton Server base URL. In order to forward the requests to the +Proton Server(s), the same backend driver mechanism will be used by the Gluon +Wrapper Plugin as was used by the Gluon Sever. + +Since we can no longer replace the Networking API plugin in Nova, we must +provide a consistent “Neutron” networking model to Nova. Therefore, we have +to maintain the Network, Subnet and Port associations required by the logic in +the Neutron API plugin (in Nova). In the short term, we can create a “dummy” +Network and Subnet object in the Neutron Server that can be associated with all +Gluon ports. In the long term, it may be possible to add attributes to the +Network and Subnet objects to change the semantics of the objects to reflect a +more logical association with the Gluon ports. This document describes the +creation and usage of the Network and Subnet “dummy” objects without any +changes to the existing Neutron model. + +The “dummy” Network and Subnet objects need to be created during system turn +up. The Network and Subnet objects must be uniquely identifiable by the Gluon +Wrapper Plugin. One approach would be to specify the UUID of these objects in +the configuration file which can be loaded when the Neutron Server starts. +Another approach would be to give the objects unique names that can be +retrieved at runtime. The Network object needs to be created as a local shared +provider network. The Subnet object created for the Network should have the +gateway and DHCP disabled. The CIDR should not matter. + +**Plugin Processing** + +The Gluon Wrapper Plugin only has to intercept and handle the following methods +from the Core plugin base class: + +- update_port() - Update port values for bind/unbind operations +- get_port() - Return port values for specific port +- get_ports() - Return a list of ports + +The following diagram show the component interaction required to support the +processing of the above requests. + + +:: + + Neutron API + + | update_port() + | get_port() + | get_ports() + | + v + +------------------+ Function +------------------+ + | | Call | | + | | | | + | Gluon Wrapper | | Proton Backend | + | Plugin |-------------------->| Driver | + | | bind_port() | | + | | unbind_port() | | + +------------------+ get_port() +------------------+ + | | + | | + | read(port) | + | read(directory) | HTTP/REST + | | + | | + v v + +-----------+ +------------------+ + | etcd | | | + | | | | + +-----------+ | Proton Server | + | | + | | + | | + +------------------+ + +The Neutron API will convert updates to the port object into an update_port() +method call to the Core Plugin. The port UUID is passed as a parameter to this +method. The Gluon Wrapper Plugin overrides this method and will attempt to read +the corresponding backend information for the port from the etcd database. The +key used is “/gluon/port/”. If no backend information is found, the port +is assumed to be a Neutron port and the superclass update_port() method is +called. If the backend information is found, the network service identifier is +used to retrieve the backend driver for the specific networking service. The +port values are examined to determine if the port is being bound or unbound. +The host identifier field is used for this determination. The bind_port() or +unbind_port() method is called on the backend driver. The backend driver will +convert the "bind/unbind" operation into the appropriate REST calls to a Proton +Server. It is possible to have multiple Proton Server endpoints. The base URL +from the backend information is used to identify the Proton Server hosting the +networking service API. It is the responsibility of the backend driver to +collect the response(s) from the Proton Server and reformat the response into +the format expected by the plugin. In this case, the entire set of port values +is expected in the response. The backend driver will also insert the network_id +and fixed_ips fields in the response to make the object fit in the Neutron +model. The network_id is the UUID of the “dummy” Gluon Network object. The +fixed_ips field contains the UUID of the “dummy” Gluon Subnet object with the +IP address taken from the Gluon port (if applicable). + +The Neutron API will convert a retrieval of a port object into a get_port() +method call to the Core Plugin. The port UUID is passed as a parameter to this +method. The Gluon Wrapper Plugin overrides this method and will attempt to read +the corresponding backend information for the port from the etcd database. The +key used is “/gluon/port/”. If no backend information is found, the port +is assumed to be a Neutron port and the superclass get_port() method is called. +If the backend information is found, the network service identifier is used to +retrieve the backend driver for the specific networking service. The +get_port() method is called on the backend driver. The backend driver will +convert the “get" operation into the appropriate REST calls to a Proton Server. +It is possible to have multiple Proton Server endpoints. The base URL from the +backend information is used to identify the Proton Server hosting the +networking service API. It is the responsibility of the backend driver to +collect the response(s) from the Proton Server and reformat the response into +the format expected by the plugin. In this case, the entire set of port values +is expected in the response. The backend driver will also insert the network_id +and fixed_ips fields in the response to make the object fit in the Neutron +model. The network_id is the UUID of the “dummy” Gluon Network object. The +fixed_ips field contains the UUID of the “dummy” Gluon Subnet object with the +IP address taken from the Gluon port (if applicable). + +The Neutron API will convert a retrieval of multiple port objects into a +get_ports() method call to the Core Plugin. An optional filter parameter may +be passed to restrict the list of ports to be returned. The Gluon Wrapper +Plugin overrides this method and will first call the superclass method to get +the list of Neutron ports meeting the filter criteria. Next the etcd database +is read to get all of the values in the “/gluon/port” directory. For each UUID +found, the corresponding backend driver get_port() method is called to retrieve +the port information. The filter is applied to the port data and if passes the +port is appended to the port list. The final result is a list of Neutron and +Gluon ports that meet the filter criteria. + +**Plugin Usage** + +The Gluon package must be installed on the same controller server as the Neutron +package. The core_plugin option in the neutron.conf has to be changed to +point to the Gluon Wrapper plugin. For example, edit /etc/neutron.conf and set +core_plugin as follows: + +``core_plugin = gluon.plugin.core.GluonPlugin`` + +Restart the Neutron Server. It should pickup the Gluon Plugin. You can verify +by looking for "gluon" in the neutron server log file. + +For now, the GluonPlugin expects the etcd server and Proton Server to be +running on the same server. This will be changed when configuration parameters +are added to the .conf file. + +Before a Gluon port can be used, the "dummy" objects need to be created in +Neutron (as admin). The names are significant for now. + +Create Gluon Network object: + +*neutron net-create --shared --provider:network_type local GluonNetwork* + +Create Gluon Subnet object: + +*neutron subnet-create --name GluonSubnet --no-gateway --disable-dhcp GluonNetwork 0.0.0.0/1* + +At this point you should be able to create the objects in the Proton Server and +use nova boot to create a VM using the Gluon port. + + +