Merge "Add policy check for type show and type list"
This commit is contained in:
commit
fdb5083b22
|
@ -27,6 +27,7 @@ from cinder.api.openstack import wsgi
|
||||||
from cinder.api.v2.views import types as views_types
|
from cinder.api.v2.views import types as views_types
|
||||||
from cinder import exception
|
from cinder import exception
|
||||||
from cinder.i18n import _
|
from cinder.i18n import _
|
||||||
|
from cinder.policies import volume_type as type_policy
|
||||||
from cinder import utils
|
from cinder import utils
|
||||||
from cinder.volume import volume_types
|
from cinder.volume import volume_types
|
||||||
|
|
||||||
|
@ -40,7 +41,10 @@ class VolumeTypesController(wsgi.Controller):
|
||||||
|
|
||||||
def index(self, req):
|
def index(self, req):
|
||||||
"""Returns the list of volume types."""
|
"""Returns the list of volume types."""
|
||||||
|
context = req.environ['cinder.context']
|
||||||
|
context.authorize(type_policy.GET_ALL_POLICY)
|
||||||
limited_types = self._get_volume_types(req)
|
limited_types = self._get_volume_types(req)
|
||||||
|
|
||||||
req.cache_resource(limited_types, name='types')
|
req.cache_resource(limited_types, name='types')
|
||||||
return self._view_builder.index(req, limited_types)
|
return self._view_builder.index(req, limited_types)
|
||||||
|
|
||||||
|
@ -59,7 +63,7 @@ class VolumeTypesController(wsgi.Controller):
|
||||||
# Not found exception will be handled at wsgi level
|
# Not found exception will be handled at wsgi level
|
||||||
vol_type = volume_types.get_volume_type(context, id)
|
vol_type = volume_types.get_volume_type(context, id)
|
||||||
req.cache_resource(vol_type, name='types')
|
req.cache_resource(vol_type, name='types')
|
||||||
|
context.authorize(type_policy.GET_POLICY, target_obj=vol_type)
|
||||||
return self._view_builder.show(req, vol_type)
|
return self._view_builder.show(req, vol_type)
|
||||||
|
|
||||||
def _parse_is_public(self, is_public):
|
def _parse_is_public(self, is_public):
|
||||||
|
|
|
@ -22,6 +22,8 @@ MANAGE_POLICY = "volume_extension:types_manage"
|
||||||
ENCRYPTION_POLICY = "volume_extension:volume_type_encryption"
|
ENCRYPTION_POLICY = "volume_extension:volume_type_encryption"
|
||||||
QOS_POLICY = "volume_extension:access_types_qos_specs_id"
|
QOS_POLICY = "volume_extension:access_types_qos_specs_id"
|
||||||
EXTRA_SPEC_POLICY = "volume_extension:access_types_extra_specs"
|
EXTRA_SPEC_POLICY = "volume_extension:access_types_extra_specs"
|
||||||
|
GET_POLICY = "volume_extension:type_get"
|
||||||
|
GET_ALL_POLICY = "volume_extension:type_get_all"
|
||||||
|
|
||||||
volume_type_policies = [
|
volume_type_policies = [
|
||||||
policy.DocumentedRuleDefault(
|
policy.DocumentedRuleDefault(
|
||||||
|
@ -42,6 +44,26 @@ volume_type_policies = [
|
||||||
'path': '/types'
|
'path': '/types'
|
||||||
}
|
}
|
||||||
]),
|
]),
|
||||||
|
policy.DocumentedRuleDefault(
|
||||||
|
name=GET_POLICY,
|
||||||
|
check_str="",
|
||||||
|
description="Get one specific volume type.",
|
||||||
|
operations=[
|
||||||
|
{
|
||||||
|
'method': 'GET',
|
||||||
|
'path': '/types/{type_id}'
|
||||||
|
}
|
||||||
|
]),
|
||||||
|
policy.DocumentedRuleDefault(
|
||||||
|
name=GET_ALL_POLICY,
|
||||||
|
check_str="",
|
||||||
|
description="List volume types.",
|
||||||
|
operations=[
|
||||||
|
{
|
||||||
|
'method': 'GET',
|
||||||
|
'path': '/types/'
|
||||||
|
}
|
||||||
|
]),
|
||||||
policy.DocumentedRuleDefault(
|
policy.DocumentedRuleDefault(
|
||||||
name=ENCRYPTION_POLICY,
|
name=ENCRYPTION_POLICY,
|
||||||
check_str=base.RULE_ADMIN_API,
|
check_str=base.RULE_ADMIN_API,
|
||||||
|
|
|
@ -24,6 +24,7 @@ from cinder.api.v2 import types
|
||||||
from cinder.api.v2.views import types as views_types
|
from cinder.api.v2.views import types as views_types
|
||||||
from cinder import context
|
from cinder import context
|
||||||
from cinder import exception
|
from cinder import exception
|
||||||
|
from cinder.policies import volume_type as type_policy
|
||||||
from cinder import test
|
from cinder import test
|
||||||
from cinder.tests.unit.api import fakes
|
from cinder.tests.unit.api import fakes
|
||||||
from cinder.tests.unit import fake_constants as fake
|
from cinder.tests.unit import fake_constants as fake
|
||||||
|
@ -91,6 +92,8 @@ class VolumeTypesApiTest(test.TestCase):
|
||||||
self.ctxt = context.RequestContext(user_id=fake.USER_ID,
|
self.ctxt = context.RequestContext(user_id=fake.USER_ID,
|
||||||
project_id=fake.PROJECT_ID,
|
project_id=fake.PROJECT_ID,
|
||||||
is_admin=True)
|
is_admin=True)
|
||||||
|
self.mock_authorize = self.patch(
|
||||||
|
'cinder.context.RequestContext.authorize')
|
||||||
self.type_id1 = self._create_volume_type('volume_type1',
|
self.type_id1 = self._create_volume_type('volume_type1',
|
||||||
{'key1': 'value1'})
|
{'key1': 'value1'})
|
||||||
self.type_id2 = self._create_volume_type('volume_type2',
|
self.type_id2 = self._create_volume_type('volume_type2',
|
||||||
|
@ -114,6 +117,7 @@ class VolumeTypesApiTest(test.TestCase):
|
||||||
self.assertEqual(set(expected_names), set(actual_names))
|
self.assertEqual(set(expected_names), set(actual_names))
|
||||||
for entry in res_dict['volume_types']:
|
for entry in res_dict['volume_types']:
|
||||||
self.assertEqual('value1', entry['extra_specs']['key1'])
|
self.assertEqual('value1', entry['extra_specs']['key1'])
|
||||||
|
self.mock_authorize.assert_any_call(type_policy.GET_ALL_POLICY)
|
||||||
|
|
||||||
def test_volume_types_index_no_data(self):
|
def test_volume_types_index_no_data(self):
|
||||||
self.mock_object(volume_types, 'get_all_types',
|
self.mock_object(volume_types, 'get_all_types',
|
||||||
|
@ -242,6 +246,8 @@ class VolumeTypesApiTest(test.TestCase):
|
||||||
self.assertEqual(type_id, res_dict['volume_type']['id'])
|
self.assertEqual(type_id, res_dict['volume_type']['id'])
|
||||||
type_name = 'vol_type_' + type_id
|
type_name = 'vol_type_' + type_id
|
||||||
self.assertEqual(type_name, res_dict['volume_type']['name'])
|
self.assertEqual(type_name, res_dict['volume_type']['name'])
|
||||||
|
self.mock_authorize.assert_any_call(
|
||||||
|
type_policy.GET_POLICY, target_obj=mock.ANY)
|
||||||
|
|
||||||
def test_volume_types_show_not_found(self):
|
def test_volume_types_show_not_found(self):
|
||||||
self.mock_object(volume_types, 'get_volume_type',
|
self.mock_object(volume_types, 'get_volume_type',
|
||||||
|
@ -275,7 +281,7 @@ class VolumeTypesApiTest(test.TestCase):
|
||||||
|
|
||||||
def test_view_builder_show(self):
|
def test_view_builder_show(self):
|
||||||
view_builder = views_types.ViewBuilder()
|
view_builder = views_types.ViewBuilder()
|
||||||
|
self.mock_authorize.return_value = False
|
||||||
now = timeutils.utcnow().isoformat()
|
now = timeutils.utcnow().isoformat()
|
||||||
raw_volume_type = dict(
|
raw_volume_type = dict(
|
||||||
name='new_type',
|
name='new_type',
|
||||||
|
@ -304,7 +310,7 @@ class VolumeTypesApiTest(test.TestCase):
|
||||||
|
|
||||||
def test_view_builder_show_admin(self):
|
def test_view_builder_show_admin(self):
|
||||||
view_builder = views_types.ViewBuilder()
|
view_builder = views_types.ViewBuilder()
|
||||||
|
self.mock_authorize.return_value = True
|
||||||
now = timeutils.utcnow().isoformat()
|
now = timeutils.utcnow().isoformat()
|
||||||
raw_volume_type = dict(
|
raw_volume_type = dict(
|
||||||
name='new_type',
|
name='new_type',
|
||||||
|
@ -458,7 +464,7 @@ class VolumeTypesApiTest(test.TestCase):
|
||||||
|
|
||||||
def test_view_builder_list(self):
|
def test_view_builder_list(self):
|
||||||
view_builder = views_types.ViewBuilder()
|
view_builder = views_types.ViewBuilder()
|
||||||
|
self.mock_authorize.return_value = False
|
||||||
now = timeutils.utcnow().isoformat()
|
now = timeutils.utcnow().isoformat()
|
||||||
raw_volume_types = []
|
raw_volume_types = []
|
||||||
for i in range(0, 10):
|
for i in range(0, 10):
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
fixes:
|
||||||
|
- Two new policies "volume_extension:type_get" and
|
||||||
|
"volume_extension:type_get_all" have been added to
|
||||||
|
control type show and type list APIs.
|
Loading…
Reference in New Issue