Totally freeze the extension_info API

The extension will be removed from the Nova API totally. The extension_info
API is just for backward compatibility. And there is no way to disable/enable
the extension, also the discovery policy rules are removed, so it is time
to just hard-code most of the logic at here.

Partial-implement-blueprint api-no-more-extensions-pike

Change-Id: I56d859beb675199b209587bfe0a23cd9b75233ad
This commit is contained in:
He Jie Xu 2017-05-05 14:06:29 +08:00
parent 60e059fdcd
commit 68bbddd8ae
24 changed files with 841 additions and 904 deletions

View File

@ -24,8 +24,6 @@ from nova.compute import vm_states
from nova import exception from nova import exception
from nova.policies import admin_actions as aa_policies from nova.policies import admin_actions as aa_policies
ALIAS = "os-admin-actions"
# States usable in resetState action # States usable in resetState action
# NOTE: It is necessary to update the schema of nova/api/openstack/compute/ # NOTE: It is necessary to update the schema of nova/api/openstack/compute/
# schemas/reset_server_state.py, when updating this state_map. # schemas/reset_server_state.py, when updating this state_map.
@ -83,22 +81,3 @@ class AdminActionsController(wsgi.Controller):
instance.vm_state = state instance.vm_state = state
instance.task_state = None instance.task_state = None
instance.save(admin_state_reset=True) instance.save(admin_state_reset=True)
class AdminActions(extensions.V21APIExtensionBase):
"""Enable admin-only server actions
Actions include: resetNetwork, injectNetworkInfo, os-resetState
"""
name = "AdminActions"
alias = ALIAS
version = 1
def get_controller_extensions(self):
controller = AdminActionsController()
extension = extensions.ControllerExtension(self, 'servers', controller)
return [extension]
def get_resources(self):
return []

View File

@ -25,9 +25,6 @@ from nova.i18n import _
from nova.policies import admin_password as ap_policies from nova.policies import admin_password as ap_policies
ALIAS = "os-admin-password"
class AdminPasswordController(wsgi.Controller): class AdminPasswordController(wsgi.Controller):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
@ -63,19 +60,3 @@ class AdminPasswordController(wsgi.Controller):
except NotImplementedError: except NotImplementedError:
msg = _("Unable to set password on instance") msg = _("Unable to set password on instance")
common.raise_feature_not_supported(msg=msg) common.raise_feature_not_supported(msg=msg)
class AdminPassword(extensions.V21APIExtensionBase):
"""Admin password management support."""
name = "AdminPassword"
alias = ALIAS
version = 1
def get_resources(self):
return []
def get_controller_extensions(self):
controller = AdminPasswordController()
extension = extensions.ControllerExtension(self, 'servers', controller)
return [extension]

View File

@ -17,11 +17,9 @@
from nova.api.openstack.compute.schemas import config_drive as \ from nova.api.openstack.compute.schemas import config_drive as \
schema_config_drive schema_config_drive
from nova.api.openstack import extensions
from nova.api.openstack import wsgi from nova.api.openstack import wsgi
from nova.policies import config_drive as cd_policies from nova.policies import config_drive as cd_policies
ALIAS = "os-config-drive"
ATTRIBUTE_NAME = "config_drive" ATTRIBUTE_NAME = "config_drive"
@ -54,22 +52,6 @@ class ConfigDriveController(wsgi.Controller):
self._add_config_drive(req, servers) self._add_config_drive(req, servers)
class ConfigDrive(extensions.V21APIExtensionBase):
"""Config Drive Extension."""
name = "ConfigDrive"
alias = ALIAS
version = 1
def get_controller_extensions(self):
controller = ConfigDriveController()
extension = extensions.ControllerExtension(self, 'servers', controller)
return [extension]
def get_resources(self):
return []
# NOTE(gmann): This function is not supposed to use 'body_deprecated_param' # NOTE(gmann): This function is not supposed to use 'body_deprecated_param'
# parameter as this is placed to handle scheduler_hint extension for V2.1. # parameter as this is placed to handle scheduler_hint extension for V2.1.
def server_create(server_dict, create_kwargs, body_deprecated_param): def server_create(server_dict, create_kwargs, body_deprecated_param):

View File

