]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Return volume_type extra specs based on policy
authorNate Potter <nathaniel.potter@intel.com>
Mon, 19 Oct 2015 16:24:29 +0000 (16:24 +0000)
committerNate Potter <nathaniel.potter@intel.com>
Thu, 29 Oct 2015 15:35:10 +0000 (15:35 +0000)
Currently extra specs are only shown to the admin user
when showing volume types. This patch grants the flexibility
to grant other users privelages to see them based on policy.

It also hides the extra_specs entry in the dictionary from
users who can't see it rather than just showing "None" as
the value.

Closes-Bug: #1504577
APIImpact

Change-Id: Ia8f71180f048ba9b253e35ee136915812ef8df0c

cinder/api/v2/types.py
cinder/api/v2/views/types.py
cinder/tests/unit/api/v2/test_types.py
etc/cinder/policy.json

index 4109ec541352b28df5b2e817cd2d35b626dce850..c6816447aa0a73e5b924bd312e1db552ffc3ae3e 100644 (file)
@@ -21,11 +21,14 @@ from webob import exc
 from cinder.api.openstack import wsgi
 from cinder.api.v2.views import types as views_types
 from cinder.api import xmlutil
+from cinder import context as ctx
 from cinder import exception
 from cinder.i18n import _
 from cinder import utils
 from cinder.volume import volume_types
 
+import cinder.policy
+
 
 def make_voltype(elem):
     elem.set('id')
@@ -57,6 +60,18 @@ class VolumeTypesController(wsgi.Controller):
 
     _view_builder_class = views_types.ViewBuilder
 
+    def _validate_policy(self, context):
+        target = {
+            'project_id': context.project_id,
+            'user_id': context.user_id,
+        }
+        try:
+            action = 'volume_extension:access_types_extra_specs'
+            cinder.policy.enforce(context, action, target)
+            return True
+        except Exception:
+            return False
+
     @wsgi.serializers(xml=VolumeTypesTemplate)
     def index(self, req):
         """Returns the list of volume types."""
@@ -69,6 +84,9 @@ class VolumeTypesController(wsgi.Controller):
         """Return a single volume type item."""
         context = req.environ['cinder.context']
 
+        if not context.is_admin and self._validate_policy(context):
+            context = ctx.get_admin_context()
+
         # get default volume type
         if id is not None and id == 'default':
             vol_type = volume_types.get_default_volume_type()
@@ -109,6 +127,8 @@ class VolumeTypesController(wsgi.Controller):
         """Helper function that returns a list of type dicts."""
         filters = {}
         context = req.environ['cinder.context']
+        if not context.is_admin and self._validate_policy(context):
+            context = ctx.get_admin_context()
         if context.is_admin:
             # Only admin has query access to all volume types
             filters['is_public'] = self._parse_is_public(
index af8a0495427f95dbac054d574f364603fbfc1259..6c93f01b9127c2939435a3ad09b475e1fb1cd3c6 100644 (file)
@@ -25,10 +25,10 @@ class ViewBuilder(common.ViewBuilder):
         trimmed = dict(id=volume_type.get('id'),
                        name=volume_type.get('name'),
                        is_public=volume_type.get('is_public'),
-                       extra_specs=volume_type.get('extra_specs'),
                        description=volume_type.get('description'))
         if context.is_admin:
             trimmed['qos_specs_id'] = volume_type.get('qos_specs_id')
+            trimmed['extra_specs'] = volume_type.get('extra_specs')
         return trimmed if brief else dict(volume_type=trimmed)
 
     def index(self, request, volume_types):
index e9287d5baa8221aee76b109e654f6815f0cebdd8..d05e28d99e6d8e7c6e2ffd6210739c672527504a 100644 (file)
@@ -85,7 +85,7 @@ class VolumeTypesApiTest(test.TestCase):
         self.stubs.Set(volume_types, 'get_all_types',
                        return_volume_types_get_all_types)
 
-        req = fakes.HTTPRequest.blank('/v2/fake/types')
+        req = fakes.HTTPRequest.blank('/v2/fake/types', use_admin_context=True)
         res_dict = self.controller.index(req)
 
         self.assertEqual(3, len(res_dict['volume_types']))
@@ -171,7 +171,6 @@ class VolumeTypesApiTest(test.TestCase):
             name='new_type',
             description='new_type_desc',
             is_public=True,
-            extra_specs={},
             id=42,
         )
         self.assertDictMatch(output['volume_type'], expected_volume_type)
@@ -237,7 +236,6 @@ class VolumeTypesApiTest(test.TestCase):
                 name='new_type',
                 description='new_type_desc',
                 is_public=True,
-                extra_specs={},
                 id=42 + i
             )
             self.assertDictMatch(output['volume_types'][i],
index 4c8a8aa5079c85fb3eea6174903e6aae080f3829..1b07629a9a8eaa6e98e567a4f9a18e4cc1ebf76b 100644 (file)
@@ -25,6 +25,7 @@
 
     "volume_extension:types_manage": "rule:admin_api",
     "volume_extension:types_extra_specs": "rule:admin_api",
+    "volume_extension:access_types_extra_specs": "rule:admin_api",
     "volume_extension:volume_type_access": "rule:admin_or_owner",
     "volume_extension:volume_type_access:addProjectAccess": "rule:admin_api",
     "volume_extension:volume_type_access:removeProjectAccess": "rule:admin_api",