def _check_version(self, version, headers=None): if headers is None: headers = {} # ensure that major version in the URL matches the header if version.major != BASE_VERSION: raise exc.HTTPNotAcceptable( _("Mutually exclusive versions requested. Version %(ver)s " "requested but not supported by this service. The supported " "version range is: [%(min)s, %(max)s].") % { 'ver': version, 'min': versions.min_version_string(), 'max': versions.max_version_string() }, headers=headers) # ensure the minor version is within the supported range if version < min_version() or version > max_version(): raise exc.HTTPNotAcceptable( _("Version %(ver)s was requested but the minor version is not " "supported by this service. The supported version range is: " "[%(min)s, %(max)s].") % { 'ver': version, 'min': versions.min_version_string(), 'max': versions.max_version_string() }, headers=headers)
def _add_version_attributes(self): v = base.Version(api.request.headers, versions.min_version_string(), versions.max_version_string()) # Always set the min and max headers api.response.headers[base.Version.min_string] = ( versions.min_version_string()) api.response.headers[base.Version.max_string] = ( versions.max_version_string()) # assert that requested version is supported self._check_version(v, api.response.headers) api.response.headers[base.Version.string] = str(v) api.request.version = v
def _route(self, args, request=None): v = base.Version(pecan.request.headers, versions.min_version_string(), versions.max_version_string()) # Always set the min and max headers pecan.response.headers[base.Version.min_string] = ( versions.min_version_string()) pecan.response.headers[base.Version.max_string] = ( versions.max_version_string()) # assert that requested version is supported self._check_version(v, pecan.response.headers) pecan.response.headers[base.Version.string] = str(v) pecan.request.version = v return super(Controller, self)._route(args, request)
def _test_get_root(self, headers=None, additional_expected_resources=None): if headers is None: headers = {} if additional_expected_resources is None: additional_expected_resources = [] data = self.get_json('/', headers=headers) self.assertEqual('v1', data['id']) # Check fields are not empty for f in data: self.assertNotIn(f, ['', []]) # Check if all known resources are present and there are no extra ones. not_resources = ('id', 'links', 'media_types', 'version') actual_resources = tuple(set(data) - set(not_resources)) expected_resources = (['chassis', 'drivers', 'nodes', 'ports'] + additional_expected_resources) self.assertEqual(sorted(expected_resources), sorted(actual_resources)) self.assertIn({'type': 'application/vnd.openstack.ironic.v1+json', 'base': 'application/json'}, data['media_types']) version1 = data['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'])
def _test_get_root(self, headers=None, additional_expected_resources=None): if headers is None: headers = {} if additional_expected_resources is None: additional_expected_resources = [] data = self.get_json('/', headers=headers) self.assertEqual('v1', data['id']) # Check fields are not empty for f in data: self.assertNotIn(f, ['', []]) # Check if all known resources are present and there are no extra ones. not_resources = ('id', 'links', 'media_types', 'version') actual_resources = tuple(set(data) - set(not_resources)) expected_resources = (['chassis', 'drivers', 'nodes', 'ports'] + additional_expected_resources) self.assertEqual(sorted(expected_resources), sorted(actual_resources)) self.assertEqual( { 'type': 'application/vnd.openstack.ironic.v1+json', 'base': 'application/json' }, data['media_types']) version1 = data['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'])
def default_version(): """Return a dict representing the current default version id: The ID of the (major) version, also acts as the release number links: A list containing one link that points to the current version of the API status: Status of the version, one of CURRENT, SUPPORTED, DEPRECATED min_version: The current, maximum supported (major.minor) version of API. version: Minimum supported (major.minor) version of API. """ # NOTE(dtantsur): avoid circular imports from ironic.api.controllers.v1 import versions return { 'id': ID_VERSION1, 'links': [ link.make_link('self', api.request.public_url, ID_VERSION1, '', bookmark=True) ], 'status': 'CURRENT', 'min_version': versions.min_version_string(), 'version': versions.max_version_string() }
def convert(): root = Root() root.name = "OpenStack Ironic API" root.description = ("Ironic is an OpenStack project which aims to " "provision baremetal machines.") root.default_version = Version(ID_VERSION1, versions.min_version_string(), versions.max_version_string()) root.versions = [root.default_version] return root
def _check_version(self, version, headers=None): if headers is None: headers = {} # ensure that major version in the URL matches the header if version.major != BASE_VERSION: raise exc.HTTPNotAcceptable(_( "Mutually exclusive versions requested. Version %(ver)s " "requested but not supported by this service. The supported " "version range is: [%(min)s, %(max)s].") % {'ver': version, 'min': versions.min_version_string(), 'max': versions.max_version_string()}, headers=headers) # ensure the minor version is within the supported range if version < min_version() or version > max_version(): raise exc.HTTPNotAcceptable(_( "Version %(ver)s was requested but the minor version is not " "supported by this service. The supported version range is: " "[%(min)s, %(max)s].") % {'ver': version, 'min': versions.min_version_string(), 'max': versions.max_version_string()}, headers=headers)
def test_get_root(self): response = self.get_json('/', path_prefix='') # Check fields are not empty [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'])
def max_version(): return base.Version( {base.Version.string: versions.max_version_string()}, versions.min_version_string(), versions.max_version_string())
def default_version(): # NOTE(dtantsur): avoid circular imports from ironic.api.controllers.v1 import versions return Version(ID_VERSION1, versions.min_version_string(), versions.max_version_string())
def test_max_version(self): response = self.get_json('/', headers={ 'Accept': 'application/json', 'X-OpenStack-Ironic-API-Version': versions.max_version_string() }) self.assertEqual( { 'id': 'v1', 'links': [{ 'href': 'http://localhost/v1/', 'rel': 'self' }, { 'href': 'https://docs.openstack.org//ironic/latest' '/contributor//webapi.html', 'rel': 'describedby', 'type': 'text/html' }], 'media_types': { 'base': 'application/json', 'type': 'application/vnd.openstack.ironic.v1+json' }, 'version': { 'id': 'v1', 'links': [{ 'href': 'http://localhost/v1/', 'rel': 'self' }], 'status': 'CURRENT', 'min_version': versions.min_version_string(), 'version': versions.max_version_string() }, 'allocations': [{ 'href': 'http://localhost/v1/allocations/', 'rel': 'self' }, { 'href': 'http://localhost/allocations/', 'rel': 'bookmark' }], 'chassis': [{ 'href': 'http://localhost/v1/chassis/', 'rel': 'self' }, { 'href': 'http://localhost/chassis/', 'rel': 'bookmark' }], 'conductors': [{ 'href': 'http://localhost/v1/conductors/', 'rel': 'self' }, { 'href': 'http://localhost/conductors/', 'rel': 'bookmark' }], 'deploy_templates': [{ 'href': 'http://localhost/v1/deploy_templates/', 'rel': 'self' }, { 'href': 'http://localhost/deploy_templates/', 'rel': 'bookmark' }], 'drivers': [{ 'href': 'http://localhost/v1/drivers/', 'rel': 'self' }, { 'href': 'http://localhost/drivers/', 'rel': 'bookmark' }], 'events': [{ 'href': 'http://localhost/v1/events/', 'rel': 'self' }, { 'href': 'http://localhost/events/', 'rel': 'bookmark' }], 'heartbeat': [{ 'href': 'http://localhost/v1/heartbeat/', 'rel': 'self' }, { 'href': 'http://localhost/heartbeat/', 'rel': 'bookmark' }], 'lookup': [{ 'href': 'http://localhost/v1/lookup/', 'rel': 'self' }, { 'href': 'http://localhost/lookup/', 'rel': 'bookmark' }], 'nodes': [{ 'href': 'http://localhost/v1/nodes/', 'rel': 'self' }, { 'href': 'http://localhost/nodes/', 'rel': 'bookmark' }], 'portgroups': [{ 'href': 'http://localhost/v1/portgroups/', 'rel': 'self' }, { 'href': 'http://localhost/portgroups/', 'rel': 'bookmark' }], 'ports': [{ 'href': 'http://localhost/v1/ports/', 'rel': 'self' }, { 'href': 'http://localhost/ports/', 'rel': 'bookmark' }], 'volume': [{ 'href': 'http://localhost/v1/volume/', 'rel': 'self' }, { 'href': 'http://localhost/volume/', 'rel': 'bookmark' }] }, response)