@ -27,8 +27,6 @@ from nova import compute
from nova import exception from nova import exception
from nova.policies import console_output as co_policies from nova.policies import console_output as co_policies
ALIAS = "os-console-output"
class ConsoleOutputController(wsgi.Controller): class ConsoleOutputController(wsgi.Controller):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
@ -71,19 +69,3 @@ class ConsoleOutputController(wsgi.Controller):
output = remove_re.sub('', output) output = remove_re.sub('', output)
return {'output': output} return {'output': output}
class ConsoleOutput(extensions.V21APIExtensionBase):
"""Console log output support, with tailing ability."""
name = "ConsoleOutput"
alias = ALIAS
version = 1
def get_controller_extensions(self):
controller = ConsoleOutputController()
extension = extensions.ControllerExtension(self, 'servers', controller)
return [extension]
def get_resources(self):
return []

View File

@ -25,8 +25,6 @@ from nova import compute
from nova import exception from nova import exception
from nova.policies import create_backup as cb_policies from nova.policies import create_backup as cb_policies
ALIAS = "os-create-backup"
class CreateBackupController(wsgi.Controller): class CreateBackupController(wsgi.Controller):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
@ -94,19 +92,3 @@ class CreateBackupController(wsgi.Controller):
resp.headers['Location'] = image_ref resp.headers['Location'] = image_ref
return resp return resp
class CreateBackup(extensions.V21APIExtensionBase):
"""Create a backup of a server."""
name = "CreateBackup"
alias = ALIAS
version = 1
def get_controller_extensions(self):
controller = CreateBackupController()
extension = extensions.ControllerExtension(self, 'servers', controller)
return [extension]
def get_resources(self):
return []

View File

@ -24,8 +24,6 @@ from nova import compute
from nova import exception from nova import exception
from nova.policies import deferred_delete as dd_policies from nova.policies import deferred_delete as dd_policies
ALIAS = 'os-deferred-delete'
class DeferredDeleteController(wsgi.Controller): class DeferredDeleteController(wsgi.Controller):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
@ -67,19 +65,3 @@ class DeferredDeleteController(wsgi.Controller):
raise webob.exc.HTTPNotFound(explanation=e.format_message()) raise webob.exc.HTTPNotFound(explanation=e.format_message())
except exception.InstanceIsLocked as e: except exception.InstanceIsLocked as e:
raise webob.exc.HTTPConflict(explanation=e.format_message()) raise webob.exc.HTTPConflict(explanation=e.format_message())
class DeferredDelete(extensions.V21APIExtensionBase):
"""Instance deferred delete."""
name = "DeferredDelete"
alias = "os-deferred-delete"
version = 1
def get_controller_extensions(self):
controller = DeferredDeleteController()
extension = extensions.ControllerExtension(self, 'servers', controller)
return [extension]
def get_resources(self):
return []

View File

@ -31,8 +31,6 @@ from nova import utils
CONF = nova.conf.CONF CONF = nova.conf.CONF
ALIAS = "os-evacuate"
class EvacuateController(wsgi.Controller): class EvacuateController(wsgi.Controller):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
@ -133,19 +131,3 @@ class EvacuateController(wsgi.Controller):
return {'adminPass': password} return {'adminPass': password}
else: else:
return None return None
class Evacuate(extensions.V21APIExtensionBase):
"""Enables server evacuation."""
name = "Evacuate"
alias = ALIAS
version = 1
def get_resources(self):
return []
def get_controller_extensions(self):
controller = EvacuateController()
extension = extensions.ControllerExtension(self, 'servers', controller)
return [extension]

View File

@ -15,12 +15,10 @@
"""The Extended Availability Zone Status API extension.""" """The Extended Availability Zone Status API extension."""
from nova.api.openstack import extensions
from nova.api.openstack import wsgi from nova.api.openstack import wsgi
from nova import availability_zones as avail_zone from nova import availability_zones as avail_zone
from nova.policies import extended_availability_zone as eaz_policies from nova.policies import extended_availability_zone as eaz_policies
ALIAS = "os-extended-availability-zone"
PREFIX = "OS-EXT-AZ" PREFIX = "OS-EXT-AZ"
@ -49,19 +47,3 @@ class ExtendedAZController(wsgi.Controller):
for server in servers: for server in servers:
db_instance = req.get_db_instance(server['id']) db_instance = req.get_db_instance(server['id'])
self._extend_server(context, server, db_instance) self._extend_server(context, server, db_instance)
class ExtendedAvailabilityZone(extensions.V21APIExtensionBase):
"""Extended Availability Zone support."""
name = "ExtendedAvailabilityZone"
alias = ALIAS
version = 1
def get_controller_extensions(self):
controller = ExtendedAZController()
extension = extensions.ControllerExtension(self, 'servers', controller)
return [extension]
def get_resources(self):
return []

