summaryrefslogtreecommitdiffstats
path: root/nova/api
diff options
context:
space:
mode:
authorMatt Dietz <matt.dietz@rackspace.com>2011-11-08 14:12:46 -0600
committerMatt Dietz <matt.dietz@rackspace.com>2011-11-08 14:13:21 -0600
commit0973f558561173bdc84d7f4f8eb33da9fedafac2 (patch)
treed91112fcffa384bb925e0e7d34389bafae77cbaf /nova/api
parent1c389d0bd8e9c9f21f760f9b8f5b79baffd38d39 (diff)
downloadnova-0973f558561173bdc84d7f4f8eb33da9fedafac2.tar.gz
nova-0973f558561173bdc84d7f4f8eb33da9fedafac2.tar.xz
nova-0973f558561173bdc84d7f4f8eb33da9fedafac2.zip
Adds extended status information via the Admin API to the servers calls
Change-Id: I294e64e878f1f6ebf33b83198abb2cdd8b6c5185
Diffstat (limited to 'nova/api')
-rw-r--r--nova/api/openstack/contrib/extended_status.py110
-rw-r--r--nova/api/openstack/wsgi.py2
2 files changed, 111 insertions, 1 deletions
diff --git a/nova/api/openstack/contrib/extended_status.py b/nova/api/openstack/contrib/extended_status.py
new file mode 100644
index 000000000..625f3ab2b
--- /dev/null
+++ b/nova/api/openstack/contrib/extended_status.py
@@ -0,0 +1,110 @@
+# 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 Extended Status Admin API extension."""
+
+import traceback
+
+import webob
+from webob import exc
+
+from nova import compute
+from nova import exception
+from nova import flags
+from nova import log as logging
+from nova.api.openstack import extensions
+from nova.api.openstack import faults
+from nova.api.openstack import xmlutil
+
+
+FLAGS = flags.FLAGS
+LOG = logging.getLogger("nova.api.openstack.contrib.extendedstatus")
+
+
+class Extended_status(extensions.ExtensionDescriptor):
+ """Extended Status support"""
+
+ name = "ExtendedStatus"
+ alias = "OS-EXT-STS"
+ namespace = "http://docs.openstack.org/ext/extended_status/api/v1.1"
+ updated = "2011-11-03T00:00:00+00:00"
+
+ def get_request_extensions(self):
+ request_extensions = []
+
+ def _get_and_extend_one(context, server_id, body):
+ compute_api = compute.API()
+ try:
+ inst_ref = compute_api.routing_get(context, server_id)
+ except exception.NotFound:
+ explanation = _("Server not found.")
+ raise exc.HTTPNotFound(explanation=explanation)
+
+ for state in ['task_state', 'vm_state', 'power_state']:
+ key = "%s:%s" % (Extended_status.alias, state)
+ body['server'][key] = inst_ref[state]
+
+ def _get_and_extend_all(context, body):
+ # TODO(mdietz): This is a brilliant argument for this to *not*
+ # be an extension. The problem is we either have to 1) duplicate
+ # the logic from the servers controller or 2) do what we did
+ # and iterate over the list of potentially sorted, limited
+ # and whatever else elements and find each individual.
+ compute_api = compute.API()
+
+ for server in body['servers']:
+ try:
+ inst_ref = compute_api.routing_get(context, server['id'])
+ except exception.NotFound:
+ explanation = _("Server not found.")
+ raise exc.HTTPNotFound(explanation=explanation)
+
+ for state in ['task_state', 'vm_state', 'power_state']:
+ key = "%s:%s" % (Extended_status.alias, state)
+ server[key] = inst_ref[state]
+
+ def _extended_status_handler(req, res, body):
+ context = req.environ['nova.context']
+ server_id = req.environ['wsgiorg.routing_args'][1].get('id')
+
+ if 'nova.template' in req.environ:
+ tmpl = req.environ['nova.template']
+ tmpl.attach(ExtendedStatusTemplate())
+
+ if server_id:
+ _get_and_extend_one(context, server_id, body)
+ else:
+ _get_and_extend_all(context, body)
+ return res
+
+ if FLAGS.allow_admin_api:
+ req_ext = extensions.RequestExtension('GET',
+ '/:(project_id)/servers/:(id)',
+ _extended_status_handler)
+ request_extensions.append(req_ext)
+
+ return request_extensions
+
+
+class ExtendedStatusTemplate(xmlutil.TemplateBuilder):
+ def construct(self):
+ root = xmlutil.TemplateElement('server')
+ root.set('{%s}task_state' % Extended_status.namespace,
+ '%s:task_state' % Extended_status.alias)
+ root.set('{%s}power_state' % Extended_status.namespace,
+ '%s:power_state' % Extended_status.alias)
+ root.set('{%s}vm_state' % Extended_status.namespace,
+ '%s:vm_state' % Extended_status.alias)
+ return xmlutil.SlaveTemplate(root, 1, nsmap={
+ Extended_status.alias: Extended_status.namespace})
diff --git a/nova/api/openstack/wsgi.py b/nova/api/openstack/wsgi.py
index f96a12eab..7deba6382 100644
--- a/nova/api/openstack/wsgi.py
+++ b/nova/api/openstack/wsgi.py
@@ -477,6 +477,7 @@ class ResponseSerializer(object):
request.environ['nova.action'] = action
if (hasattr(serializer, 'get_template') and
'nova.template' not in request.environ):
+
template = serializer.get_template(action)
request.environ['nova.template'] = template
else:
@@ -512,7 +513,6 @@ class LazySerializationMiddleware(wsgi.Middleware):
# Re-serialize the body
response.body = serializer.serialize(utils.loads(response.body),
**kwargs)
-
return response