api: Only check minimum API version
As noted in [1], we were passing arguments to the 'is_supported' function inconsistently. Given we only have four easily converted users of the 'max_version' argument, we can simplify the calls by only passing a *minimum* API version and negating there where necessary. This is good enough for our use cases. [1] https://review.opendev.org/c/openstack/nova/+/936366/ Change-Id: I71a95b8b4b6b59485273f136f255811b6d57b657 Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
This commit is contained in:
@@ -306,22 +306,18 @@ def max_api_version():
|
|||||||
return APIVersionRequest(_MAX_API_VERSION)
|
return APIVersionRequest(_MAX_API_VERSION)
|
||||||
|
|
||||||
|
|
||||||
def is_supported(req, min_version=_MIN_API_VERSION,
|
def is_supported(req, version):
|
||||||
max_version=_MAX_API_VERSION):
|
|
||||||
"""Check if API request version satisfies version restrictions.
|
"""Check if API request version satisfies version restrictions.
|
||||||
|
|
||||||
:param req: request object
|
:param req: request object
|
||||||
:param min_version: minimal version of API needed for correct
|
:param version: minimal version of API needed for correct
|
||||||
request processing
|
|
||||||
:param max_version: maximum version of API needed for correct
|
|
||||||
request processing
|
request processing
|
||||||
|
|
||||||
:returns: True if request satisfies minimal and maximum API version
|
:returns: True if request satisfies minimal and maximum API version
|
||||||
requirements. False in other case.
|
requirements. False in other case.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return (APIVersionRequest(max_version) >= req.api_version_request >=
|
return req.api_version_request >= APIVersionRequest(version)
|
||||||
APIVersionRequest(min_version))
|
|
||||||
|
|
||||||
|
|
||||||
class APIVersionRequest(object):
|
class APIVersionRequest(object):
|
||||||
|
|||||||
@@ -274,7 +274,7 @@ class AggregateController(wsgi.Controller):
|
|||||||
return {"aggregate": _aggregate}
|
return {"aggregate": _aggregate}
|
||||||
|
|
||||||
def _build_aggregate_items(self, req, aggregate):
|
def _build_aggregate_items(self, req, aggregate):
|
||||||
show_uuid = api_version_request.is_supported(req, min_version="2.41")
|
show_uuid = api_version_request.is_supported(req, "2.41")
|
||||||
keys = aggregate.obj_fields
|
keys = aggregate.obj_fields
|
||||||
# NOTE(rlrossit): Within the compute API, metadata will always be
|
# NOTE(rlrossit): Within the compute API, metadata will always be
|
||||||
# set on the aggregate object (at a minimum to {}). Because of this,
|
# set on the aggregate object (at a minimum to {}). Because of this,
|
||||||
|
|||||||
@@ -65,9 +65,7 @@ class CreateBackupController(wsgi.Controller):
|
|||||||
props = {}
|
props = {}
|
||||||
metadata = entity.get('metadata', {})
|
metadata = entity.get('metadata', {})
|
||||||
# Starting from microversion 2.39 we don't check quotas on createBackup
|
# Starting from microversion 2.39 we don't check quotas on createBackup
|
||||||
if api_version_request.is_supported(
|
if not api_version_request.is_supported(req, '2.39'):
|
||||||
req, max_version=
|
|
||||||
api_version_request.MAX_IMAGE_META_PROXY_API_VERSION):
|
|
||||||
common.check_img_metadata_properties_quota(context, metadata)
|
common.check_img_metadata_properties_quota(context, metadata)
|
||||||
props.update(metadata)
|
props.update(metadata)
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ class EvacuateController(wsgi.Controller):
|
|||||||
self.host_api = compute.HostAPI()
|
self.host_api = compute.HostAPI()
|
||||||
|
|
||||||
def _get_on_shared_storage(self, req, evacuate_body):
|
def _get_on_shared_storage(self, req, evacuate_body):
|
||||||
if api_version_request.is_supported(req, min_version='2.14'):
|
if api_version_request.is_supported(req, '2.14'):
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
return strutils.bool_from_string(evacuate_body["onSharedStorage"])
|
return strutils.bool_from_string(evacuate_body["onSharedStorage"])
|
||||||
@@ -108,7 +108,7 @@ class EvacuateController(wsgi.Controller):
|
|||||||
force = None
|
force = None
|
||||||
|
|
||||||
target_state = None
|
target_state = None
|
||||||
if api_version_request.is_supported(req, min_version='2.95'):
|
if api_version_request.is_supported(req, '2.95'):
|
||||||
min_ver = objects.service.get_minimum_version_all_cells(
|
min_ver = objects.service.get_minimum_version_all_cells(
|
||||||
context, ['nova-compute'])
|
context, ['nova-compute'])
|
||||||
if min_ver < MIN_VER_NOVA_COMPUTE_EVACUATE_STOPPED:
|
if min_ver < MIN_VER_NOVA_COMPUTE_EVACUATE_STOPPED:
|
||||||
@@ -122,13 +122,13 @@ class EvacuateController(wsgi.Controller):
|
|||||||
|
|
||||||
on_shared_storage = self._get_on_shared_storage(req, evacuate_body)
|
on_shared_storage = self._get_on_shared_storage(req, evacuate_body)
|
||||||
|
|
||||||
if api_version_request.is_supported(req, min_version='2.29'):
|
if api_version_request.is_supported(req, '2.29'):
|
||||||
force = body["evacuate"].get("force", False)
|
force = body["evacuate"].get("force", False)
|
||||||
force = strutils.bool_from_string(force, strict=True)
|
force = strutils.bool_from_string(force, strict=True)
|
||||||
if force is True and not host:
|
if force is True and not host:
|
||||||
message = _("Can't force to a non-provided destination")
|
message = _("Can't force to a non-provided destination")
|
||||||
raise exc.HTTPBadRequest(explanation=message)
|
raise exc.HTTPBadRequest(explanation=message)
|
||||||
if api_version_request.is_supported(req, min_version='2.14'):
|
if api_version_request.is_supported(req, '2.14'):
|
||||||
password = self._get_password_v214(req, evacuate_body)
|
password = self._get_password_v214(req, evacuate_body)
|
||||||
else:
|
else:
|
||||||
password = self._get_password(req, evacuate_body,
|
password = self._get_password(req, evacuate_body,
|
||||||
@@ -151,8 +151,8 @@ class EvacuateController(wsgi.Controller):
|
|||||||
on_shared_storage, password, force,
|
on_shared_storage, password, force,
|
||||||
target_state)
|
target_state)
|
||||||
except exception.InstanceInvalidState as state_error:
|
except exception.InstanceInvalidState as state_error:
|
||||||
common.raise_http_conflict_for_instance_invalid_state(state_error,
|
common.raise_http_conflict_for_instance_invalid_state(
|
||||||
'evacuate', id)
|
state_error, 'evacuate', id)
|
||||||
except (
|
except (
|
||||||
exception.ComputeServiceInUse,
|
exception.ComputeServiceInUse,
|
||||||
exception.ForbiddenPortsWithAccelerator,
|
exception.ForbiddenPortsWithAccelerator,
|
||||||
@@ -163,11 +163,14 @@ class EvacuateController(wsgi.Controller):
|
|||||||
raise exc.HTTPConflict(explanation=e.format_message())
|
raise exc.HTTPConflict(explanation=e.format_message())
|
||||||
except (
|
except (
|
||||||
exception.ForbiddenSharesNotSupported,
|
exception.ForbiddenSharesNotSupported,
|
||||||
exception.ForbiddenWithShare) as e:
|
exception.ForbiddenWithShare,
|
||||||
|
) as e:
|
||||||
raise exc.HTTPConflict(explanation=e.format_message())
|
raise exc.HTTPConflict(explanation=e.format_message())
|
||||||
|
|
||||||
if (not api_version_request.is_supported(req, min_version='2.14') and
|
if (
|
||||||
CONF.api.enable_instance_password):
|
not api_version_request.is_supported(req, '2.14') and
|
||||||
|
CONF.api.enable_instance_password
|
||||||
|
):
|
||||||
return {'adminPass': password}
|
return {'adminPass': password}
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ class FlavorActionController(wsgi.Controller):
|
|||||||
flavor = common.get_flavor(context, id)
|
flavor = common.get_flavor(context, id)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if api_version_request.is_supported(req, min_version='2.7'):
|
if api_version_request.is_supported(req, '2.7'):
|
||||||
if flavor.is_public:
|
if flavor.is_public:
|
||||||
exp = _("Can not add access to a public flavor.")
|
exp = _("Can not add access to a public flavor.")
|
||||||
raise webob.exc.HTTPConflict(explanation=exp)
|
raise webob.exc.HTTPConflict(explanation=exp)
|
||||||
|
|||||||
@@ -79,8 +79,7 @@ class FlavorsController(wsgi.Controller):
|
|||||||
is_public = vals.get('os-flavor-access:is_public', True)
|
is_public = vals.get('os-flavor-access:is_public', True)
|
||||||
|
|
||||||
# The user can specify a description starting with microversion 2.55.
|
# The user can specify a description starting with microversion 2.55.
|
||||||
include_description = api_version_request.is_supported(
|
include_description = api_version_request.is_supported(req, '2.55')
|
||||||
req, flavors_view.FLAVOR_DESCRIPTION_MICROVERSION)
|
|
||||||
description = vals.get('description') if include_description else None
|
description = vals.get('description') if include_description else None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -97,8 +96,7 @@ class FlavorsController(wsgi.Controller):
|
|||||||
raise webob.exc.HTTPConflict(explanation=err.format_message())
|
raise webob.exc.HTTPConflict(explanation=err.format_message())
|
||||||
|
|
||||||
include_extra_specs = False
|
include_extra_specs = False
|
||||||
if api_version_request.is_supported(
|
if api_version_request.is_supported(req, '2.61'):
|
||||||
req, flavors_view.FLAVOR_EXTRA_SPECS_MICROVERSION):
|
|
||||||
include_extra_specs = context.can(
|
include_extra_specs = context.can(
|
||||||
fes_policies.POLICY_ROOT % 'index', fatal=False)
|
fes_policies.POLICY_ROOT % 'index', fatal=False)
|
||||||
# NOTE(yikun): This empty extra_specs only for keeping consistent
|
# NOTE(yikun): This empty extra_specs only for keeping consistent
|
||||||
@@ -130,8 +128,7 @@ class FlavorsController(wsgi.Controller):
|
|||||||
raise webob.exc.HTTPNotFound(explanation=e.format_message())
|
raise webob.exc.HTTPNotFound(explanation=e.format_message())
|
||||||
|
|
||||||
include_extra_specs = False
|
include_extra_specs = False
|
||||||
if api_version_request.is_supported(
|
if api_version_request.is_supported(req, '2.61'):
|
||||||
req, flavors_view.FLAVOR_EXTRA_SPECS_MICROVERSION):
|
|
||||||
include_extra_specs = context.can(
|
include_extra_specs = context.can(
|
||||||
fes_policies.POLICY_ROOT % 'index', fatal=False)
|
fes_policies.POLICY_ROOT % 'index', fatal=False)
|
||||||
return self._view_builder.show(req, flavor, include_description=True,
|
return self._view_builder.show(req, flavor, include_description=True,
|
||||||
@@ -157,11 +154,12 @@ class FlavorsController(wsgi.Controller):
|
|||||||
"""Return all flavors in detail."""
|
"""Return all flavors in detail."""
|
||||||
context = req.environ['nova.context']
|
context = req.environ['nova.context']
|
||||||
limited_flavors = self._get_flavors(req)
|
limited_flavors = self._get_flavors(req)
|
||||||
|
|
||||||
include_extra_specs = False
|
include_extra_specs = False
|
||||||
if api_version_request.is_supported(
|
if api_version_request.is_supported(req, '2.61'):
|
||||||
req, flavors_view.FLAVOR_EXTRA_SPECS_MICROVERSION):
|
|
||||||
include_extra_specs = context.can(
|
include_extra_specs = context.can(
|
||||||
fes_policies.POLICY_ROOT % 'index', fatal=False)
|
fes_policies.POLICY_ROOT % 'index', fatal=False)
|
||||||
|
|
||||||
return self._view_builder.detail(
|
return self._view_builder.detail(
|
||||||
req, limited_flavors, include_extra_specs=include_extra_specs)
|
req, limited_flavors, include_extra_specs=include_extra_specs)
|
||||||
|
|
||||||
@@ -180,12 +178,12 @@ class FlavorsController(wsgi.Controller):
|
|||||||
raise webob.exc.HTTPNotFound(explanation=e.format_message())
|
raise webob.exc.HTTPNotFound(explanation=e.format_message())
|
||||||
|
|
||||||
include_extra_specs = False
|
include_extra_specs = False
|
||||||
if api_version_request.is_supported(
|
if api_version_request.is_supported(req, '2.61'):
|
||||||
req, flavors_view.FLAVOR_EXTRA_SPECS_MICROVERSION):
|
|
||||||
include_extra_specs = context.can(
|
include_extra_specs = context.can(
|
||||||
fes_policies.POLICY_ROOT % 'index', fatal=False)
|
fes_policies.POLICY_ROOT % 'index', fatal=False)
|
||||||
include_description = api_version_request.is_supported(
|
|
||||||
req, flavors_view.FLAVOR_DESCRIPTION_MICROVERSION)
|
include_description = api_version_request.is_supported(req, '2.55')
|
||||||
|
|
||||||
return self._view_builder.show(
|
return self._view_builder.show(
|
||||||
req, flavor, include_description=include_description,
|
req, flavor, include_description=include_description,
|
||||||
include_extra_specs=include_extra_specs)
|
include_extra_specs=include_extra_specs)
|
||||||
|
|||||||
@@ -35,9 +35,7 @@ class FlavorExtraSpecsController(wsgi.Controller):
|
|||||||
return dict(extra_specs=flavor.extra_specs)
|
return dict(extra_specs=flavor.extra_specs)
|
||||||
|
|
||||||
def _check_extra_specs_value(self, req, specs):
|
def _check_extra_specs_value(self, req, specs):
|
||||||
validation_supported = api_version_request.is_supported(
|
validation_supported = api_version_request.is_supported(req, '2.86')
|
||||||
req, min_version='2.86',
|
|
||||||
)
|
|
||||||
|
|
||||||
for name, value in specs.items():
|
for name, value in specs.items():
|
||||||
# NOTE(gmann): Max length for numeric value is being checked
|
# NOTE(gmann): Max length for numeric value is being checked
|
||||||
|
|||||||
@@ -53,8 +53,7 @@ class HypervisorsController(wsgi.Controller):
|
|||||||
):
|
):
|
||||||
alive = self.servicegroup_api.service_is_up(service)
|
alive = self.servicegroup_api.service_is_up(service)
|
||||||
# The 2.53 microversion returns the compute node uuid rather than id.
|
# The 2.53 microversion returns the compute node uuid rather than id.
|
||||||
uuid_for_id = api_version_request.is_supported(
|
uuid_for_id = api_version_request.is_supported(req, "2.53")
|
||||||
req, min_version="2.53")
|
|
||||||
|
|
||||||
hyp_dict = {
|
hyp_dict = {
|
||||||
'id': hypervisor.uuid if uuid_for_id else hypervisor.id,
|
'id': hypervisor.uuid if uuid_for_id else hypervisor.id,
|
||||||
@@ -77,9 +76,7 @@ class HypervisorsController(wsgi.Controller):
|
|||||||
|
|
||||||
# The 2.88 microversion removed these fields, so only add them on older
|
# The 2.88 microversion removed these fields, so only add them on older
|
||||||
# microversions
|
# microversions
|
||||||
if detail and api_version_request.is_supported(
|
if detail and not api_version_request.is_supported(req, '2.88'):
|
||||||
req, max_version='2.87',
|
|
||||||
):
|
|
||||||
for field in (
|
for field in (
|
||||||
'vcpus', 'memory_mb', 'local_gb', 'vcpus_used',
|
'vcpus', 'memory_mb', 'local_gb', 'vcpus_used',
|
||||||
'memory_mb_used', 'local_gb_used', 'free_ram_mb',
|
'memory_mb_used', 'local_gb_used', 'free_ram_mb',
|
||||||
@@ -88,18 +85,16 @@ class HypervisorsController(wsgi.Controller):
|
|||||||
):
|
):
|
||||||
hyp_dict[field] = getattr(hypervisor, field)
|
hyp_dict[field] = getattr(hypervisor, field)
|
||||||
|
|
||||||
if api_version_request.is_supported(req, max_version='2.27'):
|
if api_version_request.is_supported(req, '2.28'):
|
||||||
hyp_dict['cpu_info'] = hypervisor.cpu_info
|
|
||||||
else:
|
|
||||||
if hypervisor.cpu_info:
|
if hypervisor.cpu_info:
|
||||||
hyp_dict['cpu_info'] = jsonutils.loads(hypervisor.cpu_info)
|
hyp_dict['cpu_info'] = jsonutils.loads(hypervisor.cpu_info)
|
||||||
else:
|
else:
|
||||||
hyp_dict['cpu_info'] = {}
|
hyp_dict['cpu_info'] = {}
|
||||||
|
else:
|
||||||
|
hyp_dict['cpu_info'] = hypervisor.cpu_info
|
||||||
|
|
||||||
# The 2.88 microversion also *added* the 'uptime' field to the response
|
# The 2.88 microversion also *added* the 'uptime' field to the response
|
||||||
if detail and api_version_request.is_supported(
|
if detail and api_version_request.is_supported(req, '2.88'):
|
||||||
req, min_version='2.88',
|
|
||||||
):
|
|
||||||
try:
|
try:
|
||||||
hyp_dict['uptime'] = self.host_api.get_host_uptime(
|
hyp_dict['uptime'] = self.host_api.get_host_uptime(
|
||||||
req.environ['nova.context'], hypervisor.host)
|
req.environ['nova.context'], hypervisor.host)
|
||||||
@@ -121,9 +116,7 @@ class HypervisorsController(wsgi.Controller):
|
|||||||
# The 2.75 microversion adds 'servers' field always in response.
|
# The 2.75 microversion adds 'servers' field always in response.
|
||||||
# Empty list if there are no servers on hypervisors and it is
|
# Empty list if there are no servers on hypervisors and it is
|
||||||
# requested in request.
|
# requested in request.
|
||||||
elif with_servers and api_version_request.is_supported(
|
elif with_servers and api_version_request.is_supported(req, '2.75'):
|
||||||
req, min_version='2.75',
|
|
||||||
):
|
|
||||||
hyp_dict['servers'] = []
|
hyp_dict['servers'] = []
|
||||||
|
|
||||||
return hyp_dict
|
return hyp_dict
|
||||||
@@ -152,7 +145,7 @@ class HypervisorsController(wsgi.Controller):
|
|||||||
# The 2.53 microversion moves the search and servers routes into
|
# The 2.53 microversion moves the search and servers routes into
|
||||||
# GET /os-hypervisors and GET /os-hypervisors/detail with query
|
# GET /os-hypervisors and GET /os-hypervisors/detail with query
|
||||||
# parameters.
|
# parameters.
|
||||||
if api_version_request.is_supported(req, min_version="2.53"):
|
if api_version_request.is_supported(req, "2.53"):
|
||||||
hypervisor_match = req.GET.get('hypervisor_hostname_pattern')
|
hypervisor_match = req.GET.get('hypervisor_hostname_pattern')
|
||||||
with_servers = strutils.bool_from_string(
|
with_servers = strutils.bool_from_string(
|
||||||
req.GET.get('with_servers', False), strict=True)
|
req.GET.get('with_servers', False), strict=True)
|
||||||
@@ -295,7 +288,7 @@ class HypervisorsController(wsgi.Controller):
|
|||||||
:raises: webob.exc.HTTPNotFound if the requested microversion is
|
:raises: webob.exc.HTTPNotFound if the requested microversion is
|
||||||
less than 2.53 and the id is not an integer.
|
less than 2.53 and the id is not an integer.
|
||||||
"""
|
"""
|
||||||
if api_version_request.is_supported(req, min_version="2.53"):
|
if api_version_request.is_supported(req, "2.53"):
|
||||||
if not uuidutils.is_uuid_like(hypervisor_id):
|
if not uuidutils.is_uuid_like(hypervisor_id):
|
||||||
msg = _('Invalid uuid %s') % hypervisor_id
|
msg = _('Invalid uuid %s') % hypervisor_id
|
||||||
raise webob.exc.HTTPBadRequest(explanation=msg)
|
raise webob.exc.HTTPBadRequest(explanation=msg)
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ class InstanceActionsController(wsgi.Controller):
|
|||||||
return event
|
return event
|
||||||
|
|
||||||
def _get_instance(self, req, context, server_id):
|
def _get_instance(self, req, context, server_id):
|
||||||
if not api_version_request.is_supported(req, min_version="2.21"):
|
if not api_version_request.is_supported(req, '2.21'):
|
||||||
return common.get_instance(self.compute_api, context, server_id)
|
return common.get_instance(self.compute_api, context, server_id)
|
||||||
|
|
||||||
with utils.temporary_mutation(context, read_deleted='yes'):
|
with utils.temporary_mutation(context, read_deleted='yes'):
|
||||||
@@ -119,7 +119,7 @@ class InstanceActionsController(wsgi.Controller):
|
|||||||
except exception.MarkerNotFound as e:
|
except exception.MarkerNotFound as e:
|
||||||
raise exc.HTTPBadRequest(explanation=e.format_message())
|
raise exc.HTTPBadRequest(explanation=e.format_message())
|
||||||
|
|
||||||
if api_version_request.is_supported(req, min_version="2.58"):
|
if api_version_request.is_supported(req, '2.58'):
|
||||||
actions = [self._format_action(action, ACTION_KEYS_V258)
|
actions = [self._format_action(action, ACTION_KEYS_V258)
|
||||||
for action in actions_raw]
|
for action in actions_raw]
|
||||||
else:
|
else:
|
||||||
@@ -150,7 +150,7 @@ class InstanceActionsController(wsgi.Controller):
|
|||||||
raise exc.HTTPNotFound(explanation=msg)
|
raise exc.HTTPNotFound(explanation=msg)
|
||||||
|
|
||||||
action_id = action['id']
|
action_id = action['id']
|
||||||
if api_version_request.is_supported(req, min_version="2.58"):
|
if api_version_request.is_supported(req, '2.58'):
|
||||||
action = self._format_action(action, ACTION_KEYS_V258)
|
action = self._format_action(action, ACTION_KEYS_V258)
|
||||||
else:
|
else:
|
||||||
action = self._format_action(action, ACTION_KEYS)
|
action = self._format_action(action, ACTION_KEYS)
|
||||||
|
|||||||
@@ -41,8 +41,10 @@ class LockServerController(wsgi.Controller):
|
|||||||
target={'user_id': instance.user_id,
|
target={'user_id': instance.user_id,
|
||||||
'project_id': instance.project_id})
|
'project_id': instance.project_id})
|
||||||
reason = None
|
reason = None
|
||||||
if (api_version_request.is_supported(req, min_version='2.73') and
|
if (
|
||||||
body['lock'] is not None):
|
api_version_request.is_supported(req, '2.73') and
|
||||||
|
body['lock'] is not None
|
||||||
|
):
|
||||||
reason = body['lock'].get('locked_reason')
|
reason = body['lock'].get('locked_reason')
|
||||||
self.compute_api.lock(context, instance, reason=reason)
|
self.compute_api.lock(context, instance, reason=reason)
|
||||||
|
|
||||||
|
|||||||
@@ -48,8 +48,10 @@ class MigrateServerController(wsgi.Controller):
|
|||||||
instance = common.get_instance(self.compute_api, context, id,
|
instance = common.get_instance(self.compute_api, context, id,
|
||||||
expected_attrs=['flavor', 'services'])
|
expected_attrs=['flavor', 'services'])
|
||||||
host_name = None
|
host_name = None
|
||||||
if (api_version_request.is_supported(req, min_version='2.56') and
|
if (
|
||||||
body['migrate'] is not None):
|
api_version_request.is_supported(req, '2.56') and
|
||||||
|
body['migrate'] is not None
|
||||||
|
):
|
||||||
host_name = body['migrate'].get('host')
|
host_name = body['migrate'].get('host')
|
||||||
|
|
||||||
if host_name:
|
if host_name:
|
||||||
@@ -111,10 +113,10 @@ class MigrateServerController(wsgi.Controller):
|
|||||||
host = body["os-migrateLive"]["host"]
|
host = body["os-migrateLive"]["host"]
|
||||||
block_migration = body["os-migrateLive"]["block_migration"]
|
block_migration = body["os-migrateLive"]["block_migration"]
|
||||||
force = None
|
force = None
|
||||||
async_ = api_version_request.is_supported(req, min_version='2.34')
|
async_ = api_version_request.is_supported(req, '2.34')
|
||||||
if api_version_request.is_supported(req, min_version='2.30'):
|
if api_version_request.is_supported(req, '2.30'):
|
||||||
force = self._get_force_param_for_live_migration(body, host)
|
force = self._get_force_param_for_live_migration(body, host)
|
||||||
if api_version_request.is_supported(req, min_version='2.25'):
|
if api_version_request.is_supported(req, '2.25'):
|
||||||
if block_migration == 'auto':
|
if block_migration == 'auto':
|
||||||
block_migration = None
|
block_migration = None
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ class ServerDiagnosticsController(wsgi.Controller):
|
|||||||
target={'project_id': instance.project_id})
|
target={'project_id': instance.project_id})
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if api_version_request.is_supported(req, min_version='2.48'):
|
if api_version_request.is_supported(req, '2.48'):
|
||||||
diagnostics = self.compute_api.get_instance_diagnostics(
|
diagnostics = self.compute_api.get_instance_diagnostics(
|
||||||
context, instance)
|
context, instance)
|
||||||
return self._view_builder.instance_diagnostics(diagnostics)
|
return self._view_builder.instance_diagnostics(diagnostics)
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ class ServerGroupController(wsgi.Controller):
|
|||||||
server_group = {}
|
server_group = {}
|
||||||
server_group['id'] = group.uuid
|
server_group['id'] = group.uuid
|
||||||
server_group['name'] = group.name
|
server_group['name'] = group.name
|
||||||
if api_version_request.is_supported(req, min_version='2.64'):
|
if api_version_request.is_supported(req, '2.64'):
|
||||||
server_group['policy'] = group.policy
|
server_group['policy'] = group.policy
|
||||||
server_group['rules'] = group.rules
|
server_group['rules'] = group.rules
|
||||||
else:
|
else:
|
||||||
@@ -109,7 +109,7 @@ class ServerGroupController(wsgi.Controller):
|
|||||||
server_group['members'] = members
|
server_group['members'] = members
|
||||||
# Add project id information to the response data for
|
# Add project id information to the response data for
|
||||||
# API version v2.13
|
# API version v2.13
|
||||||
if api_version_request.is_supported(req, min_version="2.13"):
|
if api_version_request.is_supported(req, "2.13"):
|
||||||
server_group['project_id'] = group.project_id
|
server_group['project_id'] = group.project_id
|
||||||
server_group['user_id'] = group.user_id
|
server_group['user_id'] = group.user_id
|
||||||
return server_group
|
return server_group
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ class ServerSharesController(wsgi.Controller):
|
|||||||
@wsgi.Controller.api_version("2.97")
|
@wsgi.Controller.api_version("2.97")
|
||||||
@wsgi.response(201)
|
@wsgi.response(201)
|
||||||
@wsgi.expected_errors((400, 403, 404, 409))
|
@wsgi.expected_errors((400, 403, 404, 409))
|
||||||
@validation.schema(schema.create, min_version='2.97')
|
@validation.schema(schema.create, '2.97')
|
||||||
@validation.response_body_schema(schema.show_response)
|
@validation.response_body_schema(schema.show_response)
|
||||||
def create(self, req, server_id, body):
|
def create(self, req, server_id, body):
|
||||||
def _try_create_share_mapping(context, share_mapping):
|
def _try_create_share_mapping(context, share_mapping):
|
||||||
|
|||||||
@@ -146,8 +146,7 @@ class ServersController(wsgi.Controller):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _is_cell_down_supported(req, search_opts):
|
def _is_cell_down_supported(req, search_opts):
|
||||||
cell_down_support = api_version_request.is_supported(
|
cell_down_support = api_version_request.is_supported(req, '2.69')
|
||||||
req, min_version='2.69')
|
|
||||||
|
|
||||||
if cell_down_support:
|
if cell_down_support:
|
||||||
# NOTE(tssurya): Minimal constructs would be returned from the down
|
# NOTE(tssurya): Minimal constructs would be returned from the down
|
||||||
@@ -200,7 +199,7 @@ class ServersController(wsgi.Controller):
|
|||||||
states = common.task_and_vm_state_from_status(statuses)
|
states = common.task_and_vm_state_from_status(statuses)
|
||||||
vm_state, task_state = states
|
vm_state, task_state = states
|
||||||
if not vm_state and not task_state:
|
if not vm_state and not task_state:
|
||||||
if api_version_request.is_supported(req, min_version='2.38'):
|
if api_version_request.is_supported(req, '2.38'):
|
||||||
msg = _('Invalid status value')
|
msg = _('Invalid status value')
|
||||||
raise exc.HTTPBadRequest(explanation=msg)
|
raise exc.HTTPBadRequest(explanation=msg)
|
||||||
|
|
||||||
@@ -264,7 +263,7 @@ class ServersController(wsgi.Controller):
|
|||||||
msg = _("Only administrators may list deleted instances")
|
msg = _("Only administrators may list deleted instances")
|
||||||
raise exc.HTTPForbidden(explanation=msg)
|
raise exc.HTTPForbidden(explanation=msg)
|
||||||
|
|
||||||
if api_version_request.is_supported(req, min_version='2.26'):
|
if api_version_request.is_supported(req, '2.26'):
|
||||||
for tag_filter in TAG_SEARCH_FILTERS:
|
for tag_filter in TAG_SEARCH_FILTERS:
|
||||||
if tag_filter in search_opts:
|
if tag_filter in search_opts:
|
||||||
search_opts[tag_filter] = search_opts[
|
search_opts[tag_filter] = search_opts[
|
||||||
@@ -301,7 +300,7 @@ class ServersController(wsgi.Controller):
|
|||||||
limit, marker = common.get_limit_and_marker(req)
|
limit, marker = common.get_limit_and_marker(req)
|
||||||
sort_keys, sort_dirs = common.get_sort_params(req.params)
|
sort_keys, sort_dirs = common.get_sort_params(req.params)
|
||||||
blacklist = schema.SERVER_LIST_IGNORE_SORT_KEY
|
blacklist = schema.SERVER_LIST_IGNORE_SORT_KEY
|
||||||
if api_version_request.is_supported(req, min_version='2.73'):
|
if api_version_request.is_supported(req, '2.73'):
|
||||||
blacklist = schema.SERVER_LIST_IGNORE_SORT_KEY_V273
|
blacklist = schema.SERVER_LIST_IGNORE_SORT_KEY_V273
|
||||||
sort_keys, sort_dirs = remove_invalid_sort_keys(
|
sort_keys, sort_dirs = remove_invalid_sort_keys(
|
||||||
context, sort_keys, sort_dirs, blacklist, ('host', 'node'))
|
context, sort_keys, sort_dirs, blacklist, ('host', 'node'))
|
||||||
@@ -462,10 +461,8 @@ class ServersController(wsgi.Controller):
|
|||||||
def show(self, req, id):
|
def show(self, req, id):
|
||||||
"""Returns server details by server id."""
|
"""Returns server details by server id."""
|
||||||
context = req.environ['nova.context']
|
context = req.environ['nova.context']
|
||||||
cell_down_support = api_version_request.is_supported(
|
cell_down_support = api_version_request.is_supported(req, '2.69')
|
||||||
req, min_version='2.69')
|
show_server_groups = api_version_request.is_supported(req, '2.71')
|
||||||
show_server_groups = api_version_request.is_supported(
|
|
||||||
req, min_version='2.71')
|
|
||||||
|
|
||||||
instance = self._get_server(
|
instance = self._get_server(
|
||||||
context, req, id, is_detail=True,
|
context, req, id, is_detail=True,
|
||||||
@@ -687,10 +684,10 @@ class ServersController(wsgi.Controller):
|
|||||||
password = self._get_server_admin_password(server_dict)
|
password = self._get_server_admin_password(server_dict)
|
||||||
name = common.normalize_name(server_dict['name'])
|
name = common.normalize_name(server_dict['name'])
|
||||||
description = name
|
description = name
|
||||||
if api_version_request.is_supported(req, min_version='2.19'):
|
if api_version_request.is_supported(req, '2.19'):
|
||||||
description = server_dict.get('description')
|
description = server_dict.get('description')
|
||||||
hostname = None
|
hostname = None
|
||||||
if api_version_request.is_supported(req, min_version='2.90'):
|
if api_version_request.is_supported(req, '2.90'):
|
||||||
hostname = server_dict.get('hostname')
|
hostname = server_dict.get('hostname')
|
||||||
|
|
||||||
# Arguments to be passed to instance create function
|
# Arguments to be passed to instance create function
|
||||||
@@ -731,7 +728,7 @@ class ServersController(wsgi.Controller):
|
|||||||
|
|
||||||
availability_zone = server_dict.pop("availability_zone", None)
|
availability_zone = server_dict.pop("availability_zone", None)
|
||||||
|
|
||||||
if api_version_request.is_supported(req, min_version='2.52'):
|
if api_version_request.is_supported(req, '2.52'):
|
||||||
create_kwargs['tags'] = server_dict.get('tags')
|
create_kwargs['tags'] = server_dict.get('tags')
|
||||||
|
|
||||||
helpers.translate_attributes(helpers.CREATE,
|
helpers.translate_attributes(helpers.CREATE,
|
||||||
@@ -763,7 +760,7 @@ class ServersController(wsgi.Controller):
|
|||||||
availability_zone = self._validate_host_availability_zone(
|
availability_zone = self._validate_host_availability_zone(
|
||||||
context, availability_zone, host)
|
context, availability_zone, host)
|
||||||
|
|
||||||
if api_version_request.is_supported(req, min_version='2.74'):
|
if api_version_request.is_supported(req, '2.74'):
|
||||||
self._process_hosts_for_create(context, target, server_dict,
|
self._process_hosts_for_create(context, target, server_dict,
|
||||||
create_kwargs, host, node)
|
create_kwargs, host, node)
|
||||||
|
|
||||||
@@ -919,8 +916,7 @@ class ServersController(wsgi.Controller):
|
|||||||
ctxt.can(server_policies.SERVERS % 'update',
|
ctxt.can(server_policies.SERVERS % 'update',
|
||||||
target={'user_id': instance.user_id,
|
target={'user_id': instance.user_id,
|
||||||
'project_id': instance.project_id})
|
'project_id': instance.project_id})
|
||||||
show_server_groups = api_version_request.is_supported(
|
show_server_groups = api_version_request.is_supported(req, '2.71')
|
||||||
req, min_version='2.71')
|
|
||||||
|
|
||||||
server = body['server']
|
server = body['server']
|
||||||
|
|
||||||
@@ -943,8 +939,7 @@ class ServersController(wsgi.Controller):
|
|||||||
|
|
||||||
# NOTE(gmann): Starting from microversion 2.75, PUT and Rebuild
|
# NOTE(gmann): Starting from microversion 2.75, PUT and Rebuild
|
||||||
# API response will show all attributes like GET /servers API.
|
# API response will show all attributes like GET /servers API.
|
||||||
show_all_attributes = api_version_request.is_supported(
|
show_all_attributes = api_version_request.is_supported(req, '2.75')
|
||||||
req, min_version='2.75')
|
|
||||||
extend_address = show_all_attributes
|
extend_address = show_all_attributes
|
||||||
show_AZ = show_all_attributes
|
show_AZ = show_all_attributes
|
||||||
show_config_drive = show_all_attributes
|
show_config_drive = show_all_attributes
|
||||||
@@ -1222,22 +1217,21 @@ class ServersController(wsgi.Controller):
|
|||||||
helpers.translate_attributes(helpers.REBUILD, rebuild_dict, kwargs)
|
helpers.translate_attributes(helpers.REBUILD, rebuild_dict, kwargs)
|
||||||
|
|
||||||
if (
|
if (
|
||||||
api_version_request.is_supported(req, min_version='2.54') and
|
api_version_request.is_supported(req, '2.54') and
|
||||||
'key_name' in rebuild_dict
|
'key_name' in rebuild_dict
|
||||||
):
|
):
|
||||||
kwargs['key_name'] = rebuild_dict.get('key_name')
|
kwargs['key_name'] = rebuild_dict.get('key_name')
|
||||||
|
|
||||||
# If user_data is not specified, we don't include it in kwargs because
|
# If user_data is not specified, we don't include it in kwargs because
|
||||||
# we don't want to overwrite the existing user_data.
|
# we don't want to overwrite the existing user_data.
|
||||||
include_user_data = api_version_request.is_supported(
|
include_user_data = api_version_request.is_supported(req, '2.57')
|
||||||
req, min_version='2.57')
|
|
||||||
if include_user_data and 'user_data' in rebuild_dict:
|
if include_user_data and 'user_data' in rebuild_dict:
|
||||||
kwargs['user_data'] = rebuild_dict['user_data']
|
kwargs['user_data'] = rebuild_dict['user_data']
|
||||||
|
|
||||||
# Skip policy check for 'rebuild:trusted_certs' if no trusted
|
# Skip policy check for 'rebuild:trusted_certs' if no trusted
|
||||||
# certificate IDs were provided.
|
# certificate IDs were provided.
|
||||||
if (
|
if (
|
||||||
api_version_request.is_supported(req, min_version='2.63') and
|
api_version_request.is_supported(req, '2.63') and
|
||||||
# Note that this is different from server create since with
|
# Note that this is different from server create since with
|
||||||
# rebuild a user can unset/reset the trusted certs by
|
# rebuild a user can unset/reset the trusted certs by
|
||||||
# specifying trusted_image_certificates=None, similar to
|
# specifying trusted_image_certificates=None, similar to
|
||||||
@@ -1250,12 +1244,12 @@ class ServersController(wsgi.Controller):
|
|||||||
target=target)
|
target=target)
|
||||||
|
|
||||||
if (
|
if (
|
||||||
api_version_request.is_supported(req, min_version='2.90') and
|
api_version_request.is_supported(req, '2.90') and
|
||||||
'hostname' in rebuild_dict
|
'hostname' in rebuild_dict
|
||||||
):
|
):
|
||||||
kwargs['hostname'] = rebuild_dict['hostname']
|
kwargs['hostname'] = rebuild_dict['hostname']
|
||||||
|
|
||||||
if api_version_request.is_supported(req, min_version='2.93'):
|
if api_version_request.is_supported(req, '2.93'):
|
||||||
kwargs['reimage_boot_volume'] = True
|
kwargs['reimage_boot_volume'] = True
|
||||||
|
|
||||||
for request_attribute, instance_attribute in attr_map.items():
|
for request_attribute, instance_attribute in attr_map.items():
|
||||||
@@ -1307,15 +1301,12 @@ class ServersController(wsgi.Controller):
|
|||||||
|
|
||||||
# NOTE(liuyulong): set the new key_name for the API response.
|
# NOTE(liuyulong): set the new key_name for the API response.
|
||||||
# from microversion 2.54 onwards.
|
# from microversion 2.54 onwards.
|
||||||
show_keypair = api_version_request.is_supported(
|
show_keypair = api_version_request.is_supported(req, '2.54')
|
||||||
req, min_version='2.54')
|
show_server_groups = api_version_request.is_supported(req, '2.71')
|
||||||
show_server_groups = api_version_request.is_supported(
|
|
||||||
req, min_version='2.71')
|
|
||||||
|
|
||||||
# NOTE(gmann): Starting from microversion 2.75, PUT and Rebuild
|
# NOTE(gmann): Starting from microversion 2.75, PUT and Rebuild
|
||||||
# API response will show all attributes like GET /servers API.
|
# API response will show all attributes like GET /servers API.
|
||||||
show_all_attributes = api_version_request.is_supported(
|
show_all_attributes = api_version_request.is_supported(req, '2.75')
|
||||||
req, min_version='2.75')
|
|
||||||
extend_address = show_all_attributes
|
extend_address = show_all_attributes
|
||||||
show_AZ = show_all_attributes
|
show_AZ = show_all_attributes
|
||||||
show_config_drive = show_all_attributes
|
show_config_drive = show_all_attributes
|
||||||
@@ -1379,9 +1370,7 @@ class ServersController(wsgi.Controller):
|
|||||||
metadata = entity.get('metadata', {})
|
metadata = entity.get('metadata', {})
|
||||||
|
|
||||||
# Starting from microversion 2.39 we don't check quotas on createImage
|
# Starting from microversion 2.39 we don't check quotas on createImage
|
||||||
if api_version_request.is_supported(
|
if not api_version_request.is_supported(req, '2.39'):
|
||||||
req, max_version=
|
|
||||||
api_version_request.MAX_IMAGE_META_PROXY_API_VERSION):
|
|
||||||
common.check_img_metadata_properties_quota(context, metadata)
|
common.check_img_metadata_properties_quota(context, metadata)
|
||||||
|
|
||||||
bdms = objects.BlockDeviceMappingList.get_by_instance_uuid(
|
bdms = objects.BlockDeviceMappingList.get_by_instance_uuid(
|
||||||
@@ -1443,20 +1432,20 @@ class ServersController(wsgi.Controller):
|
|||||||
# probably not trivial.
|
# probably not trivial.
|
||||||
opt_list = ('reservation_id', 'name', 'status', 'image', 'flavor',
|
opt_list = ('reservation_id', 'name', 'status', 'image', 'flavor',
|
||||||
'ip', 'changes-since', 'all_tenants')
|
'ip', 'changes-since', 'all_tenants')
|
||||||
if api_version_request.is_supported(req, min_version='2.5'):
|
if api_version_request.is_supported(req, '2.5'):
|
||||||
opt_list += ('ip6',)
|
opt_list += ('ip6',)
|
||||||
if api_version_request.is_supported(req, min_version='2.26'):
|
if api_version_request.is_supported(req, '2.26'):
|
||||||
opt_list += TAG_SEARCH_FILTERS
|
opt_list += TAG_SEARCH_FILTERS
|
||||||
if api_version_request.is_supported(req, min_version='2.66'):
|
if api_version_request.is_supported(req, '2.66'):
|
||||||
opt_list += ('changes-before',)
|
opt_list += ('changes-before',)
|
||||||
if api_version_request.is_supported(req, min_version='2.73'):
|
if api_version_request.is_supported(req, '2.73'):
|
||||||
opt_list += ('locked',)
|
opt_list += ('locked',)
|
||||||
if api_version_request.is_supported(req, min_version='2.83'):
|
if api_version_request.is_supported(req, '2.83'):
|
||||||
opt_list += ('availability_zone', 'config_drive', 'key_name',
|
opt_list += ('availability_zone', 'config_drive', 'key_name',
|
||||||
'created_at', 'launched_at', 'terminated_at',
|
'created_at', 'launched_at', 'terminated_at',
|
||||||
'power_state', 'task_state', 'vm_state', 'progress',
|
'power_state', 'task_state', 'vm_state', 'progress',
|
||||||
'user_id',)
|
'user_id',)
|
||||||
if api_version_request.is_supported(req, min_version='2.90'):
|
if api_version_request.is_supported(req, '2.90'):
|
||||||
opt_list += ('hostname',)
|
opt_list += ('hostname',)
|
||||||
return opt_list
|
return opt_list
|
||||||
|
|
||||||
|
|||||||
@@ -58,8 +58,7 @@ class ServiceController(wsgi.Controller):
|
|||||||
|
|
||||||
context = req.environ['nova.context']
|
context = req.environ['nova.context']
|
||||||
|
|
||||||
cell_down_support = api_version_request.is_supported(
|
cell_down_support = api_version_request.is_supported(req, '2.69')
|
||||||
req, min_version='2.69')
|
|
||||||
|
|
||||||
_services = [
|
_services = [
|
||||||
s
|
s
|
||||||
@@ -98,8 +97,7 @@ class ServiceController(wsgi.Controller):
|
|||||||
active = 'disabled'
|
active = 'disabled'
|
||||||
updated_time = self.servicegroup_api.get_updated_time(svc)
|
updated_time = self.servicegroup_api.get_updated_time(svc)
|
||||||
|
|
||||||
uuid_for_id = api_version_request.is_supported(
|
uuid_for_id = api_version_request.is_supported(req, '2.53')
|
||||||
req, min_version='2.53')
|
|
||||||
|
|
||||||
if 'availability_zone' not in svc:
|
if 'availability_zone' not in svc:
|
||||||
# The service wasn't loaded with the AZ so we need to do it here.
|
# The service wasn't loaded with the AZ so we need to do it here.
|
||||||
@@ -127,8 +125,7 @@ class ServiceController(wsgi.Controller):
|
|||||||
|
|
||||||
def _get_services_list(self, req, additional_fields=()):
|
def _get_services_list(self, req, additional_fields=()):
|
||||||
_services = self._get_services(req)
|
_services = self._get_services(req)
|
||||||
cell_down_support = api_version_request.is_supported(
|
cell_down_support = api_version_request.is_supported(req, '2.69')
|
||||||
req, min_version='2.69')
|
|
||||||
return [self._get_service_detail(svc, additional_fields, req,
|
return [self._get_service_detail(svc, additional_fields, req,
|
||||||
cell_down_support=cell_down_support) for svc in _services]
|
cell_down_support=cell_down_support) for svc in _services]
|
||||||
|
|
||||||
@@ -248,7 +245,7 @@ class ServiceController(wsgi.Controller):
|
|||||||
context = req.environ['nova.context']
|
context = req.environ['nova.context']
|
||||||
context.can(services_policies.BASE_POLICY_NAME % 'delete', target={})
|
context.can(services_policies.BASE_POLICY_NAME % 'delete', target={})
|
||||||
|
|
||||||
if api_version_request.is_supported(req, min_version='2.53'):
|
if api_version_request.is_supported(req, '2.53'):
|
||||||
if not uuidutils.is_uuid_like(id):
|
if not uuidutils.is_uuid_like(id):
|
||||||
msg = _('Invalid uuid %s') % id
|
msg = _('Invalid uuid %s') % id
|
||||||
raise webob.exc.HTTPBadRequest(explanation=msg)
|
raise webob.exc.HTTPBadRequest(explanation=msg)
|
||||||
@@ -378,7 +375,7 @@ class ServiceController(wsgi.Controller):
|
|||||||
"""
|
"""
|
||||||
context = req.environ['nova.context']
|
context = req.environ['nova.context']
|
||||||
context.can(services_policies.BASE_POLICY_NAME % 'list', target={})
|
context.can(services_policies.BASE_POLICY_NAME % 'list', target={})
|
||||||
if api_version_request.is_supported(req, min_version='2.11'):
|
if api_version_request.is_supported(req, '2.11'):
|
||||||
_services = self._get_services_list(req, ['forced_down'])
|
_services = self._get_services_list(req, ['forced_down'])
|
||||||
else:
|
else:
|
||||||
_services = self._get_services_list(req)
|
_services = self._get_services_list(req)
|
||||||
@@ -401,7 +398,7 @@ class ServiceController(wsgi.Controller):
|
|||||||
path of the request to uniquely identify the service record on which to
|
path of the request to uniquely identify the service record on which to
|
||||||
perform a given update, which is defined in the body of the request.
|
perform a given update, which is defined in the body of the request.
|
||||||
"""
|
"""
|
||||||
if api_version_request.is_supported(req, min_version='2.53'):
|
if api_version_request.is_supported(req, '2.53'):
|
||||||
return self._update_v253(req, id, body)
|
return self._update_v253(req, id, body)
|
||||||
else:
|
else:
|
||||||
return self._update_v21(req, id, body)
|
return self._update_v21(req, id, body)
|
||||||
@@ -409,7 +406,7 @@ class ServiceController(wsgi.Controller):
|
|||||||
def _update_v21(self, req, id, body):
|
def _update_v21(self, req, id, body):
|
||||||
context = req.environ['nova.context']
|
context = req.environ['nova.context']
|
||||||
context.can(services_policies.BASE_POLICY_NAME % 'update', target={})
|
context.can(services_policies.BASE_POLICY_NAME % 'update', target={})
|
||||||
if api_version_request.is_supported(req, min_version='2.11'):
|
if api_version_request.is_supported(req, '2.11'):
|
||||||
actions = self.actions.copy()
|
actions = self.actions.copy()
|
||||||
actions["force-down"] = self._forced_down
|
actions["force-down"] = self._forced_down
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -16,9 +16,6 @@
|
|||||||
from nova.api.openstack import api_version_request
|
from nova.api.openstack import api_version_request
|
||||||
from nova.api.openstack import common
|
from nova.api.openstack import common
|
||||||
|
|
||||||
FLAVOR_DESCRIPTION_MICROVERSION = '2.55'
|
|
||||||
FLAVOR_EXTRA_SPECS_MICROVERSION = '2.61'
|
|
||||||
|
|
||||||
|
|
||||||
class ViewBuilder(common.ViewBuilder):
|
class ViewBuilder(common.ViewBuilder):
|
||||||
|
|
||||||
@@ -78,16 +75,14 @@ class ViewBuilder(common.ViewBuilder):
|
|||||||
def index(self, request, flavors):
|
def index(self, request, flavors):
|
||||||
"""Return the 'index' view of flavors."""
|
"""Return the 'index' view of flavors."""
|
||||||
coll_name = self._collection_name
|
coll_name = self._collection_name
|
||||||
include_description = api_version_request.is_supported(
|
include_description = api_version_request.is_supported(request, '2.55')
|
||||||
request, FLAVOR_DESCRIPTION_MICROVERSION)
|
|
||||||
return self._list_view(self.basic, request, flavors, coll_name,
|
return self._list_view(self.basic, request, flavors, coll_name,
|
||||||
include_description=include_description)
|
include_description=include_description)
|
||||||
|
|
||||||
def detail(self, request, flavors, include_extra_specs=False):
|
def detail(self, request, flavors, include_extra_specs=False):
|
||||||
"""Return the 'detail' view of flavors."""
|
"""Return the 'detail' view of flavors."""
|
||||||
coll_name = self._collection_name + '/detail'
|
coll_name = self._collection_name + '/detail'
|
||||||
include_description = api_version_request.is_supported(
|
include_description = api_version_request.is_supported(request, '2.55')
|
||||||
request, FLAVOR_DESCRIPTION_MICROVERSION)
|
|
||||||
return self._list_view(self.show, request, flavors, coll_name,
|
return self._list_view(self.show, request, flavors, coll_name,
|
||||||
include_description=include_description,
|
include_description=include_description,
|
||||||
include_extra_specs=include_extra_specs)
|
include_extra_specs=include_extra_specs)
|
||||||
|
|||||||
@@ -268,7 +268,7 @@ class ViewBuilder(common.ViewBuilder):
|
|||||||
# detail will pre-calculate this for us. If we're doing show,
|
# detail will pre-calculate this for us. If we're doing show,
|
||||||
# then figure it out here.
|
# then figure it out here.
|
||||||
show_extra_specs = False
|
show_extra_specs = False
|
||||||
if api_version_request.is_supported(request, min_version='2.47'):
|
if api_version_request.is_supported(request, '2.47'):
|
||||||
context = request.environ['nova.context']
|
context = request.environ['nova.context']
|
||||||
show_extra_specs = context.can(
|
show_extra_specs = context.can(
|
||||||
servers_policies.SERVERS % 'show:flavor-extra-specs',
|
servers_policies.SERVERS % 'show:flavor-extra-specs',
|
||||||
@@ -330,11 +330,11 @@ class ViewBuilder(common.ViewBuilder):
|
|||||||
# attributes after v2.1. They are only in v2.1 for backward compat
|
# attributes after v2.1. They are only in v2.1 for backward compat
|
||||||
# with v2.0.
|
# with v2.0.
|
||||||
server["server"]["OS-EXT-AZ:availability_zone"] = az or ''
|
server["server"]["OS-EXT-AZ:availability_zone"] = az or ''
|
||||||
if api_version_request.is_supported(request, min_version='2.96'):
|
if api_version_request.is_supported(request, '2.96'):
|
||||||
pinned_az = self._get_pinned_az(context, instance, provided_az)
|
pinned_az = self._get_pinned_az(context, instance, provided_az)
|
||||||
server['server']['pinned_availability_zone'] = pinned_az
|
server['server']['pinned_availability_zone'] = pinned_az
|
||||||
|
|
||||||
if api_version_request.is_supported(request, min_version='2.100'):
|
if api_version_request.is_supported(request, '2.100'):
|
||||||
server['server']['scheduler_hints'] = (
|
server['server']['scheduler_hints'] = (
|
||||||
self._get_scheduler_hints(
|
self._get_scheduler_hints(
|
||||||
context, instance, provided_sched_hints))
|
context, instance, provided_sched_hints))
|
||||||
@@ -364,7 +364,7 @@ class ViewBuilder(common.ViewBuilder):
|
|||||||
|
|
||||||
if show_extended_attr:
|
if show_extended_attr:
|
||||||
properties = ['host', 'name', 'node']
|
properties = ['host', 'name', 'node']
|
||||||
if api_version_request.is_supported(request, min_version='2.3'):
|
if api_version_request.is_supported(request, '2.3'):
|
||||||
# NOTE(mriedem): These will use the OS-EXT-SRV-ATTR prefix
|
# NOTE(mriedem): These will use the OS-EXT-SRV-ATTR prefix
|
||||||
# below and that's OK for microversion 2.3 which is being
|
# below and that's OK for microversion 2.3 which is being
|
||||||
# compatible with v2.0 for the ec2 API split out from Nova.
|
# compatible with v2.0 for the ec2 API split out from Nova.
|
||||||
@@ -408,7 +408,7 @@ class ViewBuilder(common.ViewBuilder):
|
|||||||
# for new attributes after v2.1. They are only in v2.1 for backward
|
# for new attributes after v2.1. They are only in v2.1 for backward
|
||||||
# compat with v2.0.
|
# compat with v2.0.
|
||||||
add_delete_on_termination = api_version_request.is_supported(
|
add_delete_on_termination = api_version_request.is_supported(
|
||||||
request, min_version='2.3')
|
request, '2.3')
|
||||||
if bdms is None:
|
if bdms is None:
|
||||||
bdms = objects.BlockDeviceMappingList.bdms_by_instance_uuid(
|
bdms = objects.BlockDeviceMappingList.bdms_by_instance_uuid(
|
||||||
context, [instance["uuid"]])
|
context, [instance["uuid"]])
|
||||||
@@ -416,7 +416,7 @@ class ViewBuilder(common.ViewBuilder):
|
|||||||
bdms,
|
bdms,
|
||||||
add_delete_on_termination)
|
add_delete_on_termination)
|
||||||
|
|
||||||
if api_version_request.is_supported(request, min_version='2.16'):
|
if api_version_request.is_supported(request, '2.16'):
|
||||||
if show_host_status is None:
|
if show_host_status is None:
|
||||||
unknown_only = self._get_host_status_unknown_only(
|
unknown_only = self._get_host_status_unknown_only(
|
||||||
context, instance)
|
context, instance)
|
||||||
@@ -435,22 +435,22 @@ class ViewBuilder(common.ViewBuilder):
|
|||||||
host_status == fields.HostStatus.UNKNOWN):
|
host_status == fields.HostStatus.UNKNOWN):
|
||||||
server["server"]['host_status'] = host_status
|
server["server"]['host_status'] = host_status
|
||||||
|
|
||||||
if api_version_request.is_supported(request, min_version="2.9"):
|
if api_version_request.is_supported(request, "2.9"):
|
||||||
server["server"]["locked"] = (True if instance["locked_by"]
|
server["server"]["locked"] = (True if instance["locked_by"]
|
||||||
else False)
|
else False)
|
||||||
|
|
||||||
if api_version_request.is_supported(request, min_version="2.73"):
|
if api_version_request.is_supported(request, "2.73"):
|
||||||
server["server"]["locked_reason"] = (instance.system_metadata.get(
|
server["server"]["locked_reason"] = (instance.system_metadata.get(
|
||||||
"locked_reason"))
|
"locked_reason"))
|
||||||
|
|
||||||
if api_version_request.is_supported(request, min_version="2.19"):
|
if api_version_request.is_supported(request, "2.19"):
|
||||||
server["server"]["description"] = instance.get(
|
server["server"]["description"] = instance.get(
|
||||||
"display_description")
|
"display_description")
|
||||||
|
|
||||||
if api_version_request.is_supported(request, min_version="2.26"):
|
if api_version_request.is_supported(request, "2.26"):
|
||||||
server["server"]["tags"] = [t.tag for t in instance.tags]
|
server["server"]["tags"] = [t.tag for t in instance.tags]
|
||||||
|
|
||||||
if api_version_request.is_supported(request, min_version="2.63"):
|
if api_version_request.is_supported(request, "2.63"):
|
||||||
trusted_certs = None
|
trusted_certs = None
|
||||||
if instance.trusted_certs:
|
if instance.trusted_certs:
|
||||||
trusted_certs = instance.trusted_certs.ids
|
trusted_certs = instance.trusted_certs.ids
|
||||||
@@ -458,7 +458,7 @@ class ViewBuilder(common.ViewBuilder):
|
|||||||
|
|
||||||
# TODO(stephenfin): Remove this check once we remove the
|
# TODO(stephenfin): Remove this check once we remove the
|
||||||
# OS-EXT-SRV-ATTR:hostname policy checks from the policy is Y or later
|
# OS-EXT-SRV-ATTR:hostname policy checks from the policy is Y or later
|
||||||
if api_version_request.is_supported(request, min_version='2.90'):
|
if api_version_request.is_supported(request, '2.90'):
|
||||||
# API 2.90 made this field visible to non-admins, but we only show
|
# API 2.90 made this field visible to non-admins, but we only show
|
||||||
# it if it's not already added
|
# it if it's not already added
|
||||||
if not show_extended_attr:
|
if not show_extended_attr:
|
||||||
@@ -482,7 +482,7 @@ class ViewBuilder(common.ViewBuilder):
|
|||||||
coll_name = self._collection_name + '/detail'
|
coll_name = self._collection_name + '/detail'
|
||||||
context = request.environ['nova.context']
|
context = request.environ['nova.context']
|
||||||
|
|
||||||
if api_version_request.is_supported(request, min_version='2.47'):
|
if api_version_request.is_supported(request, '2.47'):
|
||||||
# Determine if we should show extra_specs in the inlined flavor
|
# Determine if we should show extra_specs in the inlined flavor
|
||||||
# once before we iterate the list of instances
|
# once before we iterate the list of instances
|
||||||
show_extra_specs = context.can(
|
show_extra_specs = context.can(
|
||||||
@@ -510,7 +510,7 @@ class ViewBuilder(common.ViewBuilder):
|
|||||||
bdms=bdms,
|
bdms=bdms,
|
||||||
cell_down_support=cell_down_support)
|
cell_down_support=cell_down_support)
|
||||||
|
|
||||||
if api_version_request.is_supported(request, min_version='2.16'):
|
if api_version_request.is_supported(request, '2.16'):
|
||||||
unknown_only = self._get_host_status_unknown_only(context)
|
unknown_only = self._get_host_status_unknown_only(context)
|
||||||
# If we're not allowed by policy to show host status at all, don't
|
# If we're not allowed by policy to show host status at all, don't
|
||||||
# bother requesting instance host status from the compute API.
|
# bother requesting instance host status from the compute API.
|
||||||
@@ -548,7 +548,7 @@ class ViewBuilder(common.ViewBuilder):
|
|||||||
req_specs = None
|
req_specs = None
|
||||||
req_specs_dict = {}
|
req_specs_dict = {}
|
||||||
sched_hints_dict = {}
|
sched_hints_dict = {}
|
||||||
if api_version_request.is_supported(request, min_version='2.96'):
|
if api_version_request.is_supported(request, '2.96'):
|
||||||
context = request.environ['nova.context']
|
context = request.environ['nova.context']
|
||||||
instance_uuids = [s.uuid for s in servers]
|
instance_uuids = [s.uuid for s in servers]
|
||||||
req_specs = objects.RequestSpec.get_by_instance_uuids(
|
req_specs = objects.RequestSpec.get_by_instance_uuids(
|
||||||
@@ -556,7 +556,7 @@ class ViewBuilder(common.ViewBuilder):
|
|||||||
req_specs_dict.update({req.instance_uuid: req.availability_zone
|
req_specs_dict.update({req.instance_uuid: req.availability_zone
|
||||||
for req in req_specs
|
for req in req_specs
|
||||||
if req.availability_zone is not None})
|
if req.availability_zone is not None})
|
||||||
if api_version_request.is_supported(request, min_version='2.100'):
|
if api_version_request.is_supported(request, '2.100'):
|
||||||
sched_hints_dict.update({
|
sched_hints_dict.update({
|
||||||
req.instance_uuid: req.scheduler_hints
|
req.instance_uuid: req.scheduler_hints
|
||||||
for req in req_specs
|
for req in req_specs
|
||||||
@@ -633,7 +633,7 @@ class ViewBuilder(common.ViewBuilder):
|
|||||||
}],
|
}],
|
||||||
}
|
}
|
||||||
|
|
||||||
if api_version_request.is_supported(request, min_version='2.98'):
|
if api_version_request.is_supported(request, '2.98'):
|
||||||
image_props = {}
|
image_props = {}
|
||||||
for key, value in instance.system_metadata.items():
|
for key, value in instance.system_metadata.items():
|
||||||
if key.startswith(utils.SM_IMAGE_PROP_PREFIX):
|
if key.startswith(utils.SM_IMAGE_PROP_PREFIX):
|
||||||
@@ -668,7 +668,7 @@ class ViewBuilder(common.ViewBuilder):
|
|||||||
"from the DB", instance=instance)
|
"from the DB", instance=instance)
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
if api_version_request.is_supported(request, min_version="2.47"):
|
if api_version_request.is_supported(request, "2.47"):
|
||||||
return self._get_flavor_dict(request, flavor, show_extra_specs)
|
return self._get_flavor_dict(request, flavor, show_extra_specs)
|
||||||
|
|
||||||
flavor_id = flavor["flavorid"]
|
flavor_id = flavor["flavorid"]
|
||||||
|
|||||||
@@ -271,7 +271,7 @@ def _translate_attachment_detail_view(
|
|||||||
|
|
||||||
|
|
||||||
def _check_request_version(req, min_version, method, server_id, server_state):
|
def _check_request_version(req, min_version, method, server_id, server_state):
|
||||||
if not api_version_request.is_supported(req, min_version=min_version):
|
if not api_version_request.is_supported(req, min_version):
|
||||||
exc_inv = exception.InstanceInvalidState(
|
exc_inv = exception.InstanceInvalidState(
|
||||||
attr='vm_state',
|
attr='vm_state',
|
||||||
instance_uuid=server_id,
|
instance_uuid=server_id,
|
||||||
@@ -496,8 +496,7 @@ class VolumeAttachmentController(wsgi.Controller):
|
|||||||
@wsgi.response(202)
|
@wsgi.response(202)
|
||||||
@wsgi.expected_errors((400, 404, 409))
|
@wsgi.expected_errors((400, 404, 409))
|
||||||
@validation.schema(volumes_schema.update_volume_attachment, '2.0', '2.84')
|
@validation.schema(volumes_schema.update_volume_attachment, '2.0', '2.84')
|
||||||
@validation.schema(volumes_schema.update_volume_attachment_v285,
|
@validation.schema(volumes_schema.update_volume_attachment_v285, '2.85')
|
||||||
min_version='2.85')
|
|
||||||
def update(self, req, server_id, id, body):
|
def update(self, req, server_id, id, body):
|
||||||
context = req.environ['nova.context']
|
context = req.environ['nova.context']
|
||||||
instance = common.get_instance(self.compute_api, context, server_id)
|
instance = common.get_instance(self.compute_api, context, server_id)
|
||||||
|
|||||||
@@ -8104,10 +8104,9 @@ class ServersViewBuilderTestV269(_ServersViewBuilderTest):
|
|||||||
self.view_builder = views.servers.ViewBuilder()
|
self.view_builder = views.servers.ViewBuilder()
|
||||||
self.ctxt = context.RequestContext('fake', self.project_id)
|
self.ctxt = context.RequestContext('fake', self.project_id)
|
||||||
|
|
||||||
def fake_is_supported(req, min_version="2.1", max_version="2.69"):
|
def fake_is_supported(req, version="2.1"):
|
||||||
return (fakes.api_version.APIVersionRequest(max_version) >=
|
return (req.api_version_request >=
|
||||||
req.api_version_request >=
|
fakes.api_version.APIVersionRequest(version))
|
||||||
fakes.api_version.APIVersionRequest(min_version))
|
|
||||||
self.stub_out('nova.api.openstack.api_version_request.is_supported',
|
self.stub_out('nova.api.openstack.api_version_request.is_supported',
|
||||||
fake_is_supported)
|
fake_is_supported)
|
||||||
|
|
||||||
|
|||||||
@@ -127,40 +127,9 @@ class APIVersionRequestTests(test.NoDBTestCase):
|
|||||||
self.assertRaises(ValueError,
|
self.assertRaises(ValueError,
|
||||||
api_version_request.APIVersionRequest().get_string)
|
api_version_request.APIVersionRequest().get_string)
|
||||||
|
|
||||||
def test_is_supported_min_version(self):
|
def test_is_supported(self):
|
||||||
req = fakes.HTTPRequest.blank(self.base_path, version='2.5')
|
req = fakes.HTTPRequest.blank(self.base_path, version='2.5')
|
||||||
|
|
||||||
self.assertTrue(api_version_request.is_supported(
|
self.assertTrue(api_version_request.is_supported(req, '2.4'))
|
||||||
req, min_version='2.4'))
|
self.assertTrue(api_version_request.is_supported(req, '2.5'))
|
||||||
self.assertTrue(api_version_request.is_supported(
|
self.assertFalse(api_version_request.is_supported(req, '2.6'))
|
||||||
req, min_version='2.5'))
|
|
||||||
self.assertFalse(api_version_request.is_supported(
|
|
||||||
req, min_version='2.6'))
|
|
||||||
|
|
||||||
def test_is_supported_max_version(self):
|
|
||||||
req = fakes.HTTPRequest.blank(self.base_path, version='2.5')
|
|
||||||
|
|
||||||
self.assertFalse(api_version_request.is_supported(
|
|
||||||
req, max_version='2.4'))
|
|
||||||
self.assertTrue(api_version_request.is_supported(
|
|
||||||
req, max_version='2.5'))
|
|
||||||
self.assertTrue(api_version_request.is_supported(
|
|
||||||
req, max_version='2.6'))
|
|
||||||
|
|
||||||
def test_is_supported_min_and_max_version(self):
|
|
||||||
req = fakes.HTTPRequest.blank(self.base_path, version='2.5')
|
|
||||||
|
|
||||||
self.assertFalse(api_version_request.is_supported(
|
|
||||||
req, min_version='2.3', max_version='2.4'))
|
|
||||||
self.assertTrue(api_version_request.is_supported(
|
|
||||||
req, min_version='2.3', max_version='2.5'))
|
|
||||||
self.assertTrue(api_version_request.is_supported(
|
|
||||||
req, min_version='2.3', max_version='2.7'))
|
|
||||||
self.assertTrue(api_version_request.is_supported(
|
|
||||||
req, min_version='2.5', max_version='2.7'))
|
|
||||||
self.assertFalse(api_version_request.is_supported(
|
|
||||||
req, min_version='2.6', max_version='2.7'))
|
|
||||||
self.assertTrue(api_version_request.is_supported(
|
|
||||||
req, min_version='2.5', max_version='2.5'))
|
|
||||||
self.assertFalse(api_version_request.is_supported(
|
|
||||||
req, min_version='2.10', max_version='2.1'))
|
|
||||||
|
|||||||
Reference in New Issue
Block a user