diff options
| author | Jenkins <jenkins@review.openstack.org> | 2012-04-30 21:18:34 +0000 |
|---|---|---|
| committer | Gerrit Code Review <review@openstack.org> | 2012-04-30 21:18:34 +0000 |
| commit | 89be02810fd02497beaf8541b35345c31c03bde0 (patch) | |
| tree | b697eda53fbb64e203c42f7abfdfcf53884a739d /nova/api | |
| parent | 62bcf379597c15606fca6a0255dc731a048a5029 (diff) | |
| parent | 15c0847341b2a182019c865ec787c129fb21dae6 (diff) | |
| download | nova-89be02810fd02497beaf8541b35345c31c03bde0.tar.gz nova-89be02810fd02497beaf8541b35345c31c03bde0.tar.xz nova-89be02810fd02497beaf8541b35345c31c03bde0.zip | |
Merge "Port types and extra specs to volume api"
Diffstat (limited to 'nova/api')
| -rw-r--r-- | nova/api/openstack/compute/contrib/volumetypes.py | 27 | ||||
| -rw-r--r-- | nova/api/openstack/volume/contrib/types_extra_specs.py | 152 | ||||
| -rw-r--r-- | nova/api/openstack/volume/contrib/types_manage.py | 91 |
3 files changed, 249 insertions, 21 deletions
diff --git a/nova/api/openstack/compute/contrib/volumetypes.py b/nova/api/openstack/compute/contrib/volumetypes.py index 16a423f80..4255ac149 100644 --- a/nova/api/openstack/compute/contrib/volumetypes.py +++ b/nova/api/openstack/compute/contrib/volumetypes.py @@ -85,8 +85,6 @@ class VolumeTypesController(object): try: volume_types.create(context, name, specs) vol_type = volume_types.get_volume_type_by_name(context, name) - except exception.QuotaError as error: - self._handle_quota_error(error) except exception.NotFound: raise exc.HTTPNotFound() @@ -171,12 +169,9 @@ class VolumeTypeExtraSpecsController(object): authorize(context) self._check_body(body) specs = body.get('extra_specs') - try: - db.volume_type_extra_specs_update_or_create(context, - vol_type_id, - specs) - except exception.QuotaError as error: - self._handle_quota_error(error) + db.volume_type_extra_specs_update_or_create(context, + vol_type_id, + specs) return body @wsgi.serializers(xml=VolumeTypeExtraSpecTemplate) @@ -190,13 +185,9 @@ class VolumeTypeExtraSpecsController(object): if len(body) > 1: expl = _('Request body contains too many items') raise exc.HTTPBadRequest(explanation=expl) - try: - db.volume_type_extra_specs_update_or_create(context, - vol_type_id, - body) - except exception.QuotaError as error: - self._handle_quota_error(error) - + db.volume_type_extra_specs_update_or_create(context, + vol_type_id, + body) return body @wsgi.serializers(xml=VolumeTypeExtraSpecTemplate) @@ -216,12 +207,6 @@ class VolumeTypeExtraSpecsController(object): authorize(context) db.volume_type_extra_specs_delete(context, vol_type_id, id) - def _handle_quota_error(self, error): - """Reraise quota errors as api-specific http exceptions.""" - if error.code == "MetadataLimitExceeded": - raise exc.HTTPBadRequest(explanation=error.message) - raise error - class Volumetypes(extensions.ExtensionDescriptor): """Volume types support""" diff --git a/nova/api/openstack/volume/contrib/types_extra_specs.py b/nova/api/openstack/volume/contrib/types_extra_specs.py new file mode 100644 index 000000000..d70e24538 --- /dev/null +++ b/nova/api/openstack/volume/contrib/types_extra_specs.py @@ -0,0 +1,152 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright (c) 2011 Zadara Storage Inc. +# Copyright (c) 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 volume types extra specs extension""" + +import webob + +from nova.api.openstack import extensions +from nova.api.openstack import wsgi +from nova.api.openstack import xmlutil +from nova import db +from nova import exception +from nova.volume import volume_types + + +authorize = extensions.extension_authorizer('volume', 'types_extra_specs') + + +class VolumeTypeExtraSpecsTemplate(xmlutil.TemplateBuilder): + def construct(self): + root = xmlutil.make_flat_dict('extra_specs', selector='extra_specs') + return xmlutil.MasterTemplate(root, 1) + + +class VolumeTypeExtraSpecTemplate(xmlutil.TemplateBuilder): + def construct(self): + tagname = xmlutil.Selector('key') + + def extraspec_sel(obj, do_raise=False): + # Have to extract the key and value for later use... + key, value = obj.items()[0] + return dict(key=key, value=value) + + root = xmlutil.TemplateElement(tagname, selector=extraspec_sel) + root.text = 'value' + return xmlutil.MasterTemplate(root, 1) + + +class VolumeTypeExtraSpecsController(object): + """ The volume type extra specs API controller for the OpenStack API """ + + def _get_extra_specs(self, context, type_id): + extra_specs = db.volume_type_extra_specs_get(context, type_id) + specs_dict = {} + for key, value in extra_specs.iteritems(): + specs_dict[key] = value + return dict(extra_specs=specs_dict) + + def _check_body(self, body): + if not body: + expl = _('No Request Body') + raise webob.exc.HTTPBadRequest(explanation=expl) + + def _check_type(self, context, type_id): + try: + volume_types.get_volume_type(context, type_id) + except exception.NotFound as ex: + raise webob.exc.HTTPNotFound(explanation=unicode(ex)) + + @wsgi.serializers(xml=VolumeTypeExtraSpecsTemplate) + def index(self, req, type_id): + """ Returns the list of extra specs for a given volume type """ + context = req.environ['nova.context'] + authorize(context) + self._check_type(context, type_id) + return self._get_extra_specs(context, type_id) + + @wsgi.serializers(xml=VolumeTypeExtraSpecsTemplate) + def create(self, req, type_id, body=None): + context = req.environ['nova.context'] + authorize(context) + self._check_type(context, type_id) + self._check_body(body) + specs = body.get('extra_specs') + if not isinstance(specs, dict): + expl = _('Malformed extra specs') + raise webob.exc.HTTPBadRequest(explanation=expl) + db.volume_type_extra_specs_update_or_create(context, + type_id, + specs) + return body + + @wsgi.serializers(xml=VolumeTypeExtraSpecTemplate) + def update(self, req, type_id, id, body=None): + context = req.environ['nova.context'] + authorize(context) + self._check_type(context, type_id) + self._check_body(body) + if not id in body: + expl = _('Request body and URI mismatch') + raise webob.exc.HTTPBadRequest(explanation=expl) + if len(body) > 1: + expl = _('Request body contains too many items') + raise webob.exc.HTTPBadRequest(explanation=expl) + db.volume_type_extra_specs_update_or_create(context, + type_id, + body) + return body + + @wsgi.serializers(xml=VolumeTypeExtraSpecTemplate) + def show(self, req, type_id, id): + """Return a single extra spec item.""" + context = req.environ['nova.context'] + authorize(context) + self._check_type(context, type_id) + specs = self._get_extra_specs(context, type_id) + if id in specs['extra_specs']: + return {id: specs['extra_specs'][id]} + else: + raise webob.exc.HTTPNotFound() + + def delete(self, req, type_id, id): + """ Deletes an existing extra spec """ + context = req.environ['nova.context'] + self._check_type(context, type_id) + authorize(context) + db.volume_type_extra_specs_delete(context, type_id, id) + return webob.Response(status_int=202) + + +class Types_extra_specs(extensions.ExtensionDescriptor): + """Types extra specs support""" + + name = "TypesExtraSpecs" + alias = "os-types-extra-specs" + namespace = "http://docs.openstack.org/volume/ext/types-extra-specs/api/v1" + updated = "2011-08-24T00:00:00+00:00" + + def get_resources(self): + resources = [] + res = extensions.ResourceExtension('extra_specs', + VolumeTypeExtraSpecsController(), + parent=dict( + member_name='type', + collection_name='types')) + resources.append(res) + + return resources diff --git a/nova/api/openstack/volume/contrib/types_manage.py b/nova/api/openstack/volume/contrib/types_manage.py new file mode 100644 index 000000000..e84f787ab --- /dev/null +++ b/nova/api/openstack/volume/contrib/types_manage.py @@ -0,0 +1,91 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright (c) 2011 Zadara Storage Inc. +# Copyright (c) 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 volume types manage extension.""" + +import webob + +from nova.api.openstack import extensions +from nova.api.openstack.volume import types +from nova.api.openstack import wsgi +from nova import exception +from nova.volume import volume_types + + +authorize = extensions.extension_authorizer('volume', 'types_manage') + + +class VolumeTypesManageController(wsgi.Controller): + """ The volume types API controller for the OpenStack API """ + + @wsgi.action("create") + @wsgi.serializers(xml=types.VolumeTypeTemplate) + def _create(self, req, body): + """Creates a new volume type.""" + context = req.environ['nova.context'] + authorize(context) + + if not body or body == "": + raise webob.exc.HTTPUnprocessableEntity() + + vol_type = body.get('volume_type', None) + if vol_type is None or vol_type == "": + raise webob.exc.HTTPUnprocessableEntity() + + name = vol_type.get('name', None) + specs = vol_type.get('extra_specs', {}) + + if name is None or name == "": + raise webob.exc.HTTPUnprocessableEntity() + + try: + volume_types.create(context, name, specs) + vol_type = volume_types.get_volume_type_by_name(context, name) + except exception.VolumeTypeExists as err: + raise webob.exc.HTTPConflict(explanation=str(err)) + except exception.NotFound: + raise webob.exc.HTTPNotFound() + + return {'volume_type': vol_type} + + @wsgi.action("delete") + def _delete(self, req, id): + """ Deletes an existing volume type """ + context = req.environ['nova.context'] + authorize(context) + + try: + vol_type = volume_types.get_volume_type(context, id) + volume_types.destroy(context, vol_type['name']) + except exception.NotFound: + raise webob.exc.HTTPNotFound() + + return webob.Response(status_int=202) + + +class Types_manage(extensions.ExtensionDescriptor): + """Types manage support""" + + name = "TypesManage" + alias = "os-types-manage" + namespace = "http://docs.openstack.org/volume/ext/types-manage/api/v1" + updated = "2011-08-24T00:00:00+00:00" + + def get_controller_extensions(self): + controller = VolumeTypesManageController() + extension = extensions.ControllerExtension(self, 'types', controller) + return [extension] |
