summaryrefslogtreecommitdiffstats
path: root/nova
diff options
context:
space:
mode:
authorJosh Kearney <josh@jk0.org>2011-08-19 00:22:45 +0000
committerTarmac <>2011-08-19 00:22:45 +0000
commit862dc7acaf86bcfaebfce423c8198ea18b5e07c4 (patch)
tree996df0ff051e3e6b635a3fc5c652094ea3025868 /nova
parent3d1de2a18ef1c1a5c5d311a1e97a417faea0ab64 (diff)
parentc718702496a98cefb434b4b21c3ea22fc6c8dc2d (diff)
downloadnova-862dc7acaf86bcfaebfce423c8198ea18b5e07c4.tar.gz
nova-862dc7acaf86bcfaebfce423c8198ea18b5e07c4.tar.xz
nova-862dc7acaf86bcfaebfce423c8198ea18b5e07c4.zip
Currently, rescue/unrescue is only available over the admin API. Non-admin tenants also need to be able to access this functionality. This patch adds rescue functionality over an API extension.
Diffstat (limited to 'nova')
-rw-r--r--nova/api/openstack/contrib/rescue.py83
-rw-r--r--nova/tests/api/openstack/contrib/test_rescue.py55
-rw-r--r--nova/tests/api/openstack/test_extensions.py1
3 files changed, 139 insertions, 0 deletions
diff --git a/nova/api/openstack/contrib/rescue.py b/nova/api/openstack/contrib/rescue.py
new file mode 100644
index 000000000..3de128895
--- /dev/null
+++ b/nova/api/openstack/contrib/rescue.py
@@ -0,0 +1,83 @@
+# Copyright 2011 Openstack, LLC.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+"""The rescue mode extension."""
+
+import webob
+from webob import exc
+
+from nova import compute
+from nova import log as logging
+from nova.api.openstack import extensions as exts
+from nova.api.openstack import faults
+
+
+LOG = logging.getLogger("nova.api.contrib.rescue")
+
+
+def wrap_errors(fn):
+ """"Ensure errors are not passed along."""
+ def wrapped(*args):
+ try:
+ fn(*args)
+ except Exception, e:
+ return faults.Fault(exc.HTTPInternalServerError())
+ return wrapped
+
+
+class Rescue(exts.ExtensionDescriptor):
+ """The Rescue controller for the OpenStack API."""
+ def __init__(self):
+ super(Rescue, self).__init__()
+ self.compute_api = compute.API()
+
+ @wrap_errors
+ def _rescue(self, input_dict, req, instance_id):
+ """Rescue an instance."""
+ context = req.environ["nova.context"]
+ self.compute_api.rescue(context, instance_id)
+
+ return webob.Response(status_int=202)
+
+ @wrap_errors
+ def _unrescue(self, input_dict, req, instance_id):
+ """Unrescue an instance."""
+ context = req.environ["nova.context"]
+ self.compute_api.unrescue(context, instance_id)
+
+ return webob.Response(status_int=202)
+
+ def get_name(self):
+ return "Rescue"
+
+ def get_alias(self):
+ return "os-rescue"
+
+ def get_description(self):
+ return "Instance rescue mode"
+
+ def get_namespace(self):
+ return "http://docs.openstack.org/ext/rescue/api/v1.1"
+
+ def get_updated(self):
+ return "2011-08-18T00:00:00+00:00"
+
+ 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
diff --git a/nova/tests/api/openstack/contrib/test_rescue.py b/nova/tests/api/openstack/contrib/test_rescue.py
new file mode 100644
index 000000000..fc8e4be4e
--- /dev/null
+++ b/nova/tests/api/openstack/contrib/test_rescue.py
@@ -0,0 +1,55 @@
+# Copyright 2011 OpenStack LLC.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import json
+import webob
+
+from nova import compute
+from nova import test
+from nova.tests.api.openstack import fakes
+
+
+def rescue(self, context, instance_id):
+ pass
+
+
+def unrescue(self, context, instance_id):
+ pass
+
+
+class RescueTest(test.TestCase):
+ def setUp(self):
+ super(RescueTest, self).setUp()
+ self.stubs.Set(compute.api.API, "rescue", rescue)
+ self.stubs.Set(compute.api.API, "unrescue", unrescue)
+
+ def test_rescue(self):
+ body = dict(rescue=None)
+ req = webob.Request.blank('/v1.1/servers/test_inst/action')
+ req.method = "POST"
+ req.body = json.dumps(body)
+ req.headers["content-type"] = "application/json"
+
+ resp = req.get_response(fakes.wsgi_app())
+ self.assertEqual(resp.status_int, 200)
+
+ def test_unrescue(self):
+ body = dict(unrescue=None)
+ req = webob.Request.blank('/v1.1/servers/test_inst/action')
+ req.method = "POST"
+ req.body = json.dumps(body)
+ req.headers["content-type"] = "application/json"
+
+ resp = req.get_response(fakes.wsgi_app())
+ self.assertEqual(resp.status_int, 200)
diff --git a/nova/tests/api/openstack/test_extensions.py b/nova/tests/api/openstack/test_extensions.py
index 5d3208e10..34a4b3f89 100644
--- a/nova/tests/api/openstack/test_extensions.py
+++ b/nova/tests/api/openstack/test_extensions.py
@@ -94,6 +94,7 @@ class ExtensionControllerTest(test.TestCase):
"Quotas",
"SecurityGroups",
"Volumes",
+ "Rescue",
]
self.ext_list.sort()