Quantum-api-filters

= Filters for Quantum API =

Summary
The goal of this blueprint is to improve the Quantum API by providing a mechanism allowing users to specify filters to be applied on responses. Such mechanism would be particularly useful for "list" API operations, which might return large amounts of data.

Typical Use Cases
We list in this section situations in which API filters might be employed by users of the Quantum API. Please feel free to add your own use cases here.


 * 1) Retrieve only ports in a specific administrative state
 * 2) Retrieve only ports in a specific operational state
 * 3) Retrieve only ports with an interface plugged
 * 4) Retrieve only networks with operational ports
 * 5) Retrieve only networks with interfaces plugged
 * 6) Retrieve only networks matching specific names or name patterns

Specification
Users will be able to specify filters using the request URI's query string. Although filters could be be specified also in appropriate request header and/or in the request body, the choice of the query string is to be preferred for consistency with the Openstack API.

For more information on the use of filters in the Openstack API, please look at the documentation for the List Servers operation.

Filters are in general resource-specific; in Quantum terms, this means that the set of filters which apply to network resource do not necessarily apply to port resource as well. User should be able to specify filters using:
 * Attributes of the resource being listed
 * Example: Retrieve only networks whose name is "private" for tenant XXX
 * Predicates made available by the resource being listed
 * Example: Retrieve only ports with an interface plugged in it for network AAA of tenant XXX
 * Example: Retrieve only ports with an interface plugged in it for network AAA of tenant XXX

Several filters can be combined on the same request URI, as in the following example, which retrieves ports which are administratively UP but operationally DOWN:

For the first prototype of this feature, to be included in Quantum API v1.1, clients will be able to perform filtering using the following attributes and filters:

NOTE: Labels used for predicates are purely hypothetical at this stage

Implementation
In this section we will consider two aspects concerning the implementation of this features:
 * 1) Parsing the query string and gathering required filters in the API layer
 * 2) Actually filtering data to be returned to client either in the plugin or in the API layer

Query string detection, validation, and parsing can be easily performed in the API layer. The alternatives here are: 1) a distinct middleware module for filtering, or 2) doing filtering in the last element of the WSGI chain (the API application) Option 2 appears to be easier, as it would allow us to easily leverage the controller classes whose are automatically invoked by the API router.

As regards filtering, ideally we would like it to be performed by plugins which should return to the API layer only the data matching specified filters. In this case the API would just pass filters to the plugins, and the plugins will appropriately respond; this will probably require changes into the plugin interface, as filters should probably be passed as kwargs parameter to  methods in the plugin.

The plugin interface will expose methods for stating whether the plugin implementation supports filtering:
 * . can_filter_networks
 * . can_filter_ports

These methods do not accept any parameter and return True if the plugins supports filtering for network/port resources, or false otherwise. Unlike the other methods in the plugin interface, a plugin is not required to implement these methods. If no implementation for these methods is provided, the default behaviour is that the plugin does not support filtering.

For plugins supporting filtering, the filters, specified by users of the Quantum API on the query string, are passed to the plugin with a special keyword parameter, named filter_opts.

For plugins which do not support filtering, there following strategies could be implemented:
 * 1) Disable filtering in the API, returning a 400 error if the user specifies filters
 * 2) Ignore filters in the API
 * 3) Perform filtering in the API after the plugin returns the whole set of data

Options #1 are #2 are the easiest from an implementation point of view. However, they do not ensure consistent behaviour, from the client's perspective, across distinct Quantum deployments with different plugins. Option #3 will ensure such consistency.

Please note that for each of these strategies, the API is supposed to know at least whether the plugin is capable or not of filtering data. The plugin should therefore make somehow these information available to the API, possibly with a "get_capabilities" operation on the plugin interface (note: this operation is not meant to be exposed through the Quantum API of course).