View File

@ -15,14 +15,11 @@
"""The Extended Server Attributes API extension.""" """The Extended Server Attributes API extension."""
from nova.api.openstack import api_version_request from nova.api.openstack import api_version_request
from nova.api.openstack import extensions
from nova.api.openstack import wsgi from nova.api.openstack import wsgi
from nova import compute from nova import compute
from nova.policies import extended_server_attributes as esa_policies from nova.policies import extended_server_attributes as esa_policies
from nova.policies import servers as servers_policies from nova.policies import servers as servers_policies
ALIAS = "os-extended-server-attributes"
class ExtendedServerAttributesController(wsgi.Controller): class ExtendedServerAttributesController(wsgi.Controller):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
@ -106,19 +103,3 @@ class ExtendedServerAttributesController(wsgi.Controller):
self._extend_server(context, server, instance, req) self._extend_server(context, server, instance, req)
if authorize_host_status: if authorize_host_status:
server['host_status'] = host_statuses[server['id']] server['host_status'] = host_statuses[server['id']]
class ExtendedServerAttributes(extensions.V21APIExtensionBase):
"""Extended Server Attributes support."""
name = "ExtendedServerAttributes"
alias = ALIAS
version = 1
def get_controller_extensions(self):
controller = ExtendedServerAttributesController()
extension = extensions.ControllerExtension(self, 'servers', controller)
return [extension]
def get_resources(self):
return []

View File

@ -14,12 +14,9 @@
"""The Extended Status Admin API extension.""" """The Extended Status Admin API extension."""
from nova.api.openstack import extensions
from nova.api.openstack import wsgi from nova.api.openstack import wsgi
from nova.policies import extended_status as es_policies from nova.policies import extended_status as es_policies
ALIAS = "os-extended-status"
class ExtendedStatusController(wsgi.Controller): class ExtendedStatusController(wsgi.Controller):
def _extend_server(self, server, instance): def _extend_server(self, server, instance):
@ -53,19 +50,3 @@ class ExtendedStatusController(wsgi.Controller):
# server['id'] is guaranteed to be in the cache due to # server['id'] is guaranteed to be in the cache due to
# the core API adding it in its 'detail' method. # the core API adding it in its 'detail' method.
self._extend_server(server, db_instance) self._extend_server(server, db_instance)
class ExtendedStatus(extensions.V21APIExtensionBase):
"""Extended Status support."""
name = "ExtendedStatus"
alias = ALIAS
version = 1
def get_controller_extensions(self):
controller = ExtendedStatusController()
extension = extensions.ControllerExtension(self, 'servers', controller)
return [extension]
def get_resources(self):
return []

View File

