Pin API version during rolling upgrade
During a rolling upgrade, when the new services are pinned to the old release, the API version will also be pinned to the old release. This will prevent users from accessing new features that may not quite work. The .sample was updated to reflect the change to the help string for the [DEFAULT]/pin_release_version configuration option. The update also pulled in changes for other options, from other (non-ironic) libraries. Change-Id: I38a0f106b589945fb62071f3dfe5bff43c6fee93 Partial-Bug: #1708549
This commit is contained in:
parent
638943dbf8
commit
feac8cfb78
@ -365,13 +365,12 @@
|
||||
#host = localhost
|
||||
|
||||
# Used for rolling upgrades. Setting this option downgrades
|
||||
# (or pins) the internal ironic RPC communication and database
|
||||
# objects to their respective versions, so they are compatible
|
||||
# with older services. When doing a rolling upgrade from
|
||||
# version N to version N+1, set (to pin) this to N. To unpin
|
||||
# (default), leave it unset and the latest versions of RPC
|
||||
# communication and database objects will be used. (string
|
||||
# value)
|
||||
# (or pins) the Bare Metal API, the internal ironic RPC
|
||||
# communication, and the database objects to their respective
|
||||
# versions, so they are compatible with older services. When
|
||||
# doing a rolling upgrade from version N to version N+1, set
|
||||
# (to pin) this to N. To unpin (default), leave it unset and
|
||||
# the latest versions will be used. (string value)
|
||||
# Allowed values: pike, 9.2, 9.1, 9.0, 8.0
|
||||
#pin_release_version = <None>
|
||||
|
||||
@ -1025,7 +1024,9 @@
|
||||
#domain_name = <None>
|
||||
|
||||
# Always use this endpoint URL for requests for this client.
|
||||
# (string value)
|
||||
# NOTE: The unversioned endpoint should be specified here; to
|
||||
# request a particular API version, use the `version`, `min-
|
||||
# version`, and/or `max-version` options. (string value)
|
||||
#endpoint_override = <None>
|
||||
|
||||
# Verify HTTPS connections. (boolean value)
|
||||
@ -1662,7 +1663,9 @@
|
||||
#domain_name = <None>
|
||||
|
||||
# Always use this endpoint URL for requests for this client.
|
||||
# (string value)
|
||||
# NOTE: The unversioned endpoint should be specified here; to
|
||||
# request a particular API version, use the `version`, `min-
|
||||
# version`, and/or `max-version` options. (string value)
|
||||
#endpoint_override = <None>
|
||||
|
||||
# DEPRECATED: Allow to perform insecure SSL (https) requests
|
||||
@ -1972,7 +1975,9 @@
|
||||
#enabled = false
|
||||
|
||||
# Always use this endpoint URL for requests for this client.
|
||||
# (string value)
|
||||
# NOTE: The unversioned endpoint should be specified here; to
|
||||
# request a particular API version, use the `version`, `min-
|
||||
# version`, and/or `max-version` options. (string value)
|
||||
#endpoint_override = <None>
|
||||
|
||||
# Verify HTTPS connections. (boolean value)
|
||||
@ -2234,6 +2239,24 @@
|
||||
# service user utilizes for validating tokens, because normal
|
||||
# end users may not be able to reach that endpoint. (string
|
||||
# value)
|
||||
# Deprecated group/name - [keystone_authtoken]/auth_uri
|
||||
#www_authenticate_uri = <None>
|
||||
|
||||
# DEPRECATED: Complete "public" Identity API endpoint. This
|
||||
# endpoint should not be an "admin" endpoint, as it should be
|
||||
# accessible by all end users. Unauthenticated clients are
|
||||
# redirected to this endpoint to authenticate. Although this
|
||||
# endpoint should ideally be unversioned, client support in
|
||||
# the wild varies. If you're using a versioned v2 endpoint
|
||||
# here, then this should *not* be the same endpoint the
|
||||
# service user utilizes for validating tokens, because normal
|
||||
# end users may not be able to reach that endpoint. This
|
||||
# option is deprecated in favor of www_authenticate_uri and
|
||||
# will be removed in the S release. (string value)
|
||||
# This option is deprecated for removal since Queens.
|
||||
# Its value may be silently ignored in the future.
|
||||
# Reason: The auth_uri option is deprecated in favor of
|
||||
# www_authenticate_uri and will be removed in the S release.
|
||||
#auth_uri = <None>
|
||||
|
||||
# API version of the admin Identity API endpoint. (string
|
||||
@ -3800,7 +3823,9 @@
|
||||
#domain_name = <None>
|
||||
|
||||
# Always use this endpoint URL for requests for this client.
|
||||
# (string value)
|
||||
# NOTE: The unversioned endpoint should be specified here; to
|
||||
# request a particular API version, use the `version`, `min-
|
||||
# version`, and/or `max-version` options. (string value)
|
||||
#endpoint_override = <None>
|
||||
|
||||
# Verify HTTPS connections. (boolean value)
|
||||
|
@ -85,8 +85,8 @@ class Root(base.APIBase):
|
||||
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)
|
||||
versions.min_version_string(),
|
||||
versions.max_version_string())
|
||||
root.versions = [root.default_version]
|
||||
return root
|
||||
|
||||
|
@ -39,12 +39,17 @@ from ironic.common.i18n import _
|
||||
|
||||
BASE_VERSION = versions.BASE_VERSION
|
||||
|
||||
MIN_VER = base.Version(
|
||||
{base.Version.string: versions.MIN_VERSION_STRING},
|
||||
versions.MIN_VERSION_STRING, versions.MAX_VERSION_STRING)
|
||||
MAX_VER = base.Version(
|
||||
{base.Version.string: versions.MAX_VERSION_STRING},
|
||||
versions.MIN_VERSION_STRING, versions.MAX_VERSION_STRING)
|
||||
|
||||
def min_version():
|
||||
return base.Version(
|
||||
{base.Version.string: versions.min_version_string()},
|
||||
versions.min_version_string(), versions.max_version_string())
|
||||
|
||||
|
||||
def max_version():
|
||||
return base.Version(
|
||||
{base.Version.string: versions.max_version_string()},
|
||||
versions.min_version_string(), versions.max_version_string())
|
||||
|
||||
|
||||
class MediaType(base.APIBase):
|
||||
@ -200,29 +205,29 @@ class Controller(rest.RestController):
|
||||
"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},
|
||||
{'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_VER or version > MAX_VER:
|
||||
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},
|
||||
{'ver': version, 'min': versions.min_version_string(),
|
||||
'max': versions.max_version_string()},
|
||||
headers=headers)
|
||||
|
||||
@pecan.expose()
|
||||
def _route(self, args, request=None):
|
||||
v = base.Version(pecan.request.headers, versions.MIN_VERSION_STRING,
|
||||
versions.MAX_VERSION_STRING)
|
||||
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)
|
||||
versions.min_version_string())
|
||||
pecan.response.headers[base.Version.max_string] = (
|
||||
versions.MAX_VERSION_STRING)
|
||||
versions.max_version_string())
|
||||
|
||||
# assert that requested version is supported
|
||||
self._check_version(v, pecan.response.headers)
|
||||
|
@ -13,6 +13,12 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from oslo_config import cfg
|
||||
|
||||
from ironic.common import release_mappings
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
# This is the version 1 API
|
||||
BASE_VERSION = 1
|
||||
|
||||
@ -104,11 +110,33 @@ MINOR_33_STORAGE_INTERFACE = 33
|
||||
MINOR_34_PORT_PHYSICAL_NETWORK = 34
|
||||
MINOR_35_REBUILD_CONFIG_DRIVE = 35
|
||||
|
||||
# When adding another version, update MINOR_MAX_VERSION and also update
|
||||
# doc/source/dev/webapi-version-history.rst with a detailed explanation of
|
||||
# what the version has changed.
|
||||
# When adding another version, update:
|
||||
# - MINOR_MAX_VERSION
|
||||
# - doc/source/dev/webapi-version-history.rst with a detailed explanation of
|
||||
# what changed in the new version
|
||||
# - common/release_mappings.py, RELEASE_MAPPING['master']['api']
|
||||
|
||||
MINOR_MAX_VERSION = MINOR_35_REBUILD_CONFIG_DRIVE
|
||||
|
||||
# String representations of the minor and maximum versions
|
||||
MIN_VERSION_STRING = '{}.{}'.format(BASE_VERSION, MINOR_1_INITIAL_VERSION)
|
||||
MAX_VERSION_STRING = '{}.{}'.format(BASE_VERSION, MINOR_MAX_VERSION)
|
||||
_MIN_VERSION_STRING = '{}.{}'.format(BASE_VERSION, MINOR_1_INITIAL_VERSION)
|
||||
_MAX_VERSION_STRING = '{}.{}'.format(BASE_VERSION, MINOR_MAX_VERSION)
|
||||
|
||||
|
||||
def min_version_string():
|
||||
"""Returns the minimum supported API version (as a string)"""
|
||||
return _MIN_VERSION_STRING
|
||||
|
||||
|
||||
def max_version_string():
|
||||
"""Returns the maximum supported API version (as a string).
|
||||
|
||||
If the service is pinned, the maximum API version is the pinned
|
||||
version. Otherwise, it is the maximum supported API version.
|
||||
"""
|
||||
release_ver = release_mappings.RELEASE_MAPPING.get(
|
||||
CONF.pin_release_version)
|
||||
if release_ver:
|
||||
return release_ver['api']
|
||||
else:
|
||||
return _MAX_VERSION_STRING
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
# NOTE(xek): The format of this dict is:
|
||||
# { '<release version>': {
|
||||
# 'api': '<Bare Metal API version>',
|
||||
# 'rpc': '<RPC API version>',
|
||||
# 'objects': {
|
||||
# '<object class name>': ['<object version>'],
|
||||
@ -55,6 +56,7 @@
|
||||
|
||||
RELEASE_MAPPING = {
|
||||
'8.0': {
|
||||
'api': '1.31',
|
||||
'rpc': '1.40',
|
||||
'objects': {
|
||||
'Node': ['1.21'],
|
||||
@ -67,6 +69,7 @@ RELEASE_MAPPING = {
|
||||
}
|
||||
},
|
||||
'9.0': {
|
||||
'api': '1.34',
|
||||
'rpc': '1.41',
|
||||
'objects': {
|
||||
'Node': ['1.21'],
|
||||
@ -79,6 +82,7 @@ RELEASE_MAPPING = {
|
||||
}
|
||||
},
|
||||
'9.1': {
|
||||
'api': '1.34',
|
||||
'rpc': '1.41',
|
||||
'objects': {
|
||||
'Node': ['1.21'],
|
||||
@ -92,6 +96,7 @@ RELEASE_MAPPING = {
|
||||
},
|
||||
'9.2': {
|
||||
'rpc': '1.41',
|
||||
'api': '1.35',
|
||||
'objects': {
|
||||
'Node': ['1.21'],
|
||||
'Conductor': ['1.2'],
|
||||
@ -103,6 +108,7 @@ RELEASE_MAPPING = {
|
||||
}
|
||||
},
|
||||
'master': {
|
||||
'api': '1.35',
|
||||
'rpc': '1.41',
|
||||
'objects': {
|
||||
'Node': ['1.21'],
|
||||
|
@ -275,13 +275,13 @@ service_opts = [
|
||||
choices=versions.RELEASE_VERSIONS,
|
||||
# TODO(xek): mutable=True,
|
||||
help=_('Used for rolling upgrades. Setting this option '
|
||||
'downgrades (or pins) the internal ironic RPC '
|
||||
'communication and database objects to their respective '
|
||||
'downgrades (or pins) the Bare Metal API, '
|
||||
'the internal ironic RPC communication, and '
|
||||
'the database objects to their respective '
|
||||
'versions, so they are compatible with older services. '
|
||||
'When doing a rolling upgrade from version N to version '
|
||||
'N+1, set (to pin) this to N. To unpin (default), leave '
|
||||
'it unset and the latest versions of RPC communication '
|
||||
'and database objects will be used.')),
|
||||
'it unset and the latest versions will be used.')),
|
||||
]
|
||||
|
||||
utils_opts = [
|
||||
|
@ -77,7 +77,7 @@ class TestListChassis(test_api_base.BaseApiTest):
|
||||
fields = 'extra,description'
|
||||
data = self.get_json(
|
||||
'/chassis/%s?fields=%s' % (chassis.uuid, fields),
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)})
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
# We always append "links"
|
||||
self.assertItemsEqual(['description', 'extra', 'links'], data)
|
||||
|
||||
@ -89,7 +89,7 @@ class TestListChassis(test_api_base.BaseApiTest):
|
||||
|
||||
data = self.get_json(
|
||||
'/chassis?fields=%s' % fields,
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)})
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
|
||||
self.assertEqual(3, len(data['chassis']))
|
||||
for ch in data['chassis']:
|
||||
@ -101,7 +101,7 @@ class TestListChassis(test_api_base.BaseApiTest):
|
||||
fields = 'uuid,spongebob'
|
||||
response = self.get_json(
|
||||
'/chassis/%s?fields=%s' % (chassis.uuid, fields),
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)},
|
||||
headers={api_base.Version.string: str(api_v1.max_version())},
|
||||
expect_errors=True)
|
||||
self.assertEqual(http_client.BAD_REQUEST, response.status_int)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
@ -112,7 +112,7 @@ class TestListChassis(test_api_base.BaseApiTest):
|
||||
fields = 'uuid,extra'
|
||||
response = self.get_json(
|
||||
'/chassis/%s?fields=%s' % (chassis.uuid, fields),
|
||||
headers={api_base.Version.string: str(api_v1.MIN_VER)},
|
||||
headers={api_base.Version.string: str(api_v1.min_version())},
|
||||
expect_errors=True)
|
||||
self.assertEqual(http_client.NOT_ACCEPTABLE, response.status_int)
|
||||
|
||||
|
@ -90,7 +90,8 @@ class TestListNodes(test_api_base.BaseApiTest):
|
||||
node = obj_utils.create_test_node(self.context,
|
||||
chassis_id=self.chassis.id)
|
||||
data = self.get_json(
|
||||
'/nodes', headers={api_base.Version.string: str(api_v1.MAX_VER)})
|
||||
'/nodes',
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
self.assertIn('instance_uuid', data['nodes'][0])
|
||||
self.assertIn('maintenance', data['nodes'][0])
|
||||
self.assertIn('power_state', data['nodes'][0])
|
||||
@ -125,7 +126,7 @@ class TestListNodes(test_api_base.BaseApiTest):
|
||||
chassis_id=self.chassis.id)
|
||||
data = self.get_json(
|
||||
'/nodes/%s' % node.uuid,
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)})
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
self.assertEqual(node.uuid, data['uuid'])
|
||||
self.assertIn('driver', data)
|
||||
self.assertIn('driver_info', data)
|
||||
@ -184,7 +185,7 @@ class TestListNodes(test_api_base.BaseApiTest):
|
||||
fields = 'extra,instance_info'
|
||||
data = self.get_json(
|
||||
'/nodes/%s?fields=%s' % (node.uuid, fields),
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)})
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
# We always append "links"
|
||||
self.assertItemsEqual(['extra', 'instance_info', 'links'], data)
|
||||
|
||||
@ -197,7 +198,7 @@ class TestListNodes(test_api_base.BaseApiTest):
|
||||
|
||||
data = self.get_json(
|
||||
'/nodes?fields=%s' % fields,
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)})
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
|
||||
self.assertEqual(3, len(data['nodes']))
|
||||
for node in data['nodes']:
|
||||
@ -210,7 +211,7 @@ class TestListNodes(test_api_base.BaseApiTest):
|
||||
fields = 'uuid,spongebob'
|
||||
response = self.get_json(
|
||||
'/nodes/%s?fields=%s' % (node.uuid, fields),
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)},
|
||||
headers={api_base.Version.string: str(api_v1.max_version())},
|
||||
expect_errors=True)
|
||||
self.assertEqual(http_client.BAD_REQUEST, response.status_int)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
@ -222,7 +223,7 @@ class TestListNodes(test_api_base.BaseApiTest):
|
||||
fields = 'uuid,extra'
|
||||
response = self.get_json(
|
||||
'/nodes/%s?fields=%s' % (node.uuid, fields),
|
||||
headers={api_base.Version.string: str(api_v1.MIN_VER)},
|
||||
headers={api_base.Version.string: str(api_v1.min_version())},
|
||||
expect_errors=True)
|
||||
self.assertEqual(http_client.NOT_ACCEPTABLE, response.status_int)
|
||||
|
||||
@ -233,7 +234,7 @@ class TestListNodes(test_api_base.BaseApiTest):
|
||||
fields = 'driver_info'
|
||||
data = self.get_json(
|
||||
'/nodes/%s?fields=%s' % (node.uuid, fields),
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)})
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
# We always append "links"
|
||||
self.assertItemsEqual(['driver_info', 'links'], data)
|
||||
self.assertEqual('******', data['driver_info']['fake_password'])
|
||||
@ -254,7 +255,7 @@ class TestListNodes(test_api_base.BaseApiTest):
|
||||
fields = 'network_interface'
|
||||
response = self.get_json(
|
||||
'/nodes/%s?fields=%s' % (node.uuid, fields),
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)})
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
self.assertIn('network_interface', response)
|
||||
|
||||
def test_get_all_interface_fields_invalid_api_version(self):
|
||||
@ -273,7 +274,7 @@ class TestListNodes(test_api_base.BaseApiTest):
|
||||
fields_arg = ','.join(api_utils.V31_FIELDS)
|
||||
response = self.get_json(
|
||||
'/nodes/%s?fields=%s' % (node.uuid, fields_arg),
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)})
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
for field in api_utils.V31_FIELDS:
|
||||
self.assertIn(field, response)
|
||||
|
||||
@ -293,7 +294,7 @@ class TestListNodes(test_api_base.BaseApiTest):
|
||||
fields = 'storage_interface'
|
||||
response = self.get_json(
|
||||
'/nodes/%s?fields=%s' % (node.uuid, fields),
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)})
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
self.assertIn('storage_interface', response)
|
||||
|
||||
def test_detail(self):
|
||||
@ -301,7 +302,7 @@ class TestListNodes(test_api_base.BaseApiTest):
|
||||
chassis_id=self.chassis.id)
|
||||
data = self.get_json(
|
||||
'/nodes/detail',
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)})
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
self.assertEqual(node.uuid, data['nodes'][0]["uuid"])
|
||||
self.assertIn('name', data['nodes'][0])
|
||||
self.assertIn('driver', data['nodes'][0])
|
||||
@ -339,7 +340,7 @@ class TestListNodes(test_api_base.BaseApiTest):
|
||||
|
||||
data = self.get_json(
|
||||
'/nodes/%s' % node.uuid,
|
||||
headers={api_base.Version.string: str(api_v1.MIN_VER)})
|
||||
headers={api_base.Version.string: str(api_v1.min_version())})
|
||||
self.assertEqual(states.NOSTATE, data['provision_state'])
|
||||
|
||||
data = self.get_json('/nodes/%s' % node.uuid,
|
||||
@ -351,7 +352,7 @@ class TestListNodes(test_api_base.BaseApiTest):
|
||||
driver_internal_info={"foo": "bar"})
|
||||
data = self.get_json(
|
||||
'/nodes/%s' % node.uuid,
|
||||
headers={api_base.Version.string: str(api_v1.MIN_VER)})
|
||||
headers={api_base.Version.string: str(api_v1.min_version())})
|
||||
self.assertNotIn('driver_internal_info', data)
|
||||
|
||||
data = self.get_json('/nodes/%s' % node.uuid,
|
||||
@ -375,7 +376,7 @@ class TestListNodes(test_api_base.BaseApiTest):
|
||||
inspection_started_at=some_time)
|
||||
data = self.get_json(
|
||||
'/nodes/%s' % node.uuid,
|
||||
headers={api_base.Version.string: str(api_v1.MIN_VER)})
|
||||
headers={api_base.Version.string: str(api_v1.min_version())})
|
||||
self.assertNotIn('inspection_finished_at', data)
|
||||
self.assertNotIn('inspection_started_at', data)
|
||||
|
||||
@ -391,7 +392,7 @@ class TestListNodes(test_api_base.BaseApiTest):
|
||||
clean_step={"foo": "bar"})
|
||||
data = self.get_json(
|
||||
'/nodes/%s' % node.uuid,
|
||||
headers={api_base.Version.string: str(api_v1.MIN_VER)})
|
||||
headers={api_base.Version.string: str(api_v1.min_version())})
|
||||
self.assertNotIn('clean_step', data)
|
||||
|
||||
data = self.get_json('/nodes/%s' % node.uuid,
|
||||
@ -737,14 +738,14 @@ class TestListNodes(test_api_base.BaseApiTest):
|
||||
|
||||
data = self.get_json(
|
||||
'/nodes/%s/volume/connectors' % node.uuid,
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)})
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
self.assertEqual(2, len(data['connectors']))
|
||||
self.assertNotIn('next', data)
|
||||
|
||||
# Test collection pagination
|
||||
data = self.get_json(
|
||||
'/nodes/%s/volume/connectors?limit=1' % node.uuid,
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)})
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
self.assertEqual(1, len(data['connectors']))
|
||||
self.assertIn('next', data)
|
||||
|
||||
@ -755,7 +756,7 @@ class TestListNodes(test_api_base.BaseApiTest):
|
||||
response = self.get_json(
|
||||
'/nodes/volume/connectors',
|
||||
expect_errors=True,
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)})
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
self.assertEqual(http_client.NOT_FOUND, response.status_int)
|
||||
|
||||
def test_volume_connectors_subresource_node_not_found(self):
|
||||
@ -763,7 +764,7 @@ class TestListNodes(test_api_base.BaseApiTest):
|
||||
response = self.get_json(
|
||||
'/nodes/%s/volume/connectors' % non_existent_uuid,
|
||||
expect_errors=True,
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)})
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
self.assertEqual(http_client.NOT_FOUND, response.status_int)
|
||||
|
||||
def test_volume_targets_subresource(self):
|
||||
@ -776,14 +777,14 @@ class TestListNodes(test_api_base.BaseApiTest):
|
||||
|
||||
data = self.get_json(
|
||||
'/nodes/%s/volume/targets' % node.uuid,
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)})
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
self.assertEqual(2, len(data['targets']))
|
||||
self.assertNotIn('next', data)
|
||||
|
||||
# Test collection pagination
|
||||
data = self.get_json(
|
||||
'/nodes/%s/volume/targets?limit=1' % node.uuid,
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)})
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
self.assertEqual(1, len(data['targets']))
|
||||
self.assertIn('next', data)
|
||||
|
||||
@ -794,7 +795,7 @@ class TestListNodes(test_api_base.BaseApiTest):
|
||||
response = self.get_json(
|
||||
'/nodes/volume/targets',
|
||||
expect_errors=True,
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)})
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
self.assertEqual(http_client.NOT_FOUND, response.status_int)
|
||||
|
||||
def test_volume_targets_subresource_node_not_found(self):
|
||||
@ -802,7 +803,7 @@ class TestListNodes(test_api_base.BaseApiTest):
|
||||
response = self.get_json(
|
||||
'/nodes/%s/volume/targets' % non_existent_uuid,
|
||||
expect_errors=True,
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)})
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
self.assertEqual(http_client.NOT_FOUND, response.status_int)
|
||||
|
||||
@mock.patch.object(timeutils, 'utcnow')
|
||||
@ -1085,7 +1086,7 @@ class TestListNodes(test_api_base.BaseApiTest):
|
||||
def test_get_nodes_by_driver_invalid_api_version(self):
|
||||
response = self.get_json(
|
||||
'/nodes?driver=fake',
|
||||
headers={api_base.Version.string: str(api_v1.MIN_VER)},
|
||||
headers={api_base.Version.string: str(api_v1.min_version())},
|
||||
expect_errors=True)
|
||||
self.assertEqual(http_client.NOT_ACCEPTABLE, response.status_code)
|
||||
self.assertTrue(response.json['error_message'])
|
||||
@ -1147,7 +1148,7 @@ class TestListNodes(test_api_base.BaseApiTest):
|
||||
|
||||
response = self.get_json(
|
||||
base_url % 'fake',
|
||||
headers={api_base.Version.string: str(api_v1.MIN_VER)},
|
||||
headers={api_base.Version.string: str(api_v1.min_version())},
|
||||
expect_errors=True)
|
||||
self.assertEqual(http_client.NOT_ACCEPTABLE, response.status_code)
|
||||
self.assertTrue(response.json['error_message'])
|
||||
@ -1307,7 +1308,7 @@ class TestListNodes(test_api_base.BaseApiTest):
|
||||
driver_info=driver_info)
|
||||
data = self.get_json(
|
||||
'/nodes/%s' % node.uuid,
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)})
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
|
||||
self.assertEqual("******", data["driver_info"]["ssh_password"])
|
||||
self.assertEqual("******", data["driver_info"]["ssh_key_contents"])
|
||||
@ -1562,7 +1563,7 @@ class TestPatch(test_api_base.BaseApiTest):
|
||||
'/nodes/%s/volume/connectors' % self.node.uuid,
|
||||
[{'path': '/extra/foo', 'value': 'bar', 'op': 'add'}],
|
||||
expect_errors=True,
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)})
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
self.assertEqual(http_client.BAD_REQUEST, response.status_int)
|
||||
|
||||
def test_patch_volume_connectors_subresource(self):
|
||||
@ -1574,7 +1575,7 @@ class TestPatch(test_api_base.BaseApiTest):
|
||||
connector.uuid),
|
||||
[{'path': '/extra/foo', 'value': 'bar', 'op': 'add'}],
|
||||
expect_errors=True,
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)})
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
self.assertEqual(http_client.FORBIDDEN, response.status_int)
|
||||
|
||||
def test_patch_volume_targets_subresource(self):
|
||||
@ -1585,7 +1586,7 @@ class TestPatch(test_api_base.BaseApiTest):
|
||||
target.uuid),
|
||||
[{'path': '/extra/foo', 'value': 'bar', 'op': 'add'}],
|
||||
expect_errors=True,
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)})
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
self.assertEqual(http_client.FORBIDDEN, response.status_int)
|
||||
|
||||
def test_remove_uuid(self):
|
||||
@ -1943,7 +1944,7 @@ class TestPatch(test_api_base.BaseApiTest):
|
||||
uuid=uuidutils.generate_uuid())
|
||||
self.mock_update_node.return_value = node
|
||||
network_interface = 'flat'
|
||||
headers = {api_base.Version.string: str(api_v1.MAX_VER)}
|
||||
headers = {api_base.Version.string: str(api_v1.max_version())}
|
||||
response = self.patch_json('/nodes/%s' % node.uuid,
|
||||
[{'path': '/network_interface',
|
||||
'value': network_interface,
|
||||
@ -2029,7 +2030,7 @@ class TestPatch(test_api_base.BaseApiTest):
|
||||
node = obj_utils.create_test_node(self.context,
|
||||
uuid=uuidutils.generate_uuid())
|
||||
self.mock_update_node.return_value = node
|
||||
headers = {api_base.Version.string: str(api_v1.MAX_VER)}
|
||||
headers = {api_base.Version.string: str(api_v1.max_version())}
|
||||
for field in api_utils.V31_FIELDS:
|
||||
response = self.patch_json('/nodes/%s' % node.uuid,
|
||||
[{'path': '/%s' % field,
|
||||
@ -2075,7 +2076,7 @@ class TestPatch(test_api_base.BaseApiTest):
|
||||
uuid=uuidutils.generate_uuid())
|
||||
self.mock_update_node.return_value = node
|
||||
storage_interface = 'cinder'
|
||||
headers = {api_base.Version.string: str(api_v1.MAX_VER)}
|
||||
headers = {api_base.Version.string: str(api_v1.max_version())}
|
||||
response = self.patch_json('/nodes/%s' % node.uuid,
|
||||
[{'path': '/storage_interface',
|
||||
'value': storage_interface,
|
||||
@ -2473,7 +2474,7 @@ class TestPost(test_api_base.BaseApiTest):
|
||||
response = self.post_json(
|
||||
'/nodes/volume/connectors', pdict,
|
||||
expect_errors=True,
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)})
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
self.assertEqual(http_client.NOT_FOUND, response.status_int)
|
||||
|
||||
def test_post_volume_connectors_subresource(self):
|
||||
@ -2483,7 +2484,7 @@ class TestPost(test_api_base.BaseApiTest):
|
||||
response = self.post_json(
|
||||
'/nodes/%s/volume/connectors' % node.uuid, pdict,
|
||||
expect_errors=True,
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)})
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
self.assertEqual(http_client.FORBIDDEN, response.status_int)
|
||||
|
||||
def test_post_volume_targets_subresource(self):
|
||||
@ -2493,7 +2494,7 @@ class TestPost(test_api_base.BaseApiTest):
|
||||
response = self.post_json(
|
||||
'/nodes/%s/volume/targets' % node.uuid, pdict,
|
||||
expect_errors=True,
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)})
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
self.assertEqual(http_client.FORBIDDEN, response.status_int)
|
||||
|
||||
def test_create_node_no_mandatory_field_driver(self):
|
||||
@ -2589,11 +2590,11 @@ class TestPost(test_api_base.BaseApiTest):
|
||||
network_interface='flat')
|
||||
response = self.post_json('/nodes', ndict,
|
||||
headers={api_base.Version.string:
|
||||
str(api_v1.MAX_VER)})
|
||||
str(api_v1.max_version())})
|
||||
self.assertEqual(http_client.CREATED, response.status_int)
|
||||
result = self.get_json('/nodes/%s' % ndict['uuid'],
|
||||
headers={api_base.Version.string:
|
||||
str(api_v1.MAX_VER)})
|
||||
str(api_v1.max_version())})
|
||||
self.assertEqual('flat', result['network_interface'])
|
||||
|
||||
def test_create_node_network_interface_old_api_version(self):
|
||||
@ -2608,7 +2609,7 @@ class TestPost(test_api_base.BaseApiTest):
|
||||
network_interface='foo')
|
||||
response = self.post_json('/nodes', ndict, expect_errors=True,
|
||||
headers={api_base.Version.string:
|
||||
str(api_v1.MAX_VER)})
|
||||
str(api_v1.max_version())})
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
self.assertEqual(http_client.BAD_REQUEST, response.status_int)
|
||||
|
||||
@ -2617,11 +2618,11 @@ class TestPost(test_api_base.BaseApiTest):
|
||||
resource_class='foo')
|
||||
response = self.post_json('/nodes', ndict,
|
||||
headers={api_base.Version.string:
|
||||
str(api_v1.MAX_VER)})
|
||||
str(api_v1.max_version())})
|
||||
self.assertEqual(http_client.CREATED, response.status_int)
|
||||
result = self.get_json('/nodes/%s' % ndict['uuid'],
|
||||
headers={api_base.Version.string:
|
||||
str(api_v1.MAX_VER)})
|
||||
str(api_v1.max_version())})
|
||||
self.assertEqual('foo', result['resource_class'])
|
||||
|
||||
def test_create_node_resource_class_old_api_version(self):
|
||||
@ -2643,7 +2644,7 @@ class TestPost(test_api_base.BaseApiTest):
|
||||
ndict = test_api_utils.post_get_test_node(storage_interface='foo')
|
||||
response = self.post_json('/nodes', ndict, expect_errors=True,
|
||||
headers={api_base.Version.string:
|
||||
str(api_v1.MAX_VER)})
|
||||
str(api_v1.max_version())})
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
self.assertEqual(http_client.BAD_REQUEST, response.status_int)
|
||||
|
||||
@ -2750,7 +2751,7 @@ class TestDelete(test_api_base.BaseApiTest):
|
||||
response = self.delete(
|
||||
'/nodes/%s/volume/connectors' % node.uuid,
|
||||
expect_errors=True,
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)})
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
self.assertEqual(http_client.BAD_REQUEST, response.status_int)
|
||||
|
||||
def test_delete_volume_connectors_subresource(self):
|
||||
@ -2760,7 +2761,7 @@ class TestDelete(test_api_base.BaseApiTest):
|
||||
response = self.delete(
|
||||
'/nodes/%s/volume/connectors/%s' % (node.uuid, connector.uuid),
|
||||
expect_errors=True,
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)})
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
self.assertEqual(http_client.FORBIDDEN, response.status_int)
|
||||
|
||||
def test_delete_volume_targets_subresource(self):
|
||||
@ -2770,7 +2771,7 @@ class TestDelete(test_api_base.BaseApiTest):
|
||||
response = self.delete(
|
||||
'/nodes/%s/volume/targets/%s' % (node.uuid, target.uuid),
|
||||
expect_errors=True,
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)})
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
self.assertEqual(http_client.FORBIDDEN, response.status_int)
|
||||
|
||||
@mock.patch.object(notification_utils, '_emit_api_notification')
|
||||
|
@ -233,7 +233,7 @@ class TestListPorts(test_api_base.BaseApiTest):
|
||||
fields = 'address,extra'
|
||||
data = self.get_json(
|
||||
'/ports/%s?fields=%s' % (port.uuid, fields),
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)})
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
# We always append "links"
|
||||
self.assertItemsEqual(['address', 'extra', 'links'], data)
|
||||
|
||||
@ -242,7 +242,7 @@ class TestListPorts(test_api_base.BaseApiTest):
|
||||
internal_info={"foo": "bar"})
|
||||
data = self.get_json(
|
||||
'/ports/%s' % port.uuid,
|
||||
headers={api_base.Version.string: str(api_v1.MIN_VER)})
|
||||
headers={api_base.Version.string: str(api_v1.min_version())})
|
||||
self.assertNotIn('internal_info', data)
|
||||
|
||||
data = self.get_json('/ports/%s' % port.uuid,
|
||||
@ -313,7 +313,7 @@ class TestListPorts(test_api_base.BaseApiTest):
|
||||
|
||||
data = self.get_json(
|
||||
'/ports?fields=%s' % fields,
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)})
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
|
||||
self.assertEqual(3, len(data['ports']))
|
||||
for port in data['ports']:
|
||||
@ -325,7 +325,7 @@ class TestListPorts(test_api_base.BaseApiTest):
|
||||
fields = 'uuid,spongebob'
|
||||
response = self.get_json(
|
||||
'/ports/%s?fields=%s' % (port.uuid, fields),
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)},
|
||||
headers={api_base.Version.string: str(api_v1.max_version())},
|
||||
expect_errors=True)
|
||||
self.assertEqual(http_client.BAD_REQUEST, response.status_int)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
@ -336,7 +336,7 @@ class TestListPorts(test_api_base.BaseApiTest):
|
||||
fields = 'uuid,extra'
|
||||
response = self.get_json(
|
||||
'/ports/%s?fields=%s' % (port.uuid, fields),
|
||||
headers={api_base.Version.string: str(api_v1.MIN_VER)},
|
||||
headers={api_base.Version.string: str(api_v1.min_version())},
|
||||
expect_errors=True)
|
||||
self.assertEqual(http_client.NOT_ACCEPTABLE, response.status_int)
|
||||
|
||||
@ -380,7 +380,7 @@ class TestListPorts(test_api_base.BaseApiTest):
|
||||
physical_network='physnet1')
|
||||
data = self.get_json(
|
||||
'/ports/detail',
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)}
|
||||
headers={api_base.Version.string: str(api_v1.max_version())}
|
||||
)
|
||||
self.assertEqual(port.uuid, data['ports'][0]["uuid"])
|
||||
self.assertIn('extra', data['ports'][0])
|
||||
@ -519,7 +519,7 @@ class TestListPorts(test_api_base.BaseApiTest):
|
||||
for invalid_key in invalid_keys_list:
|
||||
response = self.get_json(
|
||||
'/ports?sort_key=%s' % invalid_key, expect_errors=True,
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)}
|
||||
headers={api_base.Version.string: str(api_v1.max_version())}
|
||||
)
|
||||
self.assertEqual(http_client.BAD_REQUEST, response.status_int)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
@ -535,7 +535,7 @@ class TestListPorts(test_api_base.BaseApiTest):
|
||||
address='52:54:00:cf:2d:3%s' % id_,
|
||||
pxe_enabled=id_ % 2)
|
||||
port_uuids.append(port.uuid)
|
||||
headers = {api_base.Version.string: str(api_v1.MAX_VER)}
|
||||
headers = {api_base.Version.string: str(api_v1.max_version())}
|
||||
detail_str = '/detail' if detail else ''
|
||||
data = self.get_json('/ports%s?sort_key=pxe_enabled' % detail_str,
|
||||
headers=headers)
|
||||
@ -1268,7 +1268,7 @@ class TestPatch(test_api_base.BaseApiTest):
|
||||
|
||||
def test_invalid_physnet_non_text(self, mock_upd):
|
||||
physnet = 1234
|
||||
headers = {api_base.Version.string: versions.MAX_VERSION_STRING}
|
||||
headers = {api_base.Version.string: versions.max_version_string()}
|
||||
response = self.patch_json('/ports/%s' % self.port.uuid,
|
||||
[{'path': '/physical_network',
|
||||
'value': physnet,
|
||||
@ -1281,7 +1281,7 @@ class TestPatch(test_api_base.BaseApiTest):
|
||||
|
||||
def test_invalid_physnet_too_long(self, mock_upd):
|
||||
physnet = 'p' * 65
|
||||
headers = {api_base.Version.string: versions.MAX_VERSION_STRING}
|
||||
headers = {api_base.Version.string: versions.max_version_string()}
|
||||
response = self.patch_json('/ports/%s' % self.port.uuid,
|
||||
[{'path': '/physical_network',
|
||||
'value': physnet,
|
||||
@ -1319,7 +1319,7 @@ class TestPost(test_api_base.BaseApiTest):
|
||||
self.portgroup = obj_utils.create_test_portgroup(self.context,
|
||||
node_id=self.node.id)
|
||||
self.headers = {api_base.Version.string: str(
|
||||
versions.MAX_VERSION_STRING)}
|
||||
versions.max_version_string())}
|
||||
|
||||
p = mock.patch.object(rpcapi.ConductorAPI, 'get_topic_for')
|
||||
self.mock_gtf = p.start()
|
||||
@ -1370,7 +1370,7 @@ class TestPost(test_api_base.BaseApiTest):
|
||||
pdict.pop('pxe_enabled')
|
||||
pdict.pop('extra')
|
||||
pdict.pop('physical_network')
|
||||
headers = {api_base.Version.string: str(api_v1.MIN_VER)}
|
||||
headers = {api_base.Version.string: str(api_v1.min_version())}
|
||||
response = self.post_json('/ports', pdict, headers=headers)
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
self.assertEqual(http_client.CREATED, response.status_int)
|
||||
|
@ -51,7 +51,7 @@ class TestPortgroupObject(base.TestCase):
|
||||
|
||||
|
||||
class TestListPortgroups(test_api_base.BaseApiTest):
|
||||
headers = {api_base.Version.string: str(api_v1.MAX_VER)}
|
||||
headers = {api_base.Version.string: str(api_v1.max_version())}
|
||||
|
||||
def setUp(self):
|
||||
super(TestListPortgroups, self).setUp()
|
||||
@ -152,7 +152,7 @@ class TestListPortgroups(test_api_base.BaseApiTest):
|
||||
node_id=self.node.id)
|
||||
response = self.get_json(
|
||||
'/portgroups/%s' % (portgroup.uuid),
|
||||
headers={api_base.Version.string: str(api_v1.MIN_VER)},
|
||||
headers={api_base.Version.string: str(api_v1.min_version())},
|
||||
expect_errors=True)
|
||||
self.assertEqual(http_client.NOT_FOUND, response.status_int)
|
||||
|
||||
@ -170,7 +170,7 @@ class TestListPortgroups(test_api_base.BaseApiTest):
|
||||
def test_detail_invalid_api_version(self):
|
||||
response = self.get_json(
|
||||
'/portgroups/detail',
|
||||
headers={api_base.Version.string: str(api_v1.MIN_VER)},
|
||||
headers={api_base.Version.string: str(api_v1.min_version())},
|
||||
expect_errors=True)
|
||||
self.assertEqual(http_client.NOT_FOUND, response.status_int)
|
||||
|
||||
@ -274,14 +274,14 @@ class TestListPortgroups(test_api_base.BaseApiTest):
|
||||
# Test get one old api version, /portgroups controller not allowed
|
||||
response = self.get_json('/portgroups/%s/ports/%s' % (
|
||||
pg.uuid, uuidutils.generate_uuid()),
|
||||
headers={api_base.Version.string: str(api_v1.MIN_VER)},
|
||||
headers={api_base.Version.string: str(api_v1.min_version())},
|
||||
expect_errors=True)
|
||||
self.assertEqual(http_client.NOT_FOUND, response.status_int)
|
||||
|
||||
# Test get one not allowed to access to /portgroups/<uuid>/ports/<uuid>
|
||||
response = self.get_json(
|
||||
'/portgroups/%s/ports/%s' % (pg.uuid, uuidutils.generate_uuid()),
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)},
|
||||
headers={api_base.Version.string: str(api_v1.max_version())},
|
||||
expect_errors=True)
|
||||
self.assertEqual(http_client.FORBIDDEN, response.status_int)
|
||||
|
||||
@ -471,7 +471,7 @@ class TestListPortgroups(test_api_base.BaseApiTest):
|
||||
|
||||
@mock.patch.object(rpcapi.ConductorAPI, 'update_portgroup')
|
||||
class TestPatch(test_api_base.BaseApiTest):
|
||||
headers = {api_base.Version.string: str(api_v1.MAX_VER)}
|
||||
headers = {api_base.Version.string: str(api_v1.max_version())}
|
||||
|
||||
def setUp(self):
|
||||
super(TestPatch, self).setUp()
|
||||
@ -865,7 +865,7 @@ class TestPatch(test_api_base.BaseApiTest):
|
||||
'op': 'replace'}],
|
||||
expect_errors=True,
|
||||
headers={api_base.Version.string:
|
||||
str(api_v1.MIN_VER)})
|
||||
str(api_v1.min_version())})
|
||||
self.assertEqual('application/json', response.content_type)
|
||||
self.assertEqual(http_client.NOT_FOUND, response.status_int)
|
||||
self.assertTrue(response.json['error_message'])
|
||||
@ -929,7 +929,7 @@ class TestPatch(test_api_base.BaseApiTest):
|
||||
|
||||
|
||||
class TestPost(test_api_base.BaseApiTest):
|
||||
headers = {api_base.Version.string: str(api_v1.MAX_VER)}
|
||||
headers = {api_base.Version.string: str(api_v1.max_version())}
|
||||
|
||||
def setUp(self):
|
||||
super(TestPost, self).setUp()
|
||||
@ -1205,7 +1205,7 @@ class TestPost(test_api_base.BaseApiTest):
|
||||
|
||||
@mock.patch.object(rpcapi.ConductorAPI, 'destroy_portgroup')
|
||||
class TestDelete(test_api_base.BaseApiTest):
|
||||
headers = {api_base.Version.string: str(api_v1.MAX_VER)}
|
||||
headers = {api_base.Version.string: str(api_v1.max_version())}
|
||||
|
||||
def setUp(self):
|
||||
super(TestDelete, self).setUp()
|
||||
|
@ -65,14 +65,14 @@ class TestLookup(test_api_base.BaseApiTest):
|
||||
def test_nothing_provided(self):
|
||||
response = self.get_json(
|
||||
'/lookup',
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)},
|
||||
headers={api_base.Version.string: str(api_v1.max_version())},
|
||||
expect_errors=True)
|
||||
self.assertEqual(http_client.BAD_REQUEST, response.status_int)
|
||||
|
||||
def test_not_found(self):
|
||||
response = self.get_json(
|
||||
'/lookup?addresses=%s' % ','.join(self.addresses),
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)},
|
||||
headers={api_base.Version.string: str(api_v1.max_version())},
|
||||
expect_errors=True)
|
||||
self.assertEqual(http_client.NOT_FOUND, response.status_int)
|
||||
|
||||
@ -83,7 +83,7 @@ class TestLookup(test_api_base.BaseApiTest):
|
||||
|
||||
response = self.get_json(
|
||||
'/lookup?addresses=%s' % ','.join(self.addresses),
|
||||
headers={api_base.Version.string: str(api_v1.MIN_VER)},
|
||||
headers={api_base.Version.string: str(api_v1.min_version())},
|
||||
expect_errors=True)
|
||||
self.assertEqual(http_client.NOT_FOUND, response.status_int)
|
||||
|
||||
@ -94,7 +94,7 @@ class TestLookup(test_api_base.BaseApiTest):
|
||||
|
||||
data = self.get_json(
|
||||
'/lookup?addresses=%s' % ','.join(self.addresses),
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)})
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
self.assertEqual(self.node.uuid, data['node']['uuid'])
|
||||
self.assertEqual(set(ramdisk._LOOKUP_RETURN_FIELDS) | {'links'},
|
||||
set(data['node']))
|
||||
@ -110,7 +110,7 @@ class TestLookup(test_api_base.BaseApiTest):
|
||||
':f4:52:14:03:00:54:06:c2,' + ','.join(self.addresses))
|
||||
data = self.get_json(
|
||||
'/lookup?addresses=%s' % addresses,
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)})
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
self.assertEqual(self.node.uuid, data['node']['uuid'])
|
||||
self.assertEqual(set(ramdisk._LOOKUP_RETURN_FIELDS) | {'links'},
|
||||
set(data['node']))
|
||||
@ -121,7 +121,7 @@ class TestLookup(test_api_base.BaseApiTest):
|
||||
data = self.get_json(
|
||||
'/lookup?addresses=%s&node_uuid=%s' %
|
||||
(','.join(self.addresses), self.node.uuid),
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)})
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
self.assertEqual(self.node.uuid, data['node']['uuid'])
|
||||
self.assertEqual(set(ramdisk._LOOKUP_RETURN_FIELDS) | {'links'},
|
||||
set(data['node']))
|
||||
@ -130,7 +130,7 @@ class TestLookup(test_api_base.BaseApiTest):
|
||||
def test_found_by_only_uuid(self):
|
||||
data = self.get_json(
|
||||
'/lookup?node_uuid=%s' % self.node.uuid,
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)})
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
self.assertEqual(self.node.uuid, data['node']['uuid'])
|
||||
self.assertEqual(set(ramdisk._LOOKUP_RETURN_FIELDS) | {'links'},
|
||||
set(data['node']))
|
||||
@ -140,7 +140,7 @@ class TestLookup(test_api_base.BaseApiTest):
|
||||
response = self.get_json(
|
||||
'/lookup?addresses=%s&node_uuid=%s' %
|
||||
(','.join(self.addresses), self.node2.uuid),
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)},
|
||||
headers={api_base.Version.string: str(api_v1.max_version())},
|
||||
expect_errors=True)
|
||||
self.assertEqual(http_client.NOT_FOUND, response.status_int)
|
||||
|
||||
@ -149,7 +149,7 @@ class TestLookup(test_api_base.BaseApiTest):
|
||||
data = self.get_json(
|
||||
'/lookup?addresses=%s&node_uuid=%s' %
|
||||
(','.join(self.addresses), self.node2.uuid),
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)})
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
self.assertEqual(self.node2.uuid, data['node']['uuid'])
|
||||
self.assertEqual(set(ramdisk._LOOKUP_RETURN_FIELDS) | {'links'},
|
||||
set(data['node']))
|
||||
@ -163,7 +163,7 @@ class TestHeartbeat(test_api_base.BaseApiTest):
|
||||
response = self.post_json(
|
||||
'/heartbeat/%s' % uuidutils.generate_uuid(),
|
||||
{'callback_url': 'url'},
|
||||
headers={api_base.Version.string: str(api_v1.MIN_VER)},
|
||||
headers={api_base.Version.string: str(api_v1.min_version())},
|
||||
expect_errors=True)
|
||||
self.assertEqual(http_client.NOT_FOUND, response.status_int)
|
||||
|
||||
@ -171,7 +171,7 @@ class TestHeartbeat(test_api_base.BaseApiTest):
|
||||
response = self.post_json(
|
||||
'/heartbeat/%s' % uuidutils.generate_uuid(),
|
||||
{'callback_url': 'url'},
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)},
|
||||
headers={api_base.Version.string: str(api_v1.max_version())},
|
||||
expect_errors=True)
|
||||
self.assertEqual(http_client.NOT_FOUND, response.status_int)
|
||||
|
||||
@ -181,7 +181,7 @@ class TestHeartbeat(test_api_base.BaseApiTest):
|
||||
response = self.post_json(
|
||||
'/heartbeat/%s' % node.uuid,
|
||||
{'callback_url': 'url'},
|
||||
headers={api_base.Version.string: str(api_v1.MAX_VER)})
|
||||
headers={api_base.Version.string: str(api_v1.max_version())})
|
||||
self.assertEqual(http_client.ACCEPTED, response.status_int)
|
||||
self.assertEqual(b'', response.body)
|
||||
mock_heartbeat.assert_called_once_with(mock.ANY, mock.ANY,
|
||||
|
@ -40,7 +40,7 @@ class TestCheckVersions(test_base.TestCase):
|
||||
|
||||
def test_check_version_invalid_major_version(self):
|
||||
self.version.major = v1_api.BASE_VERSION + 1
|
||||
self.version.minor = v1_api.MIN_VER.minor
|
||||
self.version.minor = v1_api.min_version().minor
|
||||
self.assertRaises(
|
||||
webob_exc.HTTPNotAcceptable,
|
||||
v1_api.Controller()._check_version,
|
||||
@ -48,7 +48,7 @@ class TestCheckVersions(test_base.TestCase):
|
||||
|
||||
def test_check_version_too_low(self):
|
||||
self.version.major = v1_api.BASE_VERSION
|
||||
self.version.minor = v1_api.MIN_VER.minor - 1
|
||||
self.version.minor = v1_api.min_version().minor - 1
|
||||
self.assertRaises(
|
||||
webob_exc.HTTPNotAcceptable,
|
||||
v1_api.Controller()._check_version,
|
||||
@ -56,14 +56,14 @@ class TestCheckVersions(test_base.TestCase):
|
||||
|
||||
def test_check_version_too_high(self):
|
||||
self.version.major = v1_api.BASE_VERSION
|
||||
self.version.minor = v1_api.MAX_VER.minor + 1
|
||||
self.version.minor = v1_api.max_version().minor + 1
|
||||
e = self.assertRaises(
|
||||
webob_exc.HTTPNotAcceptable,
|
||||
v1_api.Controller()._check_version,
|
||||
self.version, {'fake-headers': v1_api.MAX_VER.minor})
|
||||
self.assertEqual(v1_api.MAX_VER.minor, e.headers['fake-headers'])
|
||||
self.version, {'fake-headers': v1_api.max_version().minor})
|
||||
self.assertEqual(v1_api.max_version().minor, e.headers['fake-headers'])
|
||||
|
||||
def test_check_version_ok(self):
|
||||
self.version.major = v1_api.BASE_VERSION
|
||||
self.version.minor = v1_api.MIN_VER.minor
|
||||
self.version.minor = v1_api.min_version().minor
|
||||
v1_api.Controller()._check_version(self.version)
|
||||
|
@ -17,7 +17,11 @@ Tests for the versions constants and methods.
|
||||
|
||||
import re
|
||||
|
||||
import mock
|
||||
|
||||
from ironic.api.controllers.v1 import versions
|
||||
from ironic.common import release_mappings
|
||||
from ironic.conf import CONF
|
||||
from ironic.tests import base
|
||||
|
||||
|
||||
@ -36,16 +40,16 @@ class TestVersionConstants(base.TestCase):
|
||||
self.minor_consts.sort(key=minor_key)
|
||||
|
||||
def test_max_ver_str(self):
|
||||
# Test to make sure MAX_VERSION_STRING corresponds with the largest
|
||||
# Test to make sure _MAX_VERSION_STRING corresponds with the largest
|
||||
# MINOR_ constant
|
||||
|
||||
max_ver = '1.{}'.format(getattr(versions, self.minor_consts[-1]))
|
||||
self.assertEqual(max_ver, versions.MAX_VERSION_STRING)
|
||||
self.assertEqual(max_ver, versions._MAX_VERSION_STRING)
|
||||
|
||||
def test_min_ver_str(self):
|
||||
# Try to make sure someone doesn't change the MIN_VERSION_STRING by
|
||||
# Try to make sure someone doesn't change the _MIN_VERSION_STRING by
|
||||
# accident and make sure it exists
|
||||
self.assertEqual('1.1', versions.MIN_VERSION_STRING)
|
||||
self.assertEqual('1.1', versions._MIN_VERSION_STRING)
|
||||
|
||||
def test_name_value_match(self):
|
||||
# Test to make sure variable name matches the value. For example
|
||||
@ -67,3 +71,25 @@ class TestVersionConstants(base.TestCase):
|
||||
value, seen_values,
|
||||
'The value {} has been used more than once'.format(value))
|
||||
seen_values.add(value)
|
||||
|
||||
|
||||
class TestMaxVersionString(base.TestCase):
|
||||
|
||||
def test_max_version_not_pinned(self):
|
||||
CONF.set_override('pin_release_version', None)
|
||||
self.assertEqual(versions._MAX_VERSION_STRING,
|
||||
versions.max_version_string())
|
||||
|
||||
@mock.patch('ironic.common.release_mappings.RELEASE_MAPPING',
|
||||
autospec=True)
|
||||
def test_max_version_pinned(self, mock_release_mapping):
|
||||
CONF.set_override('pin_release_version',
|
||||
release_mappings.RELEASE_VERSIONS[-1])
|
||||
mock_release_mapping.get.return_value = {
|
||||
'api': '1.5',
|
||||
'rpc': '1.4',
|
||||
'objects': {
|
||||
'MyObj': ['1.4'],
|
||||
}
|
||||
}
|
||||
self.assertEqual('1.5', versions.max_version_string())
|
||||
|
@ -32,7 +32,7 @@ class TestGetVolume(test_api_base.BaseApiTest):
|
||||
headers=headers))
|
||||
|
||||
def test_get_volume(self):
|
||||
headers = {api_base.Version.string: str(api_v1.MAX_VER)}
|
||||
headers = {api_base.Version.string: str(api_v1.max_version())}
|
||||
data = self.get_json('/volume/', headers=headers)
|
||||
for key in ['links', 'connectors', 'targets']:
|
||||
self._test_links(data, key, headers)
|
||||
@ -46,7 +46,7 @@ class TestGetVolume(test_api_base.BaseApiTest):
|
||||
data['targets'][1]['href'])
|
||||
|
||||
def test_get_volume_invalid_api_version(self):
|
||||
headers = {api_base.Version.string: str(api_v1.MIN_VER)}
|
||||
headers = {api_base.Version.string: str(api_v1.min_version())}
|
||||
response = self.get_json('/volume/', headers=headers,
|
||||
expect_errors=True)
|
||||
self.assertEqual(http_client.NOT_FOUND, response.status_int)
|
||||
|
@ -59,7 +59,7 @@ class TestVolumeConnectorObject(base.TestCase):
|
||||
|
||||
|
||||
class TestListVolumeConnectors(test_api_base.BaseApiTest):
|
||||
headers = {api_base.Version.string: str(api_v1.MAX_VER)}
|
||||
headers = {api_base.Version.string: str(api_v1.max_version())}
|
||||
|
||||
def setUp(self):
|
||||
super(TestListVolumeConnectors, self).setUp()
|
||||
@ -83,7 +83,7 @@ class TestListVolumeConnectors(test_api_base.BaseApiTest):
|
||||
node_id=self.node.id)
|
||||
response = self.get_json(
|
||||
'/volume/connectors',
|
||||
headers={api_base.Version.string: str(api_v1.MIN_VER)},
|
||||
headers={api_base.Version.string: str(api_v1.min_version())},
|
||||
expect_errors=True)
|
||||
self.assertEqual(http_client.NOT_FOUND, response.status_int)
|
||||
|
||||
@ -103,7 +103,7 @@ class TestListVolumeConnectors(test_api_base.BaseApiTest):
|
||||
self.context, node_id=self.node.id)
|
||||
response = self.get_json(
|
||||
'/volume/connectors/%s' % connector.uuid,
|
||||
headers={api_base.Version.string: str(api_v1.MIN_VER)},
|
||||
headers={api_base.Version.string: str(api_v1.min_version())},
|
||||
expect_errors=True)
|
||||
self.assertEqual(http_client.NOT_FOUND, response.status_int)
|
||||
|
||||
@ -151,7 +151,7 @@ class TestListVolumeConnectors(test_api_base.BaseApiTest):
|
||||
fields = 'uuid,extra'
|
||||
response = self.get_json(
|
||||
'/volume/connectors/%s?fields=%s' % (connector.uuid, fields),
|
||||
headers={api_base.Version.string: str(api_v1.MIN_VER)},
|
||||
headers={api_base.Version.string: str(api_v1.min_version())},
|
||||
expect_errors=True)
|
||||
self.assertEqual(http_client.NOT_FOUND, response.status_int)
|
||||
|
||||
@ -181,7 +181,7 @@ class TestListVolumeConnectors(test_api_base.BaseApiTest):
|
||||
node_id=self.node.id)
|
||||
response = self.get_json(
|
||||
'/volume/connectors?detail=True',
|
||||
headers={api_base.Version.string: str(api_v1.MIN_VER)},
|
||||
headers={api_base.Version.string: str(api_v1.min_version())},
|
||||
expect_errors=True)
|
||||
self.assertEqual(http_client.NOT_FOUND, response.status_int)
|
||||
|
||||
@ -348,7 +348,7 @@ class TestListVolumeConnectors(test_api_base.BaseApiTest):
|
||||
|
||||
@mock.patch.object(rpcapi.ConductorAPI, 'update_volume_connector')
|
||||
class TestPatch(test_api_base.BaseApiTest):
|
||||
headers = {api_base.Version.string: str(api_v1.MAX_VER)}
|
||||
headers = {api_base.Version.string: str(api_v1.max_version())}
|
||||
|
||||
def setUp(self):
|
||||
super(TestPatch, self).setUp()
|
||||
@ -388,7 +388,7 @@ class TestPatch(test_api_base.BaseApiTest):
|
||||
node_uuid=self.node.uuid)])
|
||||
|
||||
def test_update_invalid_api_version(self, mock_upd):
|
||||
headers = {api_base.Version.string: str(api_v1.MIN_VER)}
|
||||
headers = {api_base.Version.string: str(api_v1.min_version())}
|
||||
response = self.patch_json('/volume/connectors/%s'
|
||||
% self.connector.uuid,
|
||||
[{'path': '/extra/foo',
|
||||
@ -714,7 +714,7 @@ class TestPatch(test_api_base.BaseApiTest):
|
||||
|
||||
|
||||
class TestPost(test_api_base.BaseApiTest):
|
||||
headers = {api_base.Version.string: str(api_v1.MAX_VER)}
|
||||
headers = {api_base.Version.string: str(api_v1.max_version())}
|
||||
|
||||
def setUp(self):
|
||||
super(TestPost, self).setUp()
|
||||
@ -754,7 +754,7 @@ class TestPost(test_api_base.BaseApiTest):
|
||||
pdict = post_get_test_volume_connector()
|
||||
response = self.post_json(
|
||||
'/volume/connectors', pdict,
|
||||
headers={api_base.Version.string: str(api_v1.MIN_VER)},
|
||||
headers={api_base.Version.string: str(api_v1.min_version())},
|
||||
expect_errors=True)
|
||||
self.assertEqual(http_client.NOT_FOUND, response.status_int)
|
||||
|
||||
@ -879,7 +879,7 @@ class TestPost(test_api_base.BaseApiTest):
|
||||
|
||||
@mock.patch.object(rpcapi.ConductorAPI, 'destroy_volume_connector')
|
||||
class TestDelete(test_api_base.BaseApiTest):
|
||||
headers = {api_base.Version.string: str(api_v1.MAX_VER)}
|
||||
headers = {api_base.Version.string: str(api_v1.max_version())}
|
||||
|
||||
def setUp(self):
|
||||
super(TestDelete, self).setUp()
|
||||
@ -907,7 +907,7 @@ class TestDelete(test_api_base.BaseApiTest):
|
||||
node_uuid=self.node.uuid)])
|
||||
|
||||
def test_delete_volume_connector_byid_invalid_api_version(self, mock_dvc):
|
||||
headers = {api_base.Version.string: str(api_v1.MIN_VER)}
|
||||
headers = {api_base.Version.string: str(api_v1.min_version())}
|
||||
response = self.delete('/volume/connectors/%s' % self.connector.uuid,
|
||||
expect_errors=True, headers=headers)
|
||||
self.assertEqual(http_client.NOT_FOUND, response.status_int)
|
||||
|
@ -59,7 +59,7 @@ class TestVolumeTargetObject(base.TestCase):
|
||||
|
||||
|
||||
class TestListVolumeTargets(test_api_base.BaseApiTest):
|
||||
headers = {api_base.Version.string: str(api_v1.MAX_VER)}
|
||||
headers = {api_base.Version.string: str(api_v1.max_version())}
|
||||
|
||||
def setUp(self):
|
||||
super(TestListVolumeTargets, self).setUp()
|
||||
@ -83,7 +83,7 @@ class TestListVolumeTargets(test_api_base.BaseApiTest):
|
||||
self.context, node_id=self.node.id)
|
||||
response = self.get_json(
|
||||
'/volume/targets',
|
||||
headers={api_base.Version.string: str(api_v1.MIN_VER)},
|
||||
headers={api_base.Version.string: str(api_v1.min_version())},
|
||||
expect_errors=True)
|
||||
self.assertEqual(http_client.NOT_FOUND, response.status_int)
|
||||
|
||||
@ -103,7 +103,7 @@ class TestListVolumeTargets(test_api_base.BaseApiTest):
|
||||
node_id=self.node.id)
|
||||
response = self.get_json(
|
||||
'/volume/targets/%s' % target.uuid,
|
||||
headers={api_base.Version.string: str(api_v1.MIN_VER)},
|
||||
headers={api_base.Version.string: str(api_v1.min_version())},
|
||||
expect_errors=True)
|
||||
self.assertEqual(http_client.NOT_FOUND, response.status_int)
|
||||
|
||||
@ -170,7 +170,7 @@ class TestListVolumeTargets(test_api_base.BaseApiTest):
|
||||
node_id=self.node.id)
|
||||
response = self.get_json(
|
||||
'/volume/targets?detail=True',
|
||||
headers={api_base.Version.string: str(api_v1.MIN_VER)},
|
||||
headers={api_base.Version.string: str(api_v1.min_version())},
|
||||
expect_errors=True)
|
||||
self.assertEqual(http_client.NOT_FOUND, response.status_int)
|
||||
|
||||
@ -328,7 +328,7 @@ class TestListVolumeTargets(test_api_base.BaseApiTest):
|
||||
|
||||
@mock.patch.object(rpcapi.ConductorAPI, 'update_volume_target')
|
||||
class TestPatch(test_api_base.BaseApiTest):
|
||||
headers = {api_base.Version.string: str(api_v1.MAX_VER)}
|
||||
headers = {api_base.Version.string: str(api_v1.max_version())}
|
||||
|
||||
def setUp(self):
|
||||
super(TestPatch, self).setUp()
|
||||
@ -368,7 +368,7 @@ class TestPatch(test_api_base.BaseApiTest):
|
||||
node_uuid=self.node.uuid)])
|
||||
|
||||
def test_update_byid_invalid_api_version(self, mock_upd):
|
||||
headers = {api_base.Version.string: str(api_v1.MIN_VER)}
|
||||
headers = {api_base.Version.string: str(api_v1.min_version())}
|
||||
response = self.patch_json('/volume/targets/%s'
|
||||
% self.target.uuid,
|
||||
[{'path': '/extra/foo',
|
||||
@ -702,7 +702,7 @@ class TestPatch(test_api_base.BaseApiTest):
|
||||
|
||||
|
||||
class TestPost(test_api_base.BaseApiTest):
|
||||
headers = {api_base.Version.string: str(api_v1.MAX_VER)}
|
||||
headers = {api_base.Version.string: str(api_v1.max_version())}
|
||||
|
||||
def setUp(self):
|
||||
super(TestPost, self).setUp()
|
||||
@ -742,7 +742,7 @@ class TestPost(test_api_base.BaseApiTest):
|
||||
pdict = post_get_test_volume_target()
|
||||
response = self.post_json(
|
||||
'/volume/targets', pdict,
|
||||
headers={api_base.Version.string: str(api_v1.MIN_VER)},
|
||||
headers={api_base.Version.string: str(api_v1.min_version())},
|
||||
expect_errors=True)
|
||||
self.assertEqual(http_client.NOT_FOUND, response.status_int)
|
||||
|
||||
@ -860,7 +860,7 @@ class TestPost(test_api_base.BaseApiTest):
|
||||
|
||||
@mock.patch.object(rpcapi.ConductorAPI, 'destroy_volume_target')
|
||||
class TestDelete(test_api_base.BaseApiTest):
|
||||
headers = {api_base.Version.string: str(api_v1.MAX_VER)}
|
||||
headers = {api_base.Version.string: str(api_v1.max_version())}
|
||||
|
||||
def setUp(self):
|
||||
super(TestDelete, self).setUp()
|
||||
@ -889,7 +889,7 @@ class TestDelete(test_api_base.BaseApiTest):
|
||||
node_uuid=self.node.uuid)])
|
||||
|
||||
def test_delete_volume_target_byid_invalid_api_version(self, mock_dvc):
|
||||
headers = {api_base.Version.string: str(api_v1.MIN_VER)}
|
||||
headers = {api_base.Version.string: str(api_v1.min_version())}
|
||||
response = self.delete('/volume/targets/%s' % self.target.uuid,
|
||||
headers=headers,
|
||||
expect_errors=True)
|
||||
|
@ -31,8 +31,9 @@ class TestRoot(base.BaseApiTest):
|
||||
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'])
|
||||
self.assertEqual(versions.min_version_string(),
|
||||
version1['min_version'])
|
||||
self.assertEqual(versions.max_version_string(), version1['version'])
|
||||
|
||||
|
||||
class TestV1Root(base.BaseApiTest):
|
||||
|
@ -16,6 +16,7 @@ import mock
|
||||
from oslo_utils import versionutils
|
||||
import six
|
||||
|
||||
from ironic.api.controllers.v1 import versions as api_versions
|
||||
from ironic.common import release_mappings
|
||||
from ironic.conductor import rpcapi
|
||||
from ironic.db.sqlalchemy import models
|
||||
@ -49,7 +50,11 @@ class ReleaseMappingsTestCase(base.TestCase):
|
||||
def test_structure(self):
|
||||
for value in release_mappings.RELEASE_MAPPING.values():
|
||||
self.assertIsInstance(value, dict)
|
||||
self.assertEqual({'rpc', 'objects'}, set(value))
|
||||
self.assertEqual({'api', 'rpc', 'objects'}, set(value))
|
||||
self.assertIsInstance(value['api'], six.string_types)
|
||||
(major, minor) = value['api'].split('.')
|
||||
self.assertEqual(1, int(major))
|
||||
self.assertLessEqual(int(minor), api_versions.MINOR_MAX_VERSION)
|
||||
self.assertIsInstance(value['rpc'], six.string_types)
|
||||
self.assertIsInstance(value['objects'], dict)
|
||||
for obj_value in value['objects'].values():
|
||||
@ -110,6 +115,7 @@ class GetObjectVersionsTestCase(base.TestCase):
|
||||
|
||||
TEST_MAPPING = {
|
||||
'7.0': {
|
||||
'api': '1.30',
|
||||
'rpc': '1.40',
|
||||
'objects': {
|
||||
'Node': ['1.21'],
|
||||
@ -119,6 +125,7 @@ class GetObjectVersionsTestCase(base.TestCase):
|
||||
}
|
||||
},
|
||||
'8.0': {
|
||||
'api': '1.30',
|
||||
'rpc': '1.40',
|
||||
'objects': {
|
||||
'Node': ['1.22'],
|
||||
@ -129,6 +136,7 @@ class GetObjectVersionsTestCase(base.TestCase):
|
||||
}
|
||||
},
|
||||
'master': {
|
||||
'api': '1.34',
|
||||
'rpc': '1.40',
|
||||
'objects': {
|
||||
'Node': ['1.23'],
|
||||
|
8
releasenotes/notes/pin-api-version-029748f7d3be68d1.yaml
Normal file
8
releasenotes/notes/pin-api-version-029748f7d3be68d1.yaml
Normal file
@ -0,0 +1,8 @@
|
||||
---
|
||||
upgrade:
|
||||
- |
|
||||
During a `rolling upgrade
|
||||
<https://docs.openstack.org/ironic/latest/admin/upgrade-guide.html#during-maintenance-window>`_
|
||||
when the new services are pinned to the old release,
|
||||
the Bare Metal API version will also be pinned to the old release. This will
|
||||
prevent new features from being accessed until after the upgrade is done.
|
Loading…
Reference in New Issue
Block a user