summaryrefslogtreecommitdiffstats
path: root/nova/api
diff options
context:
space:
mode:
Diffstat (limited to 'nova/api')
-rw-r--r--nova/api/openstack/contrib/admin_only.py30
-rw-r--r--nova/api/openstack/contrib/hosts.py50
2 files changed, 77 insertions, 3 deletions
diff --git a/nova/api/openstack/contrib/admin_only.py b/nova/api/openstack/contrib/admin_only.py
new file mode 100644
index 000000000..e821c9e1f
--- /dev/null
+++ b/nova/api/openstack/contrib/admin_only.py
@@ -0,0 +1,30 @@
+# Copyright (c) 2011 Openstack, LLC.
+# All Rights Reserved.
+#
+# 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.
+
+"""Decorator for limiting extensions that should be admin-only."""
+
+from functools import wraps
+from nova import flags
+FLAGS = flags.FLAGS
+
+
+def admin_only(fnc):
+ @wraps(fnc)
+ def _wrapped(self, *args, **kwargs):
+ if FLAGS.allow_admin_api:
+ return fnc(self, *args, **kwargs)
+ return []
+ _wrapped.func_name = fnc.func_name
+ return _wrapped
diff --git a/nova/api/openstack/contrib/hosts.py b/nova/api/openstack/contrib/hosts.py
index 55e57e1a4..2714d7888 100644
--- a/nova/api/openstack/contrib/hosts.py
+++ b/nova/api/openstack/contrib/hosts.py
@@ -24,6 +24,7 @@ from nova import log as logging
from nova.api.openstack import common
from nova.api.openstack import extensions
from nova.api.openstack import faults
+from nova.api.openstack.contrib import admin_only
from nova.scheduler import api as scheduler_api
@@ -70,7 +71,7 @@ class HostController(object):
key = raw_key.lower().strip()
val = raw_val.lower().strip()
# NOTE: (dabo) Right now only 'status' can be set, but other
- # actions may follow.
+ # settings may follow.
if key == "status":
if val[:6] in ("enable", "disabl"):
return self._set_enabled_status(req, id,
@@ -78,6 +79,20 @@ class HostController(object):
else:
explanation = _("Invalid status: '%s'") % raw_val
raise webob.exc.HTTPBadRequest(explanation=explanation)
+ elif key == "power_state":
+ if val == "startup":
+ # The only valid values for 'state' are 'reboot' or
+ # 'shutdown'. For completeness' sake there is the
+ # 'startup' option to start up a host, but this is not
+ # technically feasible now, as we run the host on the
+ # XenServer box.
+ msg = _("Host startup on XenServer is not supported.")
+ raise webob.exc.HTTPBadRequest(explanation=msg)
+ elif val in ("reboot", "shutdown"):
+ return self._set_powerstate(req, id, val)
+ else:
+ explanation = _("Invalid powerstate: '%s'") % raw_val
+ raise webob.exc.HTTPBadRequest(explanation=explanation)
else:
explanation = _("Invalid update setting: '%s'") % raw_key
raise webob.exc.HTTPBadRequest(explanation=explanation)
@@ -89,8 +104,34 @@ class HostController(object):
LOG.audit(_("Setting host %(host)s to %(state)s.") % locals())
result = self.compute_api.set_host_enabled(context, host=host,
enabled=enabled)
+ if result not in ("enabled", "disabled"):
+ # An error message was returned
+ raise webob.exc.HTTPBadRequest(explanation=result)
return {"host": host, "status": result}
+ def _host_power_action(self, req, host, action):
+ """Reboots or shuts down the host."""
+ context = req.environ['nova.context']
+ result = self.compute_api.host_power_action(context, host=host,
+ action=action)
+ return {"host": host, "power_action": result}
+
+ def startup(self, req, id):
+ """The only valid values for 'action' are 'reboot' or
+ 'shutdown'. For completeness' sake there is the
+ 'startup' option to start up a host, but this is not
+ technically feasible now, as we run the host on the
+ XenServer box.
+ """
+ msg = _("Host startup on XenServer is not supported.")
+ raise webob.exc.HTTPBadRequest(explanation=msg)
+
+ def shutdown(self, req, id):
+ return self._host_power_action(req, host=id, action="shutdown")
+
+ def reboot(self, req, id):
+ return self._host_power_action(req, host=id, action="reboot")
+
class Hosts(extensions.ExtensionDescriptor):
def get_name(self):
@@ -108,7 +149,10 @@ class Hosts(extensions.ExtensionDescriptor):
def get_updated(self):
return "2011-06-29T00:00:00+00:00"
+ @admin_only.admin_only
def get_resources(self):
- resources = [extensions.ResourceExtension('os-hosts', HostController(),
- collection_actions={'update': 'PUT'}, member_actions={})]
+ resources = [extensions.ResourceExtension('os-hosts',
+ HostController(), collection_actions={'update': 'PUT'},
+ member_actions={"startup": "GET", "shutdown": "GET",
+ "reboot": "GET"})]
return resources