@ -14,13 +14,10 @@
"""The Extended Volumes API extension.""" """The Extended Volumes API extension."""
from nova.api.openstack import api_version_request from nova.api.openstack import api_version_request
from nova.api.openstack import extensions
from nova.api.openstack import wsgi from nova.api.openstack import wsgi
from nova import objects from nova import objects
from nova.policies import extended_volumes as ev_policies from nova.policies import extended_volumes as ev_policies
ALIAS = "os-extended-volumes"
class ExtendedVolumesController(wsgi.Controller): class ExtendedVolumesController(wsgi.Controller):
def _extend_server(self, context, server, req, bdms): def _extend_server(self, context, server, req, bdms):
@ -35,7 +32,7 @@ class ExtendedVolumesController(wsgi.Controller):
# NOTE(mriedem): The os-extended-volumes prefix should not be used for # NOTE(mriedem): The os-extended-volumes prefix should not be used for
# new attributes after v2.1. They are only in v2.1 for backward compat # new attributes after v2.1. They are only in v2.1 for backward compat
# with v2.0. # with v2.0.
key = "%s:volumes_attached" % ExtendedVolumes.alias key = "os-extended-volumes:volumes_attached"
server[key] = volumes_attached server[key] = volumes_attached
@wsgi.extends @wsgi.extends
@ -66,19 +63,3 @@ class ExtendedVolumesController(wsgi.Controller):
# If that instance has since been deleted, it won't be in the # If that instance has since been deleted, it won't be in the
# 'bdms' dictionary though, so use 'get' to avoid KeyErrors. # 'bdms' dictionary though, so use 'get' to avoid KeyErrors.
return bdms.get(server['id'], []) return bdms.get(server['id'], [])
class ExtendedVolumes(extensions.V21APIExtensionBase):
"""Extended Volumes support."""
name = "ExtendedVolumes"
alias = ALIAS
version = 1
def get_controller_extensions(self):
controller = ExtendedVolumesController()
extension = extensions.ControllerExtension(self, 'servers', controller)
return [extension]
def get_resources(self):
return []

File diff suppressed because it is too large Load Diff

View File

@ -15,7 +15,6 @@
"""Extension for hiding server addresses in certain states.""" """Extension for hiding server addresses in certain states."""
from nova.api.openstack import extensions
from nova.api.openstack import wsgi from nova.api.openstack import wsgi
from nova.compute import vm_states from nova.compute import vm_states
import nova.conf import nova.conf
@ -24,8 +23,6 @@ from nova.policies import hide_server_addresses as hsa_policies
CONF = nova.conf.CONF CONF = nova.conf.CONF
ALIAS = 'os-hide-server-addresses'
class Controller(wsgi.Controller): class Controller(wsgi.Controller):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
@ -66,17 +63,3 @@ class Controller(wsgi.Controller):
if 'addresses' in server: if 'addresses' in server:
instance = req.get_db_instance(server['id']) instance = req.get_db_instance(server['id'])
self._perhaps_hide_addresses(instance, server) self._perhaps_hide_addresses(instance, server)
class HideServerAddresses(extensions.V21APIExtensionBase):
"""Support hiding server addresses in certain states."""
name = 'HideServerAddresses'
alias = ALIAS
version = 1
def get_controller_extensions(self):
return [extensions.ControllerExtension(self, 'servers', Controller())]
def get_resources(self):
return []

View File

@ -19,8 +19,6 @@ from nova.api.openstack import wsgi
from nova import compute from nova import compute
from nova.policies import lock_server as ls_policies from nova.policies import lock_server as ls_policies
ALIAS = "os-lock-server"
class LockServerController(wsgi.Controller): class LockServerController(wsgi.Controller):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
@ -52,19 +50,3 @@ class LockServerController(wsgi.Controller):
instance) instance)
self.compute_api.unlock(context, instance) self.compute_api.unlock(context, instance)
class LockServer(extensions.V21APIExtensionBase):
"""Enable lock/unlock server actions."""
name = "LockServer"
alias = ALIAS
version = 1
def get_controller_extensions(self):
controller = LockServerController()
extension = extensions.ControllerExtension(self, 'servers', controller)
return [extension]
def get_resources(self):
return []

View File

@ -30,7 +30,6 @@ from nova.i18n import _
from nova.policies import migrate_server as ms_policies from nova.policies import migrate_server as ms_policies
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
ALIAS = "os-migrate-server"
class MigrateServerController(wsgi.Controller): class MigrateServerController(wsgi.Controller):
@ -131,19 +130,3 @@ class MigrateServerController(wsgi.Controller):
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)
return force return force
class MigrateServer(extensions.V21APIExtensionBase):
"""Enable migrate and live-migrate server actions."""
name = "MigrateServer"
alias = ALIAS
version = 1
def get_controller_extensions(self):
controller = MigrateServerController()
extension = extensions.ControllerExtension(self, 'servers', controller)
return [extension]
def get_resources(self):
return []

View File

