Spec: Adding a v2 API
This is a spec proposing to add a v2 API to cloudkitty. See specs/stein/implementing_cloudkittys_v2_api_root.rst for details. Story: 2004208 Change-Id: Ie18af397247993ea51eabc025eb7931468ae66b2
This commit is contained in:
parent
9616269ecf
commit
eeec4c0930
@ -4,6 +4,16 @@
|
||||
Cloudkitty Project Specifications
|
||||
=================================
|
||||
|
||||
Stein
|
||||
=====
|
||||
|
||||
.. toctree::
|
||||
:glob:
|
||||
:maxdepth: 1
|
||||
|
||||
specs/stein/*
|
||||
|
||||
|
||||
Pike
|
||||
====
|
||||
|
||||
|
251
specs/stein/adding_a_v2_api_to_cloudkitty.rst
Normal file
251
specs/stein/adding_a_v2_api_to_cloudkitty.rst
Normal file
@ -0,0 +1,251 @@
|
||||
..
|
||||
This work is licensed under a Creative Commons Attribution 3.0 Unported
|
||||
License.
|
||||
|
||||
http://creativecommons.org/licenses/by/3.0/legalcode
|
||||
|
||||
=============================
|
||||
Adding a v2 API to CloudKitty
|
||||
=============================
|
||||
|
||||
https://storyboard.openstack.org/#!/story/2004208
|
||||
|
||||
CloudKitty has gone through a lot of changes recently (v2 storage, support for
|
||||
Prometheus, standalone mode...). This requires big changes on the API: given
|
||||
that the internal data format is evolving, we need to expose the data
|
||||
differently, in order to support the new features of the v2 storage: pagination,
|
||||
grouping, filtering...
|
||||
|
||||
Problem Description
|
||||
===================
|
||||
|
||||
Several distinct problems can be identified:
|
||||
|
||||
1. CloudKitty's data needs to be exposed with more granularity. A non-exhaustive
|
||||
list of currently missing features:
|
||||
|
||||
* Pagination
|
||||
* Filtering
|
||||
* Grouping
|
||||
* ...
|
||||
|
||||
2. For its current API, CloudKitty uses WSME + pecan. Code written using these
|
||||
tools can be quite difficult to understand for new contributors. In addition
|
||||
to that, pecan's development seems to have slowed down:
|
||||
https://github.com/pecan/pecan/commits/master .
|
||||
|
||||
3. Semantics. A lot of endpoints are still using OpenStack-related terms
|
||||
(tenant, service...).
|
||||
|
||||
Proposed Change
|
||||
===============
|
||||
|
||||
In consequence to the previously evoked reasons, the CloudKitty development
|
||||
team proposes to implement a new API, which will be based on Flask/Werkzeug
|
||||
and Flask-RESTful. These frameworks have been chosen for the following reasons:
|
||||
|
||||
- Flask is a well-known and easy-to-use framework. This will make contributions
|
||||
easier for new contributors. It is solid and used by other OpenStack projects,
|
||||
like Keystone.
|
||||
|
||||
- Flask-RESTful makes code easier to read and routing is also eased. The idea
|
||||
would be to have each important endpoint (for example ``/rating/hashmap``)
|
||||
mapped to a blueprint, and each sub-endpoint (``rating/hashmap/services``)
|
||||
mapped to a Flask-RESTful resource. This would make adding new endpoints easy,
|
||||
and leaves space for the v2 API to evolve. Below a working code sample, with
|
||||
voluptuous input and output validation:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@api_utils.add_output_schema(GET_OUTPUT_EXAMPLE_SCHEMA)
|
||||
def get(self):
|
||||
policy.authorize(flask.request.context, 'example:get_example', {})
|
||||
return {}
|
||||
|
||||
@api_utils.add_input_schema(POST_INPUT_EXAMPLE_SCHEMA)
|
||||
def post(self, fruit='banana'):
|
||||
policy.authorize(flask.request.context, 'example:submit_fruit', {})
|
||||
if fruit not in ['banana', 'strawberry']:
|
||||
raise http_exceptions.Forbidden(
|
||||
'You submitted a forbidden fruit',
|
||||
)
|
||||
return {
|
||||
'msg': 'Your fruit is a ' + fruit
|
||||
}
|
||||
|
||||
- Flask-RESTful forces (or at least encourages) contributors to have a restful
|
||||
approach to the API, whereas Flask leaves them too much freedom.
|
||||
|
||||
This new API will make it easy to add a new endpoint, and will be a container
|
||||
to new features. Any new endpoint will be added to this API.
|
||||
|
||||
This v2 API will only be compatible with the v2 storage, allowing new endpoints
|
||||
to completely exploit the capacities of the v2 storage, without having to handle
|
||||
backward compatibility. The v1 API is completely compatible with the v2 storage,
|
||||
so data will still be accessible through the v1 API, compatibilty with
|
||||
existing scripts etc, will be kept. The v2 API will be disabled when a v1
|
||||
storage backend is used.
|
||||
|
||||
In order to limit the workload, not all v1 endpoints will be migrated at once.
|
||||
The proposition will be to have one WSGI app per API version, and to
|
||||
distinguish between them through routing. This could be done with Werkzeug's
|
||||
``DispatcherMiddleware``: http://werkzeug.pocoo.org/docs/0.14/middlewares/#werkzeug.wsgi.DispatcherMiddleware.
|
||||
In case a v1 storage backend is used, the v2 API will simply not be loaded.
|
||||
|
||||
V1 endpoints will be migrated one after another. Once the entire v1 API has
|
||||
been migrated, the v2 API will be marked as ``CURRENT``, and the v1 API will
|
||||
be marked as ``DEPRECATED``. Until that point is reached, v1 will be
|
||||
``CURRENT`` and v2 will be ``EXPERIMENTAL``.
|
||||
|
||||
The proposed workflow for adding an endpoint is the following:
|
||||
|
||||
- Write a spec detailing what the endpoint does, its impact on the client,
|
||||
the dashboard and the tempest plugin.
|
||||
|
||||
- **Once the spec is reviewed and merged**, create a storyboard story
|
||||
linking to your spec and containing one task for each of the following points:
|
||||
|
||||
* Adding the endpoint to the API
|
||||
|
||||
* Adding support for the endpoint to the client
|
||||
|
||||
* Adding tests for this endpoint to the tempest plugin
|
||||
|
||||
* (Optional) Adding support for the endpoint to the dashboard
|
||||
|
||||
Each of these tasks must be the subject of a new patch. Each task which is
|
||||
not marked as optional is mandatory.
|
||||
|
||||
- The patches adding client/dashboard support as well as the patch adding
|
||||
tests to the tempest plugin must depend on the patch adding the endpoint
|
||||
to the API.
|
||||
|
||||
Once the v2 API is stable and marked as the current API, it will be
|
||||
**microversioned** in order to have an indicator of its capabilities. A
|
||||
microversion increase will be indicating a new feature (new endpoint).
|
||||
However, API endpoints in OpenStack's service catalog will **not** be
|
||||
microversioned. The exact version of the API will be available at the API root
|
||||
(``/``).
|
||||
|
||||
Versioning will be done using **semantic versioning** (https://semver.org/).
|
||||
Once all v1 endpoint have been migrated, and the v2 API is considered stable,
|
||||
its version will be ``2.0``. Before that version, each version will be suffixed
|
||||
with ``-beta.version``.
|
||||
|
||||
Example: ``v2.0-beta.1`` -> ... -> ``v2.0-beta.x`` -> ``v2.0``.
|
||||
|
||||
Alternatives
|
||||
------------
|
||||
|
||||
Migrate the whole v1 API to Flask and extend existing endpoints in order to
|
||||
support the features listed above: This would imply to migrate the whole API
|
||||
codebase at once, which can't be done. Also, this wouldn't address the
|
||||
semantics problem.
|
||||
|
||||
Data model impact
|
||||
-----------------
|
||||
|
||||
This particular change (creating a v2 WSGI app and changing the way requests
|
||||
are routed) has no impact on the datamodel. Each v2 API endpoint will be the
|
||||
subject of a new spec. Potential data model impact will be detailed in these
|
||||
upcoming specs.
|
||||
|
||||
REST API impact
|
||||
---------------
|
||||
|
||||
* v1 API will go from ``EXPERIMENTAL`` to ``CURRENT`` current state.
|
||||
|
||||
* A v2 API, marked as ``EXPERIMENTAL``, will be available.
|
||||
|
||||
* A new route (``/v2``) will be available. It will contain a placeholder
|
||||
indicating that this will be the prefix for all upcoming v2 endpoints.
|
||||
|
||||
Security impact
|
||||
---------------
|
||||
|
||||
None
|
||||
|
||||
Notifications Impact
|
||||
--------------------
|
||||
|
||||
None
|
||||
|
||||
Other end user impact
|
||||
---------------------
|
||||
|
||||
None. However, ``python-cloudkittyclient`` will need to be compatible with the
|
||||
new v2 endpoints.
|
||||
|
||||
Performance Impact
|
||||
------------------
|
||||
|
||||
Pagination will allow to lower the load on the network.
|
||||
|
||||
Other deployer impact
|
||||
---------------------
|
||||
|
||||
None
|
||||
|
||||
Developer impact
|
||||
----------------
|
||||
|
||||
For developers, adding a new enpoint should be way easier.
|
||||
|
||||
A dependency on Flask and Flask-RESTful will be added.
|
||||
|
||||
Implementation
|
||||
==============
|
||||
|
||||
Assignee(s)
|
||||
-----------
|
||||
|
||||
Primary assignee:
|
||||
lukapeschke/peschk_l
|
||||
|
||||
Gerrit topic:
|
||||
cloudkitty-v2-api
|
||||
|
||||
Work Items
|
||||
----------
|
||||
|
||||
* Mark the v1 API as ``CURRENT``
|
||||
|
||||
* Route the API with Werkzeug instead of Pecan
|
||||
|
||||
* Add an Example endpoint showing how to implement an endpoint, and how to
|
||||
document it. This example endpoint should be removed as soon as the first
|
||||
real endpoint is implemented.
|
||||
|
||||
* Update the documentation: Update the developer documentation with an
|
||||
explanation about how to add an enpoint and generate the documentation of
|
||||
the v2 API.
|
||||
|
||||
Dependencies
|
||||
============
|
||||
|
||||
* Flask
|
||||
|
||||
* Flask-RESTful
|
||||
|
||||
* os-api-ref (for API reference generation)
|
||||
|
||||
Testing
|
||||
=======
|
||||
|
||||
This particular feature will be tested with unit tests only (gabbi and
|
||||
unittest). Endpoints to come will also add some tests to the tempest plugin.
|
||||
|
||||
Documentation Impact
|
||||
====================
|
||||
|
||||
The developer documentation will be updated to detail how requests are
|
||||
routed and how to add a new endpoint. The user documentation will also be
|
||||
updated in order to include the v2 API reference. The API reference will be
|
||||
generated with ``os-api-ref``.
|
||||
|
||||
References
|
||||
==========
|
||||
|
||||
* os-api-ref documentation: https://docs.openstack.org/os-api-ref/latest/
|
||||
|
||||
* API WG wiki: https://wiki.openstack.org/wiki/API_Special_Interest_Group
|
Loading…
Reference in New Issue
Block a user