Merge "Add docstring for rbac_rule_validation is_authorized"
diff --git a/patrole_tempest_plugin/tests/api/volume/rbac_base.py b/patrole_tempest_plugin/tests/api/volume/rbac_base.py
index 1d390b7..953a834 100644
--- a/patrole_tempest_plugin/tests/api/volume/rbac_base.py
+++ b/patrole_tempest_plugin/tests/api/volume/rbac_base.py
@@ -47,6 +47,8 @@
}
cls.volume_hosts_client, cls.volume_types_client = \
version_checker[cls._api_version]
+ cls.groups_client = cls.os_primary.groups_v3_client
+ cls.group_types_client = cls.os_primary.group_types_v3_client
@classmethod
def resource_setup(cls):
@@ -56,6 +58,8 @@
@classmethod
def resource_cleanup(cls):
super(BaseVolumeRbacTest, cls).resource_cleanup()
+ # Allow volumes to be cleared first, so only clear volume types
+ # after super's resource_cleanup.
cls.clear_volume_types()
@classmethod
@@ -64,15 +68,33 @@
name = name or data_utils.rand_name(cls.__name__ + '-volume-type')
volume_type = cls.volume_types_client.create_volume_type(
name=name, **kwargs)['volume_type']
- cls.volume_types.append(volume_type['id'])
+ cls.volume_types.append(volume_type)
return volume_type
+ def create_group_type(self, name=None, ignore_notfound=False, **kwargs):
+ """Create a test group-type"""
+ name = name or data_utils.rand_name(
+ self.__class__.__name__ + '-group-type')
+ group_type = self.group_types_client.create_group_type(
+ name=name, **kwargs)['group_type']
+
+ if ignore_notfound:
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.group_types_client.delete_group_type,
+ group_type['id'])
+ else:
+ self.addCleanup(self.group_types_client.delete_group_type,
+ group_type['id'])
+
+ return group_type
+
@classmethod
def clear_volume_types(cls):
for vol_type in cls.volume_types:
test_utils.call_and_ignore_notfound_exc(
- cls.volume_types_client.delete_volume_type, vol_type)
+ cls.volume_types_client.delete_volume_type, vol_type['id'])
for vol_type in cls.volume_types:
test_utils.call_and_ignore_notfound_exc(
- cls.volume_types_client.wait_for_resource_deletion, vol_type)
+ cls.volume_types_client.wait_for_resource_deletion,
+ vol_type['id'])
diff --git a/patrole_tempest_plugin/tests/api/volume/test_groups_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_groups_rbac.py
new file mode 100644
index 0000000..6b07aaa
--- /dev/null
+++ b/patrole_tempest_plugin/tests/api/volume/test_groups_rbac.py
@@ -0,0 +1,143 @@
+# Copyright 2017 AT&T Corporation.
+# 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 tempest.common import waiters
+from tempest.lib.common.utils import data_utils
+from tempest.lib.common.utils import test_utils
+from tempest.lib import decorators
+
+from patrole_tempest_plugin import rbac_exceptions
+from patrole_tempest_plugin import rbac_rule_validation
+from patrole_tempest_plugin.tests.api.volume import rbac_base
+
+
+class GroupsV3RbacTest(rbac_base.BaseVolumeRbacTest):
+ _api_version = 3
+ min_microversion = '3.14'
+ max_microversion = 'latest'
+
+ def setUp(self):
+ super(GroupsV3RbacTest, self).setUp()
+ self.volume_type_id = self.create_volume_type()['id']
+ self.group_type_id = self.create_group_type()['id']
+
+ def _create_group(self, name=None, ignore_notfound=False, **kwargs):
+ group_name = name or data_utils.rand_name(
+ self.__class__.__name__ + '-Group')
+ group = self.groups_client.create_group(name=group_name, **kwargs)[
+ 'group']
+ waiters.wait_for_volume_resource_status(
+ self.groups_client, group['id'], 'available')
+
+ if ignore_notfound:
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self._delete_group, group['id'])
+ else:
+ self.addCleanup(self._delete_group, group['id'])
+
+ return group
+
+ def _delete_group(self, group_id, delete_volumes=True):
+ self.groups_client.delete_group(group_id, delete_volumes)
+ self.groups_client.wait_for_resource_deletion(group_id)
+
+ @decorators.idempotent_id('43235328-66ae-424f-bc7f-f709c0ca268c')
+ @rbac_rule_validation.action(
+ service="cinder",
+ rule="group:create")
+ def test_create_group(self):
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self._create_group(ignore_notfound=True,
+ group_type=self.group_type_id,
+ volume_types=[self.volume_type_id])
+
+ @decorators.idempotent_id('9dc34a62-ae3e-439e-92b6-9389ea4c2863')
+ @rbac_rule_validation.action(
+ service="cinder",
+ rule="group:get")
+ def test_show_group(self):
+ group = self._create_group(group_type=self.group_type_id,
+ volume_types=[self.volume_type_id])
+
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.groups_client.show_group(group['id'])
+
+ @decorators.idempotent_id('db43841b-a173-4317-acfc-f83e4e48e4ee')
+ @rbac_rule_validation.action(
+ service="cinder",
+ rule="group:get_all")
+ def test_list_groups(self):
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.groups_client.list_groups()['groups']
+
+ @decorators.idempotent_id('5378da93-9c26-4ad4-b039-0555e2b8f668')
+ @rbac_rule_validation.action(
+ service="cinder",
+ rule="group:get_all")
+ def test_list_groups_with_details(self):
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.groups_client.list_groups(detail=True)['groups']
+
+ @decorators.idempotent_id('66fda391-5774-42a9-a018-80b34e57ab76')
+ @rbac_rule_validation.action(
+ service="cinder",
+ rule="group:delete")
+ def test_delete_group(self):
+ group = self._create_group(ignore_notfound=True,
+ group_type=self.group_type_id,
+ volume_types=[self.volume_type_id])
+
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.groups_client.delete_group(group['id'])
+
+
+class GroupTypesV3RbacTest(rbac_base.BaseVolumeRbacTest):
+ _api_version = 3
+ min_microversion = '3.11'
+ max_microversion = 'latest'
+
+ @decorators.idempotent_id('2820f12c-4681-4c7f-b28d-e6925637dff6')
+ @rbac_rule_validation.action(
+ service="cinder",
+ rule="group:group_types_manage")
+ def test_create_group_type(self):
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.create_group_type(ignore_notfound=True)
+
+ @decorators.idempotent_id('a5f88c26-df7c-4f21-a3ae-7a4c2d6212b4')
+ @rbac_rule_validation.action(
+ service="cinder",
+ rule="group:access_group_types_specs")
+ def test_create_group_type_group_specs(self):
+ # TODO(felipemonteiro): Combine with ``test_create_group_type``
+ # once multiple policy testing is supported. This policy is
+ # only enforced after "group:group_types_manage".
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ group_type = self.create_group_type(ignore_notfound=True)
+
+ if 'group_specs' not in group_type:
+ raise rbac_exceptions.RbacActionFailed(
+ 'Policy %s does not return %s in response body.' %
+ ('group:access_group_types_specs', 'group_specs'))
+
+ @decorators.idempotent_id('f77f8156-4fc9-4f02-be15-8930f748e10c')
+ @rbac_rule_validation.action(
+ service="cinder",
+ rule="group:group_types_manage")
+ def test_delete_group_type(self):
+ goup_type = self.create_group_type(ignore_notfound=True)
+
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.group_types_client.delete_group_type(goup_type['id'])
diff --git a/patrole_tempest_plugin/tests/api/volume/test_volume_actions_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_volume_actions_rbac.py
index 8bb92f4..b666a2d 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_volume_actions_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_volume_actions_rbac.py
@@ -155,10 +155,13 @@
@rbac_rule_validation.action(service="cinder",
rule="volume:retype")
def test_volume_retype(self):
- volume = self.create_volume()
vol_type = self.create_volume_type()['name']
+ volume = self.create_volume()
+
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.volumes_client.retype_volume(volume['id'], new_type=vol_type)
+ waiters.wait_for_volume_retype(
+ self.os_admin.volumes_client, volume['id'], vol_type)
@rbac_rule_validation.action(
service="cinder",
diff --git a/patrole_tempest_plugin/tests/api/volume/test_volumes_backup_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_volumes_backup_rbac.py
index dfe6495..e6944cc 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_volumes_backup_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_volumes_backup_rbac.py
@@ -57,7 +57,7 @@
@rbac_rule_validation.action(service="cinder",
rule="backup:create")
@decorators.idempotent_id('6887ec94-0bcf-4ab7-b30f-3808a4b5a2a5')
- def test_volume_backup_create(self):
+ def test_create_backup(self):
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.create_backup(volume_id=self.volume['id'])
@@ -65,7 +65,7 @@
@rbac_rule_validation.action(service="cinder",
rule="backup:get")
@decorators.idempotent_id('abd92bdd-b0fb-4dc4-9cfc-de9e968f8c8a')
- def test_volume_backup_get(self):
+ def test_show_backup(self):
backup = self.create_backup(volume_id=self.volume['id'])
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.backups_client.show_backup(backup['id'])
@@ -73,15 +73,36 @@
@rbac_rule_validation.action(service="cinder",
rule="backup:get_all")
@decorators.idempotent_id('4d18f0f0-7e01-4007-b622-dedc859b22f6')
- def test_volume_backup_list(self):
+ def test_list_backups(self):
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.backups_client.list_backups()
+ @decorators.idempotent_id('dbd69865-876f-4835-b70e-7341153fb162')
+ @rbac_rule_validation.action(service="cinder",
+ rule="backup:get_all")
+ def test_list_backups_with_details(self):
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.backups_client.list_backups(detail=True)
+
+ @decorators.idempotent_id('50f43bde-205e-438e-9a05-5eac07fc3d63')
+ @rbac_rule_validation.action(
+ service="cinder",
+ rule="volume_extension:backup_admin_actions:reset_status")
+ def test_reset_backup_status(self):
+ volume = self.create_volume()
+ backup = self.create_backup(volume_id=volume['id'])
+
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.backups_client.reset_backup_status(backup_id=backup['id'],
+ status='error')
+ waiters.wait_for_volume_resource_status(self.os_admin.backups_client,
+ backup['id'], 'error')
+
@test.attr(type=["slow"])
@rbac_rule_validation.action(service="cinder",
rule="backup:restore")
@decorators.idempotent_id('9c794bf9-2446-4f41-8fe0-80b71e757f9d')
- def test_volume_backup_restore(self):
+ def test_restore_backup(self):
backup = self.create_backup(volume_id=self.volume['id'])
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
restore = self.backups_client.restore_backup(backup['id'])['restore']
@@ -92,7 +113,7 @@
@rbac_rule_validation.action(service="cinder",
rule="backup:delete")
@decorators.idempotent_id('d5d0c6a2-413d-437e-a73f-4bf2b41a20ed')
- def test_volume_backup_delete(self):
+ def test_delete_backup(self):
# Do not call the create_backup in Tempest's base volume class, because
# it doesn't use ``test_utils.call_and_ignore_notfound_exc`` for clean
# up.
@@ -112,7 +133,7 @@
@rbac_rule_validation.action(service="cinder",
rule="backup:backup-export")
@decorators.idempotent_id('e984ec8d-e8eb-485c-98bc-f1856020303c')
- def test_volume_backup_export(self):
+ def test_export_backup(self):
backup = self.create_backup(volume_id=self.volume['id'])
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.backups_client.export_backup(backup['id'])['backup-record']
@@ -121,7 +142,7 @@
@rbac_rule_validation.action(service="cinder",
rule="backup:backup-import")
@decorators.idempotent_id('1e70f039-4556-44cc-9cc1-edf2b7ed648b')
- def test_volume_backup_import(self):
+ def test_import_backup(self):
backup = self.create_backup(volume_id=self.volume['id'])
export_backup = self.backups_client.export_backup(
backup['id'])['backup-record']
diff --git a/releasenotes/notes/more-volume-backup-tests-c3f10aa245df2a4b.yaml b/releasenotes/notes/more-volume-backup-tests-c3f10aa245df2a4b.yaml
new file mode 100644
index 0000000..8d71130
--- /dev/null
+++ b/releasenotes/notes/more-volume-backup-tests-c3f10aa245df2a4b.yaml
@@ -0,0 +1,5 @@
+---
+features:
+ - |
+ Add additional RBAC tests to ``VolumesBackupsRbacTest``, providing coverage
+ for "volume_extension:backup_admin_actions:reset_status".
diff --git a/releasenotes/notes/volume-v3-groups-rbac-tests-60bddf6fa509545d.yaml b/releasenotes/notes/volume-v3-groups-rbac-tests-60bddf6fa509545d.yaml
new file mode 100644
index 0000000..92b1123
--- /dev/null
+++ b/releasenotes/notes/volume-v3-groups-rbac-tests-60bddf6fa509545d.yaml
@@ -0,0 +1,12 @@
+---
+features:
+ - |
+ Add RBAC tests for the volume v3 groups and group types APIs, providing
+ coverage for the following policy actions:
+
+ * group:create
+ * group:get
+ * group:get_all
+ * group:delete
+ * group:group_types_manage
+ * group:access_group_types_specs
diff --git a/requirements.txt b/requirements.txt
index 6871057..126a3dc 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -2,10 +2,10 @@
# of appearance. Changing the order has an impact on the overall integration
# process, which may cause wedges in the gate later.
hacking!=0.13.0,<0.14,>=0.12.0 # Apache-2.0
-pbr>=1.8 # Apache-2.0
-urllib3>=1.15.1 # MIT
-oslo.log>=3.11.0 # Apache-2.0
-oslo.config>=3.22.0 # Apache-2.0
-oslo.policy>=1.17.0 # Apache-2.0
-tempest>=14.0.0 # Apache-2.0
-stevedore>=1.20.0 # Apache-2.0
+pbr!=2.1.0,>=2.0.0 # Apache-2.0
+urllib3>=1.21.1 # MIT
+oslo.log>=3.22.0 # Apache-2.0
+oslo.config!=4.3.0,!=4.4.0,>=4.0.0 # Apache-2.0
+oslo.policy>=1.23.0 # Apache-2.0
+tempest>=14.0.0 # Apache-2.0
+stevedore>=1.20.0 # Apache-2.0
diff --git a/setup.py b/setup.py
index f730546..566d844 100644
--- a/setup.py
+++ b/setup.py
@@ -1,5 +1,4 @@
-# Copyright 2017 ATT Corporation.
-# All Rights Reserved.
+# Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -26,5 +25,5 @@
pass
setuptools.setup(
- setup_requires=['pbr>=1.8'],
+ setup_requires=['pbr>=2.0.0'],
pbr=True)
diff --git a/test-requirements.txt b/test-requirements.txt
index 0639513..3e03437 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -1,16 +1,16 @@
# The order of packages is significant, because pip processes them in the order
# of appearance. Changing the order has an impact on the overall integration
# process, which may cause wedges in the gate later.
-hacking>=0.12.0,!=0.13.0,<0.14 # Apache-2.0
+hacking!=0.13.0,<0.14,>=0.12.0 # Apache-2.0
-sphinx>=1.2.1,!=1.3b1,<1.4 # BSD
+sphinx>=1.6.2 # BSD
openstackdocstheme>=1.11.0 # Apache-2.0
-reno>=1.8.0 # Apache-2.0
+reno!=2.3.1,>=1.8.0 # Apache-2.0
mock>=2.0 # BSD
-coverage>=4.0 # Apache-2.0
+coverage!=4.4,>=4.0 # Apache-2.0
nose # LGPL
nosexcover # BSD
oslotest>=1.10.0 # Apache-2.0
-oslo.policy>=1.17.0 # Apache-2.0
-oslo.log>=3.11.0 # Apache-2.0
-tempest>=12.1.0 # Apache-2.0
+oslo.policy>=1.23.0 # Apache-2.0
+oslo.log>=3.22.0 # Apache-2.0
+tempest>=14.0.0 # Apache-2.0