@ -27,9 +27,6 @@ from nova import exception
from nova.policies import multinic as multinic_policies from nova.policies import multinic as multinic_policies
ALIAS = "os-multinic"
class MultinicController(wsgi.Controller): class MultinicController(wsgi.Controller):
"""This API is deprecated from Microversion '2.44'.""" """This API is deprecated from Microversion '2.44'."""
@ -75,21 +72,3 @@ class MultinicController(wsgi.Controller):
raise exc.HTTPNotFound(explanation=e.format_message()) raise exc.HTTPNotFound(explanation=e.format_message())
except exception.FixedIpNotFoundForSpecificInstance as e: except exception.FixedIpNotFoundForSpecificInstance as e:
raise exc.HTTPBadRequest(explanation=e.format_message()) raise exc.HTTPBadRequest(explanation=e.format_message())
# Note: The class name is as it has to be for this to be loaded as an
# extension--only first character capitalized.
class Multinic(extensions.V21APIExtensionBase):
"""Multiple network support."""
name = "Multinic"
alias = ALIAS
version = 1
def get_controller_extensions(self):
controller = MultinicController()
extension = extensions.ControllerExtension(self, 'servers', controller)
return [extension]
def get_resources(self):
return []

View File

@ -22,8 +22,6 @@ from nova import compute
from nova import exception from nova import exception
from nova.policies import pause_server as ps_policies from nova.policies import pause_server as ps_policies
ALIAS = "os-pause-server"
class PauseServerController(wsgi.Controller): class PauseServerController(wsgi.Controller):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
@ -73,19 +71,3 @@ class PauseServerController(wsgi.Controller):
raise exc.HTTPNotFound(explanation=e.format_message()) raise exc.HTTPNotFound(explanation=e.format_message())
except NotImplementedError: except NotImplementedError:
common.raise_feature_not_supported() common.raise_feature_not_supported()
class PauseServer(extensions.V21APIExtensionBase):
"""Enable pause/unpause server actions."""
name = "PauseServer"
alias = ALIAS
version = 1
def get_controller_extensions(self):
controller = PauseServerController()
extension = extensions.ControllerExtension(self, 'servers', controller)
return [extension]
def get_resources(self):
return []

View File

@ -27,8 +27,6 @@ from nova import exception
from nova.policies import rescue as rescue_policies from nova.policies import rescue as rescue_policies
from nova import utils from nova import utils
ALIAS = "os-rescue"
CONF = nova.conf.CONF CONF = nova.conf.CONF
@ -100,19 +98,3 @@ class RescueController(wsgi.Controller):
common.raise_http_conflict_for_instance_invalid_state(state_error, common.raise_http_conflict_for_instance_invalid_state(state_error,
'unrescue', 'unrescue',
id) id)
class Rescue(extensions.V21APIExtensionBase):
"""Instance rescue mode."""
name = "Rescue"
alias = ALIAS
version = 1
def get_resources(self):
return []
def get_controller_extensions(self):
controller = RescueController()
extension = extensions.ControllerExtension(self, 'servers', controller)
return [extension]

View File

@ -13,23 +13,6 @@
# under the License. # under the License.
from nova.api.openstack.compute.schemas import scheduler_hints as schema from nova.api.openstack.compute.schemas import scheduler_hints as schema
from nova.api.openstack import extensions
ALIAS = "os-scheduler-hints"
class SchedulerHints(extensions.V21APIExtensionBase):
"""Pass arbitrary key/value pairs to the scheduler."""
name = "SchedulerHints"
alias = ALIAS
version = 1
def get_controller_extensions(self):
return []
def get_resources(self):
return []
# NOTE(gmann): Accepting request body in this function to fetch "scheduler # NOTE(gmann): Accepting request body in this function to fetch "scheduler

View File

@ -12,13 +12,10 @@
# 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 nova.api.openstack import extensions
from nova.api.openstack import wsgi from nova.api.openstack import wsgi
from nova.policies import server_usage as su_policies from nova.policies import server_usage as su_policies
ALIAS = "os-server-usage"
resp_topic = "OS-SRV-USG" resp_topic = "OS-SRV-USG"
@ -54,19 +51,3 @@ class ServerUsageController(wsgi.Controller):
# server['id'] is guaranteed to be in the cache due to # server['id'] is guaranteed to be in the cache due to
# the core API adding it in its 'detail' method. # the core API adding it in its 'detail' method.
self._extend_server(server, db_instance) self._extend_server(server, db_instance)
class ServerUsage(extensions.V21APIExtensionBase):
"""Adds launched_at and terminated_at on Servers."""
name = "ServerUsage"
alias = ALIAS
version = 1
def get_controller_extensions(self):
controller = ServerUsageController()
extension = extensions.ControllerExtension(self, 'servers', controller)
return [extension]
def get_resources(self):
return []

