diff options
| author | Jenkins <jenkins@review.openstack.org> | 2012-01-16 23:15:18 +0000 |
|---|---|---|
| committer | Gerrit Code Review <review@openstack.org> | 2012-01-16 23:15:18 +0000 |
| commit | 1fd26203b29d6432325ae1365e3dcbecc9d97864 (patch) | |
| tree | eb25f90688bd16d67cc6458ea841fecdde6887cb | |
| parent | 7afc12b9a21abc1c99a70fd61b24d10746ed1bd2 (diff) | |
| parent | 8be89626681388c3a0e8f3c94830aff7c2a4c37e (diff) | |
Merge "Update some extensions (1)"
11 files changed, 226 insertions, 281 deletions
diff --git a/nova/api/openstack/compute/contrib/admin_actions.py b/nova/api/openstack/compute/contrib/admin_actions.py index dedef3061..a4164fcb8 100644 --- a/nova/api/openstack/compute/contrib/admin_actions.py +++ b/nova/api/openstack/compute/contrib/admin_actions.py @@ -20,6 +20,7 @@ from webob import exc from nova.api.openstack import common from nova.api.openstack import extensions +from nova.api.openstack import wsgi from nova import compute from nova import exception from nova import flags @@ -31,26 +32,17 @@ FLAGS = flags.FLAGS LOG = logging.getLogger("nova.api.openstack.compute.contrib.admin_actions") -class Admin_actions(extensions.ExtensionDescriptor): - """Enable admin-only server actions - - Actions include: pause, unpause, suspend, resume, migrate, - resetNetwork, injectNetworkInfo, lock, unlock, createBackup - """ - - name = "AdminActions" - alias = "os-admin-actions" - namespace = "http://docs.openstack.org/compute/ext/admin-actions/api/v1.1" - updated = "2011-09-20T00:00:00+00:00" - admin_only = True - - def __init__(self, ext_mgr): - super(Admin_actions, self).__init__(ext_mgr) +class AdminActionsController(wsgi.Controller): + def __init__(self, *args, **kwargs): + super(AdminActionsController, self).__init__(*args, **kwargs) self.compute_api = compute.API() + # TODO(bcwaldon): These action names should be prefixed with 'os-' + + @wsgi.action('pause') @exception.novaclient_converter @scheduler_api.redirect_handler - def _pause(self, input_dict, req, id): + def _pause(self, req, id, body): """Permit Admins to pause the server""" ctxt = req.environ['nova.context'] try: @@ -65,9 +57,10 @@ class Admin_actions(extensions.ExtensionDescriptor): raise exc.HTTPUnprocessableEntity() return webob.Response(status_int=202) + @wsgi.action('unpause') @exception.novaclient_converter @scheduler_api.redirect_handler - def _unpause(self, input_dict, req, id): + def _unpause(self, req, id, body): """Permit Admins to unpause the server""" ctxt = req.environ['nova.context'] try: @@ -82,9 +75,10 @@ class Admin_actions(extensions.ExtensionDescriptor): raise exc.HTTPUnprocessableEntity() return webob.Response(status_int=202) + @wsgi.action('suspend') @exception.novaclient_converter @scheduler_api.redirect_handler - def _suspend(self, input_dict, req, id): + def _suspend(self, req, id, body): """Permit admins to suspend the server""" context = req.environ['nova.context'] try: @@ -99,9 +93,10 @@ class Admin_actions(extensions.ExtensionDescriptor): raise exc.HTTPUnprocessableEntity() return webob.Response(status_int=202) + @wsgi.action('resume') @exception.novaclient_converter @scheduler_api.redirect_handler - def _resume(self, input_dict, req, id): + def _resume(self, req, id, body): """Permit admins to resume the server from suspend""" context = req.environ['nova.context'] try: @@ -116,9 +111,10 @@ class Admin_actions(extensions.ExtensionDescriptor): raise exc.HTTPUnprocessableEntity() return webob.Response(status_int=202) + @wsgi.action('migrate') @exception.novaclient_converter @scheduler_api.redirect_handler - def _migrate(self, input_dict, req, id): + def _migrate(self, req, id, body): """Permit admins to migrate a server to a new host""" context = req.environ['nova.context'] try: @@ -132,9 +128,10 @@ class Admin_actions(extensions.ExtensionDescriptor): raise exc.HTTPBadRequest() return webob.Response(status_int=202) + @wsgi.action('resetNetwork') @exception.novaclient_converter @scheduler_api.redirect_handler - def _reset_network(self, input_dict, req, id): + def _reset_network(self, req, id, body): """Permit admins to reset networking on an server""" context = req.environ['nova.context'] try: @@ -146,9 +143,10 @@ class Admin_actions(extensions.ExtensionDescriptor): raise exc.HTTPUnprocessableEntity() return webob.Response(status_int=202) + @wsgi.action('injectNetworkInfo') @exception.novaclient_converter @scheduler_api.redirect_handler - def _inject_network_info(self, input_dict, req, id): + def _inject_network_info(self, req, id, body): """Permit admins to inject network info into a server""" context = req.environ['nova.context'] try: @@ -162,9 +160,10 @@ class Admin_actions(extensions.ExtensionDescriptor): raise exc.HTTPUnprocessableEntity() return webob.Response(status_int=202) + @wsgi.action('lock') @exception.novaclient_converter @scheduler_api.redirect_handler - def _lock(self, input_dict, req, id): + def _lock(self, req, id, body): """Permit admins to lock a server""" context = req.environ['nova.context'] try: @@ -178,9 +177,10 @@ class Admin_actions(extensions.ExtensionDescriptor): raise exc.HTTPUnprocessableEntity() return webob.Response(status_int=202) + @wsgi.action('unlock') @exception.novaclient_converter @scheduler_api.redirect_handler - def _unlock(self, input_dict, req, id): + def _unlock(self, req, id, body): """Permit admins to lock a server""" context = req.environ['nova.context'] try: @@ -194,7 +194,8 @@ class Admin_actions(extensions.ExtensionDescriptor): raise exc.HTTPUnprocessableEntity() return webob.Response(status_int=202) - def _create_backup(self, input_dict, req, instance_id): + @wsgi.action('createBackup') + def _create_backup(self, req, id, body): """Backup a server instance. Images now have an `image_type` associated with them, which can be @@ -208,7 +209,7 @@ class Admin_actions(extensions.ExtensionDescriptor): context = req.environ["nova.context"] try: - entity = input_dict["createBackup"] + entity = body["createBackup"] except (KeyError, TypeError): raise exc.HTTPBadRequest(_("Malformed request body")) @@ -232,7 +233,7 @@ class Admin_actions(extensions.ExtensionDescriptor): raise exc.HTTPBadRequest(explanation=msg) # preserve link to server in image properties - server_ref = os.path.join(req.application_url, 'servers', instance_id) + server_ref = os.path.join(req.application_url, 'servers', id) props = {'instance_ref': server_ref} metadata = entity.get('metadata', {}) @@ -244,7 +245,7 @@ class Admin_actions(extensions.ExtensionDescriptor): raise exc.HTTPBadRequest(explanation=msg) try: - instance = self.compute_api.get(context, instance_id) + instance = self.compute_api.get(context, id) except exception.NotFound: raise exc.HTTPNotFound(_("Instance not found")) @@ -263,29 +264,21 @@ class Admin_actions(extensions.ExtensionDescriptor): resp.headers['Location'] = image_ref return resp - def get_actions(self): - actions = [ - #TODO(bcwaldon): These actions should be prefixed with 'os-' - extensions.ActionExtension("servers", "pause", self._pause), - extensions.ActionExtension("servers", "unpause", self._unpause), - extensions.ActionExtension("servers", "suspend", self._suspend), - extensions.ActionExtension("servers", "resume", self._resume), - extensions.ActionExtension("servers", "migrate", self._migrate), - extensions.ActionExtension("servers", - "createBackup", - self._create_backup), - - extensions.ActionExtension("servers", - "resetNetwork", - self._reset_network), +class Admin_actions(extensions.ExtensionDescriptor): + """Enable admin-only server actions - extensions.ActionExtension("servers", - "injectNetworkInfo", - self._inject_network_info), + Actions include: pause, unpause, suspend, resume, migrate, + resetNetwork, injectNetworkInfo, lock, unlock, createBackup + """ - extensions.ActionExtension("servers", "lock", self._lock), - extensions.ActionExtension("servers", "unlock", self._unlock), - ] + name = "AdminActions" + alias = "os-admin-actions" + namespace = "http://docs.openstack.org/compute/ext/admin-actions/api/v1.1" + updated = "2011-09-20T00:00:00+00:00" + admin_only = True - return actions + def get_controller_extensions(self): + controller = AdminActionsController() + extension = extensions.ControllerExtension(self, 'servers', controller) + return [extension] diff --git a/nova/api/openstack/compute/contrib/console_output.py b/nova/api/openstack/compute/contrib/console_output.py index a27d8663b..ac578676e 100644 --- a/nova/api/openstack/compute/contrib/console_output.py +++ b/nova/api/openstack/compute/contrib/console_output.py @@ -22,35 +22,29 @@ from nova import compute from nova import exception from nova import log as logging from nova.api.openstack import extensions +from nova.api.openstack import wsgi LOG = logging.getLogger('nova.api.openstack.compute.contrib.console_output') -class Console_output(extensions.ExtensionDescriptor): - """Console log output support, with tailing ability.""" - - name = "Console_output" - alias = "os-console-output" - namespace = "http://docs.openstack.org/compute/ext/" \ - "os-console-output/api/v2" - updated = "2011-12-08T00:00:00+00:00" - - def __init__(self, ext_mgr): +class ConsoleOutputController(wsgi.Controller): + def __init__(self, *args, **kwargs): + super(ConsoleOutputController, self).__init__(*args, **kwargs) self.compute_api = compute.API() - super(Console_output, self).__init__(ext_mgr) - def get_console_output(self, input_dict, req, server_id): + @wsgi.action('os-getConsoleOutput') + def get_console_output(self, req, id, body): """Get text console output.""" context = req.environ['nova.context'] try: - instance = self.compute_api.routing_get(context, server_id) + instance = self.compute_api.routing_get(context, id) except exception.NotFound: raise webob.exc.HTTPNotFound(_('Instance not found')) try: - length = input_dict['os-getConsoleOutput'].get('length') + length = body['os-getConsoleOutput'].get('length') except (TypeError, KeyError): raise webob.exc.HTTPBadRequest(_('Malformed request body')) @@ -65,9 +59,17 @@ class Console_output(extensions.ExtensionDescriptor): return {'output': output} - def get_actions(self): - """Return the actions the extension adds, as required by contract.""" - actions = [extensions.ActionExtension("servers", "os-getConsoleOutput", - self.get_console_output)] - return actions +class Console_output(extensions.ExtensionDescriptor): + """Console log output support, with tailing ability.""" + + name = "Console_output" + alias = "os-console-output" + namespace = "http://docs.openstack.org/compute/ext/" \ + "os-console-output/api/v2" + updated = "2011-12-08T00:00:00+00:00" + + def get_controller_extensions(self): + controller = ConsoleOutputController() + extension = extensions.ControllerExtension(self, 'servers', controller) + return [extension] diff --git a/nova/api/openstack/compute/contrib/deferred_delete.py b/nova/api/openstack/compute/contrib/deferred_delete.py index 6c07e8ee6..c0164eead 100644 --- a/nova/api/openstack/compute/contrib/deferred_delete.py +++ b/nova/api/openstack/compute/contrib/deferred_delete.py @@ -19,6 +19,7 @@ import webob from nova.api.openstack import common from nova.api.openstack import extensions +from nova.api.openstack import wsgi from nova import compute from nova import exception from nova import log as logging @@ -27,24 +28,17 @@ from nova import log as logging LOG = logging.getLogger("nova.api.openstack.compute.contrib.deferred-delete") -class Deferred_delete(extensions.ExtensionDescriptor): - """Instance deferred delete""" - - name = "DeferredDelete" - alias = "os-deferred-delete" - namespace = "http://docs.openstack.org/compute/ext/" \ - "deferred-delete/api/v1.1" - updated = "2011-09-01T00:00:00+00:00" - - def __init__(self, ext_mgr): - super(Deferred_delete, self).__init__(ext_mgr) +class DeferredDeleteController(wsgi.Controller): + def __init__(self, *args, **kwargs): + super(DeferredDeleteController, self).__init__(*args, **kwargs) self.compute_api = compute.API() - def _restore(self, input_dict, req, instance_id): + @wsgi.action('restore') + def _restore(self, req, id, body): """Restore a previously deleted instance.""" context = req.environ["nova.context"] - instance = self.compute_api.get(context, instance_id) + instance = self.compute_api.get(context, id) try: self.compute_api.restore(context, instance) except exception.InstanceInvalidState as state_error: @@ -52,11 +46,12 @@ class Deferred_delete(extensions.ExtensionDescriptor): 'restore') return webob.Response(status_int=202) - def _force_delete(self, input_dict, req, instance_id): + @wsgi.action('forceDelete') + def _force_delete(self, req, id, body): """Force delete of instance before deferred cleanup.""" context = req.environ["nova.context"] - instance = self.compute_api.get(context, instance_id) + instance = self.compute_api.get(context, id) try: self.compute_api.force_delete(context, instance) except exception.InstanceInvalidState as state_error: @@ -64,13 +59,17 @@ class Deferred_delete(extensions.ExtensionDescriptor): 'forceDelete') return webob.Response(status_int=202) - def get_actions(self): - """Return the actions the extension adds, as required by contract.""" - actions = [ - extensions.ActionExtension("servers", "restore", - self._restore), - extensions.ActionExtension("servers", "forceDelete", - self._force_delete), - ] - return actions +class Deferred_delete(extensions.ExtensionDescriptor): + """Instance deferred delete""" + + name = "DeferredDelete" + alias = "os-deferred-delete" + namespace = "http://docs.openstack.org/compute/ext/" \ + "deferred-delete/api/v1.1" + updated = "2011-09-01T00:00:00+00:00" + + def get_controller_extensions(self): + controller = DeferredDeleteController() + extension = extensions.ControllerExtension(self, 'servers', controller) + return [extension] diff --git a/nova/api/openstack/compute/contrib/floating_ips.py b/nova/api/openstack/compute/contrib/floating_ips.py index a7e29d5fb..3cfbc0604 100644 --- a/nova/api/openstack/compute/contrib/floating_ips.py +++ b/nova/api/openstack/compute/contrib/floating_ips.py @@ -19,9 +19,9 @@ import webob +from nova.api.openstack import extensions from nova.api.openstack import wsgi from nova.api.openstack import xmlutil -from nova.api.openstack import extensions from nova import compute from nova import exception from nova import log as logging @@ -178,33 +178,19 @@ class FloatingIPController(object): return self.network_api.get_floating_ip(context, value)['address'] -class FloatingIPSerializer(xmlutil.XMLTemplateSerializer): - def index(self): - return FloatingIPsTemplate() - - def default(self): - return FloatingIPTemplate() - - -class Floating_ips(extensions.ExtensionDescriptor): - """Floating IPs support""" - - name = "Floating_ips" - alias = "os-floating-ips" - namespace = "http://docs.openstack.org/compute/ext/floating_ips/api/v1.1" - updated = "2011-06-16T00:00:00+00:00" - - def __init__(self, ext_mgr): +class FloatingIPActionController(wsgi.Controller): + def __init__(self, *args, **kwargs): + super(FloatingIPActionController, self).__init__(*args, **kwargs) self.compute_api = compute.API() self.network_api = network.API() - super(Floating_ips, self).__init__(ext_mgr) - def _add_floating_ip(self, input_dict, req, instance_id): + @wsgi.action('addFloatingIp') + def _add_floating_ip(self, req, id, body): """Associate floating_ip to an instance.""" context = req.environ['nova.context'] try: - address = input_dict['addFloatingIp']['address'] + address = body['addFloatingIp']['address'] except TypeError: msg = _("Missing parameter dict") raise webob.exc.HTTPBadRequest(explanation=msg) @@ -213,7 +199,7 @@ class Floating_ips(extensions.ExtensionDescriptor): raise webob.exc.HTTPBadRequest(explanation=msg) try: - instance = self.compute_api.get(context, instance_id) + instance = self.compute_api.get(context, id) self.compute_api.associate_floating_ip(context, instance, address) except exception.ApiError, e: @@ -223,12 +209,13 @@ class Floating_ips(extensions.ExtensionDescriptor): return webob.Response(status_int=202) - def _remove_floating_ip(self, input_dict, req, instance_id): + @wsgi.action('removeFloatingIp') + def _remove_floating_ip(self, req, id, body): """Dissociate floating_ip from an instance.""" context = req.environ['nova.context'] try: - address = input_dict['removeFloatingIp']['address'] + address = body['removeFloatingIp']['address'] except TypeError: msg = _("Missing parameter dict") raise webob.exc.HTTPBadRequest(explanation=msg) @@ -246,6 +233,15 @@ class Floating_ips(extensions.ExtensionDescriptor): return webob.Response(status_int=202) + +class Floating_ips(extensions.ExtensionDescriptor): + """Floating IPs support""" + + name = "Floating_ips" + alias = "os-floating-ips" + namespace = "http://docs.openstack.org/compute/ext/floating_ips/api/v1.1" + updated = "2011-06-16T00:00:00+00:00" + def get_resources(self): resources = [] @@ -256,13 +252,7 @@ class Floating_ips(extensions.ExtensionDescriptor): return resources - def get_actions(self): - """Return the actions the extension adds, as required by contract.""" - actions = [ - extensions.ActionExtension("servers", "addFloatingIp", - self._add_floating_ip), - extensions.ActionExtension("servers", "removeFloatingIp", - self._remove_floating_ip), - ] - - return actions + def get_controller_extensions(self): + controller = FloatingIPActionController() + extension = extensions.ControllerExtension(self, 'servers', controller) + return [extension] diff --git a/nova/api/openstack/compute/contrib/multinic.py b/nova/api/openstack/compute/contrib/multinic.py index 18b95e63d..eea4532df 100644 --- a/nova/api/openstack/compute/contrib/multinic.py +++ b/nova/api/openstack/compute/contrib/multinic.py @@ -19,6 +19,7 @@ import webob from webob import exc from nova.api.openstack import extensions +from nova.api.openstack import wsgi from nova import compute from nova import exception from nova import log as logging @@ -27,43 +28,11 @@ from nova import log as logging LOG = logging.getLogger("nova.api.openstack.compute.contrib.multinic") -# 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.ExtensionDescriptor): - """Multiple network support""" - - name = "Multinic" - alias = "NMN" - namespace = "http://docs.openstack.org/compute/ext/multinic/api/v1.1" - updated = "2011-06-09T00:00:00+00:00" - - def __init__(self, ext_mgr): - """Initialize the extension. - - Gets a compute.API object so we can call the back-end - add_fixed_ip() and remove_fixed_ip() methods. - """ - - super(Multinic, self).__init__(ext_mgr) +class MultinicController(wsgi.Controller): + def __init__(self, *args, **kwargs): + super(MultinicController, self).__init__(*args, **kwargs) self.compute_api = compute.API() - def get_actions(self): - """Return the actions the extension adds, as required by contract.""" - - actions = [] - - # Add the add_fixed_ip action - act = extensions.ActionExtension("servers", "addFixedIp", - self._add_fixed_ip) - actions.append(act) - - # Add the remove_fixed_ip action - act = extensions.ActionExtension("servers", "removeFixedIp", - self._remove_fixed_ip) - actions.append(act) - - return actions - def _get_instance(self, context, instance_id): try: return self.compute_api.get(context, instance_id) @@ -71,31 +40,33 @@ class Multinic(extensions.ExtensionDescriptor): msg = _("Server not found") raise exc.HTTPNotFound(msg) - def _add_fixed_ip(self, input_dict, req, id): + @wsgi.action('addFixedIp') + def _add_fixed_ip(self, req, id, body): """Adds an IP on a given network to an instance.""" # Validate the input entity - if 'networkId' not in input_dict['addFixedIp']: + if 'networkId' not in body['addFixedIp']: msg = _("Missing 'networkId' argument for addFixedIp") raise exc.HTTPUnprocessableEntity(explanation=msg) context = req.environ['nova.context'] instance = self._get_instance(context, id) - network_id = input_dict['addFixedIp']['networkId'] + network_id = body['addFixedIp']['networkId'] self.compute_api.add_fixed_ip(context, instance, network_id) return webob.Response(status_int=202) - def _remove_fixed_ip(self, input_dict, req, id): + @wsgi.action('removeFixedIp') + def _remove_fixed_ip(self, req, id, body): """Removes an IP from an instance.""" # Validate the input entity - if 'address' not in input_dict['removeFixedIp']: + if 'address' not in body['removeFixedIp']: msg = _("Missing 'address' argument for removeFixedIp") raise exc.HTTPUnprocessableEntity(explanation=msg) context = req.environ['nova.context'] instance = self._get_instance(context, id) - address = input_dict['removeFixedIp']['address'] + address = body['removeFixedIp']['address'] try: self.compute_api.remove_fixed_ip(context, instance, address) @@ -104,3 +75,19 @@ class Multinic(extensions.ExtensionDescriptor): raise exc.HTTPBadRequest() return webob.Response(status_int=202) + + +# 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.ExtensionDescriptor): + """Multiple network support""" + + name = "Multinic" + alias = "NMN" + namespace = "http://docs.openstack.org/compute/ext/multinic/api/v1.1" + updated = "2011-06-09T00:00:00+00:00" + + def get_controller_extensions(self): + controller = MultinicController() + extension = extensions.ControllerExtension(self, 'servers', controller) + return [extension] diff --git a/nova/api/openstack/compute/contrib/rescue.py b/nova/api/openstack/compute/contrib/rescue.py index 0ea77cc6a..b0d5c6f97 100644 --- a/nova/api/openstack/compute/contrib/rescue.py +++ b/nova/api/openstack/compute/contrib/rescue.py @@ -18,6 +18,7 @@ import webob from webob import exc from nova.api.openstack import extensions as exts +from nova.api.openstack import wsgi from nova import compute from nova import exception from nova import flags @@ -29,16 +30,9 @@ FLAGS = flags.FLAGS LOG = logging.getLogger("nova.api.openstack.compute.contrib.rescue") -class Rescue(exts.ExtensionDescriptor): - """Instance rescue mode""" - - name = "Rescue" - alias = "os-rescue" - namespace = "http://docs.openstack.org/compute/ext/rescue/api/v1.1" - updated = "2011-08-18T00:00:00+00:00" - - def __init__(self, ext_mgr): - super(Rescue, self).__init__(ext_mgr) +class RescueController(wsgi.Controller): + def __init__(self, *args, **kwargs): + super(RescueController, self).__init__(*args, **kwargs) self.compute_api = compute.API() def _get_instance(self, context, instance_id): @@ -48,33 +42,40 @@ class Rescue(exts.ExtensionDescriptor): msg = _("Server not found") raise exc.HTTPNotFound(msg) + @wsgi.action('rescue') @exts.wrap_errors - def _rescue(self, input_dict, req, instance_id): + def _rescue(self, req, id, body): """Rescue an instance.""" context = req.environ["nova.context"] - if input_dict['rescue'] and 'adminPass' in input_dict['rescue']: - password = input_dict['rescue']['adminPass'] + if body['rescue'] and 'adminPass' in body['rescue']: + password = body['rescue']['adminPass'] else: password = utils.generate_password(FLAGS.password_length) - instance = self._get_instance(context, instance_id) + instance = self._get_instance(context, id) self.compute_api.rescue(context, instance, rescue_password=password) return {'adminPass': password} + @wsgi.action('unrescue') @exts.wrap_errors - def _unrescue(self, input_dict, req, instance_id): + def _unrescue(self, req, id, body): """Unrescue an instance.""" context = req.environ["nova.context"] - instance = self._get_instance(context, instance_id) + instance = self._get_instance(context, id) self.compute_api.unrescue(context, instance) return webob.Response(status_int=202) - def get_actions(self): - """Return the actions the extension adds, as required by contract.""" - actions = [ - exts.ActionExtension("servers", "rescue", self._rescue), - exts.ActionExtension("servers", "unrescue", self._unrescue), - ] - return actions +class Rescue(exts.ExtensionDescriptor): + """Instance rescue mode""" + + name = "Rescue" + alias = "os-rescue" + namespace = "http://docs.openstack.org/compute/ext/rescue/api/v1.1" + updated = "2011-08-18T00:00:00+00:00" + + def get_controller_extensions(self): + controller = RescueController() + extension = exts.ControllerExtension(self, 'servers', controller) + return [extension] diff --git a/nova/api/openstack/compute/contrib/security_groups.py b/nova/api/openstack/compute/contrib/security_groups.py index f0d3dfe16..23b741145 100644 --- a/nova/api/openstack/compute/contrib/security_groups.py +++ b/nova/api/openstack/compute/contrib/security_groups.py @@ -497,23 +497,17 @@ class SecurityGroupRulesController(SecurityGroupController): return webob.Response(status_int=202) -class Security_groups(extensions.ExtensionDescriptor): - """Security group support""" - - name = "SecurityGroups" - alias = "security_groups" - namespace = "http://docs.openstack.org/compute/ext/securitygroups/api/v1.1" - updated = "2011-07-21T00:00:00+00:00" - - def __init__(self, ext_mgr): +class SecurityGroupActionController(wsgi.Controller): + def __init__(self, *args, **kwargs): + super(SecurityGroupActionController, self).__init__(*args, **kwargs) self.compute_api = compute.API() - super(Security_groups, self).__init__(ext_mgr) - def _addSecurityGroup(self, input_dict, req, instance_id): + @wsgi.action('addSecurityGroup') + def _addSecurityGroup(self, req, id, body): context = req.environ['nova.context'] try: - body = input_dict['addSecurityGroup'] + body = body['addSecurityGroup'] group_name = body['name'] except TypeError: msg = _("Missing parameter dict") @@ -527,7 +521,7 @@ class Security_groups(extensions.ExtensionDescriptor): raise webob.exc.HTTPBadRequest(explanation=msg) try: - instance = self.compute_api.get(context, instance_id) + instance = self.compute_api.get(context, id) self.compute_api.add_security_group(context, instance, group_name) except exception.SecurityGroupNotFound as exp: raise exc.HTTPNotFound(explanation=unicode(exp)) @@ -538,11 +532,12 @@ class Security_groups(extensions.ExtensionDescriptor): return webob.Response(status_int=202) - def _removeSecurityGroup(self, input_dict, req, instance_id): + @wsgi.action('removeSecurityGroup') + def _removeSecurityGroup(self, req, id, body): context = req.environ['nova.context'] try: - body = input_dict['removeSecurityGroup'] + body = body['removeSecurityGroup'] group_name = body['name'] except TypeError: msg = _("Missing parameter dict") @@ -556,7 +551,7 @@ class Security_groups(extensions.ExtensionDescriptor): raise webob.exc.HTTPBadRequest(explanation=msg) try: - instance = self.compute_api.get(context, instance_id) + instance = self.compute_api.get(context, id) self.compute_api.remove_security_group(context, instance, group_name) except exception.SecurityGroupNotFound as exp: @@ -568,15 +563,19 @@ class Security_groups(extensions.ExtensionDescriptor): return webob.Response(status_int=202) - def get_actions(self): - """Return the actions the extensions adds""" - actions = [ - extensions.ActionExtension("servers", "addSecurityGroup", - self._addSecurityGroup), - extensions.ActionExtension("servers", "removeSecurityGroup", - self._removeSecurityGroup) - ] - return actions + +class Security_groups(extensions.ExtensionDescriptor): + """Security group support""" + + name = "SecurityGroups" + alias = "security_groups" + namespace = "http://docs.openstack.org/compute/ext/securitygroups/api/v1.1" + updated = "2011-07-21T00:00:00+00:00" + + def get_controller_extensions(self): + controller = SecurityGroupActionController() + extension = extensions.ControllerExtension(self, 'servers', controller) + return [extension] def get_resources(self): resources = [] diff --git a/nova/api/openstack/extensions.py b/nova/api/openstack/extensions.py index d1eb7c000..ce37e0a34 100644 --- a/nova/api/openstack/extensions.py +++ b/nova/api/openstack/extensions.py @@ -580,9 +580,9 @@ class ExtensionsXMLSerializer(xmlutil.XMLTemplateSerializer): def wrap_errors(fn): """Ensure errors are not passed along.""" - def wrapped(*args): + def wrapped(*args, **kwargs): try: - return fn(*args) + return fn(*args, **kwargs) except Exception, e: raise webob.exc.HTTPInternalServerError() return wrapped diff --git a/nova/tests/api/openstack/compute/contrib/test_deferred_delete.py b/nova/tests/api/openstack/compute/contrib/test_deferred_delete.py index d81ae8ef9..a864aa595 100644 --- a/nova/tests/api/openstack/compute/contrib/test_deferred_delete.py +++ b/nova/tests/api/openstack/compute/contrib/test_deferred_delete.py @@ -23,11 +23,6 @@ from nova import exception from nova import test -class FakeExtensionDescriptor(object): - def register(*args, **kwargs): - pass - - class FakeRequest(object): def __init__(self, context): self.environ = {'nova.context': context} @@ -36,8 +31,7 @@ class FakeRequest(object): class DeferredDeleteExtensionTest(test.TestCase): def setUp(self): super(DeferredDeleteExtensionTest, self).setUp() - self.extension = deferred_delete.Deferred_delete( - FakeExtensionDescriptor()) + self.extension = deferred_delete.DeferredDeleteController() self.fake_input_dict = {} self.fake_uuid = 'fake_uuid' self.fake_context = 'fake_context' @@ -54,8 +48,8 @@ class DeferredDeleteExtensionTest(test.TestCase): compute.API.force_delete(self.fake_context, fake_instance) self.mox.ReplayAll() - res = self.extension._force_delete(self.fake_input_dict, - self.fake_req, self.fake_uuid) + res = self.extension._force_delete(self.fake_req, self.fake_uuid, + self.fake_input_dict) self.mox.VerifyAll() self.assertEqual(res.status_int, 202) @@ -72,8 +66,8 @@ class DeferredDeleteExtensionTest(test.TestCase): self.mox.ReplayAll() self.assertRaises(webob.exc.HTTPConflict, - self.extension._force_delete, self.fake_input_dict, - self.fake_req, self.fake_uuid) + self.extension._force_delete, self.fake_req, self.fake_uuid, + self.fake_input_dict) self.mox.VerifyAll() def test_restore(self): @@ -87,8 +81,8 @@ class DeferredDeleteExtensionTest(test.TestCase): compute.API.restore(self.fake_context, fake_instance) self.mox.ReplayAll() - res = self.extension._restore(self.fake_input_dict, - self.fake_req, self.fake_uuid) + res = self.extension._restore(self.fake_req, self.fake_uuid, + self.fake_input_dict) self.mox.VerifyAll() self.assertEqual(res.status_int, 202) @@ -105,15 +99,5 @@ class DeferredDeleteExtensionTest(test.TestCase): self.mox.ReplayAll() self.assertRaises(webob.exc.HTTPConflict, self.extension._restore, - self.fake_input_dict, self.fake_req, self.fake_uuid) + self.fake_req, self.fake_uuid, self.fake_input_dict) self.mox.VerifyAll() - - def test_get_actions(self): - result = self.extension.get_actions() - self.assertEqual(len(result), 2) - - action_and_methods = [(x.action_name, x.handler) for x in result] - self.assertIn(('restore', self.extension._restore), - action_and_methods) - self.assertIn(('forceDelete', self.extension._force_delete), - action_and_methods) diff --git a/nova/tests/api/openstack/compute/contrib/test_floating_ips.py b/nova/tests/api/openstack/compute/contrib/test_floating_ips.py index 27c980f00..a8dddf08f 100644 --- a/nova/tests/api/openstack/compute/contrib/test_floating_ips.py +++ b/nova/tests/api/openstack/compute/contrib/test_floating_ips.py @@ -107,11 +107,6 @@ def fake_instance_get(context, instance_id): "project_id": '123'} -class StubExtensionManager(object): - def register(self, *args): - pass - - class FloatingIpTest(test.TestCase): floating_ip = "10.10.10.10" @@ -151,7 +146,7 @@ class FloatingIpTest(test.TestCase): self._create_floating_ip() self.controller = floating_ips.FloatingIPController() - self.manager = floating_ips.Floating_ips(StubExtensionManager()) + self.manager = floating_ips.FloatingIPActionController() def tearDown(self): self._delete_floating_ip() @@ -264,13 +259,13 @@ class FloatingIpTest(test.TestCase): body = dict(addFloatingIp=dict(address=self.floating_ip)) req = fakes.HTTPRequest.blank('/v2/fake/servers/test_inst/action') - self.manager._add_floating_ip(body, req, 'test_inst') + self.manager._add_floating_ip(req, 'test_inst', body) def test_floating_ip_disassociate(self): body = dict(removeFloatingIp=dict(address='10.10.10.10')) req = fakes.HTTPRequest.blank('/v2/fake/servers/test_inst/action') - self.manager._remove_floating_ip(body, req, 'test_inst') + self.manager._remove_floating_ip(req, 'test_inst', body) # these are a few bad param tests @@ -279,24 +274,24 @@ class FloatingIpTest(test.TestCase): req = fakes.HTTPRequest.blank('/v2/fake/servers/test_inst/action') self.assertRaises(webob.exc.HTTPBadRequest, - self.manager._add_floating_ip, body, req, - 'test_inst') + self.manager._add_floating_ip, req, 'test_inst', + body) def test_missing_dict_param_in_remove_floating_ip(self): body = dict(removeFloatingIp='11.0.0.1') req = fakes.HTTPRequest.blank('/v2/fake/servers/test_inst/action') self.assertRaises(webob.exc.HTTPBadRequest, - self.manager._remove_floating_ip, body, req, - 'test_inst') + self.manager._remove_floating_ip, req, 'test_inst', + body) def test_missing_dict_param_in_add_floating_ip(self): body = dict(addFloatingIp='11.0.0.1') req = fakes.HTTPRequest.blank('/v2/fake/servers/test_inst/action') self.assertRaises(webob.exc.HTTPBadRequest, - self.manager._add_floating_ip, body, req, - 'test_inst') + self.manager._add_floating_ip, req, 'test_inst', + body) class FloatingIpSerializerTest(test.TestCase): diff --git a/nova/tests/api/openstack/compute/contrib/test_security_groups.py b/nova/tests/api/openstack/compute/contrib/test_security_groups.py index 76e9cab3f..2acc513a9 100644 --- a/nova/tests/api/openstack/compute/contrib/test_security_groups.py +++ b/nova/tests/api/openstack/compute/contrib/test_security_groups.py @@ -105,17 +105,12 @@ def return_server_nonexistent(context, server_id): raise exception.InstanceNotFound(instance_id=server_id) -class StubExtensionManager(object): - def register(self, *args): - pass - - class TestSecurityGroups(test.TestCase): def setUp(self): super(TestSecurityGroups, self).setUp() self.controller = security_groups.SecurityGroupController() - self.manager = security_groups.Security_groups(StubExtensionManager()) + self.manager = security_groups.SecurityGroupActionController() def tearDown(self): super(TestSecurityGroups, self).tearDown() @@ -308,14 +303,14 @@ class TestSecurityGroups(test.TestCase): req = fakes.HTTPRequest.blank('/v2/fake/servers/1/action') self.assertRaises(webob.exc.HTTPNotFound, - self.manager._addSecurityGroup, body, req, '1') + self.manager._addSecurityGroup, req, '1', body) def test_associate_by_invalid_server_id(self): body = dict(addSecurityGroup=dict(name='test')) req = fakes.HTTPRequest.blank('/v2/fake/servers/invalid/action') self.assertRaises(webob.exc.HTTPNotFound, - self.manager._addSecurityGroup, body, req, 'invalid') + self.manager._addSecurityGroup, req, 'invalid', body) def test_associate_without_body(self): self.stubs.Set(nova.db, 'instance_get', return_server) @@ -323,7 +318,7 @@ class TestSecurityGroups(test.TestCase): req = fakes.HTTPRequest.blank('/v2/fake/servers/1/action') self.assertRaises(webob.exc.HTTPBadRequest, - self.manager._addSecurityGroup, body, req, '1') + self.manager._addSecurityGroup, req, '1', body) def test_associate_no_security_group_name(self): self.stubs.Set(nova.db, 'instance_get', return_server) @@ -331,7 +326,7 @@ class TestSecurityGroups(test.TestCase): req = fakes.HTTPRequest.blank('/v2/fake/servers/1/action') self.assertRaises(webob.exc.HTTPBadRequest, - self.manager._addSecurityGroup, body, req, '1') + self.manager._addSecurityGroup, req, '1', body) def test_associate_security_group_name_with_whitespaces(self): self.stubs.Set(nova.db, 'instance_get', return_server) @@ -339,7 +334,7 @@ class TestSecurityGroups(test.TestCase): req = fakes.HTTPRequest.blank('/v2/fake/servers/1/action') self.assertRaises(webob.exc.HTTPBadRequest, - self.manager._addSecurityGroup, body, req, '1') + self.manager._addSecurityGroup, req, '1', body) def test_associate_non_existing_instance(self): self.stubs.Set(nova.db, 'instance_get', return_server_nonexistent) @@ -349,7 +344,7 @@ class TestSecurityGroups(test.TestCase): req = fakes.HTTPRequest.blank('/v2/fake/servers/1/action') self.assertRaises(webob.exc.HTTPNotFound, - self.manager._addSecurityGroup, body, req, '1') + self.manager._addSecurityGroup, req, '1', body) def test_associate_non_running_instance(self): self.stubs.Set(nova.db, 'instance_get', return_non_running_server) @@ -361,7 +356,7 @@ class TestSecurityGroups(test.TestCase): req = fakes.HTTPRequest.blank('/v2/fake/servers/1/action') self.assertRaises(webob.exc.HTTPBadRequest, - self.manager._addSecurityGroup, body, req, '1') + self.manager._addSecurityGroup, req, '1', body) def test_associate_already_associated_security_group_to_instance(self): self.stubs.Set(nova.db, 'instance_get', return_server) @@ -373,7 +368,7 @@ class TestSecurityGroups(test.TestCase): req = fakes.HTTPRequest.blank('/v2/fake/servers/1/action') self.assertRaises(webob.exc.HTTPBadRequest, - self.manager._addSecurityGroup, body, req, '1') + self.manager._addSecurityGroup, req, '1', body) def test_associate(self): self.stubs.Set(nova.db, 'instance_get', return_server) @@ -390,14 +385,14 @@ class TestSecurityGroups(test.TestCase): body = dict(addSecurityGroup=dict(name="test")) req = fakes.HTTPRequest.blank('/v2/fake/servers/1/action') - self.manager._addSecurityGroup(body, req, '1') + self.manager._addSecurityGroup(req, '1', body) def test_disassociate_by_non_existing_security_group_name(self): body = dict(removeSecurityGroup=dict(name='non-existing')) req = fakes.HTTPRequest.blank('/v2/fake/servers/1/action') self.assertRaises(webob.exc.HTTPNotFound, - self.manager._removeSecurityGroup, body, req, '1') + self.manager._removeSecurityGroup, req, '1', body) def test_disassociate_by_invalid_server_id(self): self.stubs.Set(nova.db, 'security_group_get_by_name', @@ -406,8 +401,8 @@ class TestSecurityGroups(test.TestCase): req = fakes.HTTPRequest.blank('/v2/fake/servers/invalid/action') self.assertRaises(webob.exc.HTTPNotFound, - self.manager._removeSecurityGroup, body, req, - 'invalid') + self.manager._removeSecurityGroup, req, 'invalid', + body) def test_disassociate_without_body(self): self.stubs.Set(nova.db, 'instance_get', return_server) @@ -415,7 +410,7 @@ class TestSecurityGroups(test.TestCase): req = fakes.HTTPRequest.blank('/v2/fake/servers/1/action') self.assertRaises(webob.exc.HTTPBadRequest, - self.manager._removeSecurityGroup, body, req, '1') + self.manager._removeSecurityGroup, req, '1', body) def test_disassociate_no_security_group_name(self): self.stubs.Set(nova.db, 'instance_get', return_server) @@ -423,7 +418,7 @@ class TestSecurityGroups(test.TestCase): req = fakes.HTTPRequest.blank('/v2/fake/servers/1/action') self.assertRaises(webob.exc.HTTPBadRequest, - self.manager._removeSecurityGroup, body, req, '1') + self.manager._removeSecurityGroup, req, '1', body) def test_disassociate_security_group_name_with_whitespaces(self): self.stubs.Set(nova.db, 'instance_get', return_server) @@ -431,7 +426,7 @@ class TestSecurityGroups(test.TestCase): req = fakes.HTTPRequest.blank('/v2/fake/servers/1/action') self.assertRaises(webob.exc.HTTPBadRequest, - self.manager._removeSecurityGroup, body, req, '1') + self.manager._removeSecurityGroup, req, '1', body) def test_disassociate_non_existing_instance(self): self.stubs.Set(nova.db, 'instance_get', return_server_nonexistent) @@ -441,7 +436,7 @@ class TestSecurityGroups(test.TestCase): req = fakes.HTTPRequest.blank('/v2/fake/servers/1/action') self.assertRaises(webob.exc.HTTPNotFound, - self.manager._removeSecurityGroup, body, req, '1') + self.manager._removeSecurityGroup, req, '1', body) def test_disassociate_non_running_instance(self): self.stubs.Set(nova.db, 'instance_get', return_non_running_server) @@ -453,7 +448,7 @@ class TestSecurityGroups(test.TestCase): req = fakes.HTTPRequest.blank('/v2/fake/servers/1/action') self.assertRaises(webob.exc.HTTPBadRequest, - self.manager._removeSecurityGroup, body, req, '1') + self.manager._removeSecurityGroup, req, '1', body) def test_disassociate_already_associated_security_group_to_instance(self): self.stubs.Set(nova.db, 'instance_get', return_server) @@ -465,7 +460,7 @@ class TestSecurityGroups(test.TestCase): req = fakes.HTTPRequest.blank('/v2/fake/servers/1/action') self.assertRaises(webob.exc.HTTPBadRequest, - self.manager._removeSecurityGroup, body, req, '1') + self.manager._removeSecurityGroup, req, '1', body) def test_disassociate(self): self.stubs.Set(nova.db, 'instance_get', return_server) @@ -482,7 +477,7 @@ class TestSecurityGroups(test.TestCase): body = dict(removeSecurityGroup=dict(name="test")) req = fakes.HTTPRequest.blank('/v2/fake/servers/1/action') - self.manager._removeSecurityGroup(body, req, '1') + self.manager._removeSecurityGroup(req, '1', body) class TestSecurityGroupRules(test.TestCase): |
