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
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')
_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."""
"""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()
"""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(
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):
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']))
name='new_type',
description='new_type_desc',
is_public=True,
- extra_specs={},
id=42,
)
self.assertDictMatch(output['volume_type'], expected_volume_type)
name='new_type',
description='new_type_desc',
is_public=True,
- extra_specs={},
id=42 + i
)
self.assertDictMatch(output['volume_types'][i],
"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",