View File

@ -54,7 +54,6 @@ from nova import objects
from nova.policies import servers as server_policies from nova.policies import servers as server_policies
from nova import utils from nova import utils
ALIAS = 'servers'
TAG_SEARCH_FILTERS = ('tags', 'tags-any', 'not-tags', 'not-tags-any') TAG_SEARCH_FILTERS = ('tags', 'tags-any', 'not-tags', 'not-tags-any')
DEVICE_TAGGING_MIN_COMPUTE_VERSION = 14 DEVICE_TAGGING_MIN_COMPUTE_VERSION = 14
@ -1162,26 +1161,3 @@ def remove_invalid_sort_keys(context, sort_keys, sort_dirs,
raise exc.HTTPForbidden(explanation=msg) raise exc.HTTPForbidden(explanation=msg)
return sort_keys, sort_dirs return sort_keys, sort_dirs
class Servers(extensions.V21APIExtensionBase):
"""Servers."""
name = "Servers"
alias = ALIAS
version = 1
def get_resources(self):
member_actions = {'action': 'POST'}
collection_actions = {'detail': 'GET'}
resources = [
extensions.ResourceExtension(
ALIAS,
ServersController(extension_info=self.extension_info),
member_name='server', collection_actions=collection_actions,
member_actions=member_actions)]
return resources
def get_controller_extensions(self):
return []

View File

@ -24,9 +24,6 @@ from nova import exception
from nova.policies import shelve as shelve_policies from nova.policies import shelve as shelve_policies
ALIAS = 'os-shelve'
class ShelveController(wsgi.Controller): class ShelveController(wsgi.Controller):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(ShelveController, self).__init__(*args, **kwargs) super(ShelveController, self).__init__(*args, **kwargs)
@ -91,19 +88,3 @@ class ShelveController(wsgi.Controller):
common.raise_http_conflict_for_instance_invalid_state(state_error, common.raise_http_conflict_for_instance_invalid_state(state_error,
'unshelve', 'unshelve',
id) id)
class Shelve(exts.V21APIExtensionBase):
"""Instance shelve mode."""
name = "Shelve"
alias = ALIAS
version = 1
def get_controller_extensions(self):
controller = ShelveController()
extension = exts.ControllerExtension(self, 'servers', controller)
return [extension]
def get_resources(self):
return []

View File

@ -21,8 +21,6 @@ from nova import compute
from nova import exception from nova import exception
from nova.policies import suspend_server as ss_policies from nova.policies import suspend_server as ss_policies
ALIAS = "os-suspend-server"
class SuspendServerController(wsgi.Controller): class SuspendServerController(wsgi.Controller):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
@ -66,19 +64,3 @@ class SuspendServerController(wsgi.Controller):
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(state_error,
'resume', id) 'resume', id)
class SuspendServer(extensions.V21APIExtensionBase):
"""Enable suspend/resume server actions."""
name = "SuspendServer"
alias = ALIAS
version = 1
def get_controller_extensions(self):
controller = SuspendServerController()
extension = extensions.ControllerExtension(self, 'servers', controller)
return [extension]
def get_resources(self):
return []

View File

