Merge "Remove admin namespace throughout Patrole - Identity tests"
diff --git a/patrole_tempest_plugin/rbac_utils.py b/patrole_tempest_plugin/rbac_utils.py
index 4bfa7fe..d952014 100644
--- a/patrole_tempest_plugin/rbac_utils.py
+++ b/patrole_tempest_plugin/rbac_utils.py
@@ -14,7 +14,6 @@
# under the License.
import sys
-import testtools
import time
from oslo_log import log as logging
@@ -137,10 +136,11 @@
self.switch_role_history.setdefault(key, None)
if self.switch_role_history[key] == toggle_rbac_role:
- # If the test was skipped, then this is a legitimate use case,
- # so do not throw an exception.
- exc_value = sys.exc_info()[1]
- if not isinstance(exc_value, testtools.TestCase.skipException):
+ # If an exception was thrown, like a skipException or otherwise,
+ # then this is a legitimate reason why `switch_role` was not
+ # called, so only raise an exception if no current exception is
+ # being handled.
+ if sys.exc_info()[0] is None:
self.switch_role_history[key] = False
error_message = '`toggle_rbac_role` must not be called with '\
'the same bool value twice. Make sure that you included '\
diff --git a/patrole_tempest_plugin/tests/api/compute/admin/__init__.py b/patrole_tempest_plugin/tests/api/compute/admin/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/patrole_tempest_plugin/tests/api/compute/admin/__init__.py
+++ /dev/null
diff --git a/patrole_tempest_plugin/tests/api/compute/rbac_base.py b/patrole_tempest_plugin/tests/api/compute/rbac_base.py
index 9da50c6..b2f830e 100644
--- a/patrole_tempest_plugin/tests/api/compute/rbac_base.py
+++ b/patrole_tempest_plugin/tests/api/compute/rbac_base.py
@@ -11,11 +11,10 @@
# License for the specific language governing permissions and limitations
# under the License.
-from tempest.lib.common.utils import data_utils
-from tempest.lib.common.utils import test_utils
-
from tempest.api.compute import base as compute_base
from tempest import config
+from tempest.lib.common.utils import data_utils
+from tempest.lib.common.utils import test_utils
from patrole_tempest_plugin.rbac_utils import rbac_utils
@@ -40,34 +39,15 @@
cls.rbac_utils = rbac_utils()
cls.rbac_utils.switch_role(cls, toggle_rbac_role=False)
-
-class BaseV2ComputeAdminRbacTest(compute_base.BaseV2ComputeAdminTest):
-
- credentials = ['admin', 'primary']
-
- @classmethod
- def skip_checks(cls):
- super(BaseV2ComputeAdminRbacTest, cls).skip_checks()
- if not CONF.rbac.enable_rbac:
- raise cls.skipException(
- '%s skipped as RBAC flag not enabled' % cls.__name__)
-
- @classmethod
- def setup_clients(cls):
- super(BaseV2ComputeAdminRbacTest, cls).setup_clients()
- cls.auth_provider = cls.os.auth_provider
- cls.rbac_utils = rbac_utils()
- cls.rbac_utils.switch_role(cls, toggle_rbac_role=False)
-
@classmethod
def resource_setup(cls):
- super(BaseV2ComputeAdminRbacTest, cls).resource_setup()
+ super(BaseV2ComputeRbacTest, cls).resource_setup()
cls.flavors = []
@classmethod
def resource_cleanup(cls):
cls.clear_flavors()
- super(BaseV2ComputeAdminRbacTest, cls).resource_cleanup()
+ super(BaseV2ComputeRbacTest, cls).resource_cleanup()
@classmethod
def clear_flavors(cls):
diff --git a/patrole_tempest_plugin/tests/api/compute/admin/test_admin_password_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_admin_password_rbac.py
similarity index 73%
rename from patrole_tempest_plugin/tests/api/compute/admin/test_admin_password_rbac.py
rename to patrole_tempest_plugin/tests/api/compute/test_admin_password_rbac.py
index 2c9809e..08a06e6 100644
--- a/patrole_tempest_plugin/tests/api/compute/admin/test_admin_password_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_admin_password_rbac.py
@@ -13,8 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-import testtools
-
from tempest import config
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
@@ -26,27 +24,24 @@
CONF = config.CONF
-class PasswordAdminRbacTest(rbac_base.BaseV2ComputeAdminRbacTest):
-
- @classmethod
- def setup_clients(cls):
- super(PasswordAdminRbacTest, cls).setup_clients()
- cls.client = cls.servers_client
+class AdminPasswordRbacTest(rbac_base.BaseV2ComputeRbacTest):
@classmethod
def skip_checks(cls):
- super(PasswordAdminRbacTest, cls).skip_checks()
- if not CONF.compute_feature_enabled.api_extensions:
- raise cls.skipException(
- '%s skipped as no compute extensions enabled' % cls.__name__)
+ super(AdminPasswordRbacTest, cls).skip_checks()
+ if not CONF.compute_feature_enabled.change_password:
+ raise cls.skipException('Change password not available.')
+
+ @classmethod
+ def setup_clients(cls):
+ super(AdminPasswordRbacTest, cls).setup_clients()
+ cls.client = cls.servers_client
@classmethod
def resource_setup(cls):
- super(PasswordAdminRbacTest, cls).resource_setup()
+ super(AdminPasswordRbacTest, cls).resource_setup()
cls.server_id = cls.create_test_server(wait_until='ACTIVE')['id']
- @testtools.skipUnless(CONF.compute_feature_enabled.change_password,
- 'Change password not available.')
@rbac_rule_validation.action(
service="nova", rule="os_compute_api:os-admin-password")
@decorators.idempotent_id('908a7d59-3a66-441c-94cf-38e57ed14956')
diff --git a/patrole_tempest_plugin/tests/api/compute/admin/test_admin_server_actions_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_admin_server_actions_rbac.py
similarity index 82%
rename from patrole_tempest_plugin/tests/api/compute/admin/test_admin_server_actions_rbac.py
rename to patrole_tempest_plugin/tests/api/compute/test_admin_server_actions_rbac.py
index 2f0d03e..a2d23af 100644
--- a/patrole_tempest_plugin/tests/api/compute/admin/test_admin_server_actions_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_admin_server_actions_rbac.py
@@ -15,31 +15,31 @@
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 ServersAdminRbacTest(rbac_base.BaseV2ComputeAdminRbacTest):
+class AdminServerActionsRbacTest(rbac_base.BaseV2ComputeRbacTest):
@classmethod
def setup_clients(cls):
- super(ServersAdminRbacTest, cls).setup_clients()
+ super(AdminServerActionsRbacTest, cls).setup_clients()
cls.client = cls.servers_client
@classmethod
def skip_checks(cls):
- super(ServersAdminRbacTest, cls).skip_checks()
- if not CONF.compute_feature_enabled.api_extensions:
- raise cls.skipException(
- '%s skipped as no compute extensions enabled' % cls.__name__)
+ super(AdminServerActionsRbacTest, cls).skip_checks()
+ if not test.is_extension_enabled('os-admin-actions', 'compute'):
+ msg = "%s skipped as os-admin-actions not enabled." % cls.__name__
+ raise cls.skipException(msg)
@classmethod
def resource_setup(cls):
- super(ServersAdminRbacTest, cls).resource_setup()
+ super(AdminServerActionsRbacTest, cls).resource_setup()
cls.server_id = cls.create_test_server(wait_until='ACTIVE')['id']
@rbac_rule_validation.action(
diff --git a/patrole_tempest_plugin/tests/api/compute/test_flavor_access_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_flavor_access_rbac.py
index 5c3f55a..2019331 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_flavor_access_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_flavor_access_rbac.py
@@ -14,7 +14,6 @@
# under the License.
from oslo_config import cfg
-from oslo_log import log
from tempest.lib.common.utils import test_utils
from tempest.lib import decorators
@@ -24,19 +23,18 @@
from patrole_tempest_plugin.tests.api.compute import rbac_base
CONF = cfg.CONF
-LOG = log.getLogger(__name__)
-class FlavorAccessAdminRbacTest(rbac_base.BaseV2ComputeAdminRbacTest):
+class FlavorAccessRbacTest(rbac_base.BaseV2ComputeRbacTest):
@classmethod
def setup_clients(cls):
- super(FlavorAccessAdminRbacTest, cls).setup_clients()
+ super(FlavorAccessRbacTest, cls).setup_clients()
cls.client = cls.flavors_client
@classmethod
def skip_checks(cls):
- super(FlavorAccessAdminRbacTest, cls).skip_checks()
+ super(FlavorAccessRbacTest, cls).skip_checks()
if not test.is_extension_enabled('OS-FLV-EXT-DATA', 'compute'):
msg = "%s skipped as OS-FLV-EXT-DATA extension not enabled."\
% cls.__name__
@@ -44,7 +42,7 @@
@classmethod
def resource_setup(cls):
- super(FlavorAccessAdminRbacTest, cls).resource_setup()
+ super(FlavorAccessRbacTest, cls).resource_setup()
cls.flavor_id = cls._create_flavor(is_public=False)['id']
cls.public_flavor_id = CONF.compute.flavor_ref
cls.tenant_id = cls.auth_provider.credentials.tenant_id
diff --git a/patrole_tempest_plugin/tests/api/compute/test_flavor_extra_specs_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_flavor_extra_specs_rbac.py
index 0cf789b..0ee8d9a 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_flavor_extra_specs_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_flavor_extra_specs_rbac.py
@@ -22,30 +22,30 @@
from patrole_tempest_plugin.tests.api.compute import rbac_base
-class FlavorExtraSpecsAdminRbacTest(rbac_base.BaseV2ComputeAdminRbacTest):
+class FlavorExtraSpecsRbacTest(rbac_base.BaseV2ComputeRbacTest):
@classmethod
def setup_clients(cls):
- super(FlavorExtraSpecsAdminRbacTest, cls).setup_clients()
+ super(FlavorExtraSpecsRbacTest, cls).setup_clients()
cls.client = cls.flavors_client
@classmethod
def skip_checks(cls):
- super(FlavorExtraSpecsAdminRbacTest, cls).skip_checks()
+ super(FlavorExtraSpecsRbacTest, cls).skip_checks()
if not test.is_extension_enabled('os-flavor-extra-specs', 'compute'):
msg = "os-flavor-extra-specs extension not enabled."
raise cls.skipException(msg)
@classmethod
def resource_setup(cls):
- super(FlavorExtraSpecsAdminRbacTest, cls).resource_setup()
+ super(FlavorExtraSpecsRbacTest, cls).resource_setup()
cls.flavor = cls._create_flavor()
@classmethod
def resource_cleanup(cls):
cls.client.delete_flavor(cls.flavor['id'])
cls.client.wait_for_resource_deletion(cls.flavor['id'])
- super(FlavorExtraSpecsAdminRbacTest, cls).resource_cleanup()
+ super(FlavorExtraSpecsRbacTest, cls).resource_cleanup()
def _set_flavor_extra_spec(self):
rand_key = data_utils.rand_name('key')
diff --git a/patrole_tempest_plugin/tests/api/compute/test_flavor_rxtx_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_flavor_rxtx_rbac.py
index bc33d3b..7f070eb 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_flavor_rxtx_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_flavor_rxtx_rbac.py
@@ -20,16 +20,16 @@
from patrole_tempest_plugin.tests.api.compute import rbac_base
-class FlavorRxtxAdminRbacTest(rbac_base.BaseV2ComputeAdminRbacTest):
+class FlavorRxtxRbacTest(rbac_base.BaseV2ComputeRbacTest):
@classmethod
def setup_clients(cls):
- super(FlavorRxtxAdminRbacTest, cls).setup_clients()
+ super(FlavorRxtxRbacTest, cls).setup_clients()
cls.client = cls.flavors_client
@classmethod
def skip_checks(cls):
- super(FlavorRxtxAdminRbacTest, cls).skip_checks()
+ super(FlavorRxtxRbacTest, cls).skip_checks()
if not test.is_extension_enabled('os-flavor-rxtx', 'compute'):
msg = "os-flavor-rxtx extension not enabled."
raise cls.skipException(msg)
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 b03de11..53e3a70 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_hosts_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_hosts_rbac.py
@@ -22,16 +22,16 @@
CONF = config.CONF
-class HostsAdminRbacTest(rbac_base.BaseV2ComputeAdminRbacTest):
+class HostsRbacTest(rbac_base.BaseV2ComputeRbacTest):
@classmethod
def setup_clients(cls):
- super(HostsAdminRbacTest, cls).setup_clients()
+ super(HostsRbacTest, cls).setup_clients()
cls.client = cls.os.hosts_client
@classmethod
def skip_checks(cls):
- super(HostsAdminRbacTest, cls).skip_checks()
+ 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__)
diff --git a/patrole_tempest_plugin/tests/api/compute/test_hypervisor_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_hypervisor_rbac.py
index 36ac916..ecd0fd3 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_hypervisor_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_hypervisor_rbac.py
@@ -20,16 +20,16 @@
from patrole_tempest_plugin.tests.api.compute import rbac_base
-class HypervisorAdminRbacTest(rbac_base.BaseV2ComputeAdminRbacTest):
+class HypervisorRbacTest(rbac_base.BaseV2ComputeRbacTest):
@classmethod
def setup_clients(cls):
- super(HypervisorAdminRbacTest, cls).setup_clients()
+ super(HypervisorRbacTest, cls).setup_clients()
cls.client = cls.hypervisor_client
@classmethod
def skip_checks(cls):
- super(HypervisorAdminRbacTest, cls).skip_checks()
+ super(HypervisorRbacTest, cls).skip_checks()
if not test.is_extension_enabled('os-hypervisors', 'compute'):
msg = "%s skipped as os-hypervisors extension not enabled." \
% cls.__name__
diff --git a/patrole_tempest_plugin/tests/api/compute/test_instance_usages_audit_log_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_instance_usages_audit_log_rbac.py
index 7b116e4..cff3167 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_instance_usages_audit_log_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_instance_usages_audit_log_rbac.py
@@ -20,12 +20,12 @@
from patrole_tempest_plugin.tests.api.compute import rbac_base
-class InstanceUsagesAuditLogAdminRbacTest(
- rbac_base.BaseV2ComputeAdminRbacTest):
+class InstanceUsagesAuditLogRbacTest(
+ rbac_base.BaseV2ComputeRbacTest):
@classmethod
def skip_checks(cls):
- super(InstanceUsagesAuditLogAdminRbacTest, cls).skip_checks()
+ super(InstanceUsagesAuditLogRbacTest, cls).skip_checks()
if not test.is_extension_enabled('os-instance-usage-audit-log',
'compute'):
msg = "os-instance-usage-audit-log extension not enabled."
@@ -33,7 +33,7 @@
@classmethod
def setup_clients(cls):
- super(InstanceUsagesAuditLogAdminRbacTest, cls).setup_clients()
+ super(InstanceUsagesAuditLogRbacTest, cls).setup_clients()
cls.client = cls.instance_usages_audit_log_client
@decorators.idempotent_id('c80246c0-5c13-4ab0-97ba-91551cd53dc1')
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 0a21bcb..fda9071 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_migrations_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_migrations_rbac.py
@@ -22,16 +22,16 @@
CONF = config.CONF
-class MigrationsAdminRbacTest(rbac_base.BaseV2ComputeAdminRbacTest):
+class MigrationsRbacTest(rbac_base.BaseV2ComputeRbacTest):
@classmethod
def setup_clients(cls):
- super(MigrationsAdminRbacTest, cls).setup_clients()
+ super(MigrationsRbacTest, cls).setup_clients()
cls.client = cls.migrations_client
@classmethod
def skip_checks(cls):
- super(MigrationsAdminRbacTest, cls).skip_checks()
+ 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__)
diff --git a/patrole_tempest_plugin/tests/api/compute/test_services_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_services_rbac.py
index c25303f..82de5a3 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_services_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_services_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 ServicesAdminRbacTest(rbac_base.BaseV2ComputeAdminRbacTest):
+class ServicesRbacTest(rbac_base.BaseV2ComputeRbacTest):
@classmethod
def setup_clients(cls):
- super(ServicesAdminRbacTest, cls).setup_clients()
+ super(ServicesRbacTest, cls).setup_clients()
cls.client = cls.services_client
@classmethod
def skip_checks(cls):
- super(ServicesAdminRbacTest, cls).skip_checks()
- if not CONF.compute_feature_enabled.api_extensions:
+ super(ServicesRbacTest, cls).skip_checks()
+ if not test.is_extension_enabled('os-services', 'compute'):
raise cls.skipException(
- '%s skipped as no compute extensions enabled' % cls.__name__)
+ '%s skipped as os-services not enabled' % cls.__name__)
@rbac_rule_validation.action(
service="nova",
diff --git a/patrole_tempest_plugin/tests/api/image/v2/test_image_namespace_objects_rbac.py b/patrole_tempest_plugin/tests/api/image/v2/test_image_namespace_objects_rbac.py
index e7c7199..1c937b0 100644
--- a/patrole_tempest_plugin/tests/api/image/v2/test_image_namespace_objects_rbac.py
+++ b/patrole_tempest_plugin/tests/api/image/v2/test_image_namespace_objects_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,8 +20,6 @@
from patrole_tempest_plugin import rbac_rule_validation
from patrole_tempest_plugin.tests.api.image import rbac_base
-CONF = config.CONF
-
class ImageNamespacesObjectsRbacTest(rbac_base.BaseV2ImageRbacTest):
diff --git a/patrole_tempest_plugin/tests/api/image/v2/test_image_namespace_property_rbac.py b/patrole_tempest_plugin/tests/api/image/v2/test_image_namespace_property_rbac.py
index 946837e..0d194b7 100644
--- a/patrole_tempest_plugin/tests/api/image/v2/test_image_namespace_property_rbac.py
+++ b/patrole_tempest_plugin/tests/api/image/v2/test_image_namespace_property_rbac.py
@@ -13,15 +13,12 @@
# 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 import decorators
from patrole_tempest_plugin import rbac_rule_validation
from patrole_tempest_plugin.tests.api.image import rbac_base
-CONF = config.CONF
-
class NamespacesPropertyRbacTest(rbac_base.BaseV2ImageRbacTest):
diff --git a/patrole_tempest_plugin/tests/api/image/v2/test_image_namespace_rbac.py b/patrole_tempest_plugin/tests/api/image/v2/test_image_namespace_rbac.py
index 1010796..fb4a599 100644
--- a/patrole_tempest_plugin/tests/api/image/v2/test_image_namespace_rbac.py
+++ b/patrole_tempest_plugin/tests/api/image/v2/test_image_namespace_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,8 +20,6 @@
from patrole_tempest_plugin import rbac_rule_validation
from patrole_tempest_plugin.tests.api.image import rbac_base
-CONF = config.CONF
-
class ImageNamespacesRbacTest(rbac_base.BaseV2ImageRbacTest):
diff --git a/patrole_tempest_plugin/tests/api/image/v2/test_image_namespace_tags_rbac.py b/patrole_tempest_plugin/tests/api/image/v2/test_image_namespace_tags_rbac.py
new file mode 100644
index 0000000..cfd544c
--- /dev/null
+++ b/patrole_tempest_plugin/tests/api/image/v2/test_image_namespace_tags_rbac.py
@@ -0,0 +1,112 @@
+# 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.common.utils import test_utils
+from tempest.lib import decorators
+
+from patrole_tempest_plugin import rbac_rule_validation
+from patrole_tempest_plugin.tests.api.image import rbac_base as base
+
+
+class NamespaceTagsRbacTest(base.BaseV2ImageRbacTest):
+ """RBAC tests for namespace_tags_client.
+
+ Performs RBAC testing for the endpoints in namespace_tags_client, except
+ for
+
+ 1) delete_namespace_tag
+ 2) delete_namespace_tags
+
+ because Glance does not currently do policy enforcement for them.
+ """
+
+ @classmethod
+ def setup_clients(cls):
+ super(NamespaceTagsRbacTest, cls).setup_clients()
+ cls.client = cls.namespace_tags_client
+
+ @classmethod
+ def resource_setup(cls):
+ super(NamespaceTagsRbacTest, cls).resource_setup()
+ cls.namespace = cls.namespaces_client.create_namespace(
+ namespace=data_utils.rand_name('namespace'))['namespace']
+
+ @classmethod
+ def resource_cleanup(cls):
+ cls.namespaces_client.delete_namespace(cls.namespace)
+ super(NamespaceTagsRbacTest, cls).resource_cleanup()
+
+ def _create_namespace_tag(self, multiple=False):
+ tag_count = 2 if multiple else 1
+ namespace_tag_names = []
+
+ for i in range(tag_count):
+ tag_name = data_utils.rand_name('tag')
+ namespace_tag_names.append({'name': tag_name})
+
+ if multiple:
+ namespace_tags = self.client.create_namespace_tags(
+ self.namespace, tags=namespace_tag_names)['tags']
+ else:
+ namespace_tags = self.client.create_namespace_tag(
+ self.namespace, namespace_tag_names[0]['name'])
+
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.client.delete_namespace_tags,
+ self.namespace)
+
+ return [nt['name'] for nt in namespace_tags] if multiple \
+ else namespace_tags['name']
+
+ @decorators.idempotent_id('50bedccb-9d0b-4138-8d95-31a89250edf6')
+ @rbac_rule_validation.action(service="glance",
+ rule="add_metadef_tag")
+ def test_create_namespace_tag(self):
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self._create_namespace_tag()
+
+ @decorators.idempotent_id('4acf70cc-05da-4b1e-87b2-d5e4475164e7')
+ @rbac_rule_validation.action(service="glance",
+ rule="get_metadef_tag")
+ def test_show_namespace_tag(self):
+ tag_name = self._create_namespace_tag()
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.client.show_namespace_tag(self.namespace, tag_name)
+
+ @decorators.idempotent_id('01593828-3edb-461e-8abc-8fdeb3927e37')
+ @rbac_rule_validation.action(service="glance",
+ rule="modify_metadef_tag")
+ def test_update_namespace_tag(self):
+ tag_name = self._create_namespace_tag()
+ updated_tag_name = data_utils.rand_name('tag')
+
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.client.update_namespace_tag(self.namespace, tag_name,
+ name=updated_tag_name)
+
+ @decorators.idempotent_id('20ffaf76-ebdc-4267-a1ad-194346f5cc91')
+ @rbac_rule_validation.action(service="glance",
+ rule="add_metadef_tags")
+ def test_create_namespace_tags(self):
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self._create_namespace_tag(multiple=True)
+
+ @decorators.idempotent_id('d37c1501-e787-449d-89b3-754a942a459a')
+ @rbac_rule_validation.action(service="glance",
+ rule="get_metadef_tags")
+ def test_list_namespace_tags(self):
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.client.list_namespace_tags(self.namespace)
diff --git a/patrole_tempest_plugin/tests/api/image/v2/test_image_namespace_resource_type.py b/patrole_tempest_plugin/tests/api/image/v2/test_image_resource_types_rbac.py
similarity index 94%
rename from patrole_tempest_plugin/tests/api/image/v2/test_image_namespace_resource_type.py
rename to patrole_tempest_plugin/tests/api/image/v2/test_image_resource_types_rbac.py
index 87d88c0..94c704f 100644
--- a/patrole_tempest_plugin/tests/api/image/v2/test_image_namespace_resource_type.py
+++ b/patrole_tempest_plugin/tests/api/image/v2/test_image_resource_types_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,10 +20,8 @@
from patrole_tempest_plugin import rbac_rule_validation
from patrole_tempest_plugin.tests.api.image import rbac_base
-CONF = config.CONF
-
-class ImageNamespacesResourceTypeRbacTest(rbac_base.BaseV2ImageRbacTest):
+class ImageResourceTypesRbacTest(rbac_base.BaseV2ImageRbacTest):
@rbac_rule_validation.action(service="glance",
rule="list_metadef_resource_types")
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 16d27f3..07d4015 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
@@ -13,16 +13,11 @@
# 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
from patrole_tempest_plugin import rbac_rule_validation
from patrole_tempest_plugin.tests.api.image import rbac_base as base
-CONF = config.CONF
-LOG = logging.getLogger(__name__)
-
class ImagesMemberRbacTest(base.BaseV2ImageRbacTest):
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 456b6ec..fa492bb 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
@@ -15,17 +15,12 @@
from six import moves
-from oslo_log import log as logging
-from tempest import config
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
from patrole_tempest_plugin import rbac_rule_validation
from patrole_tempest_plugin.tests.api.image import rbac_base
-CONF = config.CONF
-LOG = logging.getLogger(__name__)
-
class BasicOperationsImagesRbacTest(rbac_base.BaseV2ImageRbacTest):
diff --git a/patrole_tempest_plugin/tests/api/volume/admin/__init__.py b/patrole_tempest_plugin/tests/api/volume/admin/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/patrole_tempest_plugin/tests/api/volume/admin/__init__.py
+++ /dev/null
diff --git a/patrole_tempest_plugin/tests/api/volume/admin/test_volumes_backup_admin_rbac.py b/patrole_tempest_plugin/tests/api/volume/admin/test_volumes_backup_admin_rbac.py
deleted file mode 100644
index e3d2438..0000000
--- a/patrole_tempest_plugin/tests/api/volume/admin/test_volumes_backup_admin_rbac.py
+++ /dev/null
@@ -1,88 +0,0 @@
-# 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 oslo_serialization import base64
-from oslo_serialization import jsonutils as json
-from tempest import config
-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
-
-CONF = config.CONF
-
-
-class VolumesBackupsAdminRbacTest(rbac_base.BaseVolumeAdminRbacTest):
-
- @classmethod
- def skip_checks(cls):
- super(VolumesBackupsAdminRbacTest, cls).skip_checks()
- if not CONF.volume_feature_enabled.backup:
- raise cls.skipException("Cinder backup feature disabled")
-
- @classmethod
- def resource_setup(cls):
- super(VolumesBackupsAdminRbacTest, cls).resource_setup()
- cls.volume = cls.create_volume()
-
- def _decode_url(self, backup_url):
- return json.loads(base64.decode_as_text(backup_url))
-
- def _encode_backup(self, backup):
- retval = json.dumps(backup)
- return base64.encode_as_text(retval)
-
- def _modify_backup_url(self, backup_url, changes):
- backup = self._decode_url(backup_url)
- backup.update(changes)
- return self._encode_backup(backup)
-
- @test.attr(type='slow')
- @rbac_rule_validation.action(service="cinder",
- rule="backup:backup-export")
- @decorators.idempotent_id('e984ec8d-e8eb-485c-98bc-f1856020303c')
- def test_volume_backup_export(self):
- # Create a temp backup
- backup = self.create_backup(volume_id=self.volume['id'])
- # Export Backup
- self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- self.backups_client.export_backup(
- backup['id'])['backup-record']
-
- @test.attr(type='slow')
- @rbac_rule_validation.action(service="cinder",
- rule="backup:backup-import")
- @decorators.idempotent_id('1e70f039-4556-44cc-9cc1-edf2b7ed648b')
- def test_volume_backup_import(self):
- # Create a temp backup
- backup = self.create_backup(volume_id=self.volume['id'])
- # Export a temp backup
- export_backup = self.backups_client.export_backup(
- backup['id'])['backup-record']
- new_id = data_utils.rand_uuid()
- new_url = self._modify_backup_url(
- export_backup['backup_url'], {'id': new_id})
- # Import the temp backup
- self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- import_backup = self.backups_client.import_backup(
- backup_service=export_backup['backup_service'],
- backup_url=new_url)['backup']
- self.addCleanup(self.backups_client.delete_backup, import_backup['id'])
-
-
-class VolumesBackupsAdminV3RbacTest(VolumesBackupsAdminRbacTest):
- _api_version = 3
diff --git a/patrole_tempest_plugin/tests/api/volume/rbac_base.py b/patrole_tempest_plugin/tests/api/volume/rbac_base.py
index d47f8ff..a2d5345 100644
--- a/patrole_tempest_plugin/tests/api/volume/rbac_base.py
+++ b/patrole_tempest_plugin/tests/api/volume/rbac_base.py
@@ -28,33 +28,16 @@
super(BaseVolumeRbacTest, cls).skip_checks()
if not CONF.rbac.enable_rbac:
raise cls.skipException(
- "%s skipped as RBAC Flag not enabled" % cls.__name__)
+ "%s skipped as RBAC testing not enabled" % cls.__name__)
@classmethod
def setup_clients(cls):
super(BaseVolumeRbacTest, cls).setup_clients()
cls.auth_provider = cls.os.auth_provider
+
cls.rbac_utils = rbac_utils()
cls.rbac_utils.switch_role(cls, toggle_rbac_role=False)
-
-class BaseVolumeAdminRbacTest(vol_base.BaseVolumeAdminTest):
-
- credentials = ['admin', 'primary']
-
- @classmethod
- def skip_checks(cls):
- super(BaseVolumeAdminRbacTest, cls).skip_checks()
- if not CONF.rbac.enable_rbac:
- raise cls.skipException(
- "%s skipped as RBAC Flag not enabled" % cls.__name__)
-
- @classmethod
- def setup_clients(cls):
- super(BaseVolumeAdminRbacTest, cls).setup_clients()
- cls.auth_provider = cls.os.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],
diff --git a/patrole_tempest_plugin/tests/api/volume/test_availability_zone_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_availability_zone_rbac.py
deleted file mode 100644
index 95b5949..0000000
--- a/patrole_tempest_plugin/tests/api/volume/test_availability_zone_rbac.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# 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 import config
-from tempest.lib import decorators
-
-from patrole_tempest_plugin import rbac_rule_validation
-from patrole_tempest_plugin.tests.api.volume import rbac_base
-
-CONF = config.CONF
-
-
-class AvailabilityZoneRbacTest(rbac_base.BaseVolumeRbacTest):
-
- @classmethod
- def setup_clients(cls):
- super(AvailabilityZoneRbacTest, cls).setup_clients()
- cls.client = cls.availability_zone_client
-
- @rbac_rule_validation.action(service="cinder",
- rule="volume:availability_zone_list")
- @decorators.idempotent_id('8cfd920c-4b6c-402d-b6e2-ede86bedc702')
- def test_get_availability_zone_list(self):
- self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- self.client.list_availability_zones()
diff --git a/patrole_tempest_plugin/tests/api/volume/test_extensions_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_extensions_rbac.py
deleted file mode 100644
index 3304452..0000000
--- a/patrole_tempest_plugin/tests/api/volume/test_extensions_rbac.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# 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 import config
-from tempest.lib import decorators
-
-from patrole_tempest_plugin import rbac_rule_validation
-from patrole_tempest_plugin.tests.api.volume import rbac_base
-
-CONF = config.CONF
-
-
-class ExtensionsRbacTest(rbac_base.BaseVolumeRbacTest):
-
- @rbac_rule_validation.action(service="cinder",
- rule="volume:list_extensions")
- @decorators.idempotent_id('7f2dcc41-e850-493f-a400-82db4e2b50c0')
- def test_list_extensions(self):
- self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- self.volumes_extension_client.list_extensions()
-
-
-class ExtensionsV3RbacTest(ExtensionsRbacTest):
- _api_version = 3
diff --git a/patrole_tempest_plugin/tests/api/volume/admin/test_qos_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_qos_rbac.py
similarity index 86%
rename from patrole_tempest_plugin/tests/api/volume/admin/test_qos_rbac.py
rename to patrole_tempest_plugin/tests/api/volume/test_qos_rbac.py
index 74230a7..c3cca0d 100644
--- a/patrole_tempest_plugin/tests/api/volume/admin/test_qos_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_qos_rbac.py
@@ -14,22 +14,30 @@
# under the License.
from tempest.common import waiters
-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 patrole_tempest_plugin import rbac_rule_validation
from patrole_tempest_plugin.tests.api.volume import rbac_base
-CONF = config.CONF
-
-class VolumeQOSRbacTest(rbac_base.BaseVolumeAdminRbacTest):
+class VolumeQOSRbacTest(rbac_base.BaseVolumeRbacTest):
@classmethod
def setup_clients(cls):
super(VolumeQOSRbacTest, cls).setup_clients()
cls.auth_provider = cls.os.auth_provider
- cls.client = cls.admin_volume_qos_client
+ cls.client = cls.os.volume_qos_v2_client
+
+ def _create_test_qos_specs(self, name=None, consumer=None, **kwargs):
+ """Create a test Qos-Specs."""
+ name = name or data_utils.rand_name(self.__class__.__name__ + '-QoS')
+ consumer = consumer or 'front-end'
+ qos_specs = self.client.create_qos(
+ name=name, consumer=consumer, **kwargs)['qos_specs']
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.client.delete_qos, qos_specs['id'])
+ return qos_specs
@rbac_rule_validation.action(
service="cinder", rule="volume_extension:qos_specs_manage:create")
@@ -37,14 +45,14 @@
def test_create_qos_with_consumer(self):
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
# Create a qos
- self.create_test_qos_specs()
+ self._create_test_qos_specs()
@rbac_rule_validation.action(
service="cinder", rule="volume_extension:qos_specs_manage:delete")
@decorators.idempotent_id('fbc8a77e-6b6d-45ae-bebe-c496eb8f06f7')
def test_delete_qos_with_consumer(self):
# Create a qos
- qos = self.create_test_qos_specs()
+ qos = self._create_test_qos_specs()
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
# Delete a qos
self.client.delete_qos(qos['id'])
@@ -54,7 +62,7 @@
@decorators.idempotent_id('22aff0dd-0343-408d-ae80-e77551956e14')
def test_get_qos(self):
# Create a qos
- qos = self.create_test_qos_specs()
+ qos = self._create_test_qos_specs()
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
# Get a qos
self.client.show_qos(qos['id'])['qos_specs']
@@ -72,7 +80,7 @@
@decorators.idempotent_id('89b630b7-c170-47c3-ac80-50ed425c2d98')
def test_set_qos_key(self):
# Create a qos
- qos = self.create_test_qos_specs()
+ qos = self._create_test_qos_specs()
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
# set key
self.client.set_qos_key(qos['id'], iops_bytes='500')['qos_specs']
@@ -82,7 +90,7 @@
@decorators.idempotent_id('6c50c837-de77-4dae-a2ec-30e05c62969c')
def test_unset_qos_key(self):
# Create a qos
- qos = self.create_test_qos_specs()
+ qos = self._create_test_qos_specs()
# Set key
self.client.set_qos_key(qos['id'], iops_bytes='500')['qos_specs']
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
@@ -98,7 +106,7 @@
@decorators.idempotent_id('2047b347-8bbe-405e-bf5a-c75a0d7e3930')
def test_associate_qos(self):
# Create a qos
- qos = self.create_test_qos_specs()
+ qos = self._create_test_qos_specs()
# create a test volume-type
vol_type = self.create_volume_type()['id']
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
@@ -111,7 +119,7 @@
@decorators.idempotent_id('ff1e98f3-d456-40a9-96d4-c7e4a55dcffa')
def test_get_association_qos(self):
# create a test volume-type
- qos = self.create_test_qos_specs()
+ qos = self._create_test_qos_specs()
vol_type = self.create_volume_type()['id']
# associate the qos-specs with volume-types
self.client.associate_qos(qos['id'], vol_type)
@@ -125,7 +133,7 @@
@decorators.idempotent_id('f12aeca1-0c02-4f33-b805-014171e5b2d4')
def test_disassociate_qos(self):
# create a test volume-type
- qos = self.create_test_qos_specs()
+ qos = self._create_test_qos_specs()
vol_type = self.create_volume_type()['id']
# associate the qos-specs with volume-types
self.client.associate_qos(qos['id'], vol_type)
@@ -142,7 +150,7 @@
service="cinder", rule="volume_extension:qos_specs_manage:update")
@decorators.idempotent_id('9f6e664d-a5d9-4e71-b122-73a3086be1b9')
def test_disassociate_all_qos(self):
- qos = self.create_test_qos_specs()
+ qos = self._create_test_qos_specs()
# create a test volume-type
vol_type = self.create_volume_type()['id']
# associate the qos-specs with volume-types
diff --git a/patrole_tempest_plugin/tests/api/volume/test_snapshots_metadata_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_snapshots_metadata_rbac.py
index bf48716..81cd854 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_snapshots_metadata_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_snapshots_metadata_rbac.py
@@ -57,7 +57,7 @@
self._create_test_snapshot_metadata()
@rbac_rule_validation.action(service="cinder",
- rule="volume:get_volume_image_metadata")
+ rule="volume:get_snapshot_metadata")
@decorators.idempotent_id('f6912bb1-62e6-483d-bcd0-e98c1641f4c3')
def test_get_snapshot_metadata(self):
# Create volume and snapshot metadata
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 e1f9430..70c73fc 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
@@ -73,7 +73,7 @@
@test.attr(type="slow")
@rbac_rule_validation.action(service="cinder", rule="volume:detach")
@decorators.idempotent_id('5a042f6a-688b-42e6-a02e-fe5c47b89b07')
- def test_detach_volume_to_instance(self):
+ def test_detach_volume_from_instance(self):
# Attach the volume
server = self._create_server()
self._attach_volume(server)
diff --git a/patrole_tempest_plugin/tests/api/volume/test_volume_basic_crud.py b/patrole_tempest_plugin/tests/api/volume/test_volume_basic_crud_rbac.py
similarity index 97%
rename from patrole_tempest_plugin/tests/api/volume/test_volume_basic_crud.py
rename to patrole_tempest_plugin/tests/api/volume/test_volume_basic_crud_rbac.py
index 6bc9e4e..b98c39a 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_volume_basic_crud.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_volume_basic_crud_rbac.py
@@ -57,7 +57,7 @@
@rbac_rule_validation.action(
service="cinder",
- rule="volume_extension:get_volumes_image_metadata")
+ rule="volume_extension:volume_image_metadata")
@decorators.idempotent_id('3d48ca91-f02b-4616-a69d-4a8b296c8529')
def test_volume_list_image_metadata(self):
# Get a list of Volumes
diff --git a/patrole_tempest_plugin/tests/api/volume/test_volume_hosts_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_volume_hosts_rbac.py
index d4d010b..18a2768 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_volume_hosts_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_volume_hosts_rbac.py
@@ -19,7 +19,7 @@
from patrole_tempest_plugin.tests.api.volume import rbac_base
-class VolumeHostsAdminRbacTest(rbac_base.BaseVolumeAdminRbacTest):
+class VolumeHostsRbacTest(rbac_base.BaseVolumeRbacTest):
@rbac_rule_validation.action(service="cinder",
rule="volume_extension:hosts")
diff --git a/patrole_tempest_plugin/tests/api/volume/admin/test_volume_quotas_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_volume_quotas_rbac.py
similarity index 89%
rename from patrole_tempest_plugin/tests/api/volume/admin/test_volume_quotas_rbac.py
rename to patrole_tempest_plugin/tests/api/volume/test_volume_quotas_rbac.py
index 28adfa7..a104782 100644
--- a/patrole_tempest_plugin/tests/api/volume/admin/test_volume_quotas_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_volume_quotas_rbac.py
@@ -27,16 +27,16 @@
LOG = logging.getLogger(__name__)
-class VolumeQuotasAdminRbacTest(rbac_base.BaseVolumeAdminRbacTest):
+class VolumeQuotasRbacTest(rbac_base.BaseVolumeRbacTest):
@classmethod
def setup_credentials(cls):
- super(VolumeQuotasAdminRbacTest, cls).setup_credentials()
+ super(VolumeQuotasRbacTest, cls).setup_credentials()
cls.demo_tenant_id = cls.os.credentials.tenant_id
@classmethod
def setup_clients(cls):
- super(VolumeQuotasAdminRbacTest, cls).setup_clients()
+ super(VolumeQuotasRbacTest, cls).setup_clients()
cls.client = cls.os.volume_quotas_client
@rbac_rule_validation.action(service="cinder",
@@ -61,5 +61,5 @@
**new_quota_set)['quota_set']
-class VolumeQuotasAdminV3RbacTest(VolumeQuotasAdminRbacTest):
+class VolumeQuotasV3RbacTest(VolumeQuotasRbacTest):
_api_version = 3
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 6978166..33bc5ae 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,22 +13,30 @@
# 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 import decorators
from patrole_tempest_plugin import rbac_rule_validation
from patrole_tempest_plugin.tests.api.volume import rbac_base
-CONF = config.CONF
+class VolumeTypesExtraSpecsRbacTest(rbac_base.BaseVolumeRbacTest):
-class VolumeTypesExtraSpecsAdminRbacTest(rbac_base.BaseVolumeAdminRbacTest):
+ 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_volume_type_extra_specs_list(self):
- vol_type = self.create_volume_type()
+ def test_create_volume_type_extra_specs(self):
+ 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 6e1b9f1..6a3367a 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
@@ -13,6 +13,9 @@
# License for the specific language governing permissions and limitations
# under the License.
+from oslo_serialization import base64
+from oslo_serialization import jsonutils as json
+
from tempest.common import waiters
from tempest import config
from tempest.lib.common.utils import data_utils
@@ -50,6 +53,18 @@
self.backups_client, backup['id'], 'available')
return backup
+ def _decode_url(self, backup_url):
+ return json.loads(base64.decode_as_text(backup_url))
+
+ def _encode_backup(self, backup):
+ retval = json.dumps(backup)
+ return base64.encode_as_text(retval)
+
+ def _modify_backup_url(self, backup_url, changes):
+ backup = self._decode_url(backup_url)
+ backup.update(changes)
+ return self._encode_backup(backup)
+
@test.attr(type="slow")
@rbac_rule_validation.action(service="cinder",
rule="backup:create")
@@ -101,6 +116,39 @@
self.backups_client.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')
+ def test_volume_backup_export(self):
+ # Create a temp backup
+ backup = self._create_backup(volume_id=self.volume['id'])
+
+ # Export Backup
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.backups_client.export_backup(backup['id'])['backup-record']
+
+ @test.attr(type='slow')
+ @rbac_rule_validation.action(service="cinder",
+ rule="backup:backup-import")
+ @decorators.idempotent_id('1e70f039-4556-44cc-9cc1-edf2b7ed648b')
+ def test_volume_backup_import(self):
+ # Create a temp backup
+ backup = self._create_backup(volume_id=self.volume['id'])
+ # Export a temp backup
+ export_backup = self.backups_client.export_backup(
+ backup['id'])['backup-record']
+ new_id = data_utils.rand_uuid()
+ new_url = self._modify_backup_url(
+ export_backup['backup_url'], {'id': new_id})
+
+ # Import the temp backup
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ import_backup = self.backups_client.import_backup(
+ backup_service=export_backup['backup_service'],
+ backup_url=new_url)['backup']
+ self.addCleanup(self.backups_client.delete_backup, import_backup['id'])
+
class VolumesBackupsV3RbacTest(VolumesBackupsRbacTest):
_api_version = 3
diff --git a/patrole_tempest_plugin/tests/unit/test_rbac_rule_validation.py b/patrole_tempest_plugin/tests/unit/test_rbac_rule_validation.py
index 38b5fea..78d8e66 100644
--- a/patrole_tempest_plugin/tests/unit/test_rbac_rule_validation.py
+++ b/patrole_tempest_plugin/tests/unit/test_rbac_rule_validation.py
@@ -274,6 +274,11 @@
def test_invalid_policy_rule_throws_parsing_exception(
self, mock_rbac_policy_parser):
"""Test that invalid policy action causes test to be skipped."""
+ CONF.set_override('strict_policy_check', True, group='rbac',
+ enforce_type=True)
+ self.addCleanup(CONF.clear_override, 'strict_policy_check',
+ group='rbac')
+
mock_rbac_policy_parser.RbacPolicyParser.return_value.allowed.\
side_effect = rbac_exceptions.RbacParsingException
diff --git a/patrole_tempest_plugin/tests/unit/test_rbac_utils.py b/patrole_tempest_plugin/tests/unit/test_rbac_utils.py
index feccfe5..057ce20 100644
--- a/patrole_tempest_plugin/tests/unit/test_rbac_utils.py
+++ b/patrole_tempest_plugin/tests/unit/test_rbac_utils.py
@@ -195,23 +195,38 @@
autospec=True, return_value=False)
@mock.patch.object(rbac_utils, 'LOG', autospec=True)
@mock.patch.object(rbac_utils, 'sys', autospec=True)
- def test_rbac_utils_switch_roles_with_skip_exception(self, mock_sys,
- mock_log, _):
+ def test_rbac_utils_switch_roles_with_unhandled_exception(self, mock_sys,
+ mock_log, _):
+ """Test whether throwing an unhandled exception doesn't throw error.
+
+ If a skip exception, say, is thrown then this means that switch_role is
+ never called within the test function. But if an unhandled exception
+ or skip exception is thrown, then this should not result in an error
+ being raised.
+ """
self._mock_list_user_roles_on_project('member_id')
- mock_skip_exception = mock.Mock(spec=testtools.TestCase.skipException)
- mock_sys.exc_info.return_value = [None, mock_skip_exception]
+ # Skip exception is an example of a legitimate case where `switch_role`
+ # is thrown. AttributeError, on the other hand, is an example of an
+ # unexpected exception being thrown that should be allowed to bubble
+ # up, rather than being obfuscated by `switch_role` error being thrown
+ # instead.
+ unhandled_exceptions = [testtools.TestCase.skipException,
+ AttributeError]
- # Ordinarily switching to the same role would result in an error,
- # but because the skipException is thrown before the test finishes,
- # this is not treated as a failure.
- self.rbac_utils.switch_role(self.mock_test_obj, False)
- self.rbac_utils.switch_role(self.mock_test_obj, False)
- mock_log.error.assert_not_called()
+ for unhandled_exception in unhandled_exceptions:
+ mock_sys.exc_info.return_value = [unhandled_exception]
- self.rbac_utils.switch_role(self.mock_test_obj, True)
- self.rbac_utils.switch_role(self.mock_test_obj, True)
- mock_log.error.assert_not_called()
+ # Ordinarily switching to the same role would result in an error,
+ # but because the skipException is thrown before the test finishes,
+ # this is not treated as a failure.
+ self.rbac_utils.switch_role(self.mock_test_obj, False)
+ self.rbac_utils.switch_role(self.mock_test_obj, False)
+ mock_log.error.assert_not_called()
+
+ self.rbac_utils.switch_role(self.mock_test_obj, True)
+ self.rbac_utils.switch_role(self.mock_test_obj, True)
+ mock_log.error.assert_not_called()
@mock.patch.object(rbac_utils.rbac_utils, '_clear_user_roles',
autospec=True, return_value=False)