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