Remove microversions spec from backlog

This was a discussion that we had at the Pike PTG in Atlanta and is
recapped in our weekly meeting:

  http://eavesdrop.openstack.org/meetings/keystone/2017/keystone.2017-02-28-18.00.log.html#l-47

This commit removes the microversions spec from the backlog because
there are some overall decisions regarding microversions that need to
be made at the API-WG level. Once those issues are resolved, we can
repropose a more accurate representation of the spec.

Change-Id: Ie4185344a150020785071d914c25cb901ba89b3a
This commit is contained in:
Lance Bragstad 2017-02-28 22:20:03 +00:00
parent 14459c552b
commit d1a83c8ee8
1 changed files with 0 additions and 437 deletions

View File

@ -1,437 +0,0 @@
..
This work is licensed under a Creative Commons Attribution 3.0 Unported
License.
http://creativecommons.org/licenses/by/3.0/legalcode
=============
Microversions
=============
`bp microversions <https://blueprints.launchpad.net/keystone/+spec/microversions>`_
Clone the Nova approach to using Microversions to provide API access
to features.
Problem Description
===================
Nova uses a framework called API Microversions for allowing changes
to the API while preserving backward compatibility. The basic idea is
that a user has to explicitly ask for their request to be treated with
a particular version of the API. So breaking changes can be added to
the API without breaking users who dont specifically ask for it. This
is done with an HTTP header X-OpenStack-Nova-API-Version which is a
monotonically increasing semantic version number.
If a user makes a request without specifying a version, they will get
the DEFAULT_API_VERSION as defined in nova/api/openstack/wsgi.py. This
value is currently 2.1 and is expected to remain so for quite a long
time.
There is a special value latest which can be specified, which will
allow a client to always receive the most recent version of API
responses from the server.
Keystone has similar requirements to Nova in wanting to be able to introduce
changes that change the API behaviour of individual APIs, but currently does
not formally support the concept of microversions.
Proposed Change
===============
Implement the same microversion approach in keystone. In fact, keystone has
had a form of microversions since the introduction of 3.0. At each release, the
microversion of the API is defined in the Identity Specification (Mitaka was
version 3.6). This microversion is also returned as part of the versions
response from the / and /v3 API calls. What keystone does not currently allow
is for a client to request a particular microversion - you always get the
latest one. Hence the change proposed here is to support this client-server
interrogation, as well as the server to support more than version at a time.
Microversions are implemented in the API through the supporting the standard
OpenStack version HTTP header 'X-OpenStack-API-Version', with a service
type of 'identity'. For example::
'X-OpenStack-API-Version': identity 3.7
This approach is laid out in the cross-project specification:
<https://specs.openstack.org/openstack/api-wg/guidelines/microversion_specification.html>`_.
This header is accepted by keystone so a client can indicate which version of
the API it wants to use for communication, and likewise for keystone to
indicate which version it is using for communication.
For the Identity API, if no HTTP header is supplied, microversion 3.6 of the v3
API is used (stable/mitaka) - i.e. the last version before microversions were
introduced. If an invalid version is specified in the HTTP header, an HTTP 406
Not Acceptable is returned. If the special 'latest' version is specified,
keystone will use its most recent version (3.7 for Newton). Asking for a
specific microversion before 3.6 will not be supported (and any such request
will be treated as an invalid version).
Use Cases
---------
The following represents the keystone equivalent set of the user cases that are
supported in the nova approach, in this case between keystone and
python-keystoneclient.
For the purposes of definition, we will use the term "KeystoneV3" to refer to
a version of keystone that predates microversions and has no knowledge of them.
Likewise, we will use the term "KeystoneV3Microversioned" to refer to a version
of keystone that includes support for microversions. Microversioning is not
supported on the keystone v2.0 API, only the v3 API can have its version
negotiated.
In the use case below, for python-keystoneclient, the label "old client" refers
to a version of python-keystoneclient which doesn't support microversions and
"new client" to version of python-keystoneclient which does supports it.
Use Case 1: Old Client communicating with KeystoneV3
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This is exactly the same behaviour that was seen prior to the introduction
of microversions - no change to either the client or server is required
for this case.
Use Case 2: Old Client communicating with KeystoneV3Microversioned
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This is where keystone is updated to a new version that supports microversions,
but an old client is used to communicate to it.
* The client makes a connection to keystone, not specifying the HTTP header
X-OpenStack-API-Version
* Keystone does not see the X-OpenStack-API-Version HTTP header
* Keystone communicates using the 3.6 microversion of the v3 API(stable/mitaka)
and all communication with the client uses that version of the interface.
Use Case 3A: New Client communicating with KeystoneV3 (not user-specified)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This is the where the user does not request a particular microversion to a
new client that support microversions and tries to communicate with an old
keystone.
* The user does not specify the microversion to use in communication with
the client.
* The client makes a connection to keystone and asks for supported API
versions (using the GET /v3/ API)
* Keystone doesn't look for, or parse the HTTP header. It just returns the
versions json response.
* The client checks versions info, and selects the latest non-microversioned
API level supported by the server (which by definition can be no later
than 3.6). Note that this is different to the nova approach (where if no
version is specified, they fail) - this is justified by the fact that our
client already will select the latest version in this scenario.
Use Case 3B: New Client communicating with KeystoneV3 (user-specified)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This is the where the user requests a particular microversion to a
new client that support microversions and tries to communicate with
KeystoneV3.
* The user specifies a microversion that is valid for the client.
* The client makes a connection to KeystoneV3, supplying a
X-OpenStack-API-Version HTTP header
* Keystone doesn't know to look for, or parse the HTTP header. It communicates
using whatever the latest version it supports which, by definition, will be
no later than 3.6.
* The client does not receive a X-OpenStack-API-Version header in
the response, and from that is able to assume that the version of keystone
that it is talking to does not support microversions. That is, it is using
a version of the REST API that predates KeystoneV3Microversioned.
* The client informs the user that it cannot communicate to keystone using that
microversion and exits. (Conceptually we could allow the specific case of
asking for 3.6 against a Mitaka keystone to work here, but it does not seem
worth supporting that corner case).
Use Case 3C: New Client communicating with KeystoneV3 (backward-compatibility)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This is the way to use KeystoneV3 via new client.
* The user specifies an identity api version of "3" (for example, as is done
by the openstackclient today)
* The client checks that minor part of version is zero and hence assumes that a
microversion is not used.
* The client makes a connection to KeystoneV3, without adding a
X-OpenStack-API-Version HTTP header.
* Keystone doesn't know to look for, or parse the HTTP header. It communicates
using whatever the latest version it supports which, by definition, will be
no later than 3.6.
* The client doesn't look for, or parse the HTTP header, it knows that
microversions are not being used.
* The client processes received data, display it to user and exits.
Use Case 4: New Client, user specifying an invalid version number
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This is the case where a user provides as input to a new client an invalid
microversion identifier, such as 'spam', 'l33t', or '1.2.3.4.5'.
* The user specifies a microversion to the client that is invalid.
* The client returns an error to the user, i.e. the client should provide
some validation that a valid microversion identifier is provided.
A valid microversion identifier must comply with the following regex:
^([1-9]\d*)\.([1-9]\d*|0|latest)$
Examples of valid microversion identifier: '3.7', '3.21', '3.latest',...
Use Case 5: New Client/KeystoneV3Microversioned: Unsupported keystone version
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This is the case where a new client requests what was once a valid
microversion, but is now older than the KeystoneV3Microversioned can handle.
Although today this won't be possible (since both support the same set of
versions), in the future this may be required).
* The client makes a connection to keystone, supplying 3.x as the requested
microversion.
* Keystone responds with a 406 Not Acceptable.
* As the client does not support a version supported by keystone, it cannot
continue and reports such to the user.
Use Case 6: New Client/KeystoneV3Microversioned: Unsupported Client version
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This is the case where a new client requests a version that is newer than
the KeystoneV3Microversioned can handle. For example, the client support
microversions 3.8 to 3.9, and the particular keystone supports versions 3.7.
Steps are the same as Use Case 5.
Use Case 7: New Client/KeystoneV3Microversioned: Compatible Version
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This is the case where a new client requests a version that is supported
by KeystoneV3Microversioned. For example, the client supports microversions 3.6
to 3.7, as does the server.
* The client makes a connection to keystone, supplying 3.7 as the requested
microversion.
* As keystone can support this microversion, it responds by sending back a
response of 3.7 in the X-OpenStack-API-Version HTTP header.
Use Case 8: New Client/KeystoneV3Microversioned: Version request of 'latest'
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This is the case where a new client requests a version of 'latest' from a
KeystoneV3Microversioned.
* The user specifies 'latest' microversion is to be used.
* The client makes a connection to keystone and asks for supported API
versions (using the GET /v3/ API)
* Keystone doesn't look for, or parse the HTTP header. It just returns the
versions json response.
* The client checks API version info and makes conclusion that current version
supports microversions.
* The client chooses the latest version supported both by client and server
sides(via "version" and "min_version" values from API version response) and
makes a connection to keystone, supplying selected version in the
X-OpenStack-API-Version HTTP header
Use Case 9: New Client/KeystoneV3Microversioned: Version not specified
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This is the where the user does not request a particular microversion to a
new client that support microversions and tries to communicate with a
KeystoneV3Microversioned.
* The user does not specify the microversion to use in communication with
the client.
* The client makes a connection to keystone and asks for supported API
versions (using the GET /v3/ API)
* Keystone doesn't look for, or parse the HTTP header. It just returns the
versions json response.
* The client checks versions info, and selects the latest non-microversioned
API level supported by the server (which by definition will be 3.6). Note
that this is different to our current client where, prior to these changes,
the absolute latest version would have been selected.
Specific changes
================
The python identity API in keystoneclient should be extended to
include major and minor parts of version. It should look like:
* "X.Y" - "X" and "Y" accept numeric values. The client will use it to
communicate with keystone.
* "X.latest" - "X" accepts numeric values. The client will use the "latest"
(see `latest-microversion`_ for more details) supported both by client and
server sides microversion of "X" Major version.
* "latest" - The client will use the latest major version known by client and
"latest" (`latest-microversion`_) microversion supported both by client and
server sides.
"X" is a major part and "Y" is a minor one
The requested microversion (when it specified) should be used (unless
the client cannot support that version). The client will always
request a specific microversion in its communication with the
server. 'X.latest' is purely a signal from a python consumer that it
wants negotiation of the maximum mutually-supported version between
the server and client.
python-keystoneclient as a CLI tool
-----------------------------------
Since this is deprecated, no changes will be made to this.
python-openstackclient CLI tool
-------------------------------
Microversions should be specified with a major API version, using the
existing --os-identity-api-version option. Today this only contains the major
version (i.e. --os-identity-api-version=3), but can now be specified, for
example, as --os-compute-api-version=3.7. This value will then be passed to
python-keystoneclient.
A user may also specify --os-compute-api-version="None" which indicates that
client should use should use default major API version without microversion
(this is provided to be compatible with nova's approach and is equivalent to
setting this to 3).
Help messages should display all variations of commands, sub-commands and their
options with information about supported versions(min and max).
Once v3 is supported as the default for the identity API, the actual default
setting should be "3.latest" - so that a given version of the client will use
the latest version supported by the client library and server.
python-keystoneclient as a Python lib (keystoneclient.client entry point)
-------------------------------------------------------------------------
Module ``keystoneclient.client`` is used as entry point to
python-keystoneclient inside other python libraries.
``keystoneclient.client.Client`` already accepts a version tuple (X, Y) and
this will be used to communicate any requested microversion, in which case the
client should add the header X-OpenStack-API-Version to each server
call and validate response includes equal header too, which means the API side
supports the required microversion.
.. _latest-microversion:
"latest" microversion
~~~~~~~~~~~~~~~~~~~~~
"latest" microversion is a maximum version. Despite the fact that Identity API
accepts value "latest" in the header, the client doesn't use this ability.
The client discovers the "latest" microversion supported by both API, client
sides and uses it in communication with Nova-API.
Discover should be processed by following steps:
* The client makes one extra call to Identity API - list all versions;
* The client checks that current version supports microversions by checking
values "min_version" and "version" of current version. If current version
doesn't support microversions("min_version" and "version" are empty),
the client raises an exception with this information.
* The client chooses latest microversion supported by both keystoneclient and
Identity API.
NOTE: To decrease number of extra calls, the client should cache discovered
versions. Since different methods/API calls can have different "latest"
versions, each discovered versions should be cached with related method.
python-keystoneclient from developer point of view : adding new microversions
-----------------------------------------------------------------------------
Each "versioned" method of ResourceManager should be labeled with a specific
decorator. Such decorator should accept two arguments: start version and end
version (optional). Example:
.. code-block:: python
from keystoneclient import api_versions
from keystoneclient import base
class SomeResourceManager(base.Manager)
@api_version(start_version='3.7', end_version='3.7')
def show(self, req, id):
do work and return results specific to version 3.7
@api_versions.wrap(start_version='3.8')
def show(self, req, id):
do work and return results specific to version 3.8 onwards
A similar approach will be taken in openstackclient, to version the actual
commands (and their arguments).
Alternatives
------------
There are many possible approaches to this. The one proposed consistent with
other projects, which provides distinct advantages for operators.
Alternatives are:
* We only make purely additive changes to the API, which cannot bleed over into
other existing APIs (this could be very restrictive), and/or
* Only make breaking changes at major API levels (e.g. v3, v4, v5 etc.), where
we accept a multi-year change over period.
Security Impact
---------------
None
Notifications Impact
--------------------
None
Other End User Impact
---------------------
Clients that wish to use new features available over the REST API added since
the 'Mitaka' release will need to start using this HTTP header. The fact that
new features will only be added in new versions will encourage them to do so.
Performance Impact
------------------
None
Other Deployer Impact
---------------------
None
Developer Impact
----------------
Any future changes to the Identity REST API (whether that be in the request or
any response) *must* result in a microversion update, and guarded in the code
appropriately.
Implementation
==============
Assignee(s)
-----------
Primary assignee:
Henry Nash (henry-nash)
Other contributors:
Adam Young (ayoung)
Morgan Fainberg (notmorgan)
Work Items
----------
Dependencies
============
None. Many will depend on this.
Documentation Impact
====================
This change will resonate through the docs.
References
==========
[1] https://specs.openstack.org/openstack/api-wg/guidelines/microversion_specification.html
[2] http://git.openstack.org/cgit/openstack/nova-specs/tree/specs/kilo/implemented/api-microversions.rst
[3] http://docs.openstack.org/developer/nova/api_microversions.html