@ -12,8 +12,6 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import copy
import mock import mock
import webob import webob
@ -24,163 +22,15 @@ from nova import test
from nova.tests.unit.api.openstack import fakes from nova.tests.unit.api.openstack import fakes
FAKE_UPDATED_DATE = extension_info.FAKE_UPDATED_DATE
# NOTE(sdague): this whole test module is short term while we shift
# the extensions into main path code. Some short cuts are taken in the
# interim to keep these extension tests.
class fake_extension(object):
def __init__(self, name, alias, description, version):
self.name = name
self.alias = alias
self.__doc__ = description
self.version = version
fake_extensions = {
'ext1-alias': fake_extension('ext1', 'ext1-alias', 'ext1 description', 1),
'ext2-alias': fake_extension('ext2', 'ext2-alias', 'ext2 description', 2),
'ext3-alias': fake_extension('ext3', 'ext3-alias', 'ext3 description', 1)
}
simulated_extension_list = {
'servers': fake_extension('Servers', 'servers', 'Servers.', 1),
'images': fake_extension('Images', 'images', 'Images.', 2),
'os-quota-sets': fake_extension('Quotas', 'os-quota-sets',
'Quotas management support', 1),
'os-cells': fake_extension('Cells', 'os-cells',
'Cells description', 1),
'os-flavor-access': fake_extension('FlavorAccess', 'os-flavor-access',
'Flavor access support.', 1)
}
class ExtensionInfoTest(test.NoDBTestCase):
def setUp(self):
super(ExtensionInfoTest, self).setUp()
ext_info = extension_info.LoadedExtensionInfo()
ext_info.extensions = fake_extensions
self.controller = extension_info.ExtensionInfoController(ext_info)
@mock.patch.object(policy, 'authorize', mock.Mock(return_value=True))
def test_extension_info_list(self):
req = fakes.HTTPRequestV21.blank('/extensions')
res_dict = self.controller.index(req)
# NOTE(sdague): because of hardcoded extensions the count is
# going to grow, and that's fine. We'll just check that it's
# greater than the 3 that we inserted.
self.assertGreaterEqual(len(res_dict['extensions']), 3)
# NOTE(sdague): filter the extension list by only ones that
# are the fake alias names, otherwise we get errors as we
# migrate extensions into the hardcoded list.
for e in [x for x in res_dict['extensions'] if '-alias' in x['alias']]:
self.assertIn(e['alias'], fake_extensions)
self.assertEqual(e['name'], fake_extensions[e['alias']].name)
self.assertEqual(e['alias'], fake_extensions[e['alias']].alias)
self.assertEqual(e['description'],
fake_extensions[e['alias']].__doc__)
self.assertEqual(e['updated'], FAKE_UPDATED_DATE)
self.assertEqual(e['links'], [])
self.assertEqual(6, len(e))
@mock.patch.object(policy, 'authorize', mock.Mock(return_value=True))
def test_extension_info_show(self):
req = fakes.HTTPRequestV21.blank('/extensions/ext1-alias')
res_dict = self.controller.show(req, 'ext1-alias')
self.assertEqual(1, len(res_dict))
self.assertEqual(res_dict['extension']['name'],
fake_extensions['ext1-alias'].name)
self.assertEqual(res_dict['extension']['alias'],
fake_extensions['ext1-alias'].alias)
self.assertEqual(res_dict['extension']['description'],
fake_extensions['ext1-alias'].__doc__)
self.assertEqual(res_dict['extension']['updated'], FAKE_UPDATED_DATE)
self.assertEqual(res_dict['extension']['links'], [])
self.assertEqual(6, len(res_dict['extension']))
class ExtensionInfoV21Test(test.NoDBTestCase): class ExtensionInfoV21Test(test.NoDBTestCase):
def setUp(self): def setUp(self):
super(ExtensionInfoV21Test, self).setUp() super(ExtensionInfoV21Test, self).setUp()
ext_info = extension_info.LoadedExtensionInfo() self.controller = extension_info.ExtensionInfoController()
ext_info.extensions = simulated_extension_list
self.controller = extension_info.ExtensionInfoController(ext_info)
patcher = mock.patch.object(policy, 'authorize', return_value=True) patcher = mock.patch.object(policy, 'authorize', return_value=True)
patcher.start() patcher.start()
self.addCleanup(patcher.stop) self.addCleanup(patcher.stop)
def test_extension_info_list(self):
req = fakes.HTTPRequest.blank('/extensions')
res_dict = self.controller.index(req)
# NOTE(sdague): because of hardcoded extensions the count is
# going to grow, and that's fine. We'll just check that it's
# greater than the 12 that we inserted.
self.assertGreaterEqual(len(res_dict['extensions']), 12)
expected_output = copy.deepcopy(simulated_extension_list)
del expected_output['images']
del expected_output['servers']
expected_output['os-cell-capacities'] = fake_extension(
'CellCapacities', 'os-cell-capacities', 'Adding functionality'
' to get cell capacities.', -1)
expected_output['os-server-sort-keys'] = fake_extension(
'ServerSortKeys', 'os-server-sort-keys', 'Add sorting'
' support in get Server v2 API.', -1)
expected_output['os-user-quotas'] = fake_extension(
'UserQuotas', 'os-user-quotas', 'Project user quota support.', -1)
expected_output['os-extended-quotas'] = fake_extension(
'ExtendedQuotas', 'os-extended-quotas', 'Adds ability for'
' admins to delete quota and optionally force the update'
' Quota command.', -1)
expected_output['os-create-server-ext'] = fake_extension(
'Createserverext', 'os-create-server-ext', 'Extended support to'
' the Create Server v1.1 API.', -1)
expected_output['OS-EXT-IPS'] = fake_extension(
'ExtendedIps', 'OS-EXT-IPS', 'Adds type parameter to the'
' ip list.', -1)
expected_output['OS-EXT-IPS-MAC'] = fake_extension(
'ExtendedIpsMac', 'OS-EXT-IPS-MAC', 'Adds mac address parameter'
' to the ip list.', -1)
expected_output['os-server-list-multi-status'] = fake_extension(
'ServerListMultiStatus', 'os-server-list-multi-status',
'Allow to filter the servers by a set of status values.', -1)
expected_output['os-server-start-stop'] = fake_extension(
'ServerStartStop', 'os-server-start-stop', 'Start/Stop instance'
' compute API support.', -1)
# NOTE(sdague): filter the extension list by only ones that
# are the fake alias names, otherwise we get errors as we
# migrate extensions into the hardcoded list.
for e in [x for x in res_dict['extensions'] if '-alias' in x['alias']]:
self.assertIn(e['alias'], expected_output)
self.assertEqual(e['name'], expected_output[e['alias']].name)
self.assertEqual(e['alias'], expected_output[e['alias']].alias)
self.assertEqual(e['description'],
expected_output[e['alias']].__doc__)
self.assertEqual(e['updated'], FAKE_UPDATED_DATE)
self.assertEqual(e['links'], [])
self.assertEqual(6, len(e))
def test_extension_info_show(self):
req = fakes.HTTPRequest.blank('/extensions/os-cells')
res_dict = self.controller.show(req, 'os-cells')
self.assertEqual(1, len(res_dict))
self.assertEqual(res_dict['extension']['name'],
simulated_extension_list['os-cells'].name)
self.assertEqual(res_dict['extension']['alias'],
simulated_extension_list['os-cells'].alias)
self.assertEqual(res_dict['extension']['description'],
simulated_extension_list['os-cells'].__doc__)
self.assertEqual(res_dict['extension']['updated'], FAKE_UPDATED_DATE)
self.assertEqual(res_dict['extension']['links'], [])
self.assertEqual(6, len(res_dict['extension']))
def test_extension_info_show_servers_not_present(self): def test_extension_info_show_servers_not_present(self):
req = fakes.HTTPRequest.blank('/extensions/servers') req = fakes.HTTPRequest.blank('/extensions/servers')
self.assertRaises(webob.exc.HTTPNotFound, self.controller.show, self.assertRaises(webob.exc.HTTPNotFound, self.controller.show,
@ -190,9 +40,7 @@ class ExtensionInfoV21Test(test.NoDBTestCase):
class ExtensionInfoPolicyEnforcementV21(test.NoDBTestCase): class ExtensionInfoPolicyEnforcementV21(test.NoDBTestCase):
def setUp(self): def setUp(self):
super(ExtensionInfoPolicyEnforcementV21, self).setUp() super(ExtensionInfoPolicyEnforcementV21, self).setUp()
ext_info = extension_info.LoadedExtensionInfo() self.controller = extension_info.ExtensionInfoController()
ext_info.extensions = fake_extensions
self.controller = extension_info.ExtensionInfoController(ext_info)
self.req = fakes.HTTPRequest.blank('') self.req = fakes.HTTPRequest.blank('')
def _test_extension_policy_failed(self, action, *args): def _test_extension_policy_failed(self, action, *args):