Merge "Move tests from volumes into volumes actions."
diff --git a/contrib/post_test_hook.sh b/contrib/post_test_hook.sh
index db48fc2..af7c856 100644
--- a/contrib/post_test_hook.sh
+++ b/contrib/post_test_hook.sh
@@ -61,9 +61,7 @@
# Set strict_policy_check=False under [rbac] section in tempest.conf
iniset $TEMPEST_CONFIG rbac strict_policy_check False
# Set additional, necessary CONF values
- iniset $TEMPEST_CONFIG auth use_dynamic_credentials True
iniset $TEMPEST_CONFIG auth tempest_roles Member
- iniset $TEMPEST_CONFIG identity auth_version v3
}
function run_tests() {
diff --git a/patrole_tempest_plugin/rbac_rule_validation.py b/patrole_tempest_plugin/rbac_rule_validation.py
index 6a5ed5e..a225c7d 100644
--- a/patrole_tempest_plugin/rbac_rule_validation.py
+++ b/patrole_tempest_plugin/rbac_rule_validation.py
@@ -29,7 +29,7 @@
LOG = logging.getLogger(__name__)
-def action(service, rule, admin_only=False, expected_error_code=403,
+def action(service, rule='', admin_only=False, expected_error_code=403,
extra_target_data={}):
"""A decorator which does a policy check and matches it against test run.
diff --git a/patrole_tempest_plugin/rbac_utils.py b/patrole_tempest_plugin/rbac_utils.py
index d952014..55a5599 100644
--- a/patrole_tempest_plugin/rbac_utils.py
+++ b/patrole_tempest_plugin/rbac_utils.py
@@ -20,6 +20,7 @@
import oslo_utils.uuidutils as uuid_utils
import six
+from tempest.common import credentials_factory as credentials
from tempest import config
from patrole_tempest_plugin import rbac_exceptions
@@ -56,10 +57,12 @@
self.token = test_obj.auth_provider.get_token()
self.identity_version = test_obj.get_identity_version()
- if self.identity_version.endswith('v3'):
- self.roles_client = test_obj.os_admin.roles_v3_client
- else:
- self.roles_client = test_obj.os_admin.roles_client
+ if not credentials.is_admin_available(
+ identity_version=self.identity_version):
+ msg = "Missing Identity Admin API credentials in configuration."
+ raise rbac_exceptions.RbacResourceSetupFailed(msg)
+
+ self.roles_client = test_obj.os_admin.roles_v3_client
LOG.debug('Switching role to: %s', toggle_rbac_role)
diff --git a/patrole_tempest_plugin/tests/api/compute/rbac_base.py b/patrole_tempest_plugin/tests/api/compute/rbac_base.py
index b2f830e..bc02dbf 100644
--- a/patrole_tempest_plugin/tests/api/compute/rbac_base.py
+++ b/patrole_tempest_plugin/tests/api/compute/rbac_base.py
@@ -35,7 +35,7 @@
@classmethod
def setup_clients(cls):
super(BaseV2ComputeRbacTest, cls).setup_clients()
- cls.auth_provider = cls.os.auth_provider
+ cls.auth_provider = cls.os_primary.auth_provider
cls.rbac_utils = rbac_utils()
cls.rbac_utils.switch_role(cls, toggle_rbac_role=False)
diff --git a/patrole_tempest_plugin/tests/api/compute/test_aggregates_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_aggregates_rbac.py
index a180bc4..db504c0 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_aggregates_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_aggregates_rbac.py
@@ -13,30 +13,28 @@
# License for the specific language governing permissions and limitations
# under the License.
-from tempest import config
from tempest.lib.common.utils import data_utils
from tempest.lib.common.utils import test_utils
from tempest.lib import decorators
+from tempest import test
from patrole_tempest_plugin import rbac_rule_validation
from patrole_tempest_plugin.tests.api.compute import rbac_base
-CONF = config.CONF
-
class AggregatesRbacTest(rbac_base.BaseV2ComputeRbacTest):
@classmethod
def skip_checks(cls):
super(AggregatesRbacTest, cls).skip_checks()
- if not CONF.compute_feature_enabled.api_extensions:
- raise cls.skipException(
- '%s skipped as no compute extensions enabled' % cls.__name__)
+ if not test.is_extension_enabled('os-aggregates', 'compute'):
+ msg = "%s skipped as os-aggregates not enabled." % cls.__name__
+ raise cls.skipException(msg)
@classmethod
def setup_clients(cls):
super(AggregatesRbacTest, cls).setup_clients()
- cls.hosts_client = cls.os.hosts_client
+ cls.hosts_client = cls.os_primary.hosts_client
def _create_aggregate(self):
agg_name = data_utils.rand_name('aggregate')
diff --git a/patrole_tempest_plugin/tests/api/compute/test_attach_interfaces_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_attach_interfaces_rbac.py
index 7241c98..90b60c9 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_attach_interfaces_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_attach_interfaces_rbac.py
@@ -17,6 +17,7 @@
from tempest import config
from tempest.lib.common.utils import test_utils
from tempest.lib import decorators
+from tempest import test
from patrole_tempest_plugin import rbac_rule_validation
from patrole_tempest_plugin.tests.api.compute import rbac_base
@@ -34,9 +35,10 @@
@classmethod
def skip_checks(cls):
super(AttachInterfacesRbacTest, cls).skip_checks()
- if not CONF.compute_feature_enabled.api_extensions:
- raise cls.skipException(
- '%s skipped as no compute extensions enabled' % cls.__name__)
+ if not test.is_extension_enabled('os-attach-interfaces', 'compute'):
+ msg = ("%s skipped as os-attach-interfaces not "
+ "enabled." % cls.__name__)
+ raise cls.skipException(msg)
if not CONF.compute_feature_enabled.interface_attach:
raise cls.skipException(
"%s skipped as interface attachment is not available"
diff --git a/patrole_tempest_plugin/tests/api/compute/test_availability_zone_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_availability_zone_rbac.py
index c466ad2..0743d7c 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_availability_zone_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_availability_zone_rbac.py
@@ -11,34 +11,38 @@
# License for the specific language governing permissions and limitations
# under the License.
-from tempest import config
from tempest.lib import decorators
+from tempest import test
from patrole_tempest_plugin import rbac_rule_validation
from patrole_tempest_plugin.tests.api.compute import rbac_base
-CONF = config.CONF
-
class NovaAvailabilityZoneRbacTest(rbac_base.BaseV2ComputeRbacTest):
@classmethod
def skip_checks(cls):
super(NovaAvailabilityZoneRbacTest, cls).skip_checks()
- if not CONF.compute_feature_enabled.api_extensions:
- raise cls.skipException(
- '%s skipped as no compute extensions enabled' % cls.__name__)
+ if not test.is_extension_enabled('os-availability-zone', 'compute'):
+ msg = ("%s skipped as os-availability-zone not "
+ "enabled." % cls.__name__)
+ raise cls.skipException(msg)
+
+ @classmethod
+ def setup_clients(cls):
+ super(NovaAvailabilityZoneRbacTest, cls).setup_clients()
+ cls.client = cls.availability_zone_client
@rbac_rule_validation.action(service="nova", rule="os_compute_api:"
"os-availability-zone:list")
@decorators.idempotent_id('cd34e7ea-d26e-4fa3-a8d0-f8883726ce3d')
def test_get_availability_zone_list_rbac(self):
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- self.os.availability_zone_client.list_availability_zones()
+ self.client.list_availability_zones()
@rbac_rule_validation.action(service="nova", rule="os_compute_api:"
"os-availability-zone:detail")
@decorators.idempotent_id('2f61c191-6ece-4f21-b487-39d749e3d38e')
def test_get_availability_zone_list_detail_rbac(self):
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- self.os.availability_zone_client.list_availability_zones(detail=True)
+ self.client.list_availability_zones(detail=True)
diff --git a/patrole_tempest_plugin/tests/api/compute/test_floating_ip_pools_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_floating_ip_pools_rbac.py
index 6d78878..755bacd 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_floating_ip_pools_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_floating_ip_pools_rbac.py
@@ -33,7 +33,7 @@
@classmethod
def setup_clients(cls):
super(FloatingIpPoolsRbacTest, cls).setup_clients()
- cls.client = cls.os.floating_ip_pools_client
+ cls.client = cls.os_primary.floating_ip_pools_client
@classmethod
def skip_checks(cls):
diff --git a/patrole_tempest_plugin/tests/api/compute/test_floating_ips_bulk_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_floating_ips_bulk_rbac.py
index ab9d551..7fe4847 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_floating_ips_bulk_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_floating_ips_bulk_rbac.py
@@ -33,7 +33,7 @@
@classmethod
def setup_clients(cls):
super(FloatingIpsBulkRbacTest, cls).setup_clients()
- cls.client = cls.os.floating_ips_bulk_client
+ cls.client = cls.os_primary.floating_ips_bulk_client
@classmethod
def skip_checks(cls):
diff --git a/patrole_tempest_plugin/tests/api/compute/test_hosts_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_hosts_rbac.py
index 53e3a70..0b7f2d1 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_hosts_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_hosts_rbac.py
@@ -13,28 +13,26 @@
# License for the specific language governing permissions and limitations
# under the License.
-from tempest import config
from tempest.lib import decorators
+from tempest import test
from patrole_tempest_plugin import rbac_rule_validation
from patrole_tempest_plugin.tests.api.compute import rbac_base
-CONF = config.CONF
-
class HostsRbacTest(rbac_base.BaseV2ComputeRbacTest):
@classmethod
def setup_clients(cls):
super(HostsRbacTest, cls).setup_clients()
- cls.client = cls.os.hosts_client
+ cls.client = cls.os_primary.hosts_client
@classmethod
def skip_checks(cls):
super(HostsRbacTest, cls).skip_checks()
- if not CONF.compute_feature_enabled.api_extensions:
- raise cls.skipException(
- '%s skipped as no compute extensions enabled' % cls.__name__)
+ if not test.is_extension_enabled('os-hosts', 'compute'):
+ msg = "%s skipped as os-hosts not enabled." % cls.__name__
+ raise cls.skipException(msg)
@decorators.idempotent_id('035b7935-2fae-4218-8d37-27fa83097494')
@rbac_rule_validation.action(
diff --git a/patrole_tempest_plugin/tests/api/compute/test_images_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_images_rbac.py
index 3a4f2d6..b848509 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_images_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_images_rbac.py
@@ -48,7 +48,7 @@
def setup_clients(cls):
super(ImagesV235RbacTest, cls).setup_clients()
cls.client = cls.compute_images_client
- cls.glance_image_client = cls.os.image_client_v2
+ cls.glance_image_client = cls.os_primary.image_client_v2
@classmethod
def resource_setup(cls):
diff --git a/patrole_tempest_plugin/tests/api/compute/test_ips_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_ips_rbac.py
index 96fa243..600cfbe 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_ips_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_ips_rbac.py
@@ -15,6 +15,7 @@
from tempest import config
from tempest.lib import decorators
+from tempest import test
from patrole_tempest_plugin import rbac_rule_validation
from patrole_tempest_plugin.tests.api.compute import rbac_base
@@ -32,9 +33,9 @@
@classmethod
def skip_checks(cls):
super(IpsRbacTest, cls).skip_checks()
- if not CONF.compute_feature_enabled.api_extensions:
- raise cls.skipException(
- '%s skipped as no compute extensions enabled' % cls.__name__)
+ if not test.is_extension_enabled('os-ips', 'compute'):
+ msg = "%s skipped as os-ips not enabled." % cls.__name__
+ raise cls.skipException(msg)
if not CONF.service_available.neutron:
raise cls.skipException(
'%s skipped as Neutron is required' % cls.__name__)
diff --git a/patrole_tempest_plugin/tests/api/compute/test_limits_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_limits_rbac.py
index eb0e686..f16a635 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_limits_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_limits_rbac.py
@@ -11,14 +11,12 @@
# License for the specific language governing permissions and limitations
# under the License.
-from tempest import config
from tempest.lib import decorators
+from tempest import test
from patrole_tempest_plugin import rbac_rule_validation
from patrole_tempest_plugin.tests.api.compute import rbac_base
-CONF = config.CONF
-
class LimitsRbacTest(rbac_base.BaseV2ComputeRbacTest):
@@ -30,9 +28,9 @@
@classmethod
def skip_checks(cls):
super(LimitsRbacTest, cls).skip_checks()
- if not CONF.compute_feature_enabled.api_extensions:
- raise cls.skipException(
- '%s skipped as no compute extensions enabled' % cls.__name__)
+ if not test.is_extension_enabled('os-limits', 'compute'):
+ msg = "%s skipped as os-limits not enabled." % cls.__name__
+ raise cls.skipException(msg)
@rbac_rule_validation.action(service="nova",
rule="os_compute_api:limits")
diff --git a/patrole_tempest_plugin/tests/api/compute/test_migrations_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_migrations_rbac.py
index fda9071..b6c6c5f 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_migrations_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_migrations_rbac.py
@@ -13,14 +13,12 @@
# License for the specific language governing permissions and limitations
# under the License.
-from tempest import config
from tempest.lib import decorators
+from tempest import test
from patrole_tempest_plugin import rbac_rule_validation
from patrole_tempest_plugin.tests.api.compute import rbac_base
-CONF = config.CONF
-
class MigrationsRbacTest(rbac_base.BaseV2ComputeRbacTest):
@@ -32,9 +30,9 @@
@classmethod
def skip_checks(cls):
super(MigrationsRbacTest, cls).skip_checks()
- if not CONF.compute_feature_enabled.api_extensions:
- raise cls.skipException(
- '%s skipped as no compute extensions enabled' % cls.__name__)
+ if not test.is_extension_enabled('os-migrations', 'compute'):
+ msg = "%s skipped as os-migrations not enabled." % cls.__name__
+ raise cls.skipException(msg)
@decorators.idempotent_id('5795231c-3729-448c-a072-9a225db1a328')
@rbac_rule_validation.action(
diff --git a/patrole_tempest_plugin/tests/api/compute/test_quota_sets_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_quota_sets_rbac.py
index 826ae8d..f6706a7 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_quota_sets_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_quota_sets_rbac.py
@@ -28,7 +28,7 @@
def setup_clients(cls):
super(QuotaSetsRbacTest, cls).setup_clients()
cls.client = cls.quotas_client
- cls.projects_client = cls.os.projects_client
+ cls.projects_client = cls.os_primary.projects_client
@classmethod
def skip_checks(cls):
diff --git a/patrole_tempest_plugin/tests/api/compute/test_rescue_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_rescue_rbac.py
index acf9bd6..277ba1b 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_rescue_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_rescue_rbac.py
@@ -13,14 +13,12 @@
# License for the specific language governing permissions and limitations
# under the License.
-from tempest import config
from tempest.lib import decorators
+from tempest import test
from patrole_tempest_plugin import rbac_rule_validation
from patrole_tempest_plugin.tests.api.compute import rbac_base
-CONF = config.CONF
-
class RescueRbacTest(rbac_base.BaseV2ComputeRbacTest):
@@ -32,9 +30,9 @@
@classmethod
def skip_checks(cls):
super(RescueRbacTest, cls).skip_checks()
- if not CONF.compute_feature_enabled.api_extensions:
- raise cls.skipException(
- '%s skipped as no compute extensions enabled' % cls.__name__)
+ if not test.is_extension_enabled('os-rescue', 'compute'):
+ msg = "%s skipped as os-rescue not enabled." % cls.__name__
+ raise cls.skipException(msg)
@classmethod
def resource_setup(cls):
diff --git a/patrole_tempest_plugin/tests/api/compute/test_server_diagnostics_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_server_diagnostics_rbac.py
index dd810a5..2a309e3 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_server_diagnostics_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_server_diagnostics_rbac.py
@@ -13,14 +13,12 @@
# License for the specific language governing permissions and limitations
# under the License.
-from tempest import config
from tempest.lib import decorators
+from tempest import test
from patrole_tempest_plugin import rbac_rule_validation
from patrole_tempest_plugin.tests.api.compute import rbac_base
-CONF = config.CONF
-
class ServerDiagnosticsRbacTest(rbac_base.BaseV2ComputeRbacTest):
@@ -32,9 +30,10 @@
@classmethod
def skip_checks(cls):
super(ServerDiagnosticsRbacTest, cls).skip_checks()
- if not CONF.compute_feature_enabled.api_extensions:
- raise cls.skipException(
- '%s skipped as no compute extensions enabled' % cls.__name__)
+ if not test.is_extension_enabled('os-server-diagnostics', 'compute'):
+ msg = ("%s skipped as os-server-diagnostics not "
+ "enabled." % cls.__name__)
+ raise cls.skipException(msg)
@classmethod
def resource_setup(cls):
diff --git a/patrole_tempest_plugin/tests/api/compute/test_server_groups_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_server_groups_rbac.py
index b89750d..a75f550 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_server_groups_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_server_groups_rbac.py
@@ -13,14 +13,12 @@
# License for the specific language governing permissions and limitations
# under the License.
-from tempest import config
from tempest.lib import decorators
+from tempest import test
from patrole_tempest_plugin import rbac_rule_validation
from patrole_tempest_plugin.tests.api.compute import rbac_base
-CONF = config.CONF
-
class ServerGroupsRbacTest(rbac_base.BaseV2ComputeRbacTest):
@@ -32,9 +30,9 @@
@classmethod
def skip_checks(cls):
super(ServerGroupsRbacTest, cls).skip_checks()
- if not CONF.compute_feature_enabled.api_extensions:
- raise cls.skipException(
- '%s skipped as no compute extensions enabled' % cls.__name__)
+ if not test.is_extension_enabled('os-server-groups', 'compute'):
+ msg = "%s skipped as os-server-groups not enabled." % cls.__name__
+ raise cls.skipException(msg)
@classmethod
def resource_setup(cls):
diff --git a/patrole_tempest_plugin/tests/api/compute/test_server_migrations_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_server_migrations_rbac.py
index e5b1ea0..38ef552 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_server_migrations_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_server_migrations_rbac.py
@@ -43,8 +43,8 @@
def setup_clients(cls):
super(MigrateServerV225RbacTest, cls).setup_clients()
cls.client = cls.servers_client
- cls.admin_servers_client = cls.os_adm.servers_client
- cls.hosts_client = cls.os.hosts_client
+ cls.admin_servers_client = cls.os_admin.servers_client
+ cls.hosts_client = cls.os_primary.hosts_client
def _get_server_details(self, server_id):
body = self.client.show_server(server_id)['server']
diff --git a/patrole_tempest_plugin/tests/api/compute/test_server_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_server_rbac.py
index 4157c05..b71887c 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_server_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_server_rbac.py
@@ -37,8 +37,8 @@
def setup_clients(cls):
super(ComputeServersRbacTest, cls).setup_clients()
cls.client = cls.servers_client
- cls.networks_client = cls.os.networks_client
- cls.subnets_client = cls.os.subnets_client
+ cls.networks_client = cls.os_primary.networks_client
+ cls.subnets_client = cls.os_primary.subnets_client
@classmethod
def resource_setup(cls):
diff --git a/patrole_tempest_plugin/tests/api/compute/test_server_usage_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_server_usage_rbac.py
index 4493826..8f836a6 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_server_usage_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_server_usage_rbac.py
@@ -13,14 +13,12 @@
# License for the specific language governing permissions and limitations
# under the License.
-from tempest import config
from tempest.lib import decorators
+from tempest import test
from patrole_tempest_plugin import rbac_rule_validation
from patrole_tempest_plugin.tests.api.compute import rbac_base
-CONF = config.CONF
-
class ServerUsageRbacTest(rbac_base.BaseV2ComputeRbacTest):
@@ -32,9 +30,9 @@
@classmethod
def skip_checks(cls):
super(ServerUsageRbacTest, cls).skip_checks()
- if not CONF.compute_feature_enabled.api_extensions:
- raise cls.skipException(
- '%s skipped as no compute extensions enabled' % cls.__name__)
+ if not test.is_extension_enabled('OS-SRV-USG', 'compute'):
+ msg = "%s skipped as OS-SRV-USG not enabled." % cls.__name__
+ raise cls.skipException(msg)
@classmethod
def resource_setup(cls):
diff --git a/patrole_tempest_plugin/tests/api/compute/test_server_volume_attachments_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_server_volume_attachments_rbac.py
index ba33a0f..160affd 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_server_volume_attachments_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_server_volume_attachments_rbac.py
@@ -31,7 +31,7 @@
def setup_clients(cls):
super(ServerVolumeAttachmentRbacTest, cls).setup_clients()
cls.client = cls.servers_client
- cls.volumes_client = cls.os.volumes_client
+ cls.volumes_client = cls.os_primary.volumes_client
@classmethod
def skip_checks(cls):
diff --git a/patrole_tempest_plugin/tests/api/compute/test_simple_tenant_usage_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_simple_tenant_usage_rbac.py
index 93c179e..5ecc32a 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_simple_tenant_usage_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_simple_tenant_usage_rbac.py
@@ -13,28 +13,27 @@
# License for the specific language governing permissions and limitations
# under the License.
-from tempest import config
from tempest.lib import decorators
+from tempest import test
from patrole_tempest_plugin import rbac_rule_validation
from patrole_tempest_plugin.tests.api.compute import rbac_base
-CONF = config.CONF
-
class SimpleTenantUsageRbacTest(rbac_base.BaseV2ComputeRbacTest):
@classmethod
def setup_clients(cls):
super(SimpleTenantUsageRbacTest, cls).setup_clients()
- cls.client = cls.os.tenant_usages_client
+ cls.client = cls.os_primary.tenant_usages_client
@classmethod
def skip_checks(cls):
super(SimpleTenantUsageRbacTest, cls).skip_checks()
- if not CONF.compute_feature_enabled.api_extensions:
- raise cls.skipException(
- '%s skipped as no compute extensions enabled' % cls.__name__)
+ if not test.is_extension_enabled('os-simple-tenant-usage', 'compute'):
+ msg = ("%s skipped as os-simple-tenant-usage not "
+ "enabled." % cls.__name__)
+ raise cls.skipException(msg)
@rbac_rule_validation.action(
service="nova",
diff --git a/patrole_tempest_plugin/tests/api/compute/test_tenant_networks_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_tenant_networks_rbac.py
index 15a385a..fb834bd 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_tenant_networks_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_tenant_networks_rbac.py
@@ -34,7 +34,7 @@
@classmethod
def setup_clients(cls):
super(TenantNetworksRbacTest, cls).setup_clients()
- cls.client = cls.os.tenant_networks_client
+ cls.client = cls.os_primary.tenant_networks_client
@classmethod
def skip_checks(cls):
diff --git a/patrole_tempest_plugin/tests/api/identity/v2/rbac_base.py b/patrole_tempest_plugin/tests/api/identity/v2/rbac_base.py
index 5e5d918..bc07675 100644
--- a/patrole_tempest_plugin/tests/api/identity/v2/rbac_base.py
+++ b/patrole_tempest_plugin/tests/api/identity/v2/rbac_base.py
@@ -23,32 +23,42 @@
CONF = config.CONF
-class BaseIdentityV2RbacTest(base.BaseIdentityV2Test):
+class BaseIdentityV2AdminRbacTest(base.BaseIdentityV2Test):
+ """Base test class for the Identity v2 admin API.
+
+ Keystone's v2 API is split into two APIs: an admin and non-admin API. RBAC
+ testing is only provided for the admin API. Instead of policy enforcement,
+ these APIs execute ``self.assert_admin(request)``, which checks that the
+ request object has ``context_is_admin``. For more details, see the
+ implementation of ``assert_admin`` in ``keystone.common.wsgi``.
+ """
credentials = ['admin', 'primary']
@classmethod
def skip_checks(cls):
- super(BaseIdentityV2RbacTest, cls).skip_checks()
+ super(BaseIdentityV2AdminRbacTest, cls).skip_checks()
if not CONF.rbac.enable_rbac:
raise cls.skipException(
"%s skipped as RBAC testing not enabled" % cls.__name__)
+ if not CONF.identity_feature_enabled.api_v2_admin:
+ raise cls.skipException('Identity v2 admin not available')
@classmethod
def setup_clients(cls):
- super(BaseIdentityV2RbacTest, cls).setup_clients()
- cls.auth_provider = cls.os.auth_provider
+ super(BaseIdentityV2AdminRbacTest, cls).setup_clients()
+ cls.auth_provider = cls.os_primary.auth_provider
cls.rbac_utils = rbac_utils()
cls.rbac_utils.switch_role(cls, toggle_rbac_role=False)
- cls.client = cls.os.identity_client
- cls.endpoints_client = cls.os.endpoints_client
- cls.roles_client = cls.os.roles_client
- cls.services_client = cls.os.identity_services_client
- cls.tenants_client = cls.os.tenants_client
- cls.token_client = cls.os.token_client
- cls.users_client = cls.os.users_client
+ cls.client = cls.os_primary.identity_client
+ cls.endpoints_client = cls.os_primary.endpoints_client
+ cls.roles_client = cls.os_primary.roles_client
+ cls.services_client = cls.os_primary.identity_services_client
+ cls.tenants_client = cls.os_primary.tenants_client
+ cls.token_client = cls.os_primary.token_client
+ cls.users_client = cls.os_primary.users_client
def _create_service(self):
name = data_utils.rand_name('service')
diff --git a/patrole_tempest_plugin/tests/api/identity/v2/test_endpoints_rbac.py b/patrole_tempest_plugin/tests/api/identity/v2/test_endpoints_rbac.py
index b8677cf..f16d0aa 100644
--- a/patrole_tempest_plugin/tests/api/identity/v2/test_endpoints_rbac.py
+++ b/patrole_tempest_plugin/tests/api/identity/v2/test_endpoints_rbac.py
@@ -13,7 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-from tempest import config
from tempest.lib.common.utils import data_utils
from tempest.lib.common.utils import test_utils
from tempest.lib import decorators
@@ -21,19 +20,17 @@
from patrole_tempest_plugin import rbac_rule_validation
from patrole_tempest_plugin.tests.api.identity.v2 import rbac_base
-CONF = config.CONF
-
-class IdentityEndpointsV2RbacTest(rbac_base.BaseIdentityV2RbacTest):
+class IdentityEndpointsV2AdminRbacTest(rbac_base.BaseIdentityV2AdminRbacTest):
@classmethod
def setup_clients(cls):
- super(IdentityEndpointsV2RbacTest, cls).setup_clients()
- cls.endpoints_client = cls.os.endpoints_client
+ super(IdentityEndpointsV2AdminRbacTest, cls).setup_clients()
+ cls.endpoints_client = cls.os_primary.endpoints_client
@classmethod
def resource_setup(cls):
- super(IdentityEndpointsV2RbacTest, cls).resource_setup()
+ super(IdentityEndpointsV2AdminRbacTest, cls).resource_setup()
cls.region = data_utils.rand_name('region')
cls.public_url = data_utils.rand_url()
cls.admin_url = data_utils.rand_url()
@@ -54,7 +51,6 @@
return endpoint
@rbac_rule_validation.action(service="keystone",
- rule="identity:create_endpoint",
admin_only=True)
@decorators.idempotent_id('6bdaecd4-0843-4ed6-ab64-3a57ab0cd124')
def test_create_endpoint(self):
@@ -68,7 +64,6 @@
self._create_endpoint()
@rbac_rule_validation.action(service="keystone",
- rule="identity:delete_endpoint",
admin_only=True)
@decorators.idempotent_id('6bdaecd4-0843-4ed6-ab64-3a57ab0cd125')
def test_delete_endpoint(self):
@@ -83,7 +78,6 @@
self.endpoints_client.delete_endpoint(endpoint['endpoint']['id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:list_endpoints",
admin_only=True)
@decorators.idempotent_id('6bdaecd4-0843-4ed6-ab64-3a57ab0cd126')
def test_list_endpoints(self):
diff --git a/patrole_tempest_plugin/tests/api/identity/v2/test_projects_rbac.py b/patrole_tempest_plugin/tests/api/identity/v2/test_projects_rbac.py
index 6853b64..a557bb8 100644
--- a/patrole_tempest_plugin/tests/api/identity/v2/test_projects_rbac.py
+++ b/patrole_tempest_plugin/tests/api/identity/v2/test_projects_rbac.py
@@ -16,16 +16,16 @@
from tempest import config
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.identity.v2 import rbac_base
CONF = config.CONF
-class IdentityProjectV2RbacTest(rbac_base.BaseIdentityV2RbacTest):
+class IdentityProjectV2AdminRbacTest(rbac_base.BaseIdentityV2AdminRbacTest):
@rbac_rule_validation.action(service="keystone",
- rule="identity:create_project",
admin_only=True)
@decorators.idempotent_id('0f148510-63bf-11e6-b348-080044d0d904')
def test_create_project(self):
@@ -39,7 +39,6 @@
self._create_tenant()
@rbac_rule_validation.action(service="keystone",
- rule="identity:update_project",
admin_only=True)
@decorators.idempotent_id('0f148510-63bf-11e6-b348-080044d0d905')
def test_update_project(self):
@@ -55,7 +54,6 @@
description="Changed description")
@rbac_rule_validation.action(service="keystone",
- rule="identity:delete_project",
admin_only=True)
@decorators.idempotent_id('0f148510-63bf-11e6-b348-080044d0d906')
def test_delete_project(self):
@@ -70,7 +68,6 @@
self.tenants_client.delete_tenant(tenant['id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:get_project",
admin_only=True)
@decorators.idempotent_id('0f148510-63bf-11e6-b348-080044d0d907')
def test_get_project(self):
@@ -86,20 +83,6 @@
self.tenants_client.show_tenant(tenant['id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:list_projects",
- admin_only=True)
- @decorators.idempotent_id('0f148510-63bf-11e6-b348-080044d0d908')
- def test_get_all_projects(self):
-
- """List All Projects Test
-
- RBAC test for Identity 2.0 list_tenants
- """
- self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- self.tenants_client.list_tenants()
-
- @rbac_rule_validation.action(service="keystone",
- rule="identity:list_user_projects",
admin_only=True)
@decorators.idempotent_id('0f148510-63bf-11e6-b348-080044d0d909')
def test_list_project_users(self):
@@ -112,3 +95,37 @@
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.tenants_client.list_tenant_users(tenant['id'])
+
+ @rbac_rule_validation.action(service="keystone",
+ admin_only=True)
+ @decorators.idempotent_id('0f148510-63bf-11e6-b348-080044d0d908')
+ def test_list_all_projects(self):
+
+ """List All Projects Test
+
+ RBAC test for Identity 2.0 list_tenants (admin endpoint)
+
+ There are two separate APIs for listing tenants in the Keystone
+ v2 API: one for admin and one for non-admin. The ``os_admin`` client
+ calls the admin endpoint and the ``os_primary`` client calls the
+ non-admin endpoint. To ensure that the admin endpoint only returns
+ admin-scoped tenants, raise ``RbacActionFailed`` exception otherwise.
+ """
+ tenants_client = self.os_admin.tenants_client if \
+ CONF.identity.admin_role == CONF.rbac.rbac_test_role else \
+ self.os_primary.tenants_client
+ admin_tenant_id = self.os_admin.auth_provider.credentials.project_id
+ non_admin_tenant_id = self.auth_provider.credentials.project_id
+
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ tenants = tenants_client.list_tenants()['tenants']
+
+ tenant_ids = [t['id'] for t in tenants]
+ if admin_tenant_id not in tenant_ids:
+ raise rbac_exceptions.RbacActionFailed(
+ "The admin tenant id was not returned by the call to "
+ "``list_tenants``.")
+ if non_admin_tenant_id in tenant_ids:
+ raise rbac_exceptions.RbacActionFailed(
+ "The non-admin tenant id was returned by the call to "
+ "``list_tenants``.")
diff --git a/patrole_tempest_plugin/tests/api/identity/v2/test_roles_rbac.py b/patrole_tempest_plugin/tests/api/identity/v2/test_roles_rbac.py
index 9dd90e1..a1ec5c6 100644
--- a/patrole_tempest_plugin/tests/api/identity/v2/test_roles_rbac.py
+++ b/patrole_tempest_plugin/tests/api/identity/v2/test_roles_rbac.py
@@ -13,7 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-from tempest import config
from tempest.lib.common.utils import data_utils
from tempest.lib.common.utils import test_utils
from tempest.lib import decorators
@@ -21,15 +20,13 @@
from patrole_tempest_plugin import rbac_rule_validation
from patrole_tempest_plugin.tests.api.identity.v2 import rbac_base
-CONF = config.CONF
-
-class IdentityRoleV2RbacTest(rbac_base.BaseIdentityV2RbacTest):
+class IdentityRolesV2AdminRbacTest(rbac_base.BaseIdentityV2AdminRbacTest):
@classmethod
def setup_clients(cls):
- super(IdentityRoleV2RbacTest, cls).setup_clients()
- cls.roles_client = cls.os.roles_client
+ super(IdentityRolesV2AdminRbacTest, cls).setup_clients()
+ cls.roles_client = cls.os_primary.roles_client
def _create_role(self):
role = self.roles_client.create_role(
@@ -53,7 +50,6 @@
tenant['id'], user['id'], role['id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:create_role",
admin_only=True)
@decorators.idempotent_id('0f148510-63bf-11e6-8674-080044d0d904')
def test_create_role(self):
@@ -67,7 +63,6 @@
self._create_role()
@rbac_rule_validation.action(service="keystone",
- rule="identity:delete_role",
admin_only=True)
@decorators.idempotent_id('0f148510-63bf-11e6-8674-080044d0d905')
def test_delete_role(self):
@@ -82,7 +77,6 @@
self.roles_client.delete_role(role['id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:get_role",
admin_only=True)
@decorators.idempotent_id('0f148510-63bf-11e6-8674-080044d0d906')
def test_show_role(self):
@@ -97,7 +91,6 @@
self.roles_client.show_role(role['id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:list_roles",
admin_only=True)
@decorators.idempotent_id('0f148510-63bf-11e6-8674-080044d0d907')
def test_list_roles(self):
@@ -110,7 +103,6 @@
self.roles_client.list_roles()
@rbac_rule_validation.action(service="keystone",
- rule="identity:add_role_to_user",
admin_only=True)
@decorators.idempotent_id('0f148510-63bf-11e6-8674-080044d0d908')
def test_create_role_on_project(self):
@@ -124,7 +116,6 @@
self._create_role_on_project(tenant, user, role)
@rbac_rule_validation.action(service="keystone",
- rule="identity:remove_role_from_user",
admin_only=True)
@decorators.idempotent_id('0f148510-63bf-11e6-8674-080044d0d909')
def test_delete_role_from_user_on_project(self):
@@ -141,7 +132,6 @@
tenant['id'], user['id'], role['id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:get_user_roles",
admin_only=True)
@decorators.idempotent_id('0f148510-63bf-11e6-8674-080044d0d90a')
def test_list_user_roles_on_project(self):
diff --git a/patrole_tempest_plugin/tests/api/identity/v2/test_services_rbac.py b/patrole_tempest_plugin/tests/api/identity/v2/test_services_rbac.py
index a371bbc..ad47fd2 100644
--- a/patrole_tempest_plugin/tests/api/identity/v2/test_services_rbac.py
+++ b/patrole_tempest_plugin/tests/api/identity/v2/test_services_rbac.py
@@ -13,24 +13,20 @@
# License for the specific language governing permissions and limitations
# under the License.
-from tempest import config
from tempest.lib import decorators
from patrole_tempest_plugin import rbac_rule_validation
from patrole_tempest_plugin.tests.api.identity.v2 import rbac_base
-CONF = config.CONF
-
-class IdentityServicesV2RbacTest(rbac_base.BaseIdentityV2RbacTest):
+class IdentityServicesV2AdminRbacTest(rbac_base.BaseIdentityV2AdminRbacTest):
@classmethod
def setup_clients(cls):
- super(IdentityServicesV2RbacTest, cls).setup_clients()
- cls.services_client = cls.os.identity_services_client
+ super(IdentityServicesV2AdminRbacTest, cls).setup_clients()
+ cls.services_client = cls.os_primary.identity_services_client
@rbac_rule_validation.action(service="keystone",
- rule="identity:create_service",
admin_only=True)
@decorators.idempotent_id('370050f6-d271-4fb4-abc5-4de1d6dfbad2')
def test_create_service(self):
@@ -42,7 +38,6 @@
self._create_service()
@rbac_rule_validation.action(service="keystone",
- rule="identity:delete_service",
admin_only=True)
@decorators.idempotent_id('f6c64fc3-6a1f-423e-af91-e411add3a384')
def test_delete_service(self):
@@ -56,7 +51,6 @@
self.services_client.delete_service(service_id)
@rbac_rule_validation.action(service="keystone",
- rule="identity:get_service",
admin_only=True)
@decorators.idempotent_id('504d62bb-97d7-445e-9d6d-b1945a7c9e08')
def test_show_service(self):
@@ -70,7 +64,6 @@
self.services_client.show_service(service_id)
@rbac_rule_validation.action(service="keystone",
- rule="identity:list_services",
admin_only=True)
@decorators.idempotent_id('d7dc461d-51ad-48e0-9cd2-33add1b88de9')
def test_list_services(self):
diff --git a/patrole_tempest_plugin/tests/api/identity/v2/test_users_rbac.py b/patrole_tempest_plugin/tests/api/identity/v2/test_users_rbac.py
index 48f3d11..f90680d 100644
--- a/patrole_tempest_plugin/tests/api/identity/v2/test_users_rbac.py
+++ b/patrole_tempest_plugin/tests/api/identity/v2/test_users_rbac.py
@@ -20,10 +20,9 @@
from patrole_tempest_plugin.tests.api.identity.v2 import rbac_base
-class IdentityUserV2RbacTest(rbac_base.BaseIdentityV2RbacTest):
+class IdentityUsersV2AdminRbacTest(rbac_base.BaseIdentityV2AdminRbacTest):
@rbac_rule_validation.action(service="keystone",
- rule="identity:create_user",
admin_only=True)
@decorators.idempotent_id('0f148510-63bf-11e6-1342-080044d0d904')
def test_create_user(self):
@@ -31,7 +30,6 @@
self._create_user()
@rbac_rule_validation.action(service="keystone",
- rule="identity:update_user",
admin_only=True)
@decorators.idempotent_id('0f148510-63bf-11e6-1342-080044d0d905')
def test_update_user(self):
@@ -41,7 +39,6 @@
self.users_client.update_user(user['id'], email="changedUser@xyz.com")
@rbac_rule_validation.action(service="keystone",
- rule="identity:set_user_enabled",
admin_only=True)
@decorators.idempotent_id('0f148510-63bf-11e6-1342-080044d0d9a1')
def test_update_user_enabled(self):
@@ -51,7 +48,6 @@
self.users_client.update_user_enabled(user['id'], enabled=True)
@rbac_rule_validation.action(service="keystone",
- rule="identity:delete_user",
admin_only=True)
@decorators.idempotent_id('0f148510-63bf-11e6-1342-080044d0d906')
def test_delete_user(self):
@@ -61,7 +57,6 @@
self.users_client.delete_user(user['id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:get_users",
admin_only=True)
@decorators.idempotent_id('0f148510-63bf-11e6-1342-080044d0d907')
def test_list_users(self):
@@ -69,7 +64,6 @@
self.users_client.list_users()
@rbac_rule_validation.action(service="keystone",
- rule="identity:get_user",
admin_only=True)
@decorators.idempotent_id('0f148510-63bf-11e6-1342-080044d0d908')
def test_show_user(self):
@@ -79,7 +73,6 @@
self.users_client.show_user(user['id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:change_password",
admin_only=True)
@decorators.idempotent_id('0f148510-63bf-11e6-1342-080044d0d909')
def test_update_user_password(self):
diff --git a/patrole_tempest_plugin/tests/api/identity/v3/rbac_base.py b/patrole_tempest_plugin/tests/api/identity/v3/rbac_base.py
index 31533a3..927ec39 100644
--- a/patrole_tempest_plugin/tests/api/identity/v3/rbac_base.py
+++ b/patrole_tempest_plugin/tests/api/identity/v3/rbac_base.py
@@ -37,24 +37,24 @@
@classmethod
def setup_clients(cls):
super(BaseIdentityV3RbacTest, cls).setup_clients()
- cls.auth_provider = cls.os.auth_provider
+ cls.auth_provider = cls.os_primary.auth_provider
cls.rbac_utils = rbac_utils()
cls.rbac_utils.switch_role(cls, toggle_rbac_role=False)
- cls.creds_client = cls.os.credentials_client
- cls.consumers_client = cls.os.oauth_consumers_client
- cls.domains_client = cls.os.domains_client
- cls.endpoints_client = cls.os.endpoints_v3_client
- cls.groups_client = cls.os.groups_client
- cls.projects_client = cls.os.projects_client
- cls.policies_client = cls.os.policies_client
- cls.regions_client = cls.os.regions_client
- cls.role_assignments_client = cls.os.role_assignments_client
- cls.roles_client = cls.os.roles_v3_client
- cls.services_client = cls.os.identity_services_v3_client
- cls.trusts_client = cls.os.trusts_client
- cls.users_client = cls.os.users_v3_client
+ cls.creds_client = cls.os_primary.credentials_client
+ cls.consumers_client = cls.os_primary.oauth_consumers_client
+ cls.domains_client = cls.os_primary.domains_client
+ cls.endpoints_client = cls.os_primary.endpoints_v3_client
+ cls.groups_client = cls.os_primary.groups_client
+ cls.projects_client = cls.os_primary.projects_client
+ cls.policies_client = cls.os_primary.policies_client
+ cls.regions_client = cls.os_primary.regions_client
+ cls.role_assignments_client = cls.os_primary.role_assignments_client
+ cls.roles_client = cls.os_primary.roles_v3_client
+ cls.services_client = cls.os_primary.identity_services_v3_client
+ cls.trusts_client = cls.os_primary.trusts_client
+ cls.users_client = cls.os_primary.users_v3_client
@classmethod
def resource_setup(cls):
diff --git a/patrole_tempest_plugin/tests/api/identity/v3/test_endpoint_filter_rbac.py b/patrole_tempest_plugin/tests/api/identity/v3/test_endpoint_filter_rbac.py
new file mode 100644
index 0000000..77ad647
--- /dev/null
+++ b/patrole_tempest_plugin/tests/api/identity/v3/test_endpoint_filter_rbac.py
@@ -0,0 +1,91 @@
+# 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.lib.common.utils import test_utils
+from tempest.lib import decorators
+
+from patrole_tempest_plugin import rbac_rule_validation
+from patrole_tempest_plugin.tests.api.identity.v3 import rbac_base
+
+
+class IdentityEndpointsFilterV3RbacTest(
+ rbac_base.BaseIdentityV3RbacTest):
+
+ @classmethod
+ def setup_clients(cls):
+ super(IdentityEndpointsFilterV3RbacTest, cls).setup_clients()
+ cls.ep_api_client = cls.os_primary.endpoint_filter_client
+
+ @classmethod
+ def resource_setup(cls):
+ super(IdentityEndpointsFilterV3RbacTest, cls).resource_setup()
+ cls.project = cls.setup_test_project()
+ cls.service = cls.setup_test_service()
+ cls.endpoint = cls.setup_test_endpoint(service=cls.service)
+
+ def _add_endpoint_to_project(self):
+ # Adding and cleaning up endpoints to projects
+ self.ep_api_client.add_endpoint_to_project(
+ self.project['id'], self.endpoint['id'])
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.ep_api_client.delete_endpoint_from_project,
+ self.project['id'], self.endpoint['id'])
+
+ @rbac_rule_validation.action(
+ service="keystone",
+ rule="identity:add_endpoint_to_project")
+ @decorators.idempotent_id('9199ec13-816d-4efe-b8b1-e1cd026b9747')
+ def test_add_endpoint_to_project(self):
+ # Adding endpoints to projects
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self._add_endpoint_to_project()
+
+ @rbac_rule_validation.action(
+ service="keystone",
+ rule="identity:list_projects_for_endpoint")
+ @decorators.idempotent_id('f53dca42-ec8a-48e9-924b-0bbe6c99727f')
+ def test_list_projects_for_endpoint(self):
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.ep_api_client.list_projects_for_endpoint(
+ self.endpoint['id'])
+
+ @rbac_rule_validation.action(
+ service="keystone",
+ rule="identity:check_endpoint_in_project")
+ @decorators.idempotent_id('0c1425eb-833c-4aa1-a21d-52ffa41fdc6a')
+ def test_check_endpoint_in_project(self):
+ self._add_endpoint_to_project()
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.ep_api_client.check_endpoint_in_project(
+ self.project['id'], self.endpoint['id'])
+
+ @rbac_rule_validation.action(
+ service="keystone",
+ rule="identity:list_endpoints_for_project")
+ @decorators.idempotent_id('5d86c659-c6ad-41e0-854e-3823e95c7cc2')
+ def test_list_endpoints_in_project(self):
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.ep_api_client.list_endpoints_in_project(
+ self.project['id'])
+
+ @rbac_rule_validation.action(
+ service="keystone",
+ rule="identity:remove_endpoint_from_project")
+ @decorators.idempotent_id('b4e21c10-4f47-427b-9b8a-f5b5601adfda')
+ def test_remove_endpoint_from_project(self):
+ self._add_endpoint_to_project()
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.ep_api_client.delete_endpoint_from_project(
+ self.project['id'], self.endpoint['id'])
diff --git a/patrole_tempest_plugin/tests/api/identity/v3/test_users_rbac.py b/patrole_tempest_plugin/tests/api/identity/v3/test_users_rbac.py
index 956727b..7380531 100644
--- a/patrole_tempest_plugin/tests/api/identity/v3/test_users_rbac.py
+++ b/patrole_tempest_plugin/tests/api/identity/v3/test_users_rbac.py
@@ -20,11 +20,11 @@
from patrole_tempest_plugin.tests.api.identity.v3 import rbac_base
-class IdentityUserV3RbacTest(rbac_base.BaseIdentityV3RbacTest):
+class IdentityUserV3AdminRbacTest(rbac_base.BaseIdentityV3RbacTest):
@classmethod
def resource_setup(cls):
- super(IdentityUserV3RbacTest, cls).resource_setup()
+ super(IdentityUserV3AdminRbacTest, cls).resource_setup()
cls.default_user_id = cls.auth_provider.credentials.user_id
@rbac_rule_validation.action(service="keystone",
diff --git a/patrole_tempest_plugin/tests/api/image/rbac_base.py b/patrole_tempest_plugin/tests/api/image/rbac_base.py
index 7266079..2a45ccb 100644
--- a/patrole_tempest_plugin/tests/api/image/rbac_base.py
+++ b/patrole_tempest_plugin/tests/api/image/rbac_base.py
@@ -33,7 +33,7 @@
@classmethod
def setup_clients(cls):
super(BaseV1ImageRbacTest, cls).setup_clients()
- cls.auth_provider = cls.os.auth_provider
+ cls.auth_provider = cls.os_primary.auth_provider
cls.rbac_utils = rbac_utils()
cls.rbac_utils.switch_role(cls, toggle_rbac_role=False)
@@ -52,6 +52,6 @@
@classmethod
def setup_clients(cls):
super(BaseV2ImageRbacTest, cls).setup_clients()
- cls.auth_provider = cls.os.auth_provider
+ cls.auth_provider = cls.os_primary.auth_provider
cls.rbac_utils = rbac_utils()
cls.rbac_utils.switch_role(cls, toggle_rbac_role=False)
diff --git a/patrole_tempest_plugin/tests/api/image/v1/test_images_member_rbac.py b/patrole_tempest_plugin/tests/api/image/v1/test_images_member_rbac.py
index 643ca73..8015277 100644
--- a/patrole_tempest_plugin/tests/api/image/v1/test_images_member_rbac.py
+++ b/patrole_tempest_plugin/tests/api/image/v1/test_images_member_rbac.py
@@ -29,7 +29,7 @@
@classmethod
def setup_clients(cls):
super(ImagesMemberRbacTest, cls).setup_clients()
- cls.image_member_client = cls.os.image_member_client
+ cls.image_member_client = cls.os_primary.image_member_client
@classmethod
def resource_setup(cls):
diff --git a/patrole_tempest_plugin/tests/api/image/v2/test_images_member_rbac.py b/patrole_tempest_plugin/tests/api/image/v2/test_images_member_rbac.py
index 07d4015..a7c59f5 100644
--- a/patrole_tempest_plugin/tests/api/image/v2/test_images_member_rbac.py
+++ b/patrole_tempest_plugin/tests/api/image/v2/test_images_member_rbac.py
@@ -32,8 +32,8 @@
@classmethod
def setup_clients(cls):
super(ImagesMemberRbacTest, cls).setup_clients()
- cls.image_client = cls.os.image_client_v2
- cls.image_member_client = cls.os.image_member_client_v2
+ cls.image_client = cls.os_primary.image_client_v2
+ cls.image_member_client = cls.os_primary.image_member_client_v2
@rbac_rule_validation.action(service="glance",
rule="add_member")
diff --git a/patrole_tempest_plugin/tests/api/image/v2/test_images_rbac.py b/patrole_tempest_plugin/tests/api/image/v2/test_images_rbac.py
index fa492bb..880f892 100644
--- a/patrole_tempest_plugin/tests/api/image/v2/test_images_rbac.py
+++ b/patrole_tempest_plugin/tests/api/image/v2/test_images_rbac.py
@@ -27,7 +27,19 @@
@classmethod
def setup_clients(cls):
super(BasicOperationsImagesRbacTest, cls).setup_clients()
- cls.client = cls.os.image_client_v2
+ cls.client = cls.os_primary.image_client_v2
+
+ def _create_image(self, **kwargs):
+ image_name = data_utils.rand_name('image')
+ image = self.create_image(name=image_name,
+ container_format='bare',
+ disk_format='raw',
+ **kwargs)
+ return image
+
+ def _upload_image(self, image_id):
+ image_file = moves.cStringIO(data_utils.random_bytes())
+ return self.client.store_image_file(image_id, image_file)
@rbac_rule_validation.action(service="glance",
rule="add_image")
@@ -38,14 +50,8 @@
RBAC test for the glance create_image endpoint
"""
- uuid = '00000000-1111-2222-3333-444455556666'
- image_name = data_utils.rand_name('image')
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- self.create_image(name=image_name,
- container_format='bare',
- disk_format='raw',
- visibility='private',
- ramdisk_id=uuid)
+ self._create_image()
@rbac_rule_validation.action(service="glance",
rule="upload_image")
@@ -56,18 +62,25 @@
RBAC test for the glance upload_image endpoint
"""
- uuid = '00000000-1111-2222-3333-444455556666'
- image_name = data_utils.rand_name('image')
- body = self.create_image(name=image_name,
- container_format='bare',
- disk_format='raw',
- visibility='private',
- ramdisk_id=uuid)
+ image = self._create_image()
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- # Try uploading an image file
- image_file = moves.cStringIO(data_utils.random_bytes())
- self.client.store_image_file(body['id'], image_file)
+ self._upload_image(image['id'])
+
+ @decorators.idempotent_id('f0c268f3-cb51-49aa-9bd5-d30cf647322f')
+ @rbac_rule_validation.action(service="glance",
+ rule="download_image")
+ def test_download_image(self):
+
+ """Download Image Test
+
+ RBAC test for the glance download_image endpoint
+ """
+ image = self._create_image()
+ self._upload_image(image['id'])
+
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.client.show_image_file(image['id'])
@rbac_rule_validation.action(service="glance",
rule="delete_image")
@@ -78,16 +91,11 @@
RBAC test for the glance delete_image endpoint
"""
- image_name = data_utils.rand_name('image')
- body = self.create_image(name=image_name,
- container_format='bare',
- disk_format='raw',
- visibility='public')
- image_id = body.get('id')
- # Toggle role and delete created image
+ image = self._create_image()
+
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- self.client.delete_image(image_id)
- self.client.wait_for_resource_deletion(image_id)
+ self.client.delete_image(image['id'])
+ self.client.wait_for_resource_deletion(image['id'])
@rbac_rule_validation.action(service="glance",
rule="get_image")
@@ -98,16 +106,10 @@
RBAC test for the glance create_image endpoint
"""
+ image = self._create_image()
- image_name = data_utils.rand_name('image')
- body = self.create_image(name=image_name,
- container_format='bare',
- disk_format='raw',
- visibility='private')
- image_id = body.get('id')
- # Toggle role and get created image
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- self.client.show_image(image_id)
+ self.client.show_image(image['id'])
@rbac_rule_validation.action(service="glance",
rule="get_images")
@@ -118,10 +120,8 @@
RBAC test for the glance list_images endpoint
"""
-
- # Toggle role and get created image
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- self.client.list_images()
+ self.client.list_images()['images']
@rbac_rule_validation.action(service="glance",
rule="modify_image")
@@ -132,22 +132,42 @@
RBAC test for the glance update_image endpoint
"""
- image_name = data_utils.rand_name('image')
- body = self.create_image(name=image_name,
- container_format='bare',
- disk_format='raw',
- visibility='private')
- image_id = body.get('id')
+ image = self._create_image()
- # Now try uploading an image file
- image_file = moves.cStringIO(data_utils.random_bytes())
- self.client.store_image_file(image_id, image_file)
-
- # Toggle role and update created image
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- new_image_name = data_utils.rand_name('new-image')
- body = self.client.update_image(image_id, [
- dict(replace='/name', value=new_image_name)])
+ updated_image_name = data_utils.rand_name('image')
+ self.client.update_image(image['id'], [
+ dict(replace='/name', value=updated_image_name)])
+
+ @decorators.idempotent_id('244050d9-1b9a-446a-b3c5-f26f3ba8eb75')
+ @rbac_rule_validation.action(service="glance",
+ rule="modify_image")
+ def test_create_image_tag(self):
+
+ """Create image tag
+
+ RBAC test for the glance add_image_tag endpoint
+ """
+ image = self._create_image()
+
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.client.add_image_tag(image['id'], data_utils.rand_name('tag'))
+
+ @decorators.idempotent_id('c4a0bf9c-b78b-48c6-a31f-72c95f943c6e')
+ @rbac_rule_validation.action(service="glance",
+ rule="modify_image")
+ def test_delete_image_tag(self):
+
+ """Delete image tag
+
+ RBAC test for the glance delete_image_tag endpoint
+ """
+ image = self._create_image()
+ tag_name = data_utils.rand_name('tag')
+ self.client.add_image_tag(image['id'], tag_name)
+
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.client.delete_image_tag(image['id'], tag_name)
@rbac_rule_validation.action(service="glance",
rule="publicize_image")
@@ -158,12 +178,8 @@
RBAC test for the glance publicize_image endpoint
"""
- image_name = data_utils.rand_name('image')
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- self.create_image(name=image_name,
- container_format='bare',
- disk_format='raw',
- visibility='public')
+ self._create_image(visibility='public')
@rbac_rule_validation.action(service="glance",
rule="deactivate")
@@ -174,20 +190,11 @@
RBAC test for the glance deactivate_image endpoint
"""
- uuid = '00000000-1111-2222-3333-444455556666'
- image_name = data_utils.rand_name('image')
- body = self.create_image(name=image_name,
- container_format='bare',
- disk_format='raw',
- visibility='private',
- ramdisk_id=uuid)
- image_id = body.get('id')
- # Now try uploading an image file
- image_file = moves.cStringIO(data_utils.random_bytes())
- self.client.store_image_file(image_id=image_id, data=image_file)
- # Toggling role and deacivate image
+ image = self._create_image()
+ self._upload_image(image['id'])
+
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- self.client.deactivate_image(image_id)
+ self.client.deactivate_image(image['id'])
@rbac_rule_validation.action(service="glance",
rule="reactivate")
@@ -198,18 +205,8 @@
RBAC test for the glance reactivate_image endpoint
"""
- uuid = '00000000-1111-2222-3333-444455556666'
- image_name = data_utils.rand_name('image')
- body = self.create_image(name=image_name,
- container_format='bare',
- disk_format='raw',
- visibility='private',
- ramdisk_id=uuid)
+ image = self._create_image()
+ self._upload_image(image['id'])
- # Now try uploading an image file
- image_id = body.get('id')
- image_file = moves.cStringIO(data_utils.random_bytes())
- self.client.store_image_file(image_id=image_id, data=image_file)
- # Toggling role and reactivate image
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- self.client.reactivate_image(image_id)
+ self.client.reactivate_image(image['id'])
diff --git a/patrole_tempest_plugin/tests/api/network/rbac_base.py b/patrole_tempest_plugin/tests/api/network/rbac_base.py
index 6e7898f..629f0ca 100644
--- a/patrole_tempest_plugin/tests/api/network/rbac_base.py
+++ b/patrole_tempest_plugin/tests/api/network/rbac_base.py
@@ -35,6 +35,6 @@
@classmethod
def setup_clients(cls):
super(BaseNetworkRbacTest, cls).setup_clients()
- cls.auth_provider = cls.os.auth_provider
+ cls.auth_provider = cls.os_primary.auth_provider
cls.rbac_utils = rbac_utils()
cls.rbac_utils.switch_role(cls, toggle_rbac_role=False)
diff --git a/patrole_tempest_plugin/tests/api/network/test_metering_label_rules_rbac.py b/patrole_tempest_plugin/tests/api/network/test_metering_label_rules_rbac.py
index 2f55e30..2efb3fe 100644
--- a/patrole_tempest_plugin/tests/api/network/test_metering_label_rules_rbac.py
+++ b/patrole_tempest_plugin/tests/api/network/test_metering_label_rules_rbac.py
@@ -39,8 +39,9 @@
@classmethod
def setup_clients(cls):
super(MeteringLabelRulesRbacTest, cls).setup_clients()
- cls.metering_labels_client = cls.os.metering_labels_client
- cls.metering_label_rules_client = cls.os.metering_label_rules_client
+ cls.metering_labels_client = cls.os_primary.metering_labels_client
+ cls.metering_label_rules_client = \
+ cls.os_primary.metering_label_rules_client
@classmethod
def resource_setup(cls):
diff --git a/patrole_tempest_plugin/tests/api/network/test_metering_labels_rbac.py b/patrole_tempest_plugin/tests/api/network/test_metering_labels_rbac.py
index 091e31d..9aabfa0 100644
--- a/patrole_tempest_plugin/tests/api/network/test_metering_labels_rbac.py
+++ b/patrole_tempest_plugin/tests/api/network/test_metering_labels_rbac.py
@@ -37,7 +37,7 @@
@classmethod
def setup_clients(cls):
super(MeteringLabelsRbacTest, cls).setup_clients()
- cls.metering_labels_client = cls.os.metering_labels_client
+ cls.metering_labels_client = cls.os_primary.metering_labels_client
def _create_metering_label(self):
body = self.metering_labels_client.create_metering_label(
diff --git a/patrole_tempest_plugin/tests/api/network/test_networks_rbac.py b/patrole_tempest_plugin/tests/api/network/test_networks_rbac.py
index 9752db6..133ea74 100644
--- a/patrole_tempest_plugin/tests/api/network/test_networks_rbac.py
+++ b/patrole_tempest_plugin/tests/api/network/test_networks_rbac.py
@@ -30,12 +30,6 @@
class RbacNetworksTest(base.BaseNetworkRbacTest):
@classmethod
- def setup_clients(cls):
- super(RbacNetworksTest, cls).setup_clients()
- cls.networks_client = cls.os.networks_client
- cls.subnet_client = cls.os.subnets_client
-
- @classmethod
def resource_setup(cls):
super(RbacNetworksTest, cls).resource_setup()
diff --git a/patrole_tempest_plugin/tests/api/orchestration/rbac_base.py b/patrole_tempest_plugin/tests/api/orchestration/rbac_base.py
index b426ecd..7be7d40 100644
--- a/patrole_tempest_plugin/tests/api/orchestration/rbac_base.py
+++ b/patrole_tempest_plugin/tests/api/orchestration/rbac_base.py
@@ -33,6 +33,6 @@
@classmethod
def setup_clients(cls):
super(BaseOrchestrationRbacTest, cls).setup_clients()
- cls.auth_provider = cls.os.auth_provider
+ cls.auth_provider = cls.os_primary.auth_provider
cls.rbac_utils = rbac_utils()
cls.rbac_utils.switch_role(cls, toggle_rbac_role=False)
diff --git a/patrole_tempest_plugin/tests/api/volume/rbac_base.py b/patrole_tempest_plugin/tests/api/volume/rbac_base.py
index 79b9f0d..ccadad1 100644
--- a/patrole_tempest_plugin/tests/api/volume/rbac_base.py
+++ b/patrole_tempest_plugin/tests/api/volume/rbac_base.py
@@ -35,15 +35,18 @@
@classmethod
def setup_clients(cls):
super(BaseVolumeRbacTest, cls).setup_clients()
- cls.auth_provider = cls.os.auth_provider
+ cls.auth_provider = cls.os_primary.auth_provider
cls.rbac_utils = rbac_utils()
cls.rbac_utils.switch_role(cls, toggle_rbac_role=False)
version_checker = {
- 1: [cls.os.volume_hosts_client, cls.os.volume_types_client],
- 2: [cls.os.volume_hosts_v2_client, cls.os.volume_types_v2_client],
- 3: [cls.os.volume_hosts_v2_client, cls.os.volume_types_v2_client]
+ 1: [cls.os_primary.volume_hosts_client,
+ cls.os_primary.volume_types_client],
+ 2: [cls.os_primary.volume_hosts_v2_client,
+ cls.os_primary.volume_types_v2_client],
+ 3: [cls.os_primary.volume_hosts_v2_client,
+ cls.os_primary.volume_types_v2_client]
}
cls.volume_hosts_client, cls.volume_types_client = \
version_checker[cls._api_version]
diff --git a/patrole_tempest_plugin/tests/api/volume/test_capabilities_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_capabilities_rbac.py
index 28506c0..9d76ef3 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_capabilities_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_capabilities_rbac.py
@@ -32,8 +32,8 @@
@classmethod
def setup_clients(cls):
super(CapabilitiesRbacTest, cls).setup_clients()
- cls.client = cls.os.volume_capabilities_v2_client
- cls.hosts_client = cls.os.volume_hosts_v2_client
+ cls.client = cls.os_primary.volume_capabilities_v2_client
+ cls.hosts_client = cls.os_primary.volume_hosts_v2_client
@rbac_rule_validation.action(service="cinder",
rule="volume_extension:capabilities")
diff --git a/patrole_tempest_plugin/tests/api/volume/test_encryption_types_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_encryption_types_rbac.py
new file mode 100644
index 0000000..d829591
--- /dev/null
+++ b/patrole_tempest_plugin/tests/api/volume/test_encryption_types_rbac.py
@@ -0,0 +1,86 @@
+# 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.lib import decorators
+from tempest import test
+
+from patrole_tempest_plugin import rbac_rule_validation
+from patrole_tempest_plugin.tests.api.volume import rbac_base
+
+
+class EncryptionTypesRbacTest(rbac_base.BaseVolumeRbacTest):
+
+ @classmethod
+ def skip_checks(cls):
+ super(EncryptionTypesRbacTest, cls).skip_checks()
+ if not test.is_extension_enabled('encryption', 'volume'):
+ msg = "%s skipped as encryption not enabled." % cls.__name__
+ raise cls.skipException(msg)
+
+ @classmethod
+ def setup_clients(cls):
+ super(EncryptionTypesRbacTest, cls).setup_clients()
+ cls.client = cls.os_primary.encryption_types_v2_client
+
+ def _create_volume_type_encryption(self):
+ vol_type_id = self.create_volume_type()['id']
+ self.client.create_encryption_type(
+ vol_type_id,
+ provider="nova.volume.encryptors.luks.LuksEncryptor",
+ control_location="front-end")['encryption']
+ return vol_type_id
+
+ @decorators.idempotent_id('ffd94ce5-c24b-4b6c-84c9-c5aad8c3010c')
+ @rbac_rule_validation.action(
+ service="cinder",
+ rule="volume_extension:volume_type_encryption")
+ def test_create_volume_type_encryption(self):
+ vol_type_id = self.create_volume_type()['id']
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.client.create_encryption_type(
+ vol_type_id,
+ provider="nova.volume.encryptors.luks.LuksEncryptor",
+ control_location="front-end")['encryption']
+
+ @decorators.idempotent_id('6599e72e-acef-4c0d-a9b2-463fca30d1da')
+ @rbac_rule_validation.action(
+ service="cinder",
+ rule="volume_extension:volume_type_encryption")
+ def test_delete_volume_type_encryption(self):
+ vol_type_id = self._create_volume_type_encryption()
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.client.delete_encryption_type(vol_type_id)
+
+ @decorators.idempotent_id('42da9fec-32fd-4dca-9242-8a53b2fed25a')
+ @rbac_rule_validation.action(
+ service="cinder",
+ rule="volume_extension:volume_type_encryption")
+ def test_update_volume_type_encryption(self):
+ vol_type_id = self._create_volume_type_encryption()
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.client.update_encryption_type(vol_type_id,
+ control_location="front-end")
+
+ @decorators.idempotent_id('1381a3dc-248f-4282-b231-c9399018c804')
+ @rbac_rule_validation.action(
+ service="cinder",
+ rule="volume_extension:volume_type_encryption")
+ def test_show_volume_type_encryption(self):
+ vol_type_id = self._create_volume_type_encryption()
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.client.show_encryption_type(vol_type_id)
+
+
+class EncryptionTypesV3RbacTest(EncryptionTypesRbacTest):
+ _api_version = 3
diff --git a/patrole_tempest_plugin/tests/api/volume/test_qos_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_qos_rbac.py
index c3cca0d..4638e78 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_qos_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_qos_rbac.py
@@ -26,8 +26,8 @@
@classmethod
def setup_clients(cls):
super(VolumeQOSRbacTest, cls).setup_clients()
- cls.auth_provider = cls.os.auth_provider
- cls.client = cls.os.volume_qos_v2_client
+ cls.auth_provider = cls.os_primary.auth_provider
+ cls.client = cls.os_primary.volume_qos_v2_client
def _create_test_qos_specs(self, name=None, consumer=None, **kwargs):
"""Create a test Qos-Specs."""
diff --git a/patrole_tempest_plugin/tests/api/volume/test_quota_classes_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_quota_classes_rbac.py
new file mode 100644
index 0000000..44c0d3e
--- /dev/null
+++ b/patrole_tempest_plugin/tests/api/volume/test_quota_classes_rbac.py
@@ -0,0 +1,60 @@
+# 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.lib.common.utils import data_utils
+from tempest.lib import decorators
+from tempest import test
+
+from patrole_tempest_plugin import rbac_rule_validation
+from patrole_tempest_plugin.tests.api.volume import rbac_base
+
+
+class QuotaClassesRbacTest(rbac_base.BaseVolumeRbacTest):
+
+ @classmethod
+ def skip_checks(cls):
+ super(QuotaClassesRbacTest, cls).skip_checks()
+ if not test.is_extension_enabled('os-quota-class-sets', 'volume'):
+ msg = ("%s skipped as os-quota-class-sets not enabled."
+ % cls.__name__)
+ raise cls.skipException(msg)
+
+ @classmethod
+ def setup_clients(cls):
+ super(QuotaClassesRbacTest, cls).setup_clients()
+ cls.client = cls.os_primary.quota_classes_client
+ cls.quota_name = data_utils.rand_name(cls.__name__ + '-QuotaClass')
+
+ @decorators.idempotent_id('1a060def-2b43-4534-97f5-5eadbbe8c726')
+ @rbac_rule_validation.action(service="cinder",
+ rule="volume_extension:quota_classes")
+ def test_show_quota_class_set(self):
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.client.show_quota_class_set(self.quota_name)['quota_class_set']
+
+ @decorators.idempotent_id('72159478-23a7-4c75-989f-6bac609eca62')
+ @rbac_rule_validation.action(service="cinder",
+ rule="volume_extension:quota_classes")
+ def test_update_quota_class_set(self):
+ quota_class_set = self.client.show_quota_class_set(self.quota_name)[
+ 'quota_class_set']
+ quota_class_set.pop('id')
+
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.client.update_quota_class_set(self.quota_name, **quota_class_set)
+
+
+class QuotaClassesV3RbacTest(QuotaClassesRbacTest):
+ _api_version = 3
diff --git a/patrole_tempest_plugin/tests/api/volume/test_scheduler_stats_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_scheduler_stats_rbac.py
index bf6290a..5a36709 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_scheduler_stats_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_scheduler_stats_rbac.py
@@ -32,7 +32,7 @@
@classmethod
def setup_clients(cls):
super(SchedulerStatsRbacTest, cls).setup_clients()
- cls.client = cls.os.volume_scheduler_stats_v2_client
+ cls.client = cls.os_primary.volume_scheduler_stats_v2_client
@rbac_rule_validation.action(
service="cinder",
diff --git a/patrole_tempest_plugin/tests/api/volume/test_snapshots_actions_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_snapshots_actions_rbac.py
index b070a10..5a4e246 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_snapshots_actions_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_snapshots_actions_rbac.py
@@ -13,8 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-from oslo_log import log as logging
-
from tempest import config
from tempest.lib import decorators
@@ -22,7 +20,6 @@
from patrole_tempest_plugin.tests.api.volume import rbac_base
CONF = config.CONF
-LOG = logging.getLogger(__name__)
class SnapshotsActionsRbacTest(rbac_base.BaseVolumeRbacTest):
@@ -36,14 +33,12 @@
@classmethod
def setup_clients(cls):
super(SnapshotsActionsRbacTest, cls).setup_clients()
- cls.client = cls.os.snapshots_client
+ cls.client = cls.snapshots_client
@classmethod
def resource_setup(cls):
super(SnapshotsActionsRbacTest, cls).resource_setup()
- # Create a volume
cls.volume = cls.create_volume()
- # Create a snapshot
cls.snapshot = cls.create_snapshot(volume_id=cls.volume['id'])
cls.snapshot_id = cls.snapshot['id']
@@ -52,22 +47,17 @@
rule="volume_extension:snapshot_admin_actions:reset_status")
@decorators.idempotent_id('ea430145-34ef-408d-b678-95d5ae5f46eb')
def test_reset_snapshot_status(self):
- # Reset snapshot status to error
status = 'error'
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- self.client.\
- reset_snapshot_status(self.snapshot['id'], status)
+ self.client.reset_snapshot_status(self.snapshot['id'], status)
@rbac_rule_validation.action(
service="cinder",
- rule="volume_extension:volume_admin_actions:force_delete")
+ rule="volume_extension:snapshot_admin_actions:force_delete")
@decorators.idempotent_id('a8b0f7d8-4c00-4645-b8d5-33ab4eecc6cb')
def test_snapshot_force_delete(self):
- # Test force delete of snapshot
- # Create snapshot,
- # and force delete temp snapshot
temp_snapshot = self.create_snapshot(self.volume['id'])
- # Force delete the snapshot
+
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.client.force_delete_snapshot(temp_snapshot['id'])
self.client.wait_for_resource_deletion(temp_snapshot['id'])
diff --git a/patrole_tempest_plugin/tests/api/volume/test_user_messages_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_user_messages_rbac.py
index b1e5cba..60484f1 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_user_messages_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_user_messages_rbac.py
@@ -32,7 +32,7 @@
@classmethod
def setup_clients(cls):
super(MessagesV3RbacTest, cls).setup_clients()
- cls.client = cls.os.volume_v3_messages_client
+ cls.client = cls.os_primary.volume_v3_messages_client
def _create_user_message(self):
"""Trigger a 'no valid host' situation to generate a message."""
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 9c396e2..19cf12b 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
@@ -13,8 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-import testtools
-
from tempest.common import compute
from tempest.common import waiters
from tempest import config
@@ -31,10 +29,17 @@
class VolumesActionsRbacTest(rbac_base.BaseVolumeRbacTest):
+ # TODO(felipemonteiro): "volume_extension:volume_actions:upload_public"
+ # test can be created once volumes v3 client is created in Tempest.
+
@classmethod
def setup_clients(cls):
super(VolumesActionsRbacTest, cls).setup_clients()
- cls.client = cls.os.volumes_client
+ cls.client = cls.volumes_client
+ if CONF.image_feature_enabled.api_v1:
+ cls.image_client = cls.os_primary.image_client
+ elif CONF.image_feature_enabled.api_v2:
+ cls.image_client = cls.os_primary.image_client_v2
@classmethod
def resource_setup(cls):
@@ -42,10 +47,11 @@
cls.volume = cls.create_volume()
def _create_server(self):
- body, _ = compute.create_test_server(self.os, wait_until='ACTIVE')
+ server, _ = compute.create_test_server(
+ self.os_primary, wait_until='ACTIVE')
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
- self.servers_client.delete_server, body['id'])
- return body
+ self.servers_client.delete_server, server['id'])
+ return server
def _attach_volume(self, server):
self.servers_client.attach_volume(
@@ -60,52 +66,97 @@
waiters.wait_for_volume_resource_status(
self.client, self.volume['id'], 'available')
- @testtools.skipUnless(CONF.service_available.nova,
- "Nova is required to create a server")
+ @test.services('compute')
@rbac_rule_validation.action(service="cinder", rule="volume:attach")
@decorators.idempotent_id('f97b10e4-2eed-4f8b-8632-71c02cb9fe42')
def test_attach_volume_to_instance(self):
server = self._create_server()
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- # Attach the volume
self._attach_volume(server)
- @test.attr(type="slow")
+ @test.attr(type=["slow"])
+ @test.services('compute')
@rbac_rule_validation.action(service="cinder", rule="volume:detach")
@decorators.idempotent_id('5a042f6a-688b-42e6-a02e-fe5c47b89b07')
def test_detach_volume_from_instance(self):
- # Attach the volume
server = self._create_server()
self._attach_volume(server)
+
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- # Detach the volume
self._detach_volume()
- @testtools.skipIf(True, "Patrole bug #1672799")
- @rbac_rule_validation.action(service="cinder",
- rule="volume:copy_volume_to_image")
+ @test.services('image')
+ @rbac_rule_validation.action(
+ service="cinder",
+ rule="volume_extension:volume_actions:upload_image")
@decorators.idempotent_id('b0d0da46-903c-4445-893e-20e680d68b50')
def test_volume_upload(self):
- self.image_client = self.os.image_client
- image_name = data_utils.rand_name('image')
+ # TODO(felipemonteiro): The ``upload_volume`` endpoint also enforces
+ # "volume:copy_volume_to_image" but is not currently contained in
+ # Cinder's policy.json.
+ image_name = data_utils.rand_name(self.__class__.__name__ + '-Image')
+
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
body = self.client.upload_volume(
- self.volume['id'], image_name=image_name,
+ self.volume['id'], image_name=image_name, visibility="private",
disk_format=CONF.volume.disk_format)['os-volume_upload_image']
+ image_id = body["image_id"]
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.image_client.delete_image,
- body['image_id'])
- waiters.wait_for_volume_resource_status(
- self.client, self.volume['id'], 'available')
+ image_id)
+ waiters.wait_for_image_status(self.image_client, image_id, 'active')
+ waiters.wait_for_volume_resource_status(self.os_admin.volumes_client,
+ self.volume['id'], 'available')
@rbac_rule_validation.action(service="cinder",
rule="volume:update_readonly_flag")
@decorators.idempotent_id('2750717a-f250-4e41-9e09-02624aad6ff8')
def test_volume_readonly_update(self):
- volume = self.create_volume()
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- # Update volume readonly
- self.client.update_volume_readonly(volume['id'], readonly=True)
+
+ self.client.update_volume_readonly(self.volume['id'], readonly=True)
+ self.addCleanup(self.client.update_volume_readonly,
+ self.volume['id'], readonly=False)
+
+ @decorators.idempotent_id('72bab13c-dfaf-4b6d-a132-c83a85fb1776')
+ @rbac_rule_validation.action(
+ service="cinder",
+ rule="volume_extension:volume_unmanage")
+ def test_unmanage_volume(self):
+ volume = self.create_volume()
+
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.client.unmanage_volume(volume['id'])
+
+ @decorators.idempotent_id('59b783c0-f4ef-430c-8a90-1bad97d4ec5c')
+ @rbac_rule_validation.action(service="cinder",
+ rule="volume:update")
+ def test_volume_set_bootable(self):
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.client.set_bootable_volume(self.volume['id'], bootable=True)
+
+ @decorators.idempotent_id('41566922-75a1-4484-99c7-9c8782ee99ac')
+ @rbac_rule_validation.action(service="cinder",
+ rule="volume:reserve_volume")
+ def test_volume_reserve(self):
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.client.reserve_volume(self.volume['id'])
+
+ @decorators.idempotent_id('e5fa9564-77d9-4e57-b0c0-3e0ae4d08535')
+ @rbac_rule_validation.action(service="cinder",
+ rule="volume:unreserve_volume")
+ def test_volume_unreserve(self):
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.client.unreserve_volume(self.volume['id'])
+
+ @decorators.idempotent_id('c015c82f-7010-48cc-bd71-4ef542046f20')
+ @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']
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.client.retype_volume(volume['id'], new_type=vol_type)
@rbac_rule_validation.action(
service="cinder",
diff --git a/patrole_tempest_plugin/tests/api/volume/test_volume_metadata_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_volume_metadata_rbac.py
index 1c73e68..d07e5c6 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_volume_metadata_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_volume_metadata_rbac.py
@@ -13,8 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-from oslo_log import log as logging
-
from tempest import config
from tempest.lib import decorators
@@ -22,62 +20,95 @@
from patrole_tempest_plugin.tests.api.volume import rbac_base
CONF = config.CONF
-LOG = logging.getLogger(__name__)
class VolumeMetadataRbacTest(rbac_base.BaseVolumeRbacTest):
@classmethod
def setup_clients(cls):
super(VolumeMetadataRbacTest, cls).setup_clients()
- cls.client = cls.os.volumes_client
+ cls.client = cls.volumes_client
+ if CONF.image_feature_enabled.api_v1:
+ cls.image_client = cls.os_primary.image_client
+ elif CONF.image_feature_enabled.api_v2:
+ cls.image_client = cls.os_primary.image_client_v2
+ cls.image_id = CONF.compute.image_ref
- def _add_metadata(self, volume):
+ @classmethod
+ def resource_setup(cls):
+ super(VolumeMetadataRbacTest, cls).resource_setup()
+ cls.volume = cls.create_volume()
+ cls._add_metadata(cls.volume)
+ cls.image_id = CONF.compute.image_ref
+
+ @classmethod
+ def _add_metadata(cls, volume):
# Create metadata for the volume
metadata = {"key1": "value1",
"key2": "value2",
"key3": "value3",
"key4": "<value&special_chars>"}
- self.volumes_client.create_volume_metadata(volume['id'],
- metadata)['metadata']
+ cls.client.create_volume_metadata(cls.volume['id'],
+ metadata)['metadata']
@rbac_rule_validation.action(service="cinder",
rule="volume:update_volume_metadata")
@decorators.idempotent_id('232bbb8b-4c29-44dc-9077-b1398c20b738')
def test_create_volume_metadata(self):
- volume = self.create_volume()
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- self._add_metadata(volume)
+ self._add_metadata(self.volume)
@rbac_rule_validation.action(service="cinder",
rule="volume:get")
@decorators.idempotent_id('87ea37d9-23ab-47b2-a59c-16fc4d2c6dfa')
def test_get_volume_metadata(self):
- volume = self.create_volume()
- self._add_metadata(volume)
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- self.volumes_client.show_volume_metadata(volume['id'])['metadata']
+ self.client.show_volume_metadata(self.volume['id'])['metadata']
@rbac_rule_validation.action(service="cinder",
rule="volume:delete_volume_metadata")
@decorators.idempotent_id('7498dfc1-9db2-4423-ad20-e6dcb25d1beb')
- def test_delete_volume_metadata(self):
- volume = self.create_volume()
- self._add_metadata(volume)
+ def test_delete_volume_metadata_item(self):
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- self.volumes_client.delete_volume_metadata_item(volume['id'],
- "key1")
+ self.client.delete_volume_metadata_item(self.volume['id'], "key1")
+
+ @decorators.idempotent_id('a41c8eed-2051-4a25-b401-df036faacbdc')
+ @rbac_rule_validation.action(
+ service="cinder",
+ rule="volume:delete_volume_metadata")
+ def test_delete_volume_image_metadata(self):
+ self.client.update_volume_image_metadata(self.volume['id'],
+ image_id=self.image_id)
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.client.delete_volume_image_metadata(self.volume['id'], 'image_id')
@rbac_rule_validation.action(service="cinder",
rule="volume:update_volume_metadata")
@decorators.idempotent_id('8ce2ff80-99ba-49ae-9bb1-7e96729ee5af')
- def test_update_volume_metadata(self):
- volume = self.create_volume()
- self._add_metadata(volume)
+ def test_update_volume_metadata_item(self):
# Metadata to update
update_item = {"key3": "value3_update"}
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- self.volumes_client.update_volume_metadata_item(
- volume['id'], "key3", update_item)['meta']
+ self.client.update_volume_metadata_item(self.volume['id'], "key3",
+ update_item)['meta']
+
+ @decorators.idempotent_id('a231b445-97a5-4657-b05f-245895e88da9')
+ @rbac_rule_validation.action(service="cinder",
+ rule="volume:update_volume_metadata")
+ def test_update_volume_metadata(self):
+ # Metadata to update
+ update = {"key1": "value1",
+ "key3": "value3"}
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.client.update_volume_metadata(self.volume['id'], update)
+
+ @decorators.idempotent_id('a9d9e825-5ea3-42e6-96f3-7ac4e97b2ed0')
+ @rbac_rule_validation.action(
+ service="cinder",
+ rule="volume:update_volume_metadata")
+ def test_update_volume_image_metadata(self):
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.client.update_volume_image_metadata(self.volume['id'],
+ image_id=self.image_id)
class VolumeMetadataV3RbacTest(VolumeMetadataRbacTest):
diff --git a/patrole_tempest_plugin/tests/api/volume/test_volume_quotas_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_volume_quotas_rbac.py
index a104782..0321e13 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_volume_quotas_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_volume_quotas_rbac.py
@@ -32,12 +32,12 @@
@classmethod
def setup_credentials(cls):
super(VolumeQuotasRbacTest, cls).setup_credentials()
- cls.demo_tenant_id = cls.os.credentials.tenant_id
+ cls.demo_tenant_id = cls.os_primary.credentials.tenant_id
@classmethod
def setup_clients(cls):
super(VolumeQuotasRbacTest, cls).setup_clients()
- cls.client = cls.os.volume_quotas_client
+ cls.client = cls.os_primary.volume_quotas_client
@rbac_rule_validation.action(service="cinder",
rule="volume_extension:quotas:show")
diff --git a/patrole_tempest_plugin/tests/api/volume/test_volume_transfers_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_volume_transfers_rbac.py
index cb40c50..057379b 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_volume_transfers_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_volume_transfers_rbac.py
@@ -28,8 +28,8 @@
@classmethod
def setup_clients(cls):
super(VolumesTransfersRbacTest, cls).setup_clients()
- cls.client = cls.os.volume_transfers_v2_client
- cls.adm_volumes_client = cls.os_adm.volumes_v2_client
+ cls.client = cls.os_primary.volume_transfers_v2_client
+ cls.adm_volumes_client = cls.os_admin.volumes_v2_client
@classmethod
def resource_setup(cls):
diff --git a/patrole_tempest_plugin/tests/api/volume/test_volume_types_extra_specs_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_volume_types_extra_specs_rbac.py
index 33bc5ae..94199b5 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_volume_types_extra_specs_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_volume_types_extra_specs_rbac.py
@@ -13,7 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
from patrole_tempest_plugin import rbac_rule_validation
@@ -22,21 +21,11 @@
class VolumeTypesExtraSpecsRbacTest(rbac_base.BaseVolumeRbacTest):
- def _create_volume_type(self, name=None, **kwargs):
- """Create a test volume-type"""
- name = name or data_utils.rand_name(
- self.__class__.__name__ + '-volume-type')
- volume_type = self.volume_types_client.create_volume_type(
- name=name, **kwargs)['volume_type']
- self.addCleanup(self.volume_types_client.delete_volume_type,
- volume_type['id'])
- return volume_type
-
@rbac_rule_validation.action(service="cinder",
rule="volume_extension:types_extra_specs")
@decorators.idempotent_id('eea40251-990b-49b0-99ae-10e4585b479b')
def test_create_volume_type_extra_specs(self):
- vol_type = self._create_volume_type()
+ vol_type = self.create_volume_type()
# List Volume types extra specs.
extra_specs = {"spec1": "val1"}
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
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 6a3367a..50973b8 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
@@ -65,7 +65,7 @@
backup.update(changes)
return self._encode_backup(backup)
- @test.attr(type="slow")
+ @test.attr(type=["slow"])
@rbac_rule_validation.action(service="cinder",
rule="backup:create")
@decorators.idempotent_id('6887ec94-0bcf-4ab7-b30f-3808a4b5a2a5')
@@ -73,7 +73,7 @@
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self._create_backup(volume_id=self.volume['id'])
- @test.attr(type="slow")
+ @test.attr(type=["slow"])
@rbac_rule_validation.action(service="cinder",
rule="backup:get")
@decorators.idempotent_id('abd92bdd-b0fb-4dc4-9cfc-de9e968f8c8a')
@@ -91,7 +91,7 @@
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.backups_client.list_backups()
- @test.attr(type="slow")
+ @test.attr(type=["slow"])
@rbac_rule_validation.action(service="cinder",
rule="backup:restore")
@decorators.idempotent_id('9c794bf9-2446-4f41-8fe0-80b71e757f9d')
@@ -104,7 +104,7 @@
waiters.wait_for_volume_resource_status(
self.backups_client, restore['backup_id'], 'available')
- @test.attr(type="slow")
+ @test.attr(type=["slow"])
@rbac_rule_validation.action(service="cinder",
rule="backup:delete")
@decorators.idempotent_id('d5d0c6a2-413d-437e-a73f-4bf2b41a20ed')
@@ -116,7 +116,19 @@
self.backups_client.delete_backup(backup['id'])
self.backups_client.wait_for_resource_deletion(backup['id'])
- @test.attr(type='slow')
+ @decorators.idempotent_id('48325aaa-13f5-4ba3-96a3-24b6c9d77b6d')
+ @test.attr(type=["slow"])
+ @rbac_rule_validation.action(
+ service="cinder",
+ rule="volume_extension:backup_admin_actions:force_delete")
+ def test_volume_backup_force_delete(self):
+ backup = self._create_backup(volume_id=self.volume['id'])
+
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.backups_client.force_delete_backup(backup['id'])
+ self.backups_client.wait_for_resource_deletion(backup['id'])
+
+ @test.attr(type=["slow"])
@rbac_rule_validation.action(service="cinder",
rule="backup:backup-export")
@decorators.idempotent_id('e984ec8d-e8eb-485c-98bc-f1856020303c')
@@ -128,7 +140,7 @@
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.backups_client.export_backup(backup['id'])['backup-record']
- @test.attr(type='slow')
+ @test.attr(type=["slow"])
@rbac_rule_validation.action(service="cinder",
rule="backup:backup-import")
@decorators.idempotent_id('1e70f039-4556-44cc-9cc1-edf2b7ed648b')
diff --git a/releasenotes/notes/add-force-delete-backup-test-7e896affd1471328.yaml b/releasenotes/notes/add-force-delete-backup-test-7e896affd1471328.yaml
new file mode 100644
index 0000000..3d81baa
--- /dev/null
+++ b/releasenotes/notes/add-force-delete-backup-test-7e896affd1471328.yaml
@@ -0,0 +1,11 @@
+---
+features:
+ - |
+ Added an RBAC test for force-deleting a backup which enforces the cinder
+ policy action: "volume_extension:backup_admin_actions:force_delete".
+fixes:
+ - |
+ Corrected the policy action in the ``rbac_rule_validation`` decorator
+ for the test ``test_snapshot_force_delete`` from
+ "volume_extension:volume_admin_actions:force_delete" to
+ "volume_extension:snapshot_admin_actions:force_delete".
diff --git a/releasenotes/notes/add-quota-classes-tests-3e61e671f6e131df.yaml b/releasenotes/notes/add-quota-classes-tests-3e61e671f6e131df.yaml
new file mode 100644
index 0000000..656f6a1
--- /dev/null
+++ b/releasenotes/notes/add-quota-classes-tests-3e61e671f6e131df.yaml
@@ -0,0 +1,5 @@
+---
+features:
+ - |
+ Add RBAC tests for cinder os-quota-class-sets API, which cover the
+ policy action "volume_extension:quota_classes".
diff --git a/releasenotes/notes/admin-only-identity-v2-admin-6f382e38d7a690a4.yaml b/releasenotes/notes/admin-only-identity-v2-admin-6f382e38d7a690a4.yaml
new file mode 100644
index 0000000..750a9f1
--- /dev/null
+++ b/releasenotes/notes/admin-only-identity-v2-admin-6f382e38d7a690a4.yaml
@@ -0,0 +1,12 @@
+---
+fixes:
+ - |
+ Removed ``rule`` kwarg from ``rbac_rule_validation`` decorator for identity
+ v2 admin tests, because the identity v2 admin API does not do policy
+ enforcement, and instead checks whether the request object has
+ ``context_is_admin``.
+other:
+ - |
+ Updated the class names for identity v2 tests to include the "Admin"
+ substring, to convey the fact that these tests are only intended
+ to test the v2 admin API, not the v2 API.
diff --git a/releasenotes/notes/encryption-types-c9a2d9a3c1996da4.yaml b/releasenotes/notes/encryption-types-c9a2d9a3c1996da4.yaml
new file mode 100644
index 0000000..7b6ae0c
--- /dev/null
+++ b/releasenotes/notes/encryption-types-c9a2d9a3c1996da4.yaml
@@ -0,0 +1,4 @@
+---
+features:
+ - |
+ Adds RBAC tests for the encryption types client.
diff --git a/releasenotes/notes/endpoint-filter-projects-7f64c88659ef0c30.yaml b/releasenotes/notes/endpoint-filter-projects-7f64c88659ef0c30.yaml
new file mode 100644
index 0000000..1537618
--- /dev/null
+++ b/releasenotes/notes/endpoint-filter-projects-7f64c88659ef0c30.yaml
@@ -0,0 +1,5 @@
+---
+features:
+ - |
+ Adds RBAC tests for the project-related endpoints belonging to the
+ OS-EP-FILTER Keystone v3 extension API.
diff --git a/releasenotes/notes/volumes-client-tests-d697a4a75d3e1405.yaml b/releasenotes/notes/volumes-client-tests-d697a4a75d3e1405.yaml
new file mode 100644
index 0000000..5dc9ff3
--- /dev/null
+++ b/releasenotes/notes/volumes-client-tests-d697a4a75d3e1405.yaml
@@ -0,0 +1,8 @@
+---
+features:
+ - Added tests for volumes client functions set
+ bootable, reserve, unreserve, and update metadata.
+other:
+ - Renamed update metadata item and delete metadata
+ item tests to accurately reflect what actions are
+ being performed.