]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Trim volume type representation.
authorEoghan Glynn <eglynn@redhat.com>
Thu, 26 Jul 2012 16:26:55 +0000 (16:26 +0000)
committerEoghan Glynn <eglynn@redhat.com>
Thu, 26 Jul 2012 18:12:33 +0000 (19:12 +0100)
Fixes cinder aspect of LP 1027281.

Use view builder pattern to only include non-extraneous
volume type attributes in the representation.

Change-Id: I33f1b579fd6ed4ed98fa04e9148e91eca125213e

cinder/api/openstack/volume/contrib/types_manage.py
cinder/api/openstack/volume/types.py
cinder/api/openstack/volume/views/types.py [new file with mode: 0644]
cinder/tests/api/openstack/volume/test_types.py

index bb8921a0f3e30e8af71ed1994a484506e52cc3a6..a9e9fb280ff2cc4101607f789d595e28c52fa518 100644 (file)
@@ -21,6 +21,7 @@ import webob
 
 from cinder.api.openstack import extensions
 from cinder.api.openstack.volume import types
+from cinder.api.openstack.volume.views import types as views_types
 from cinder.api.openstack import wsgi
 from cinder import exception
 from cinder.volume import volume_types
@@ -32,6 +33,8 @@ authorize = extensions.extension_authorizer('volume', 'types_manage')
 class VolumeTypesManageController(wsgi.Controller):
     """ The volume types API controller for the OpenStack API """
 
+    _view_builder_class = views_types.ViewBuilder
+
     @wsgi.action("create")
     @wsgi.serializers(xml=types.VolumeTypeTemplate)
     def _create(self, req, body):
@@ -60,7 +63,7 @@ class VolumeTypesManageController(wsgi.Controller):
         except exception.NotFound:
             raise webob.exc.HTTPNotFound()
 
-        return {'volume_type': vol_type}
+        return self._view_builder.show(req, vol_type)
 
     @wsgi.action("delete")
     def _delete(self, req, id):
index 8fea061902c2263dbdecf0d96a96238c7c21638e..2a9bd364a16069a9a4ff2ca880887f4b32aea2d7 100644 (file)
@@ -21,6 +21,7 @@ from webob import exc
 
 from cinder.api.openstack import wsgi
 from cinder.api.openstack import xmlutil
+from cinder.api.openstack.volume.views import types as views_types
 from cinder import exception
 from cinder.volume import volume_types
 
@@ -48,14 +49,17 @@ class VolumeTypesTemplate(xmlutil.TemplateBuilder):
         return xmlutil.MasterTemplate(root, 1)
 
 
-class VolumeTypesController(object):
+class VolumeTypesController(wsgi.Controller):
     """ The volume types API controller for the OpenStack API """
 
+    _view_builder_class = views_types.ViewBuilder
+
     @wsgi.serializers(xml=VolumeTypesTemplate)
     def index(self, req):
         """ Returns the list of volume types """
         context = req.environ['cinder.context']
-        return {'volume_types': volume_types.get_all_types(context).values()}
+        vol_types = volume_types.get_all_types(context).values()
+        return self._view_builder.index(req, vol_types)
 
     @wsgi.serializers(xml=VolumeTypeTemplate)
     def show(self, req, id):
@@ -69,7 +73,7 @@ class VolumeTypesController(object):
 
         # TODO(bcwaldon): remove str cast once we use uuids
         vol_type['id'] = str(vol_type['id'])
-        return {'volume_type': vol_type}
+        return self._view_builder.show(req, vol_type)
 
 
 def create_resource():
diff --git a/cinder/api/openstack/volume/views/types.py b/cinder/api/openstack/volume/views/types.py
new file mode 100644 (file)
index 0000000..a0c510c
--- /dev/null
@@ -0,0 +1,34 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2012 Red Hat, 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.
+
+from cinder.api.openstack import common
+
+
+class ViewBuilder(common.ViewBuilder):
+
+    def show(self, request, volume_type, brief=False):
+        """Trim away extraneous volume type attributes."""
+        trimmed = dict(id=volume_type.get('id'),
+                          name=volume_type.get('name'),
+                          extra_specs=volume_type.get('extra_specs'))
+        return trimmed if brief else dict(volume_type=trimmed)
+
+    def index(self, request, volume_types):
+        """Index over trimmed volume types"""
+        volume_types_list = [self.show(request, volume_type, True)
+                             for volume_type in volume_types]
+        return dict(volume_types=volume_types_list)
index e8d98d7de419e8d419f0a385d615533b8988e27a..72a2449daa16a389c1fcb282616d7b4e46d221ea 100644 (file)
 from lxml import etree
 import webob
 
+from cinder.api.openstack.volume.views import types as views_types
 from cinder.api.openstack.volume import types
 from cinder import exception
+from cinder.openstack.common import timeutils
 from cinder import test
 from cinder.volume import volume_types
 from cinder.tests.api.openstack import fakes
@@ -103,6 +105,52 @@ class VolumeTypesApiTest(test.TestCase):
         self.assertRaises(webob.exc.HTTPNotFound, self.controller.show,
                           req, '777')
 
+    def test_view_builder_show(self):
+        view_builder = views_types.ViewBuilder()
+
+        now = timeutils.isotime()
+        raw_volume_type = dict(name='new_type',
+                               deleted=False,
+                               created_at=now,
+                               updated_at=now,
+                               extra_specs={},
+                               deleted_at=None,
+                               id=42)
+
+        request = fakes.HTTPRequest.blank("/v2")
+        output = view_builder.show(request, raw_volume_type)
+
+        self.assertTrue('volume_type' in output)
+        expected_volume_type = dict(name='new_type',
+                                    extra_specs={},
+                                    id=42)
+        self.assertDictMatch(output['volume_type'], expected_volume_type)
+
+    def test_view_builder_list(self):
+        view_builder = views_types.ViewBuilder()
+
+        now = timeutils.isotime()
+        raw_volume_types = []
+        for i in range(0, 10):
+            raw_volume_types.append(dict(name='new_type',
+                                         deleted=False,
+                                         created_at=now,
+                                         updated_at=now,
+                                         extra_specs={},
+                                         deleted_at=None,
+                                         id=42 + i))
+
+        request = fakes.HTTPRequest.blank("/v2")
+        output = view_builder.index(request, raw_volume_types)
+
+        self.assertTrue('volume_types' in output)
+        for i in range(0, 10):
+            expected_volume_type = dict(name='new_type',
+                                        extra_specs={},
+                                        id=42 + i)
+            self.assertDictMatch(output['volume_types'][i],
+                                 expected_volume_type)
+
 
 class VolumeTypesSerializerTest(test.TestCase):
     def _verify_volume_type(self, vtype, tree):