summaryrefslogtreecommitdiffstats
path: root/nova/api
diff options
context:
space:
mode:
authorArmando Migliaccio <armando.migliaccio@eu.citrix.com>2012-01-17 18:45:53 +0000
committerArmando Migliaccio <armando.migliaccio@eu.citrix.com>2012-01-25 18:33:18 +0000
commitf84a08528a5a604dbbff7e4ae0bdcd0e4e3fc19d (patch)
tree8f6a5174908af5f6d9cd105d26c44e5fa2704dad /nova/api
parent0a617713b881780bed67902833e1b971c9179042 (diff)
downloadnova-f84a08528a5a604dbbff7e4ae0bdcd0e4e3fc19d.tar.gz
nova-f84a08528a5a604dbbff7e4ae0bdcd0e4e3fc19d.tar.xz
nova-f84a08528a5a604dbbff7e4ae0bdcd0e4e3fc19d.zip
blueprint host-aggregates: OSAPI extensions
This commit introduces the OSAPI admin extensions for host aggregates. This is part of a series of commits that have started with change: https://review.openstack.org/#change,3035 Change-Id: If0c92dca7d6f5d794f84bdb2adc172c55dec6e74
Diffstat (limited to 'nova/api')
-rw-r--r--nova/api/openstack/compute/contrib/aggregates.py223
1 files changed, 223 insertions, 0 deletions
diff --git a/nova/api/openstack/compute/contrib/aggregates.py b/nova/api/openstack/compute/contrib/aggregates.py
new file mode 100644
index 000000000..c0b0001e6
--- /dev/null
+++ b/nova/api/openstack/compute/contrib/aggregates.py
@@ -0,0 +1,223 @@
+# Copyright (c) 2012 Citrix Systems, Inc.
+# 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.
+
+"""The Aggregate admin API extension."""
+
+from webob import exc
+
+from nova.api.openstack import extensions
+from nova import compute
+from nova import exception
+from nova import log as logging
+
+
+LOG = logging.getLogger("nova.api.openstack.compute.contrib.host_aggregates")
+authorize = extensions.extension_authorizer('compute', 'aggregates')
+
+
+def _get_context(req):
+ return req.environ['nova.context']
+
+
+def get_host_from_body(fn):
+ """Makes sure that the host exists."""
+ def wrapped(self, req, id, body, *args, **kwargs):
+ if len(body) == 1 and "host" in body:
+ host = body['host']
+ else:
+ raise exc.HTTPBadRequest
+ return fn(self, req, id, host, *args, **kwargs)
+ return wrapped
+
+
+class AggregateController(object):
+ """The Host Aggregates API controller for the OpenStack API."""
+ def __init__(self):
+ self.api = compute.AggregateAPI()
+
+ def index(self, req):
+ """Returns a list a host aggregate's id, name, availability_zone."""
+ context = _get_context(req)
+ authorize(context)
+ aggregates = self.api.get_aggregate_list(context)
+ return {'aggregates': aggregates}
+
+ def create(self, req, body):
+ """Creates an aggregate, given its name and availablity_zone."""
+ context = _get_context(req)
+ authorize(context)
+
+ if len(body) != 1:
+ raise exc.HTTPBadRequest
+ try:
+ host_aggregate = body["aggregate"]
+ aggregate_name = host_aggregate["name"]
+ availability_zone = host_aggregate["availability_zone"]
+ except KeyError:
+ raise exc.HTTPBadRequest
+ if len(host_aggregate) != 2:
+ raise exc.HTTPBadRequest
+
+ try:
+ aggregate = self.api.create_aggregate(context, aggregate_name,
+ availability_zone)
+ except exception.AggregateNameExists:
+ raise exc.HTTPConflict
+ return self._marshall_aggregate(aggregate)
+
+ def show(self, req, id):
+ """Shows the details of an aggregate, hosts and metadata included."""
+ context = _get_context(req)
+ authorize(context)
+ try:
+ aggregate = self.api.get_aggregate(context, id)
+ except exception.AggregateNotFound:
+ raise exc.HTTPNotFound
+ return self._marshall_aggregate(aggregate)
+
+ def update(self, req, id, body):
+ """Updates the name and/or availbility_zone of given aggregate."""
+ context = _get_context(req)
+ authorize(context)
+ aggregate = id
+
+ if len(body) != 1:
+ raise exc.HTTPBadRequest
+ try:
+ updates = body["aggregate"]
+ except KeyError:
+ raise exc.HTTPBadRequest
+
+ if len(updates) < 1:
+ raise exc.HTTPBadRequest
+
+ for key in updates.keys():
+ if not key in ["name", "availability_zone"]:
+ raise exc.HTTPBadRequest
+
+ try:
+ aggregate = self.api.update_aggregate(context, aggregate, updates)
+ except exception.AggregateNotFound:
+ raise exc.HTTPNotFound
+
+ return self._marshall_aggregate(aggregate)
+
+ def delete(self, req, id):
+ """Removes an aggregate by id."""
+ context = _get_context(req)
+ authorize(context)
+ aggregate_id = id
+ try:
+ self.api.delete_aggregate(context, aggregate_id)
+ except exception.AggregateNotFound:
+ raise exc.HTTPNotFound
+
+ def action(self, req, id, body):
+ _actions = {
+ 'add_host': self._add_host,
+ 'remove_host': self._remove_host,
+ 'set_metadata': self._set_metadata,
+ }
+ for action, data in body.iteritems():
+ try:
+ return _actions[action](req, id, data)
+ except KeyError:
+ msg = _("Aggregates does not have %s action") % action
+ raise exc.HTTPBadRequest(explanation=msg)
+
+ raise exc.HTTPBadRequest(explanation=_("Invalid request body"))
+
+ @get_host_from_body
+ def _add_host(self, req, id, host):
+ """Adds a host to the specified aggregate."""
+ context = _get_context(req)
+ authorize(context)
+ aggregate = id
+ try:
+ aggregate = self.api.add_host_to_aggregate(context,
+ aggregate, host)
+ except exception.AggregateNotFound:
+ raise exc.HTTPNotFound
+ except exception.ComputeHostNotFound:
+ raise exc.HTTPNotFound
+ except exception.AggregateHostConflict:
+ raise exc.HTTPConflict
+ except exception.AggregateHostExists:
+ raise exc.HTTPConflict
+ except exception.InvalidAggregateAction:
+ raise exc.HTTPConflict
+ return self._marshall_aggregate(aggregate)
+
+ @get_host_from_body
+ def _remove_host(self, req, id, host):
+ """Removes a host from the specified aggregate."""
+ context = _get_context(req)
+ authorize(context)
+ aggregate = id
+ try:
+ aggregate = self.api.remove_host_from_aggregate(context,
+ aggregate, host)
+ except exception.AggregateNotFound:
+ raise exc.HTTPNotFound
+ except exception.AggregateHostNotFound:
+ raise exc.HTTPNotFound
+ except exception.InvalidAggregateAction:
+ raise exc.HTTPConflict
+ return self._marshall_aggregate(aggregate)
+
+ def _set_metadata(self, req, id, body):
+ """Replaces the aggregate's existing metadata with new metadata."""
+ context = _get_context(req)
+ authorize(context)
+ aggregate = id
+
+ if len(body) != 1:
+ raise exc.HTTPBadRequest
+
+ try:
+ metadata = body["metadata"]
+ except KeyError:
+ raise exc.HTTPBadRequest
+
+ try:
+ aggregate = self.api.update_aggregate_metadata(context,
+ aggregate, metadata)
+ except exception.AggregateNotFound:
+ raise exc.HTTPNotFound
+
+ return self._marshall_aggregate(aggregate)
+
+ def _marshall_aggregate(self, aggregate):
+ return {"aggregate": aggregate}
+
+
+class Aggregates(extensions.ExtensionDescriptor):
+ """Admin-only aggregate administration"""
+
+ name = "Aggregates"
+ alias = "os-aggregates"
+ namespace = "http://docs.openstack.org/compute/ext/aggregates/api/v1.1"
+ updated = "2012-01-12T00:00:00+00:00"
+
+ def __init__(self, ext_mgr):
+ ext_mgr.register(self)
+
+ def get_resources(self):
+ resources = []
+ res = extensions.ResourceExtension('os-aggregates',
+ AggregateController(),
+ member_actions={"action": "POST", })
+ resources.append(res)
+ return resources