Expose versioning information on GET / endpoint
This returns 'min_version' (minimum supported version), 'version' (current/maximum supported version), and 'status' (of the version, is 'CURRENT' for v1) in the response to a GET / request. It makes our response to / very close to Nova's one[0], and will allow us to implement a `ironic version-list` command similar to Nova's. As this change is needed for proper versioning support on client side, it's not versioned itself. Otherwise we'll have a chicken-and-egg problem. [0]http://specs.openstack.org/openstack/nova-specs/specs/kilo/implemented/api-microversions.html#versioning Closes-Bug: #1489172 Co-Authored-By: Ruby Loo <rloo@yahoo-inc.com> Change-Id: I6dd1ea20e23137d9a9566355adc0784067d2cb5b
This commit is contained in:
parent
56ef2a001c
commit
91467d3135
|
@ -21,25 +21,47 @@ from wsme import types as wtypes
|
||||||
from ironic.api.controllers import base
|
from ironic.api.controllers import base
|
||||||
from ironic.api.controllers import link
|
from ironic.api.controllers import link
|
||||||
from ironic.api.controllers import v1
|
from ironic.api.controllers import v1
|
||||||
|
from ironic.api.controllers.v1 import versions
|
||||||
from ironic.api import expose
|
from ironic.api import expose
|
||||||
|
|
||||||
|
ID_VERSION1 = 'v1'
|
||||||
|
|
||||||
|
|
||||||
class Version(base.APIBase):
|
class Version(base.APIBase):
|
||||||
"""An API version representation."""
|
"""An API version representation.
|
||||||
|
|
||||||
|
This class represents an API version, including the minimum and
|
||||||
|
maximum minor versions that are supported within the major version.
|
||||||
|
"""
|
||||||
|
|
||||||
id = wtypes.text
|
id = wtypes.text
|
||||||
"""The ID of the version, also acts as the release number"""
|
"""The ID of the (major) version, also acts as the release number"""
|
||||||
|
|
||||||
links = [link.Link]
|
links = [link.Link]
|
||||||
"""A Link that point to a specific version of the API"""
|
"""A Link that point to a specific version of the API"""
|
||||||
|
|
||||||
@staticmethod
|
status = wtypes.text
|
||||||
def convert(id):
|
"""Status of the version.
|
||||||
version = Version()
|
|
||||||
version.id = id
|
One of:
|
||||||
version.links = [link.Link.make_link('self', pecan.request.public_url,
|
* CURRENT - the latest version of API,
|
||||||
id, '', bookmark=True)]
|
* SUPPORTED - supported, but not latest, version of API,
|
||||||
return version
|
* DEPRECATED - supported, but deprecated, version of API.
|
||||||
|
"""
|
||||||
|
|
||||||
|
version = wtypes.text
|
||||||
|
"""The current, maximum supported (major.minor) version of API."""
|
||||||
|
|
||||||
|
min_version = wtypes.text
|
||||||
|
"""Minimum supported (major.minor) version of API."""
|
||||||
|
|
||||||
|
def __init__(self, id, min_version, version, status='CURRENT'):
|
||||||
|
self.id = id
|
||||||
|
self.links = [link.Link.make_link('self', pecan.request.public_url,
|
||||||
|
self.id, '', bookmark=True)]
|
||||||
|
self.status = status
|
||||||
|
self.version = version
|
||||||
|
self.min_version = min_version
|
||||||
|
|
||||||
|
|
||||||
class Root(base.APIBase):
|
class Root(base.APIBase):
|
||||||
|
@ -62,17 +84,19 @@ class Root(base.APIBase):
|
||||||
root.name = "OpenStack Ironic API"
|
root.name = "OpenStack Ironic API"
|
||||||
root.description = ("Ironic is an OpenStack project which aims to "
|
root.description = ("Ironic is an OpenStack project which aims to "
|
||||||
"provision baremetal machines.")
|
"provision baremetal machines.")
|
||||||
root.versions = [Version.convert('v1')]
|
root.default_version = Version(ID_VERSION1,
|
||||||
root.default_version = Version.convert('v1')
|
versions.MIN_VERSION_STRING,
|
||||||
|
versions.MAX_VERSION_STRING)
|
||||||
|
root.versions = [root.default_version]
|
||||||
return root
|
return root
|
||||||
|
|
||||||
|
|
||||||
class RootController(rest.RestController):
|
class RootController(rest.RestController):
|
||||||
|
|
||||||
_versions = ['v1']
|
_versions = [ID_VERSION1]
|
||||||
"""All supported API versions"""
|
"""All supported API versions"""
|
||||||
|
|
||||||
_default_version = 'v1'
|
_default_version = ID_VERSION1
|
||||||
"""The default API version"""
|
"""The default API version"""
|
||||||
|
|
||||||
v1 = v1.Controller()
|
v1 = v1.Controller()
|
||||||
|
|
|
@ -13,16 +13,26 @@
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
from ironic.api.controllers.v1 import versions
|
||||||
from ironic.tests.unit.api import base
|
from ironic.tests.unit.api import base
|
||||||
|
|
||||||
|
|
||||||
class TestRoot(base.BaseApiTest):
|
class TestRoot(base.BaseApiTest):
|
||||||
|
|
||||||
def test_get_root(self):
|
def test_get_root(self):
|
||||||
data = self.get_json('/', path_prefix='')
|
response = self.get_json('/', path_prefix='')
|
||||||
self.assertEqual('v1', data['default_version']['id'])
|
|
||||||
# Check fields are not empty
|
# Check fields are not empty
|
||||||
[self.assertNotIn(f, ['', []]) for f in data.keys()]
|
[self.assertNotIn(f, ['', []]) for f in response]
|
||||||
|
|
||||||
|
self.assertEqual('OpenStack Ironic API', response['name'])
|
||||||
|
self.assertTrue(response['description'])
|
||||||
|
self.assertEqual([response['default_version']], response['versions'])
|
||||||
|
|
||||||
|
version1 = response['default_version']
|
||||||
|
self.assertEqual('v1', version1['id'])
|
||||||
|
self.assertEqual('CURRENT', version1['status'])
|
||||||
|
self.assertEqual(versions.MIN_VERSION_STRING, version1['min_version'])
|
||||||
|
self.assertEqual(versions.MAX_VERSION_STRING, version1['version'])
|
||||||
|
|
||||||
|
|
||||||
class TestV1Root(base.BaseApiTest):
|
class TestV1Root(base.BaseApiTest):
|
||||||
|
|
Loading…
Reference in New Issue