summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2012-01-16 23:15:18 +0000
committerGerrit Code Review <review@openstack.org>2012-01-16 23:15:18 +0000
commit1fd26203b29d6432325ae1365e3dcbecc9d97864 (patch)
treeeb25f90688bd16d67cc6458ea841fecdde6887cb
parent7afc12b9a21abc1c99a70fd61b24d10746ed1bd2 (diff)
parent8be89626681388c3a0e8f3c94830aff7c2a4c37e (diff)
Merge "Update some extensions (1)"
-rw-r--r--nova/api/openstack/compute/contrib/admin_actions.py93
-rw-r--r--nova/api/openstack/compute/contrib/console_output.py40
-rw-r--r--nova/api/openstack/compute/contrib/deferred_delete.py47
-rw-r--r--nova/api/openstack/compute/contrib/floating_ips.py58
-rw-r--r--nova/api/openstack/compute/contrib/multinic.py69
-rw-r--r--nova/api/openstack/compute/contrib/rescue.py47
-rw-r--r--nova/api/openstack/compute/contrib/security_groups.py49
-rw-r--r--nova/api/openstack/extensions.py4
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_deferred_delete.py32
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_floating_ips.py23
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_security_groups.py45
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):