Merge "Remove cinder v1 artifacts from code base"
diff --git a/HACKING.rst b/HACKING.rst
index bb337b0..b1d730d 100644
--- a/HACKING.rst
+++ b/HACKING.rst
@@ -1,6 +1,62 @@
Patrole Style Commandments
==========================
-Read the OpenStack Style Commandments: `<http://docs.openstack.org/developer/hacking/>`__
+- Step 1: Read the OpenStack Style Commandments: `<http://docs.openstack.org/developer/hacking/>`__
+- Step 2: Review Tempest's Style Commandments: `<https://docs.openstack.org/developer/tempest/HACKING.html>`__
+- Step 3: Read on
-Also review Tempest's Style Commandments: `<https://docs.openstack.org/developer/tempest/HACKING.html>`__
+Patrole Specific Commandments
+------------------------------
+
+Patrole borrows the following commandments from Tempest; refer to
+`Tempest's Commandments <https://docs.openstack.org/developer/tempest/HACKING.html>`__
+for more information:
+
+.. note::
+
+ The original Tempest Commandments do not include Patrole-specific paths.
+ Patrole-specific paths replace the Tempest-specific paths within Patrole's
+ hacking checks.
+..
+
+- [T102] Cannot import OpenStack python clients in patrole_tempest_plugin/tests/api
+- [T105] Tests cannot use setUpClass/tearDownClass
+- [T106] vim configuration should not be kept in source files.
+- [T107] Check that a service tag isn't in the module path
+- [T108] Check no hyphen at the end of rand_name() argument
+- [T109] Cannot use testtools.skip decorator; instead use
+ decorators.skip_because from tempest.lib
+- [T113] Check that tests use data_utils.rand_uuid() instead of uuid.uuid4()
+- [N322] Method's default argument shouldn't be mutable
+
+The following are Patrole's specific Commandments:
+
+- [P100] The ``rbac_rule_validation.action`` decorator must be applied to
+ an RBAC test (the check fails if the decorator is not one of the
+ two decorators directly above the function declaration)
+- [P101] RBAC test filenames must end with "_rbac.py"; for example,
+ test_servers_rbac.py, not test_servers.py
+- [P102] RBAC test class names must end in 'RbacTest'
+
+Role Switching
+--------------
+
+Correct role switching is vital to correct RBAC testing within Patrole. If a
+test does not call ``rbac_utils.switch_role`` with ``toggle_rbac_role=True``
+within the RBAC test, then the test is *not* a valid RBAC test: The API
+endpoint under test will be performed with admin credentials, which is always
+wrong unless ``CONF.rbac_test_role`` is admin.
+
+.. note::
+
+ Switching back to the admin role for setup and clean up is automatically
+ performed. Toggling ``switch_role`` with ``toggle_rbac_role=False`` within
+ the context of a test should *never* be performed and doing so will likely
+ result in an error being thrown.
+..
+
+Patrole does not have a hacking check for role switching, but does use a
+built-in mechanism for verifying that role switching is being correctly
+executed across tests. If a test does not call ``switch_role`` with
+``toggle_rbac_role=True``, then an ``RbacResourceSetupFailed`` exception
+will be raised.
diff --git a/README.rst b/README.rst
index c527c3b..ad8add0 100644
--- a/README.rst
+++ b/README.rst
@@ -24,11 +24,21 @@
Currently, Patrole supports policies contained in code and in policy.json files.
If both exist, the policy actions in the policy.json are prioritized.
+Stable Interface
+----------------
+Patrole offers a stable interface that is guaranteed to be backwards compatible and
+can be directly consumed by other projects. Currently, rbac_exceptions.py and
+rbac_policy_parser.py are guaranteed to be stable.
+
+Release Versioning
+------------------
+`Patrole Release Notes <https://docs.openstack.org/releasenotes/patrole/>`_ show
+what changes have been released.
+
.. _test-flows:
Test Flows
----------
-
There are several possible test flows.
If the ``rbac_test_role`` is allowed to access the endpoint:
@@ -47,7 +57,7 @@
Certain services like Neutron *intentionally* raise a 404 instead of a 403
for security concerns. Patrole accomodates this behavior by anticipating
- a 404 instead of a 403, if specified through a special argument. For more
+ a 404 instead of a 403, using the ``expected_exception`` argument. For more
information about Neutron's policy enforcement, see:
`<https://docs.openstack.org/developer/neutron/devref/policy.html#request-authorization>`__.
@@ -70,7 +80,6 @@
Test Execution Workflow
-----------------------
-
The workflow is as follows:
#. Each test uses the ``rbac_rule_validation.action`` decorator, like below: ::
diff --git a/contrib/post_test_hook.sh b/contrib/post_test_hook.sh
index af7c856..e934cc4 100644
--- a/contrib/post_test_hook.sh
+++ b/contrib/post_test_hook.sh
@@ -28,7 +28,6 @@
TEMPEST_COMMAND="sudo -H -u tempest tox"
DEVSTACK_GATE_TEMPEST_REGEX="(?!.*\[.*\bslow\b.*\])(^patrole_tempest_plugin\.tests\.api)"
-DEVSTACK_GATE_TEMPEST_HEAT_REGEX="(?!.*\[.*\bslow\b.*\])(^patrole_tempest_plugin\.tests\.api\.orchestration)"
DEVSTACK_MULTINODE_GATE_TEMPEST_REGEX="(?=.*\[.*\bslow\b.*\])(^patrole_tempest_plugin\.tests\.api)"
# Import devstack function 'iniset'.
@@ -76,8 +75,6 @@
if [[ "$TYPE" == "multinode" ]]; then
$TEMPEST_COMMAND -eall-plugin -- $DEVSTACK_MULTINODE_GATE_TEMPEST_REGEX --concurrency=$TEMPEST_CONCURRENCY
- elif [[ "$TYPE" == "heat" ]]; then
- $TEMPEST_COMMAND -eall-plugin -- $DEVSTACK_GATE_TEMPEST_HEAT_REGEX --concurrency=$TEMPEST_CONCURRENCY
else
$TEMPEST_COMMAND -eall-plugin -- $DEVSTACK_GATE_TEMPEST_REGEX --concurrency=$TEMPEST_CONCURRENCY
fi
diff --git a/patrole_tempest_plugin/tests/api/orchestration/__init__.py b/patrole_tempest_plugin/hacking/__init__.py
similarity index 100%
rename from patrole_tempest_plugin/tests/api/orchestration/__init__.py
rename to patrole_tempest_plugin/hacking/__init__.py
diff --git a/patrole_tempest_plugin/hacking/checks.py b/patrole_tempest_plugin/hacking/checks.py
new file mode 100644
index 0000000..e7e5cb0
--- /dev/null
+++ b/patrole_tempest_plugin/hacking/checks.py
@@ -0,0 +1,216 @@
+# Copyright 2013 IBM Corp.
+# 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.
+
+import os
+import re
+
+import pep8
+
+
+PYTHON_CLIENTS = ['cinder', 'glance', 'keystone', 'nova', 'swift', 'neutron',
+ 'ironic', 'heat', 'sahara']
+
+PYTHON_CLIENT_RE = re.compile('import (%s)client' % '|'.join(PYTHON_CLIENTS))
+TEST_DEFINITION = re.compile(r'^\s*def test.*')
+SETUP_TEARDOWN_CLASS_DEFINITION = re.compile(r'^\s+def (setUp|tearDown)Class')
+SCENARIO_DECORATOR = re.compile(r'\s*@.*services\((.*)\)')
+VI_HEADER_RE = re.compile(r"^#\s+vim?:.+")
+RAND_NAME_HYPHEN_RE = re.compile(r".*rand_name\(.+[\-\_][\"\']\)")
+MUTABLE_DEFAULT_ARGS = re.compile(r"^\s*def .+\((.+=\{\}|.+=\[\])")
+TESTTOOLS_SKIP_DECORATOR = re.compile(r'\s*@testtools\.skip\((.*)\)')
+TEST_METHOD = re.compile(r"^ def test_.+")
+CLASS = re.compile(r"^class .+")
+RBAC_CLASS_NAME_RE = re.compile(r'class .+RbacTest')
+RULE_VALIDATION_DECORATOR = re.compile(
+ r'\s*@.*rbac_rule_validation.action\((.*)\)')
+IDEMPOTENT_ID_DECORATOR = re.compile(r'\s*@decorators\.idempotent_id\((.*)\)')
+
+previous_decorator = None
+
+
+def import_no_clients_in_api_tests(physical_line, filename):
+ """Check for client imports from patrole_tempest_plugin/tests/api
+
+ T102: Cannot import OpenStack python clients
+ """
+ if "patrole_tempest_plugin/tests/api" in filename:
+ res = PYTHON_CLIENT_RE.match(physical_line)
+ if res:
+ return (physical_line.find(res.group(1)),
+ ("T102: python clients import not allowed "
+ "in patrole_tempest_plugin/tests/api/* or "
+ "patrole_tempest_plugin/tests/scenario/* tests"))
+
+
+def no_setup_teardown_class_for_tests(physical_line, filename):
+ """Check that tests do not use setUpClass/tearDownClass
+
+ T105: Tests cannot use setUpClass/tearDownClass
+ """
+ if pep8.noqa(physical_line):
+ return
+
+ if SETUP_TEARDOWN_CLASS_DEFINITION.match(physical_line):
+ return (physical_line.find('def'),
+ "T105: (setUp|tearDown)Class can not be used in tests")
+
+
+def no_vi_headers(physical_line, line_number, lines):
+ """Check for vi editor configuration in source files.
+
+ By default vi modelines can only appear in the first or
+ last 5 lines of a source file.
+
+ T106
+ """
+ # NOTE(gilliard): line_number is 1-indexed
+ if line_number <= 5 or line_number > len(lines) - 5:
+ if VI_HEADER_RE.match(physical_line):
+ return 0, "T106: Don't put vi configuration in source files"
+
+
+def service_tags_not_in_module_path(physical_line, filename):
+ """Check that a service tag isn't in the module path
+
+ A service tag should only be added if the service name isn't already in
+ the module path.
+
+ T107
+ """
+ matches = SCENARIO_DECORATOR.match(physical_line)
+ if matches:
+ services = matches.group(1).split(',')
+ for service in services:
+ service_name = service.strip().strip("'")
+ modulepath = os.path.split(filename)[0]
+ if service_name in modulepath:
+ return (physical_line.find(service_name),
+ "T107: service tag should not be in path")
+
+
+def no_hyphen_at_end_of_rand_name(logical_line, filename):
+ """Check no hyphen at the end of rand_name() argument
+
+ T108
+ """
+ msg = "T108: hyphen should not be specified at the end of rand_name()"
+ if RAND_NAME_HYPHEN_RE.match(logical_line):
+ return 0, msg
+
+
+def no_mutable_default_args(logical_line):
+ """Check that mutable object isn't used as default argument
+
+ N322: Method's default argument shouldn't be mutable
+ """
+ msg = "N322: Method's default argument shouldn't be mutable!"
+ if MUTABLE_DEFAULT_ARGS.match(logical_line):
+ yield (0, msg)
+
+
+def no_testtools_skip_decorator(logical_line):
+ """Check that methods do not have the testtools.skip decorator
+
+ T109
+ """
+ if TESTTOOLS_SKIP_DECORATOR.match(logical_line):
+ yield (0, "T109: Cannot use testtools.skip decorator; instead use "
+ "decorators.skip_because from tempest.lib")
+
+
+def use_rand_uuid_instead_of_uuid4(logical_line, filename):
+ """Check that tests use data_utils.rand_uuid() instead of uuid.uuid4()
+
+ T113
+ """
+ if 'uuid.uuid4()' not in logical_line:
+ return
+
+ msg = ("T113: Tests should use data_utils.rand_uuid()/rand_uuid_hex() "
+ "instead of uuid.uuid4()/uuid.uuid4().hex")
+ yield (0, msg)
+
+
+def no_rbac_rule_validation_decorator(physical_line, filename,
+ previous_logical):
+ """Check that each test has the ``rbac_rule_validation.action`` decorator.
+
+ Checks whether the test function has "@rbac_rule_validation.action"
+ above it; otherwise checks that it has "@decorators.idempotent_id" above
+ it and "@rbac_rule_validation.action" above that.
+
+ Assumes that ``rbac_rule_validation.action`` decorator is either the first
+ or second decorator above the test function; otherwise this check fails.
+
+ P100
+ """
+ global previous_decorator
+
+ if "patrole_tempest_plugin/tests/api" in filename:
+
+ if IDEMPOTENT_ID_DECORATOR.match(physical_line):
+ previous_decorator = previous_logical
+ return
+
+ if TEST_METHOD.match(physical_line):
+ if not RULE_VALIDATION_DECORATOR.match(previous_logical) and \
+ not RULE_VALIDATION_DECORATOR.match(previous_decorator):
+ return (0, "Must use rbac_rule_validation.action "
+ "decorator for API and scenario tests")
+
+
+def no_rbac_suffix_in_test_filename(physical_line, filename, previous_logical):
+ """Check that RBAC filenames end with "_rbac" suffix.
+
+ P101
+ """
+ if "patrole_tempest_plugin/tests/api" in filename:
+
+ if filename.endswith('rbac_base.py'):
+ return
+
+ if not filename.endswith('_rbac.py'):
+ return 0, "RBAC test filenames must end in _rbac suffix"
+
+
+def no_rbac_test_suffix_in_test_class_name(physical_line, filename,
+ previous_logical):
+ """Check that RBAC class names end with "RbacTest"
+
+ P102
+ """
+ if "patrole_tempest_plugin/tests/api" in filename:
+
+ if filename.endswith('rbac_base.py'):
+ return
+
+ if CLASS.match(physical_line):
+ if not RBAC_CLASS_NAME_RE.match(physical_line):
+ return 0, "RBAC test class names must end in 'RbacTest'"
+
+
+def factory(register):
+ register(import_no_clients_in_api_tests)
+ register(no_setup_teardown_class_for_tests)
+ register(no_vi_headers)
+ register(no_hyphen_at_end_of_rand_name)
+ register(no_mutable_default_args)
+ register(no_testtools_skip_decorator)
+ register(use_rand_uuid_instead_of_uuid4)
+ register(service_tags_not_in_module_path)
+ register(no_rbac_rule_validation_decorator)
+ register(no_rbac_suffix_in_test_filename)
+ register(no_rbac_test_suffix_in_test_class_name)
diff --git a/patrole_tempest_plugin/plugin.py b/patrole_tempest_plugin/plugin.py
index 3abf4aa..cfe5c0a 100644
--- a/patrole_tempest_plugin/plugin.py
+++ b/patrole_tempest_plugin/plugin.py
@@ -25,7 +25,7 @@
def load_tests(self):
base_path = os.path.split(os.path.dirname(
os.path.abspath(__file__)))[0]
- test_dir = "patrole_tempest_plugin/tests"
+ test_dir = "patrole_tempest_plugin/tests/api"
full_test_dir = os.path.join(base_path, test_dir)
return full_test_dir, base_path
diff --git a/patrole_tempest_plugin/rbac_policy_parser.py b/patrole_tempest_plugin/rbac_policy_parser.py
index e68921f..1047d37 100644
--- a/patrole_tempest_plugin/rbac_policy_parser.py
+++ b/patrole_tempest_plugin/rbac_policy_parser.py
@@ -40,8 +40,7 @@
each role, whether a given rule is allowed using oslo policy.
"""
- def __init__(self, project_id, user_id, service=None,
- extra_target_data={}):
+ def __init__(self, project_id, user_id, service, extra_target_data=None):
"""Initialization of Rbac Policy Parser.
Parses a policy file to create a dictionary, mapping policy actions to
@@ -64,6 +63,9 @@
:param path: type string
"""
+ if extra_target_data is None:
+ extra_target_data = {}
+
# First check if the service is valid
service = service.lower().strip() if service else None
self.admin_mgr = credentials.AdminManager()
@@ -79,7 +81,7 @@
path = getattr(CONF.rbac, '%s_policy_file' % str(service), None)
if not path:
LOG.info("No config option found for %s,"
- " using default path" % str(service))
+ " using default path", str(service))
path = os.path.join('/etc', service, 'policy.json')
self.path = path
self.rules = policy.Rules.load(self._get_policy_data(service),
@@ -168,7 +170,7 @@
return self._allowed(
access=self._get_access_token(role),
apply_rule='context_is_admin')
- return role == 'admin'
+ return role == CONF.identity.admin_role
def _get_access_token(self, role):
access_token = {
diff --git a/patrole_tempest_plugin/rbac_rule_validation.py b/patrole_tempest_plugin/rbac_rule_validation.py
index 4382259..60a0f10 100644
--- a/patrole_tempest_plugin/rbac_rule_validation.py
+++ b/patrole_tempest_plugin/rbac_rule_validation.py
@@ -31,7 +31,7 @@
def action(service, rule='', admin_only=False, expected_error_code=403,
- extra_target_data={}):
+ extra_target_data=None):
"""A decorator which does a policy check and matches it against test run.
A decorator which allows for positive and negative RBAC testing. Given
@@ -62,6 +62,10 @@
:raises Forbidden: for bullet (2) above.
:raises RbacOverPermission: for bullet (3) above.
"""
+
+ if extra_target_data is None:
+ extra_target_data = {}
+
def decorator(func):
role = CONF.rbac.rbac_test_role
@@ -77,7 +81,7 @@
LOG.info("As admin_only is True, only admin role should be "
"allowed to perform the API. Skipping oslo.policy "
"check for policy action {0}.".format(rule))
- allowed = CONF.rbac.rbac_test_role == 'admin'
+ allowed = CONF.rbac.rbac_test_role == CONF.identity.admin_role
else:
allowed = _is_authorized(test_obj, service, rule,
extra_target_data)
@@ -100,7 +104,7 @@
(role, rule))
LOG.error(msg)
raise exceptions.Forbidden(
- "%s exception was: %s" % (msg, e))
+ "%s Exception was: %s" % (msg, e))
except Exception as e:
exc_info = sys.exc_info()
error_details = exc_info[1].__str__()
@@ -111,7 +115,7 @@
six.reraise(exc_info[0], exc_info[0](msg), exc_info[2])
else:
if not allowed:
- LOG.error("Role %s was allowed to perform %s" %
+ LOG.error("Role %s was allowed to perform %s",
(role, rule))
raise rbac_exceptions.RbacOverPermission(
"OverPermission: Role %s was allowed to perform %s" %
diff --git a/patrole_tempest_plugin/rbac_utils.py b/patrole_tempest_plugin/rbac_utils.py
index 55a5599..fe2d99f 100644
--- a/patrole_tempest_plugin/rbac_utils.py
+++ b/patrole_tempest_plugin/rbac_utils.py
@@ -18,7 +18,6 @@
from oslo_log import log as logging
import oslo_utils.uuidutils as uuid_utils
-import six
from tempest.common import credentials_factory as credentials
from tempest import config
@@ -29,19 +28,11 @@
LOG = logging.getLogger(__name__)
-class Singleton(type):
- _instances = {}
-
- def __call__(cls, *args, **kwargs):
- if cls not in cls._instances:
- cls._instances[cls] = super(Singleton, cls).__call__(*args,
- **kwargs)
- return cls._instances[cls]
-
-
-@six.add_metaclass(Singleton)
class RbacUtils(object):
+ def __init__(self, test_obj):
+ self.switch_role(test_obj, toggle_rbac_role=False)
+
# References the last value of `toggle_rbac_role` that was passed to
# `switch_role`. Used for ensuring that `switch_role` is correctly used
# in a test file, so that false positives are prevented. The key used
@@ -70,7 +61,7 @@
if not self.admin_role_id or not self.rbac_role_id:
self._get_roles()
- rbac_utils._validate_switch_role(self, test_obj, toggle_rbac_role)
+ self._validate_switch_role(test_obj, toggle_rbac_role)
if toggle_rbac_role:
self._add_role_to_user(self.rbac_role_id)
@@ -160,7 +151,7 @@
for role in available_roles['roles']:
if role['name'] == CONF.rbac.rbac_test_role:
rbac_role_id = role['id']
- if role['name'] == 'admin':
+ if role['name'] == CONF.identity.admin_role:
admin_role_id = role['id']
if not admin_role_id or not rbac_role_id:
@@ -171,5 +162,3 @@
self.admin_role_id = admin_role_id
self.rbac_role_id = rbac_role_id
-
-rbac_utils = RbacUtils
diff --git a/patrole_tempest_plugin/tests/api/compute/rbac_base.py b/patrole_tempest_plugin/tests/api/compute/rbac_base.py
index bc02dbf..ff5b46f 100644
--- a/patrole_tempest_plugin/tests/api/compute/rbac_base.py
+++ b/patrole_tempest_plugin/tests/api/compute/rbac_base.py
@@ -16,7 +16,7 @@
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
+from patrole_tempest_plugin import rbac_utils
CONF = config.CONF
@@ -36,8 +36,7 @@
def setup_clients(cls):
super(BaseV2ComputeRbacTest, 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.rbac_utils = rbac_utils.RbacUtils(cls)
@classmethod
def resource_setup(cls):
@@ -58,7 +57,7 @@
@classmethod
def _create_flavor(cls, **kwargs):
flavor_kwargs = {
- "name": data_utils.rand_name('flavor'),
+ "name": data_utils.rand_name(cls.__name__ + '-flavor'),
"ram": data_utils.rand_int_id(1, 10),
"vcpus": data_utils.rand_int_id(1, 10),
"disk": data_utils.rand_int_id(1, 10),
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 db504c0..eec4030 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_aggregates_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_aggregates_rbac.py
@@ -37,7 +37,7 @@
cls.hosts_client = cls.os_primary.hosts_client
def _create_aggregate(self):
- agg_name = data_utils.rand_name('aggregate')
+ agg_name = data_utils.rand_name(self.__class__.__name__ + '-aggregate')
aggregate = self.aggregates_client.create_aggregate(name=agg_name)
aggregate_id = aggregate['aggregate']['id']
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
@@ -82,7 +82,7 @@
def test_update_aggregate_rbac(self):
aggregate_id = self._create_aggregate()
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- new_name = data_utils.rand_name('aggregate')
+ new_name = data_utils.rand_name(self.__class__.__name__ + '-aggregate')
self.aggregates_client.update_aggregate(aggregate_id, name=new_name)
@rbac_rule_validation.action(
@@ -115,8 +115,8 @@
@decorators.idempotent_id('ed6f3849-065c-4ae9-a81e-6ad7ed0d3d9d')
def test_set_metadata_on_aggregate_rbac(self):
aggregate_id = self._create_aggregate()
- rand_key = data_utils.rand_name('key')
- rand_val = data_utils.rand_name('val')
+ rand_key = data_utils.rand_name(self.__class__.__name__ + '-key')
+ rand_val = data_utils.rand_name(self.__class__.__name__ + '-val')
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.aggregates_client.set_metadata(
aggregate_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 0ee8d9a..10e27a8 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
@@ -48,8 +48,8 @@
super(FlavorExtraSpecsRbacTest, cls).resource_cleanup()
def _set_flavor_extra_spec(self):
- rand_key = data_utils.rand_name('key')
- rand_val = data_utils.rand_name('val')
+ rand_key = data_utils.rand_name(self.__class__.__name__ + '-key')
+ rand_val = data_utils.rand_name(self.__class__.__name__ + '-val')
specs = {rand_key: rand_val}
self.client.set_flavor_extra_spec(self.flavor['id'],
**specs)['extra_specs']
@@ -82,7 +82,7 @@
def test_update_flavor_extra_spec(self):
key = self._set_flavor_extra_spec()
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- update_val = data_utils.rand_name('val')
+ update_val = data_utils.rand_name(self.__class__.__name__ + '-val')
self.client.update_flavor_extra_spec(self.flavor['id'], key,
**{key: update_val})[key]
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 755bacd..75cc8f4 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
@@ -25,9 +25,10 @@
class FloatingIpPoolsRbacTest(rbac_base.BaseV2ComputeRbacTest):
- # Tests will fail with a 404 starting from microversion 2.36, according to:
- # https://developer.openstack.org/api-ref/
- # compute/?expanded=list-floating-ip-pools-detail
+ # Tests will fail with a 404 starting from microversion 2.36:
+ # See the following link for details:
+ # https://developer.openstack.org/api-ref/compute/#floating-ip-pools-os-floating-ip-pools-deprecated
+ min_microversion = '2.10'
max_microversion = '2.35'
@classmethod
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 7fe4847..bff0612 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
@@ -25,9 +25,10 @@
class FloatingIpsBulkRbacTest(rbac_base.BaseV2ComputeRbacTest):
- # Tests will fail with a 404 starting from microversion 2.36, according to:
- # https://developer.openstack.org/api-ref/
- # compute/?expanded=list-floating-ips-detail
+ # Tests will fail with a 404 starting from microversion 2.36:
+ # See the following link for details:
+ # https://developer.openstack.org/api-ref/compute/#floating-ips-bulk-os-floating-ips-bulk-deprecated
+ min_microversion = '2.10'
max_microversion = '2.35'
@classmethod
diff --git a/patrole_tempest_plugin/tests/api/compute/test_floating_ips_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_floating_ips_rbac.py
index 784a82d..0bd00a4 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_floating_ips_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_floating_ips_rbac.py
@@ -25,9 +25,10 @@
class FloatingIpsRbacTest(rbac_base.BaseV2ComputeRbacTest):
- # Tests will fail with a 404 starting from microversion 2.36, according to:
- # https://developer.openstack.org/api-ref/
- # compute/?expanded=list-floating-ip-addresses-detail
+ # Tests will fail with a 404 starting from microversion 2.36:
+ # See the following link for details:
+ # https://developer.openstack.org/api-ref/compute/#floating-ips-os-floating-ips-deprecated
+ min_microversion = '2.10'
max_microversion = '2.35'
@classmethod
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 ecd0fd3..ba85b5b 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_hypervisor_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_hypervisor_rbac.py
@@ -23,11 +23,6 @@
class HypervisorRbacTest(rbac_base.BaseV2ComputeRbacTest):
@classmethod
- def setup_clients(cls):
- super(HypervisorRbacTest, cls).setup_clients()
- cls.client = cls.hypervisor_client
-
- @classmethod
def skip_checks(cls):
super(HypervisorRbacTest, cls).skip_checks()
if not test.is_extension_enabled('os-hypervisors', 'compute'):
@@ -35,6 +30,16 @@
% cls.__name__
raise cls.skipException(msg)
+ @classmethod
+ def setup_clients(cls):
+ super(HypervisorRbacTest, cls).setup_clients()
+ cls.client = cls.hypervisor_client
+
+ @classmethod
+ def resource_setup(cls):
+ super(HypervisorRbacTest, cls).resource_setup()
+ cls.hypervisor = cls.client.list_hypervisors()['hypervisors'][0]
+
@decorators.idempotent_id('17bbeb9a-e73e-445f-a771-c794448ef562')
@rbac_rule_validation.action(
service="nova",
@@ -42,3 +47,45 @@
def test_list_hypervisors(self):
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.client.list_hypervisors()['hypervisors']
+
+ @decorators.idempotent_id('8a7f6f9e-34a6-4480-8875-bba566c3a581')
+ @rbac_rule_validation.action(
+ service="nova",
+ rule="os_compute_api:os-hypervisors")
+ def test_show_hypervisor(self):
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.client.show_hypervisor(self.hypervisor['id'])['hypervisor']
+
+ @decorators.idempotent_id('b86f03cf-2e79-4d88-9eea-62f761591413')
+ @rbac_rule_validation.action(
+ service="nova",
+ rule="os_compute_api:os-hypervisors")
+ def test_list_servers_on_hypervisor(self):
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.client.list_servers_on_hypervisor(
+ self.hypervisor['hypervisor_hostname'])['hypervisors']
+
+ @decorators.idempotent_id('ca0e465c-6365-4a7f-ae58-6f8ddbca06c2')
+ @rbac_rule_validation.action(
+ service="nova",
+ rule="os_compute_api:os-hypervisors")
+ def test_show_hypervisor_statistics(self):
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.client.show_hypervisor_statistics()['hypervisor_statistics']
+
+ @decorators.idempotent_id('109b37c5-91ba-4da5-b2a2-d7618d84406d')
+ @rbac_rule_validation.action(
+ service="nova",
+ rule="os_compute_api:os-hypervisors")
+ def test_show_hypervisor_uptime(self):
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.client.show_hypervisor_uptime(self.hypervisor['id'])['hypervisor']
+
+ @decorators.idempotent_id('3dbc71c1-8f04-4674-a67c-dcb2fd99b1b4')
+ @rbac_rule_validation.action(
+ service="nova",
+ rule="os_compute_api:os-hypervisors")
+ def test_search_hypervisor(self):
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.client.search_hypervisor(self.hypervisor['hypervisor_hostname'])[
+ 'hypervisors']
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 b848509..d546911 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_images_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_images_rbac.py
@@ -54,7 +54,7 @@
def resource_setup(cls):
super(ImagesV235RbacTest, cls).resource_setup()
cls.image = cls.glance_image_client.create_image(
- name=data_utils.rand_name('image'))
+ name=data_utils.rand_name(cls.__name__ + '-image'))
@classmethod
def resource_cleanup(cls):
@@ -111,7 +111,7 @@
rule="delete_image")
def test_delete_image(self):
image = self.glance_image_client.create_image(
- name=data_utils.rand_name('image'))
+ name=data_utils.rand_name(self.__class__.__name__ + '-image'))
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.glance_image_client.delete_image, image['id'])
diff --git a/patrole_tempest_plugin/tests/api/compute/test_keypairs_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_keypairs_rbac.py
index f7b2ace..a93d807 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_keypairs_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_keypairs_rbac.py
@@ -29,7 +29,7 @@
cls.client = cls.keypairs_client
def _create_keypair(self):
- key_name = data_utils.rand_name('key')
+ key_name = data_utils.rand_name(self.__class__.__name__ + '-key')
keypair = self.client.create_keypair(name=key_name)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.client.delete_keypair,
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 f6706a7..8e90880 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
@@ -88,7 +88,8 @@
service="nova",
rule="os_compute_api:os-quota-sets:delete")
def test_delete_quota_set(self):
- project_name = data_utils.rand_name('project')
+ project_name = data_utils.rand_name(
+ self.__class__.__name__ + '-project')
project = self.projects_client.create_project(name=project_name)
project_id = project['project']['id']
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
diff --git a/patrole_tempest_plugin/tests/api/compute/test_server_actions_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_server_actions_rbac.py
index 81266af..86b650e 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_server_actions_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_server_actions_rbac.py
@@ -301,12 +301,9 @@
class ServerActionsV216RbacTest(rbac_base.BaseV2ComputeRbacTest):
- # This class has test case(s) that requires at least version 2.16.
- #
+ # This class has test case(s) that requires at least microversion 2.16.
# See the following link for details:
- # http://developer.openstack.org/
- # api-ref-compute-v2.1.html#show-server-details
-
+ # http://developer.openstack.org/api-ref-compute-v2.1.html#show-server-details
min_microversion = '2.16'
max_microversion = 'latest'
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 b71887c..7d715ca 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_server_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_server_rbac.py
@@ -174,7 +174,7 @@
@decorators.idempotent_id('077b17cb-5621-43b9-8adf-5725f0d7a863')
def test_update_server(self):
server = self.create_test_server(wait_until='ACTIVE')
- new_name = data_utils.rand_name('server')
+ new_name = data_utils.rand_name(self.__class__.__name__ + '-server')
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
try:
self.client.update_server(server['id'], name=new_name)
diff --git a/patrole_tempest_plugin/tests/api/compute/test_server_tags_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_server_tags_rbac.py
index 4de63ce..19aa36a 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_server_tags_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_server_tags_rbac.py
@@ -44,7 +44,7 @@
cls.server = cls.create_test_server(wait_until='ACTIVE')
def _add_tag_to_server(self):
- tag_name = data_utils.rand_name('tag')
+ tag_name = data_utils.rand_name(self.__class__.__name__ + '-tag')
self.client.update_tag(self.server['id'], tag_name)
self.addCleanup(self.client.delete_all_tags, self.server['id'])
return tag_name
@@ -89,7 +89,7 @@
rule="os_compute_api:os-server-tags:update_all")
def test_update_all_tags(self):
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- new_tag_name = data_utils.rand_name('tag')
+ new_tag_name = data_utils.rand_name(self.__class__.__name__ + '-tag')
self.client.update_all_tags(self.server['id'], [new_tag_name])['tags']
@decorators.idempotent_id('89d51936-e333-42f9-a045-132a4865ba1a')
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 fb834bd..ee2b9a2 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
@@ -26,9 +26,10 @@
class TenantNetworksRbacTest(rbac_base.BaseV2ComputeRbacTest):
- # Tests will fail with a 404 starting from microversion 2.36, according to:
- # https://developer.openstack.org/api-ref/
- # compute/?expanded=list-project-networks-detail
+ # Tests will fail with a 404 starting from microversion 2.36.
+ # See the following link for details:
+ # https://developer.openstack.org/api-ref/compute/#project-networks-os-tenant-networks-deprecated
+ min_microversion = '2.10'
max_microversion = '2.35'
@classmethod
diff --git a/patrole_tempest_plugin/tests/api/compute/test_volume_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_volume_rbac.py
new file mode 100644
index 0000000..505ec18
--- /dev/null
+++ b/patrole_tempest_plugin/tests/api/compute/test_volume_rbac.py
@@ -0,0 +1,70 @@
+# 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 patrole_tempest_plugin import rbac_rule_validation
+from patrole_tempest_plugin.tests.api.compute import rbac_base
+
+from tempest import config
+
+CONF = config.CONF
+
+
+class VolumeV235RbacTest(rbac_base.BaseV2ComputeRbacTest):
+ """RBAC tests for the Nova Volume client."""
+
+ # These tests will fail with a 404 starting from microversion 2.36.
+ # For more information, see:
+ # https://developer.openstack.org/api-ref/compute/volume-extension-os-volumes-os-snapshots-deprecated
+ min_microversion = '2.10'
+ max_microversion = '2.35'
+
+ @decorators.idempotent_id('2402013e-a624-43e3-9518-44a5d1dbb32d')
+ @rbac_rule_validation.action(
+ service="nova",
+ rule="os_compute_api:os-volumes")
+ def test_create_volume(self):
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ volume = self.volumes_extensions_client.create_volume(
+ size=CONF.volume.volume_size)['volume']
+ self.addCleanup(self.volumes_extensions_client.delete_volume,
+ volume['id'])
+
+ @decorators.idempotent_id('69b3888c-dff2-47b0-9fa4-0672619c9054')
+ @rbac_rule_validation.action(
+ service="nova",
+ rule="os_compute_api:os-volumes")
+ def test_list_volumes(self):
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.volumes_extensions_client.list_volumes()
+
+ @decorators.idempotent_id('4ba0a820-040f-488b-86bb-be2e920ea12c')
+ @rbac_rule_validation.action(
+ service="nova",
+ rule="os_compute_api:os-volumes")
+ def test_show_volume(self):
+ volume = self.create_volume()
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.volumes_extensions_client.show_volume(volume['id'])
+
+ @decorators.idempotent_id('6e7870f2-1bb2-4b58-96f8-6782071ef327')
+ @rbac_rule_validation.action(
+ service="nova",
+ rule="os_compute_api:os-volumes")
+ def test_delete_volume(self):
+ volume = self.create_volume()
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.volumes_extensions_client.delete_volume(volume['id'])
diff --git a/patrole_tempest_plugin/tests/api/identity/v3/rbac_base.py b/patrole_tempest_plugin/tests/api/identity/rbac_base.py
similarity index 61%
rename from patrole_tempest_plugin/tests/api/identity/v3/rbac_base.py
rename to patrole_tempest_plugin/tests/api/identity/rbac_base.py
index 927ec39..6cb3d2f 100644
--- a/patrole_tempest_plugin/tests/api/identity/v3/rbac_base.py
+++ b/patrole_tempest_plugin/tests/api/identity/rbac_base.py
@@ -13,40 +13,211 @@
# License for the specific language governing permissions and limitations
# under the License.
+from oslo_log import log as logging
+
from tempest.api.identity import 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
+from patrole_tempest_plugin import rbac_utils
CONF = config.CONF
+LOG = logging.getLogger(__name__)
-class BaseIdentityV3RbacTest(base.BaseIdentityV3Test):
+class BaseIdentityRbacTest(base.BaseIdentityTest):
credentials = ['admin', 'primary']
@classmethod
def skip_checks(cls):
- super(BaseIdentityV3RbacTest, cls).skip_checks()
+ super(BaseIdentityRbacTest, cls).skip_checks()
if not CONF.rbac.enable_rbac:
raise cls.skipException(
"%s skipped as RBAC testing not enabled" % cls.__name__)
@classmethod
def setup_clients(cls):
- super(BaseIdentityV3RbacTest, cls).setup_clients()
+ super(BaseIdentityRbacTest, cls).setup_clients()
cls.auth_provider = cls.os_primary.auth_provider
+ cls.rbac_utils = rbac_utils.RbacUtils(cls)
- cls.rbac_utils = rbac_utils()
- cls.rbac_utils.switch_role(cls, toggle_rbac_role=False)
+ @classmethod
+ def resource_setup(cls):
+ super(BaseIdentityRbacTest, cls).resource_setup()
+ cls.endpoints = []
+ cls.roles = []
+ cls.services = []
+ cls.users = []
+ @classmethod
+ def resource_cleanup(cls):
+ for endpoint in cls.endpoints:
+ test_utils.call_and_ignore_notfound_exc(
+ cls.endpoints_client.delete_endpoint, endpoint['id'])
+
+ for role in cls.roles:
+ test_utils.call_and_ignore_notfound_exc(
+ cls.roles_client.delete_role, role['id'])
+
+ for service in cls.services:
+ test_utils.call_and_ignore_notfound_exc(
+ cls.services_client.delete_service, service['id'])
+
+ for user in cls.users:
+ test_utils.call_and_ignore_notfound_exc(
+ cls.users_client.delete_user, user['id'])
+
+ super(BaseIdentityRbacTest, cls).resource_cleanup()
+
+ @classmethod
+ def setup_test_endpoint(cls, service=None):
+ """Creates a service and an endpoint for test."""
+ interface = 'public'
+ url = data_utils.rand_url()
+ region_name = data_utils.rand_name(
+ cls.__name__ + '-region')
+ # Endpoint creation requires a service
+ if service is None:
+ service = cls.setup_test_service()
+ params = {
+ 'service_id': service['id'],
+ 'region': region_name,
+ 'interface': interface
+ }
+ if cls.identity_version == 'v2':
+ params['publicurl'] = url
+ elif cls.identity_version == 'v3':
+ params['url'] = url
+ else:
+ LOG.debug("Keystone version is invalid."
+ " Please enter a valid version number.")
+ raise KeyError
+
+ endpoint = cls.endpoints_client.create_endpoint(**params)['endpoint']
+ cls.endpoints.append(endpoint)
+
+ return endpoint
+
+ @classmethod
+ def setup_test_role(cls):
+ """Set up a test role."""
+ name = data_utils.rand_name(cls.__name__ + '-test_role')
+ role = cls.roles_client.create_role(name=name)['role']
+ cls.roles.append(role)
+
+ return role
+
+ @classmethod
+ def setup_test_service(cls):
+ """Setup a test service."""
+ name = data_utils.rand_name(cls.__name__ + '-service')
+ serv_type = data_utils.rand_name('type')
+ desc = data_utils.rand_name(cls.__name__ + '-description')
+
+ service = cls.services_client.create_service(
+ name=name,
+ type=serv_type,
+ description=desc)
+
+ if cls.identity_version == 'v2':
+ service = service['OS-KSADM:service']
+ elif cls.identity_version == 'v3':
+ service = service['service']
+ else:
+ LOG.debug("Keystone version is invalid."
+ " Please enter a valid version number.")
+ raise KeyError
+
+ cls.services.append(service)
+
+ return service
+
+ @classmethod
+ def setup_test_user(cls, password=None, **kwargs):
+ """Set up a test user."""
+ username = data_utils.rand_name(cls.__name__ + '-test_user')
+ email = username + '@testmail.tm'
+
+ user = cls.users_client.create_user(
+ name=username,
+ email=email,
+ password=password,
+ **kwargs)['user']
+ cls.users.append(user)
+
+ return user
+
+
+class BaseIdentityV2AdminRbacTest(BaseIdentityRbacTest):
+ """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``.
+ """
+
+ identity_version = 'v2'
+
+ @classmethod
+ def skip_checks(cls):
+ super(BaseIdentityV2AdminRbacTest, cls).skip_checks()
+ if not CONF.identity_feature_enabled.api_v2_admin:
+ raise cls.skipException('Identity v2 admin not available')
+
+ @classmethod
+ def setup_clients(cls):
+ super(BaseIdentityV2AdminRbacTest, cls).setup_clients()
+ 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
+
+ @classmethod
+ def resource_setup(cls):
+ super(BaseIdentityV2AdminRbacTest, cls).resource_setup()
+ cls.tenants = []
+
+ @classmethod
+ def resource_cleanup(cls):
+ for tenant in cls.tenants:
+ test_utils.call_and_ignore_notfound_exc(
+ cls.tenants_client.delete_tenant, tenant['id'])
+
+ super(BaseIdentityV2AdminRbacTest, cls).resource_cleanup()
+
+ @classmethod
+ def setup_test_tenant(cls):
+ """Set up a test tenant."""
+ name = data_utils.rand_name(cls.__name__ + '-test_tenant')
+ tenant = cls.tenants_client.create_tenant(
+ name=name,
+ description=data_utils.rand_name(
+ cls.__name__ + '-desc'))['tenant']
+ cls.tenants.append(tenant)
+ return tenant
+
+
+class BaseIdentityV3RbacTest(BaseIdentityRbacTest):
+
+ identity_version = 'v3'
+
+ @classmethod
+ def setup_clients(cls):
+ super(BaseIdentityV3RbacTest, cls).setup_clients()
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.domain_config_client = cls.os_primary.domain_config_client
cls.endpoints_client = cls.os_primary.endpoints_v3_client
cls.groups_client = cls.os_primary.groups_client
+ cls.identity_client = cls.os_primary.identity_v3_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
@@ -61,15 +232,11 @@
super(BaseIdentityV3RbacTest, cls).resource_setup()
cls.credentials = []
cls.domains = []
- cls.endpoints = []
cls.groups = []
cls.policies = []
cls.projects = []
cls.regions = []
- cls.roles = []
- cls.services = []
cls.trusts = []
- cls.users = []
@classmethod
def resource_cleanup(cls):
@@ -85,10 +252,6 @@
test_utils.call_and_ignore_notfound_exc(
cls.domains_client.delete_domain, domain['id'])
- for endpoint in cls.endpoints:
- test_utils.call_and_ignore_notfound_exc(
- cls.endpoints_client.delete_endpoint, endpoint['id'])
-
for group in cls.groups:
test_utils.call_and_ignore_notfound_exc(
cls.groups_client.delete_group, group['id'])
@@ -105,22 +268,10 @@
test_utils.call_and_ignore_notfound_exc(
cls.regions_client.delete_region, region['id'])
- for role in cls.roles:
- test_utils.call_and_ignore_notfound_exc(
- cls.roles_client.delete_role, role['id'])
-
- for service in cls.services:
- test_utils.call_and_ignore_notfound_exc(
- cls.services_client.delete_service, service['id'])
-
for trust in cls.trusts:
test_utils.call_and_ignore_notfound_exc(
cls.trusts_client.delete_trust, trust['id'])
- for user in cls.users:
- test_utils.call_and_ignore_notfound_exc(
- cls.users_client.delete_user, user['id'])
-
super(BaseIdentityV3RbacTest, cls).resource_cleanup()
@classmethod
@@ -143,33 +294,17 @@
def setup_test_domain(cls):
"""Set up a test domain."""
domain = cls.domains_client.create_domain(
- name=data_utils.rand_name('test_domain'),
- description=data_utils.rand_name('desc'))['domain']
+ name=data_utils.rand_name(cls.__name__ + '-test_domain'),
+ description=data_utils.rand_name(
+ cls.__name__ + '-desc'))['domain']
cls.domains.append(domain)
return domain
@classmethod
- def setup_test_endpoint(cls, service=None):
- """Creates a service and an endpoint for test."""
- interface = 'public'
- url = data_utils.rand_url()
- # Endpoint creation requires a service
- if service is None:
- service = cls.setup_test_service()
-
- endpoint = cls.endpoints_client.create_endpoint(
- service_id=service['id'],
- interface=interface,
- url=url)['endpoint']
- cls.endpoints.append(endpoint)
-
- return endpoint
-
- @classmethod
def setup_test_group(cls):
"""Creates a group for test."""
- name = data_utils.rand_name('test_group')
+ name = data_utils.rand_name(cls.__name__ + '-test_group')
group = cls.groups_client.create_group(name=name)['group']
cls.groups.append(group)
@@ -178,8 +313,9 @@
@classmethod
def setup_test_policy(cls):
"""Creates a policy for test."""
- blob = data_utils.rand_name('test_blob')
- policy_type = data_utils.rand_name('policy_type')
+ blob = data_utils.rand_name(cls.__name__ + '-test_blob')
+ policy_type = data_utils.rand_name(
+ cls.__name__ + '-policy_type')
policy = cls.policies_client.create_policy(
blob=blob,
@@ -193,8 +329,10 @@
def setup_test_project(cls):
"""Set up a test project."""
project = cls.projects_client.create_project(
- name=data_utils.rand_name('test_project'),
- description=data_utils.rand_name('desc'))['project']
+ name=data_utils.rand_name(
+ cls.__name__ + '-testproject'),
+ description=data_utils.rand_name(
+ cls.__name__ + '-desc'))['project']
cls.projects.append(project)
return project
@@ -202,7 +340,8 @@
@classmethod
def setup_test_region(cls):
"""Creates a region for test."""
- description = data_utils.rand_name('test_region_desc')
+ description = data_utils.rand_name(
+ cls.__name__ + '-test_region_desc')
region = cls.regions_client.create_region(
description=description)['region']
@@ -211,30 +350,6 @@
return region
@classmethod
- def setup_test_role(cls):
- """Set up a test role."""
- name = data_utils.rand_name('test_role')
- role = cls.roles_client.create_role(name=name)['role']
- cls.roles.append(role)
-
- return role
-
- @classmethod
- def setup_test_service(cls):
- """Setup a test service."""
- name = data_utils.rand_name('service')
- serv_type = data_utils.rand_name('type')
- desc = data_utils.rand_name('description')
-
- service = cls.services_client.create_service(
- name=name,
- type=serv_type,
- description=desc)['service']
- cls.services.append(service)
-
- return service
-
- @classmethod
def setup_test_trust(cls, trustee_user_id, trustor_user_id, **kwargs):
"""Setup a test trust."""
trust = cls.trusts_client.create_trust(
@@ -243,18 +358,3 @@
cls.trusts.append(trust)
return trust
-
- @classmethod
- def setup_test_user(cls, password=None, **kwargs):
- """Set up a test user."""
- username = data_utils.rand_name('test_user')
- email = username + '@testmail.tm'
-
- user = cls.users_client.create_user(
- name=username,
- email=email,
- password=password,
- **kwargs)['user']
- cls.users.append(user)
-
- return user
diff --git a/patrole_tempest_plugin/tests/api/identity/v2/rbac_base.py b/patrole_tempest_plugin/tests/api/identity/v2/rbac_base.py
deleted file mode 100644
index bc07675..0000000
--- a/patrole_tempest_plugin/tests/api/identity/v2/rbac_base.py
+++ /dev/null
@@ -1,100 +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.api.identity import 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
-
-CONF = config.CONF
-
-
-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(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(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_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')
- type = data_utils.rand_name('type')
-
- self.service = self.services_client.create_service(
- name=name, type=type,
- description="description")
- self.addCleanup(test_utils.call_and_ignore_notfound_exc,
- self.services_client.delete_service,
- self.service['OS-KSADM:service']['id'])
- return self.service
-
- def _create_user(self, name=None, email=None, password=None, **kwargs):
- """Set up a test user."""
- if name is None:
- name = data_utils.rand_name('test_user')
- if email is None:
- email = name + '@testmail.tm'
- if password is None:
- password = data_utils.rand_password()
- user = self.users_client.create_user(
- name=name, email=email, password=password, **kwargs)['user']
- self.addCleanup(test_utils.call_and_ignore_notfound_exc,
- self.users_client.delete_user,
- user['id'])
- return user
-
- def _create_tenant(self):
- """Set up a test tenant."""
- name = data_utils.rand_name('test_tenant')
- tenant = self.tenants_client.create_tenant(
- name=name,
- description=data_utils.rand_name('desc'))['tenant']
- # Delete the tenant at the end of the test
- self.addCleanup(test_utils.call_and_ignore_notfound_exc,
- self.tenants_client.delete_tenant,
- tenant['id'])
- return tenant
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 f16d0aa..0a9feef 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,43 +13,14 @@
# 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.identity.v2 import rbac_base
+from patrole_tempest_plugin.tests.api.identity import rbac_base
class IdentityEndpointsV2AdminRbacTest(rbac_base.BaseIdentityV2AdminRbacTest):
- @classmethod
- def setup_clients(cls):
- super(IdentityEndpointsV2AdminRbacTest, cls).setup_clients()
- cls.endpoints_client = cls.os_primary.endpoints_client
-
- @classmethod
- def resource_setup(cls):
- 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()
- cls.internal_url = data_utils.rand_url()
-
- def _create_endpoint(self):
- self._create_service()
- endpoint = self.endpoints_client.create_endpoint(
- service_id=self.service['OS-KSADM:service']['id'],
- region=self.region,
- publicurl=self.public_url,
- adminurl=self.admin_url,
- internalurl=self.internal_url
- )
- self.addCleanup(test_utils.call_and_ignore_notfound_exc,
- self.endpoints_client.delete_endpoint,
- endpoint['endpoint']['id'])
- return endpoint
-
@rbac_rule_validation.action(service="keystone",
admin_only=True)
@decorators.idempotent_id('6bdaecd4-0843-4ed6-ab64-3a57ab0cd124')
@@ -61,7 +32,7 @@
"""
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- self._create_endpoint()
+ self.setup_test_endpoint()
@rbac_rule_validation.action(service="keystone",
admin_only=True)
@@ -73,9 +44,9 @@
RBAC test for Identity v2 delete_endpoint
"""
- endpoint = self._create_endpoint()
+ endpoint = self.setup_test_endpoint()
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- self.endpoints_client.delete_endpoint(endpoint['endpoint']['id'])
+ self.endpoints_client.delete_endpoint(endpoint['id'])
@rbac_rule_validation.action(service="keystone",
admin_only=True)
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 a557bb8..9a4363d 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
@@ -18,7 +18,7 @@
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
+from patrole_tempest_plugin.tests.api.identity import rbac_base
CONF = config.CONF
@@ -36,7 +36,7 @@
"""
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- self._create_tenant()
+ self.setup_test_tenant()
@rbac_rule_validation.action(service="keystone",
admin_only=True)
@@ -47,7 +47,7 @@
RBAC test for Identity 2.0 update_tenant
"""
- tenant = self._create_tenant()
+ tenant = self.setup_test_tenant()
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.tenants_client.update_tenant(tenant['id'],
@@ -62,7 +62,7 @@
RBAC test for Identity 2.0 delete_tenant
"""
- tenant = self._create_tenant()
+ tenant = self.setup_test_tenant()
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.tenants_client.delete_tenant(tenant['id'])
@@ -77,7 +77,7 @@
RBAC test for Identity 2.0 show_tenant
"""
- tenant = self._create_tenant()
+ tenant = self.setup_test_tenant()
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.tenants_client.show_tenant(tenant['id'])
@@ -91,7 +91,7 @@
RBAC test for Identity 2.0 list_tenant_users
"""
- tenant = self._create_tenant()
+ tenant = self.setup_test_tenant()
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.tenants_client.list_tenant_users(tenant['id'])
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 a1ec5c6..9d80469 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,12 +13,11 @@
# 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.identity.v2 import rbac_base
+from patrole_tempest_plugin.tests.api.identity import rbac_base
class IdentityRolesV2AdminRbacTest(rbac_base.BaseIdentityV2AdminRbacTest):
@@ -28,17 +27,10 @@
super(IdentityRolesV2AdminRbacTest, cls).setup_clients()
cls.roles_client = cls.os_primary.roles_client
- def _create_role(self):
- role = self.roles_client.create_role(
- name=data_utils.rand_name('test_role'))['role']
- self.addCleanup(test_utils.call_and_ignore_notfound_exc,
- self.roles_client.delete_role, role['id'])
- return role
-
def _create_tenant_user_and_role(self):
- tenant = self._create_tenant()
- user = self._create_user(tenantid=tenant['id'])
- role = self._create_role()
+ tenant = self.setup_test_tenant()
+ user = self.setup_test_user(tenantid=tenant['id'])
+ role = self.setup_test_role()
return tenant, user, role
def _create_role_on_project(self, tenant, user, role):
@@ -60,7 +52,7 @@
"""
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- self._create_role()
+ self.setup_test_role()
@rbac_rule_validation.action(service="keystone",
admin_only=True)
@@ -71,7 +63,7 @@
RBAC test for Identity v2 delete_role
"""
- role = self._create_role()
+ role = self.setup_test_role()
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.roles_client.delete_role(role['id'])
@@ -85,7 +77,7 @@
RBAC test for Identity v2 show_role
"""
- role = self._create_role()
+ role = self.setup_test_role()
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.roles_client.show_role(role['id'])
@@ -140,8 +132,8 @@
RBAC test for Identity v2 list_user_roles_on_project
"""
- tenant = self._create_tenant()
- user = self._create_user(tenantid=tenant['id'])
+ tenant = self.setup_test_tenant()
+ user = self.setup_test_user(tenantid=tenant['id'])
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.roles_client.list_user_roles_on_project(
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 ad47fd2..8419ec9 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
@@ -16,16 +16,11 @@
from tempest.lib import decorators
from patrole_tempest_plugin import rbac_rule_validation
-from patrole_tempest_plugin.tests.api.identity.v2 import rbac_base
+from patrole_tempest_plugin.tests.api.identity import rbac_base
class IdentityServicesV2AdminRbacTest(rbac_base.BaseIdentityV2AdminRbacTest):
- @classmethod
- def setup_clients(cls):
- super(IdentityServicesV2AdminRbacTest, cls).setup_clients()
- cls.services_client = cls.os_primary.identity_services_client
-
@rbac_rule_validation.action(service="keystone",
admin_only=True)
@decorators.idempotent_id('370050f6-d271-4fb4-abc5-4de1d6dfbad2')
@@ -35,7 +30,7 @@
RBAC test for Identity v2 create_service
"""
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- self._create_service()
+ self.setup_test_service()
@rbac_rule_validation.action(service="keystone",
admin_only=True)
@@ -45,7 +40,7 @@
RBAC test for Identity v2 delete_service
"""
- service_id = self._create_service()['OS-KSADM:service']['id']
+ service_id = self.setup_test_service()['id']
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.services_client.delete_service(service_id)
@@ -58,7 +53,7 @@
RBAC test for Identity v2 show_service
"""
- service_id = self._create_service()['OS-KSADM:service']['id']
+ service_id = self.setup_test_service()['id']
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.services_client.show_service(service_id)
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 f90680d..dfe6e71 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
@@ -17,7 +17,7 @@
from tempest.lib import decorators
from patrole_tempest_plugin import rbac_rule_validation
-from patrole_tempest_plugin.tests.api.identity.v2 import rbac_base
+from patrole_tempest_plugin.tests.api.identity import rbac_base
class IdentityUsersV2AdminRbacTest(rbac_base.BaseIdentityV2AdminRbacTest):
@@ -27,13 +27,13 @@
@decorators.idempotent_id('0f148510-63bf-11e6-1342-080044d0d904')
def test_create_user(self):
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- self._create_user()
+ self.setup_test_user()
@rbac_rule_validation.action(service="keystone",
admin_only=True)
@decorators.idempotent_id('0f148510-63bf-11e6-1342-080044d0d905')
def test_update_user(self):
- user = self._create_user()
+ user = self.setup_test_user()
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.users_client.update_user(user['id'], email="changedUser@xyz.com")
@@ -42,7 +42,7 @@
admin_only=True)
@decorators.idempotent_id('0f148510-63bf-11e6-1342-080044d0d9a1')
def test_update_user_enabled(self):
- user = self._create_user()
+ user = self.setup_test_user()
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.users_client.update_user_enabled(user['id'], enabled=True)
@@ -51,7 +51,7 @@
admin_only=True)
@decorators.idempotent_id('0f148510-63bf-11e6-1342-080044d0d906')
def test_delete_user(self):
- user = self._create_user()
+ user = self.setup_test_user()
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.users_client.delete_user(user['id'])
@@ -67,7 +67,7 @@
admin_only=True)
@decorators.idempotent_id('0f148510-63bf-11e6-1342-080044d0d908')
def test_show_user(self):
- user = self._create_user()
+ user = self.setup_test_user()
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.users_client.show_user(user['id'])
@@ -76,7 +76,7 @@
admin_only=True)
@decorators.idempotent_id('0f148510-63bf-11e6-1342-080044d0d909')
def test_update_user_password(self):
- user = self._create_user()
+ user = self.setup_test_user()
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.users_client.update_user_password(
diff --git a/patrole_tempest_plugin/tests/api/identity/v3/test_auth_rbac.py b/patrole_tempest_plugin/tests/api/identity/v3/test_auth_rbac.py
new file mode 100644
index 0000000..2327cbb
--- /dev/null
+++ b/patrole_tempest_plugin/tests/api/identity/v3/test_auth_rbac.py
@@ -0,0 +1,43 @@
+# 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 patrole_tempest_plugin import rbac_rule_validation
+from patrole_tempest_plugin.tests.api.identity import rbac_base
+
+
+class IdentityAuthV3RbacTest(rbac_base.BaseIdentityV3RbacTest):
+ """Tests the APIs that enforce the auth policy actions.
+
+ For more information about the auth policy actions, see:
+ https://github.com/openstack/keystone/blob/master/keystone/common/policies/auth.py
+ """
+
+ # TODO(felipemonteiro): Add tests for identity:get_auth_catalog and
+ # identity:get_auth_domains once the endpoints are implemented in Tempest's
+ # identity v3 client.
+
+ @classmethod
+ def setup_clients(cls):
+ super(IdentityAuthV3RbacTest, cls).setup_clients()
+ cls.client = cls.identity_client
+
+ @decorators.idempotent_id('2a9fbf7f-6feb-4161-ae4b-faf7d6421b1a')
+ @rbac_rule_validation.action(service="keystone",
+ rule="identity:get_auth_projects")
+ def test_list_auth_projects(self):
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.client.list_auth_projects()['projects']
diff --git a/patrole_tempest_plugin/tests/api/identity/v3/test_credentials_rbac.py b/patrole_tempest_plugin/tests/api/identity/v3/test_credentials_rbac.py
index 42f2c01..995c3b0 100644
--- a/patrole_tempest_plugin/tests/api/identity/v3/test_credentials_rbac.py
+++ b/patrole_tempest_plugin/tests/api/identity/v3/test_credentials_rbac.py
@@ -17,7 +17,7 @@
from tempest.lib import decorators
from patrole_tempest_plugin import rbac_rule_validation
-from patrole_tempest_plugin.tests.api.identity.v3 import rbac_base
+from patrole_tempest_plugin.tests.api.identity import rbac_base
class IdentityCredentialsV3RbacTest(rbac_base.BaseIdentityV3RbacTest):
diff --git a/patrole_tempest_plugin/tests/api/identity/v3/test_domain_configuration_rbac.py b/patrole_tempest_plugin/tests/api/identity/v3/test_domain_configuration_rbac.py
new file mode 100644
index 0000000..33526e7
--- /dev/null
+++ b/patrole_tempest_plugin/tests/api/identity/v3/test_domain_configuration_rbac.py
@@ -0,0 +1,167 @@
+# 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.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.identity import rbac_base
+
+CONF = config.CONF
+
+
+class DomainConfigurationV3RbacTest(rbac_base.BaseIdentityV3RbacTest):
+ """RBAC tests for domain configuration client.
+
+ Provides coverage for the following policy actions:
+ https://github.com/openstack/keystone/blob/master/keystone/common/policies/domain_config.py
+ """
+
+ identity = {"driver": "ldap"}
+ ldap = {"url": "ldap://myldap.com:389/",
+ "user_tree_dn": "ou=Users,dc=my_new_root,dc=org"}
+
+ @classmethod
+ def setup_clients(cls):
+ super(DomainConfigurationV3RbacTest, cls).setup_clients()
+ cls.client = cls.domain_config_client
+
+ @classmethod
+ def resource_setup(cls):
+ super(DomainConfigurationV3RbacTest, cls).resource_setup()
+ cls.domain_id = cls.setup_test_domain()['id']
+
+ def setUp(self):
+ super(DomainConfigurationV3RbacTest, self).setUp()
+ self._create_domain_config(self.domain_id)
+
+ def _create_domain_config(self, domain_id):
+ domain_config = self.client.create_domain_config(
+ domain_id, identity=self.identity, ldap=self.ldap)['config']
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.client.delete_domain_config,
+ domain_id)
+ return domain_config
+
+ @rbac_rule_validation.action(service="keystone",
+ rule="identity:create_domain_config")
+ @decorators.idempotent_id('6bdaecd4-0843-4ed6-ab64-3a57ab0cd115')
+ def test_create_domain_config(self):
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self._create_domain_config(self.domain_id)
+
+ @rbac_rule_validation.action(service="keystone",
+ rule="identity:get_domain_config")
+ @decorators.idempotent_id('6bdaecd4-0843-4ed6-ab64-3a57ab0cd118')
+ def test_show_domain_config(self):
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.client.show_domain_config(self.domain_id)['config']
+
+ @decorators.idempotent_id('1b539f95-4991-4e09-960f-fa771e1007d7')
+ @rbac_rule_validation.action(service="keystone",
+ rule="identity:get_domain_config")
+ def test_show_domain_group_config(self):
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.client.show_domain_group_config(self.domain_id, 'identity')[
+ 'config']
+
+ @decorators.idempotent_id('590c774d-a294-44f8-866e-aac9f4ab3809')
+ @rbac_rule_validation.action(service="keystone",
+ rule="identity:get_domain_config")
+ def test_show_domain_group_option_config(self):
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.client.show_domain_group_option_config(self.domain_id, 'identity',
+ 'driver')['config']
+
+ @decorators.idempotent_id('21053885-1ce3-4167-b5e3-e470253481da')
+ @rbac_rule_validation.action(
+ service="keystone",
+ rule="identity:get_security_compliance_domain_config")
+ def test_show_security_compliance_domain_config(self):
+ # The "security_compliance" group can only be shown for the default
+ # domain.
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.client.show_domain_group_config(
+ CONF.identity.default_domain_id, 'security_compliance')
+
+ @decorators.idempotent_id('d1addd10-9ae4-4360-9961-47324fd22f23')
+ @rbac_rule_validation.action(service="keystone",
+ rule="identity:get_domain_config_default")
+ def test_show_default_config_settings(self):
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.client.show_default_config_settings()['config']
+
+ @decorators.idempotent_id('63183377-251f-4622-81f0-6b58a8a285c9')
+ @rbac_rule_validation.action(service="keystone",
+ rule="identity:get_domain_config_default")
+ def test_show_default_group_config(self):
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.client.show_default_group_config('identity')['config']
+
+ @decorators.idempotent_id('6440e9c1-e8da-474d-9118-89996fffe5f8')
+ @rbac_rule_validation.action(service="keystone",
+ rule="identity:get_domain_config_default")
+ def test_show_default_group_option(self):
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.client.show_default_group_option('identity', 'driver')['config']
+
+ @rbac_rule_validation.action(service="keystone",
+ rule="identity:update_domain_config")
+ @decorators.idempotent_id('6bdaecd4-0843-4ed6-ab64-3a57ab0cd116')
+ def test_update_domain_config(self):
+ updated_config = {'ldap': {'url': data_utils.rand_url()}}
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.client.update_domain_config(
+ self.domain_id, **updated_config)['config']
+
+ @decorators.idempotent_id('6e32bf96-dbe9-4ac8-b814-0e79fa948285')
+ @rbac_rule_validation.action(service="keystone",
+ rule="identity:update_domain_config")
+ def test_update_domain_group_config(self):
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.client.update_domain_group_config(
+ self.domain_id, 'identity', identity=self.identity)['config']
+
+ @decorators.idempotent_id('d2c510da-a077-4c67-9522-27745ef2812b')
+ @rbac_rule_validation.action(service="keystone",
+ rule="identity:update_domain_config")
+ def test_update_domain_group_option_config(self):
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.client.update_domain_group_option_config(
+ self.domain_id, 'identity', 'driver', driver='ldap')['config']
+
+ @rbac_rule_validation.action(service="keystone",
+ rule="identity:delete_domain_config")
+ @decorators.idempotent_id('6bdaecd4-0843-4ed6-ab64-3a57ab0cd117')
+ def test_delete_domain_config(self):
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.client.delete_domain_config(self.domain_id)
+
+ @decorators.idempotent_id('f479694b-df02-4d5a-88b6-c8b52f9341eb')
+ @rbac_rule_validation.action(service="keystone",
+ rule="identity:delete_domain_config")
+ def test_delete_domain_group_config(self):
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.client.delete_domain_group_config(self.domain_id, 'identity')
+
+ @decorators.idempotent_id('f594bde3-31c9-414f-922d-0ddafdc0ca40')
+ @rbac_rule_validation.action(service="keystone",
+ rule="identity:delete_domain_config")
+ def test_delete_domain_group_option_config(self):
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.client.delete_domain_group_option_config(
+ self.domain_id, 'identity', 'driver')
diff --git a/patrole_tempest_plugin/tests/api/identity/v3/test_domains_rbac.py b/patrole_tempest_plugin/tests/api/identity/v3/test_domains_rbac.py
index ba5d5e0..a8cd022 100644
--- a/patrole_tempest_plugin/tests/api/identity/v3/test_domains_rbac.py
+++ b/patrole_tempest_plugin/tests/api/identity/v3/test_domains_rbac.py
@@ -17,7 +17,7 @@
from tempest.lib import decorators
from patrole_tempest_plugin import rbac_rule_validation
-from patrole_tempest_plugin.tests.api.identity.v3 import rbac_base
+from patrole_tempest_plugin.tests.api.identity import rbac_base
class IdentityDomainsV3RbacTest(rbac_base.BaseIdentityV3RbacTest):
@@ -34,7 +34,8 @@
@decorators.idempotent_id('6bdaecd4-0843-4ed6-ab64-3a57ab0cd111')
def test_update_domain(self):
domain = self.setup_test_domain()
- new_domain_name = data_utils.rand_name('test_update_domain')
+ new_domain_name = data_utils.rand_name(
+ self.__class__.__name__ + '-test_update_domain')
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.domains_client.update_domain(domain['id'],
domain=domain,
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
index 77ad647..7e844e7 100644
--- 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
@@ -17,7 +17,7 @@
from tempest.lib import decorators
from patrole_tempest_plugin import rbac_rule_validation
-from patrole_tempest_plugin.tests.api.identity.v3 import rbac_base
+from patrole_tempest_plugin.tests.api.identity import rbac_base
class IdentityEndpointsFilterV3RbacTest(
diff --git a/patrole_tempest_plugin/tests/api/identity/v3/test_endpoints_rbac.py b/patrole_tempest_plugin/tests/api/identity/v3/test_endpoints_rbac.py
index eabebb6..2659bae 100644
--- a/patrole_tempest_plugin/tests/api/identity/v3/test_endpoints_rbac.py
+++ b/patrole_tempest_plugin/tests/api/identity/v3/test_endpoints_rbac.py
@@ -17,7 +17,7 @@
from tempest.lib import decorators
from patrole_tempest_plugin import rbac_rule_validation
-from patrole_tempest_plugin.tests.api.identity.v3 import rbac_base
+from patrole_tempest_plugin.tests.api.identity import rbac_base
class IdentityEndpointsV3RbacTest(rbac_base.BaseIdentityV3RbacTest):
diff --git a/patrole_tempest_plugin/tests/api/identity/v3/test_groups_rbac.py b/patrole_tempest_plugin/tests/api/identity/v3/test_groups_rbac.py
index 3cc71a6..0fc29b7 100644
--- a/patrole_tempest_plugin/tests/api/identity/v3/test_groups_rbac.py
+++ b/patrole_tempest_plugin/tests/api/identity/v3/test_groups_rbac.py
@@ -17,7 +17,7 @@
from tempest.lib import decorators
from patrole_tempest_plugin import rbac_rule_validation
-from patrole_tempest_plugin.tests.api.identity.v3 import rbac_base
+from patrole_tempest_plugin.tests.api.identity import rbac_base
class IdentityGroupsV3RbacTest(rbac_base.BaseIdentityV3RbacTest):
@@ -41,7 +41,8 @@
@decorators.idempotent_id('790fb7be-a657-4a64-9b83-c43425cf180b')
def test_update_group(self):
group = self.setup_test_group()
- new_group_name = data_utils.rand_name('group')
+ new_group_name = data_utils.rand_name(
+ self.__class__.__name__ + '-group')
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.groups_client.update_group(group['id'],
diff --git a/patrole_tempest_plugin/tests/api/identity/v3/test_oauth_consumers_rbac.py b/patrole_tempest_plugin/tests/api/identity/v3/test_oauth_consumers_rbac.py
index f331cff..5e21338 100644
--- a/patrole_tempest_plugin/tests/api/identity/v3/test_oauth_consumers_rbac.py
+++ b/patrole_tempest_plugin/tests/api/identity/v3/test_oauth_consumers_rbac.py
@@ -18,13 +18,14 @@
from tempest.lib import decorators
from patrole_tempest_plugin import rbac_rule_validation
-from patrole_tempest_plugin.tests.api.identity.v3 import rbac_base
+from patrole_tempest_plugin.tests.api.identity import rbac_base
class IdentityConsumersV3RbacTest(rbac_base.BaseIdentityV3RbacTest):
def _create_consumer(self):
- description = data_utils.rand_name('test_create_consumer')
+ description = data_utils.rand_name(
+ self.__class__.__name__ + '-test_consumer')
consumer = self.consumers_client.create_consumer(
description)['consumer']
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
@@ -53,7 +54,8 @@
@decorators.idempotent_id('0f148510-63bf-11e6-4522-080044d0d972')
def test_update_consumer(self):
consumer = self._create_consumer()
- new_description = data_utils.rand_name('test_update_consumer')
+ new_description = data_utils.rand_name(
+ self.__class__.__name__ + '-test_consumer')
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.consumers_client.update_consumer(consumer['id'],
diff --git a/patrole_tempest_plugin/tests/api/identity/v3/test_policies_rbac.py b/patrole_tempest_plugin/tests/api/identity/v3/test_policies_rbac.py
index 8f11e30..3e03ac0 100644
--- a/patrole_tempest_plugin/tests/api/identity/v3/test_policies_rbac.py
+++ b/patrole_tempest_plugin/tests/api/identity/v3/test_policies_rbac.py
@@ -17,7 +17,7 @@
from tempest.lib import decorators
from patrole_tempest_plugin import rbac_rule_validation
-from patrole_tempest_plugin.tests.api.identity.v3 import rbac_base
+from patrole_tempest_plugin.tests.api.identity import rbac_base
class IdentityPoliciesV3RbacTest(rbac_base.BaseIdentityV3RbacTest):
@@ -34,7 +34,8 @@
@decorators.idempotent_id('9cfed3c6-0b27-4d15-be67-e06e0cfb01b9')
def test_update_policy(self):
policy = self.setup_test_policy()
- updated_policy_type = data_utils.rand_name('policy_type')
+ updated_policy_type = data_utils.rand_name(
+ self.__class__.__name__ + '-policy_type')
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.policies_client.update_policy(policy['id'],
diff --git a/patrole_tempest_plugin/tests/api/identity/v3/test_projects_rbac.py b/patrole_tempest_plugin/tests/api/identity/v3/test_projects_rbac.py
index 325b987..51086ae 100644
--- a/patrole_tempest_plugin/tests/api/identity/v3/test_projects_rbac.py
+++ b/patrole_tempest_plugin/tests/api/identity/v3/test_projects_rbac.py
@@ -17,7 +17,7 @@
from tempest.lib import decorators
from patrole_tempest_plugin import rbac_rule_validation
-from patrole_tempest_plugin.tests.api.identity.v3 import rbac_base
+from patrole_tempest_plugin.tests.api.identity import rbac_base
class IdentityProjectV3RbacTest(rbac_base.BaseIdentityV3RbacTest):
@@ -34,7 +34,8 @@
@decorators.idempotent_id('0f148510-63bf-11e6-1564-080044d0d905')
def test_update_project(self):
project = self.setup_test_project()
- new_desc = data_utils.rand_name('description')
+ new_desc = data_utils.rand_name(
+ self.__class__.__name__ + '-description')
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.projects_client.update_project(project['id'],
diff --git a/patrole_tempest_plugin/tests/api/identity/v3/test_regions_rbac.py b/patrole_tempest_plugin/tests/api/identity/v3/test_regions_rbac.py
index b35facd..55a2f77 100644
--- a/patrole_tempest_plugin/tests/api/identity/v3/test_regions_rbac.py
+++ b/patrole_tempest_plugin/tests/api/identity/v3/test_regions_rbac.py
@@ -17,7 +17,7 @@
from tempest.lib import decorators
from patrole_tempest_plugin import rbac_rule_validation
-from patrole_tempest_plugin.tests.api.identity.v3 import rbac_base
+from patrole_tempest_plugin.tests.api.identity import rbac_base
class IdentityRegionsV3RbacTest(rbac_base.BaseIdentityV3RbacTest):
@@ -34,7 +34,8 @@
@decorators.idempotent_id('6bdaecd4-0843-4ed6-ab64-3a57ab0cd120')
def test_update_region(self):
region = self.setup_test_region()
- new_description = data_utils.rand_name('test_update_region')
+ new_description = data_utils.rand_name(
+ self.__class__.__name__ + '-test_update_region')
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.regions_client.update_region(region['id'],
diff --git a/patrole_tempest_plugin/tests/api/identity/v3/test_role_assignments_rbac.py b/patrole_tempest_plugin/tests/api/identity/v3/test_role_assignments_rbac.py
index 2dd0ff5..6fe6c29 100644
--- a/patrole_tempest_plugin/tests/api/identity/v3/test_role_assignments_rbac.py
+++ b/patrole_tempest_plugin/tests/api/identity/v3/test_role_assignments_rbac.py
@@ -16,7 +16,7 @@
from tempest.lib import decorators
from patrole_tempest_plugin import rbac_rule_validation
-from patrole_tempest_plugin.tests.api.identity.v3 import rbac_base
+from patrole_tempest_plugin.tests.api.identity import rbac_base
class IdentityRoleAssignmentsV3RbacTest(rbac_base.BaseIdentityV3RbacTest):
diff --git a/patrole_tempest_plugin/tests/api/identity/v3/test_roles_rbac.py b/patrole_tempest_plugin/tests/api/identity/v3/test_roles_rbac.py
index 2676bf9..22b03f5 100644
--- a/patrole_tempest_plugin/tests/api/identity/v3/test_roles_rbac.py
+++ b/patrole_tempest_plugin/tests/api/identity/v3/test_roles_rbac.py
@@ -18,7 +18,7 @@
from tempest.lib import decorators
from patrole_tempest_plugin import rbac_rule_validation
-from patrole_tempest_plugin.tests.api.identity.v3 import rbac_base
+from patrole_tempest_plugin.tests.api.identity import rbac_base
class IdentityRolesV3RbacTest(rbac_base.BaseIdentityV3RbacTest):
@@ -44,7 +44,8 @@
rule="identity:update_role")
@decorators.idempotent_id('0f148510-63bf-11e6-1395-080044d0d905')
def test_update_role(self):
- new_role_name = data_utils.rand_name('test_update_role')
+ new_role_name = data_utils.rand_name(
+ self.__class__.__name__ + '-test_update_role')
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.roles_client.update_role(self.role['id'],
diff --git a/patrole_tempest_plugin/tests/api/identity/v3/test_services_rbac.py b/patrole_tempest_plugin/tests/api/identity/v3/test_services_rbac.py
index c02b471..44ce1a1 100644
--- a/patrole_tempest_plugin/tests/api/identity/v3/test_services_rbac.py
+++ b/patrole_tempest_plugin/tests/api/identity/v3/test_services_rbac.py
@@ -17,7 +17,7 @@
from tempest.lib import decorators
from patrole_tempest_plugin import rbac_rule_validation
-from patrole_tempest_plugin.tests.api.identity.v3 import rbac_base
+from patrole_tempest_plugin.tests.api.identity import rbac_base
class IdentitySericesV3RbacTest(rbac_base.BaseIdentityV3RbacTest):
@@ -34,7 +34,7 @@
@decorators.idempotent_id('b39447d1-2cf6-40e5-a899-46f287f2ecf0')
def test_update_service(self):
service = self.setup_test_service()
- new_name = data_utils.rand_name('service')
+ new_name = data_utils.rand_name(self.__class__.__name__ + '-service')
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.services_client.update_service(service['id'],
diff --git a/patrole_tempest_plugin/tests/api/identity/v3/test_trusts_rbac.py b/patrole_tempest_plugin/tests/api/identity/v3/test_trusts_rbac.py
index 622b330..763c407 100644
--- a/patrole_tempest_plugin/tests/api/identity/v3/test_trusts_rbac.py
+++ b/patrole_tempest_plugin/tests/api/identity/v3/test_trusts_rbac.py
@@ -19,7 +19,7 @@
from tempest import test
from patrole_tempest_plugin import rbac_rule_validation
-from patrole_tempest_plugin.tests.api.identity.v3 import rbac_base
+from patrole_tempest_plugin.tests.api.identity import rbac_base
CONF = config.CONF
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 7380531..723455e 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
@@ -17,7 +17,7 @@
from tempest.lib import decorators
from patrole_tempest_plugin import rbac_rule_validation
-from patrole_tempest_plugin.tests.api.identity.v3 import rbac_base
+from patrole_tempest_plugin.tests.api.identity import rbac_base
class IdentityUserV3AdminRbacTest(rbac_base.BaseIdentityV3RbacTest):
@@ -39,7 +39,8 @@
@decorators.idempotent_id('0f148510-63bf-11e6-4522-080044d0d905')
def test_update_user(self):
user = self.setup_test_user()
- new_email = data_utils.rand_name('user_email')
+ new_email = data_utils.rand_name(
+ self.__class__.__name__ + '-user_email')
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.users_client.update_user(user['id'],
diff --git a/patrole_tempest_plugin/tests/api/image/rbac_base.py b/patrole_tempest_plugin/tests/api/image/rbac_base.py
index 2a45ccb..7270560 100644
--- a/patrole_tempest_plugin/tests/api/image/rbac_base.py
+++ b/patrole_tempest_plugin/tests/api/image/rbac_base.py
@@ -14,7 +14,7 @@
from tempest.api.image import base as image_base
from tempest import config
-from patrole_tempest_plugin.rbac_utils import rbac_utils
+from patrole_tempest_plugin import rbac_utils
CONF = config.CONF
@@ -28,14 +28,13 @@
super(BaseV1ImageRbacTest, 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(BaseV1ImageRbacTest, 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.rbac_utils = rbac_utils.RbacUtils(cls)
class BaseV2ImageRbacTest(image_base.BaseV2ImageTest):
@@ -47,11 +46,10 @@
super(BaseV2ImageRbacTest, 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(BaseV2ImageRbacTest, 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.rbac_utils = rbac_utils.RbacUtils(cls)
diff --git a/patrole_tempest_plugin/tests/api/image/v1/test_images_rbac.py b/patrole_tempest_plugin/tests/api/image/v1/test_images_rbac.py
index ae4e4d2..7010baa 100644
--- a/patrole_tempest_plugin/tests/api/image/v1/test_images_rbac.py
+++ b/patrole_tempest_plugin/tests/api/image/v1/test_images_rbac.py
@@ -35,7 +35,7 @@
RBAC test for the glance add_image policy.
"""
properties = {'prop1': 'val1'}
- image_name = data_utils.rand_name('image')
+ image_name = data_utils.rand_name(self.__class__.__name__ + '-Image')
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.create_image(name=image_name,
container_format='bare',
@@ -50,7 +50,7 @@
RBAC test for the glance delete_image policy.
"""
- image_name = data_utils.rand_name('image')
+ image_name = data_utils.rand_name(self.__class__.__name__ + '-Image')
properties = {'prop1': 'val1'}
body = self.create_image(name=image_name,
container_format='bare',
@@ -68,7 +68,7 @@
RBAC test for the glance download_image policy.
"""
- image_name = data_utils.rand_name('image')
+ image_name = data_utils.rand_name(self.__class__.__name__ + '-Image')
properties = {'prop1': 'val1'}
body = self.create_image(name=image_name,
container_format='bare',
@@ -90,7 +90,7 @@
RBAC test for the glance get_image policy.
"""
- image_name = data_utils.rand_name('image')
+ image_name = data_utils.rand_name(self.__class__.__name__ + '-Image')
properties = {'prop1': 'val1'}
body = self.create_image(name=image_name,
container_format='bare',
@@ -122,7 +122,7 @@
RBAC test for the glance modify_image policy.
"""
- image_name = data_utils.rand_name('image')
+ image_name = data_utils.rand_name(self.__class__.__name__ + '-Image')
properties = {'prop1': 'val1'}
body = self.create_image(name=image_name,
container_format='bare',
@@ -141,7 +141,7 @@
RBAC test for the glance publicize_image policy.
"""
- image_name = data_utils.rand_name('image')
+ image_name = data_utils.rand_name(self.__class__.__name__ + '-Image')
properties = {'prop1': 'val1'}
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.create_image(name=image_name,
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 1c937b0..74c64e1 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
@@ -35,7 +35,8 @@
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
# create a md object, it will be cleaned automatically after
# cleanup of namespace
- object_name = data_utils.rand_name('test-object')
+ object_name = data_utils.rand_name(
+ self.__class__.__name__ + '-test-object')
self.namespace_objects_client.create_namespace_object(
namespace['namespace'],
name=object_name)
@@ -66,7 +67,8 @@
RBAC test for the glance modify_metadef_object policy
"""
namespace = self.create_namespace()
- object_name = data_utils.rand_name('test-object')
+ object_name = data_utils.rand_name(
+ self.__class__.__name__ + '-test-object')
self.namespace_objects_client.create_namespace_object(
namespace['namespace'],
name=object_name)
@@ -89,7 +91,8 @@
RBAC test for the glance get_metadef_object policy
"""
namespace = self.create_namespace()
- object_name = data_utils.rand_name('test-object')
+ object_name = data_utils.rand_name(
+ self.__class__.__name__ + '-test-object')
self.namespace_objects_client.create_namespace_object(
namespace['namespace'],
name=object_name)
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 0d194b7..93c50c4 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
@@ -38,7 +38,8 @@
"""
namespace = self.create_namespace()
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- property_name = data_utils.rand_name('test-ns-property')
+ property_name = data_utils.rand_name(
+ self.__class__.__name__ + '-test-ns-property')
self.namespace_properties_client.create_namespace_property(
namespace=namespace['namespace'], type="string",
title=property_name, name=self.resource_name)
@@ -65,7 +66,8 @@
RBAC test for the glance get_metadef_property policy
"""
namespace = self.create_namespace()
- property_name = data_utils.rand_name('test-ns-property')
+ property_name = data_utils.rand_name(
+ self.__class__.__name__ + '-test-ns-property')
self.namespace_properties_client.create_namespace_property(
namespace=namespace['namespace'], type="string",
title=property_name, name=self.resource_name)
@@ -83,7 +85,8 @@
RBAC test for the glance modify_metadef_property policy
"""
namespace = self.create_namespace()
- property_name = data_utils.rand_name('test-ns-property')
+ property_name = data_utils.rand_name(
+ self.__class__.__name__ + '-test-ns-property')
self.namespace_properties_client.create_namespace_property(
namespace=namespace['namespace'], type="string",
title=property_name, name=self.resource_name)
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 fb4a599..c6bd60e 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
@@ -31,7 +31,8 @@
RBAC test for the glance add_metadef_namespace policy
"""
- namespace_name = data_utils.rand_name('test-ns')
+ namespace_name = data_utils.rand_name(
+ self.__class__.__name__ + '-test-ns')
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.namespaces_client.create_namespace(
namespace=namespace_name,
@@ -60,7 +61,8 @@
RBAC test for the glance modify_metadef_namespace policy
"""
- namespace_name = data_utils.rand_name('test-ns')
+ namespace_name = data_utils.rand_name(
+ self.__class__.__name__ + '-test-ns')
body = self.namespaces_client.create_namespace(
namespace=namespace_name,
protected=False)
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
index cfd544c..7750a19 100644
--- 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
@@ -42,7 +42,8 @@
def resource_setup(cls):
super(NamespaceTagsRbacTest, cls).resource_setup()
cls.namespace = cls.namespaces_client.create_namespace(
- namespace=data_utils.rand_name('namespace'))['namespace']
+ namespace=data_utils.rand_name(
+ cls.__name__ + '-namespace'))['namespace']
@classmethod
def resource_cleanup(cls):
@@ -54,7 +55,7 @@
namespace_tag_names = []
for i in range(tag_count):
- tag_name = data_utils.rand_name('tag')
+ tag_name = data_utils.rand_name(self.__class__.__name__ + '-tag')
namespace_tag_names.append({'name': tag_name})
if multiple:
@@ -91,7 +92,8 @@
rule="modify_metadef_tag")
def test_update_namespace_tag(self):
tag_name = self._create_namespace_tag()
- updated_tag_name = data_utils.rand_name('tag')
+ updated_tag_name = data_utils.rand_name(
+ self.__class__.__name__ + '-tag')
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.client.update_namespace_tag(self.namespace, tag_name,
diff --git a/patrole_tempest_plugin/tests/api/image/v2/test_image_resource_types_rbac.py b/patrole_tempest_plugin/tests/api/image/v2/test_image_resource_types_rbac.py
index 552a137..6727cc8 100644
--- a/patrole_tempest_plugin/tests/api/image/v2/test_image_resource_types_rbac.py
+++ b/patrole_tempest_plugin/tests/api/image/v2/test_image_resource_types_rbac.py
@@ -26,7 +26,8 @@
@classmethod
def resource_setup(cls):
super(ImageResourceTypesRbacTest, cls).resource_setup()
- cls.namespace_name = data_utils.rand_name('test-ns')
+ cls.namespace_name = data_utils.rand_name(
+ cls.__name__ + '-test-ns')
cls.namespaces_client.create_namespace(
namespace=cls.namespace_name,
protected=False)
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 880f892..5b7c823 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
@@ -30,7 +30,7 @@
cls.client = cls.os_primary.image_client_v2
def _create_image(self, **kwargs):
- image_name = data_utils.rand_name('image')
+ image_name = data_utils.rand_name(self.__class__.__name__ + '-Image')
image = self.create_image(name=image_name,
container_format='bare',
disk_format='raw',
@@ -135,7 +135,8 @@
image = self._create_image()
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- updated_image_name = data_utils.rand_name('image')
+ updated_image_name = data_utils.rand_name(
+ self.__class__.__name__ + '-image')
self.client.update_image(image['id'], [
dict(replace='/name', value=updated_image_name)])
@@ -151,7 +152,9 @@
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'))
+ self.client.add_image_tag(
+ image['id'],
+ data_utils.rand_name(self.__class__.__name__ + '-tag'))
@decorators.idempotent_id('c4a0bf9c-b78b-48c6-a31f-72c95f943c6e')
@rbac_rule_validation.action(service="glance",
@@ -163,7 +166,7 @@
RBAC test for the glance delete_image_tag endpoint
"""
image = self._create_image()
- tag_name = data_utils.rand_name('tag')
+ tag_name = data_utils.rand_name(self.__class__.__name__ + '-tag')
self.client.add_image_tag(image['id'], tag_name)
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
diff --git a/patrole_tempest_plugin/tests/api/network/rbac_base.py b/patrole_tempest_plugin/tests/api/network/rbac_base.py
index 629f0ca..3ee31b7 100644
--- a/patrole_tempest_plugin/tests/api/network/rbac_base.py
+++ b/patrole_tempest_plugin/tests/api/network/rbac_base.py
@@ -16,7 +16,7 @@
from tempest.api.network import base as network_base
from tempest import config
-from patrole_tempest_plugin.rbac_utils import rbac_utils
+from patrole_tempest_plugin import rbac_utils
CONF = config.CONF
@@ -30,11 +30,10 @@
super(BaseNetworkRbacTest, 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(BaseNetworkRbacTest, 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.rbac_utils = rbac_utils.RbacUtils(cls)
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 133ea74..8208fde 100644
--- a/patrole_tempest_plugin/tests/api/network/test_networks_rbac.py
+++ b/patrole_tempest_plugin/tests/api/network/test_networks_rbac.py
@@ -33,7 +33,8 @@
def resource_setup(cls):
super(RbacNetworksTest, cls).resource_setup()
- network_name = data_utils.rand_name('rbac-admin-network-')
+ network_name = data_utils.rand_name(
+ cls.__name__ + '-rbac-admin-network-')
post_body = {'name': network_name}
body = cls.networks_client.create_network(**post_body)
@@ -65,7 +66,8 @@
provider_physical_network=None,
provider_segmentation_id=None):
- network_name = data_utils.rand_name('test-network-')
+ network_name = data_utils.rand_name(
+ self.__class__.__name__ + '-test-network-')
post_body = {'name': network_name}
if shared is not None:
diff --git a/patrole_tempest_plugin/tests/api/network/test_routers_rbac.py b/patrole_tempest_plugin/tests/api/network/test_routers_rbac.py
index 5ea1180..1be46ab 100644
--- a/patrole_tempest_plugin/tests/api/network/test_routers_rbac.py
+++ b/patrole_tempest_plugin/tests/api/network/test_routers_rbac.py
@@ -74,7 +74,7 @@
RBAC test for the neutron
create_router:external_gateway_info:enable_snat policy
"""
- name = data_utils.rand_name('snat-router')
+ name = data_utils.rand_name(self.__class__.__name__ + '-snat-router')
external_gateway_info = {'network_id': self.network['id'],
'enable_snat': True}
@@ -94,7 +94,7 @@
RBAC test for the neutron
create_router:external_gateway_info:external_fixed_ips policy
"""
- name = data_utils.rand_name('snat-router')
+ name = data_utils.rand_name(self.__class__.__name__ + '-snat-router')
# Pick an unused IP address.
ip_list = net_utils.get_unused_ip_addresses(self.ports_client,
@@ -134,7 +134,8 @@
RBAC test for the neutron update_router policy
"""
- new_name = data_utils.rand_name('new-router-name')
+ new_name = data_utils.rand_name(self.__class__.__name__ +
+ '-new-router-name')
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.routers_client.update_router(self.router['id'],
name=new_name)
diff --git a/patrole_tempest_plugin/tests/api/network/test_security_groups_rbac.py b/patrole_tempest_plugin/tests/api/network/test_security_groups_rbac.py
index e04600e..20f4bea 100644
--- a/patrole_tempest_plugin/tests/api/network/test_security_groups_rbac.py
+++ b/patrole_tempest_plugin/tests/api/network/test_security_groups_rbac.py
@@ -30,7 +30,7 @@
@classmethod
def resource_setup(cls):
super(SecGroupRbacTest, cls).resource_setup()
- secgroup_name = data_utils.rand_name('secgroup')
+ secgroup_name = data_utils.rand_name(cls.__name__ + '-secgroup')
cls.secgroup = cls.security_groups_client.create_security_group(
name=secgroup_name)['security_group']
@@ -44,7 +44,7 @@
def _create_security_group(self):
# Create a security group
- name = data_utils.rand_name('secgroup')
+ name = data_utils.rand_name(self.__class__.__name__ + '-secgroup')
security_group =\
self.security_groups_client.create_security_group(
name=name)['security_group']
diff --git a/patrole_tempest_plugin/tests/api/orchestration/rbac_base.py b/patrole_tempest_plugin/tests/api/orchestration/rbac_base.py
deleted file mode 100644
index 7be7d40..0000000
--- a/patrole_tempest_plugin/tests/api/orchestration/rbac_base.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright 2017 AT&T Corporation.
-# 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.api.orchestration import base as heat_base
-from tempest import config
-
-from patrole_tempest_plugin.rbac_utils import rbac_utils
-
-CONF = config.CONF
-
-
-class BaseOrchestrationRbacTest(heat_base.BaseOrchestrationTest):
-
- credentials = ['admin', 'primary']
-
- @classmethod
- def skip_checks(cls):
- super(BaseOrchestrationRbacTest, 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(BaseOrchestrationRbacTest, 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)
diff --git a/patrole_tempest_plugin/tests/api/orchestration/test_resource_types_rbac.py b/patrole_tempest_plugin/tests/api/orchestration/test_resource_types_rbac.py
deleted file mode 100644
index a348512..0000000
--- a/patrole_tempest_plugin/tests/api/orchestration/test_resource_types_rbac.py
+++ /dev/null
@@ -1,63 +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.lib import decorators
-
-from patrole_tempest_plugin import rbac_rule_validation
-from patrole_tempest_plugin.tests.api.orchestration import rbac_base
-
-
-class ResourceTypesRbacTest(rbac_base.BaseOrchestrationRbacTest):
-
- @classmethod
- def setup_clients(cls):
- super(ResourceTypesRbacTest, cls).setup_clients()
- cls.client = cls.orchestration_client
-
- @classmethod
- def resource_setup(cls):
- super(ResourceTypesRbacTest, cls).resource_setup()
-
- cls.resource_types = cls.client.list_resource_types()['resource_types']
-
- # There should always be several resource types on a system. But just
- # in case there are none, skip these tests, as that implies the system
- # is misconfigured.
- if cls.resource_types:
- cls.resource_type_name = cls.resource_types[0]
- else:
- raise cls.skipException('No resource types found.')
-
- @decorators.idempotent_id('56c06e92-df96-47b5-bcf2-0104e74e2511')
- @rbac_rule_validation.action(service="heat",
- rule="stacks:list_resource_types")
- def test_list_resource_types(self):
- self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- self.client.list_resource_types()['resource_types']
-
- @decorators.idempotent_id('8b0290f9-0d53-479e-8e4d-3d865b0107a4')
- @rbac_rule_validation.action(service="heat",
- rule="stacks:generate_template")
- def test_show_resource_type_template(self):
- self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- self.client.show_resource_type_template(self.resource_type_name)
-
- @decorators.idempotent_id('2cdcd47f-6abe-43af-b736-c188df27dd38')
- @rbac_rule_validation.action(service="heat",
- rule="stacks:resource_schema")
- def test_show_resource_type_schema(self):
- self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- self.client.show_resource_type(self.resource_type_name)[
- 'resource_type']
diff --git a/patrole_tempest_plugin/tests/api/orchestration/test_soft_config_rbac.py b/patrole_tempest_plugin/tests/api/orchestration/test_soft_config_rbac.py
deleted file mode 100644
index d219ace..0000000
--- a/patrole_tempest_plugin/tests/api/orchestration/test_soft_config_rbac.py
+++ /dev/null
@@ -1,138 +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.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.orchestration import rbac_base
-
-
-class TestRbacSoftwareConfig(rbac_base.BaseOrchestrationRbacTest):
-
- def setUp(self):
- super(TestRbacSoftwareConfig, self).setUp()
- self.config = self._config_create('a')
- self._deployment_create(self.config['id'])
-
- @rbac_rule_validation.action(service="heat",
- rule="software_configs:show")
- @decorators.idempotent_id('b2e7c98c-e17b-4f37-82f3-5d21eff86e79')
- def test_get_software_config(self):
- self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- self.client.show_software_config(self.config['id'])
-
- @rbac_rule_validation.action(service="heat",
- rule="software_deployments:metadata")
- @decorators.idempotent_id('defa34ab-9d1f-4b14-8613-34e964c0c478')
- def test_get_deployment_metadata(self):
- self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- self.client.show_software_deployment_metadata(self.server_id)
-
- @rbac_rule_validation.action(service="heat",
- rule="software_deployments:index")
- @decorators.idempotent_id('2a4dcb91-1803-4749-9cb7-5b69ba668b18')
- def test_get_deployment_list(self):
- self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- self.client.list_software_deployments()
-
- @rbac_rule_validation.action(service="heat",
- rule="software_deployments:show")
- @decorators.idempotent_id('d4e627bc-88a3-4189-8092-151f22ed989d')
- def test_software_show_deployment(self):
- self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- self.client.show_software_deployment(self.deployment_id)
-
- @rbac_rule_validation.action(service="heat",
- rule="software_deployments:update")
- @decorators.idempotent_id('90e8958c-6fa7-4515-b6d7-6d6952979f8c')
- def test_software_deployment_update(self):
- self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- new_action = data_utils.rand_name('ACTION')
- new_status = data_utils.rand_name('STATUS')
- new_reason = data_utils.rand_name('REASON')
- self.client.update_software_deploy(self.deployment_id,
- self.server_id,
- self.config['id'],
- new_action, new_status,
- self.input_values,
- self.output_values,
- new_reason,
- self.signal_transport)
-
- @rbac_rule_validation.action(service="heat",
- rule="software_deployments:create")
- @decorators.idempotent_id('9175fe7b-4210-4c1d-acbb-954998a9fd77')
- def test_software_deployment_create(self):
- self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- self._deployment_create(self.config['id'])
-
- @rbac_rule_validation.action(service="heat",
- rule="software_deployments:delete")
- @decorators.idempotent_id('20f4683d-7316-4d88-a6ea-1ee6013da908')
- def test_software_deployment_delete(self):
- deploy_id = self._deployment_create(self.config['id'])
- self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- self.client.delete_software_deploy(deploy_id)
-
- @rbac_rule_validation.action(service="heat",
- rule="software_configs:create")
- @decorators.idempotent_id('c8fb1c73-fcb6-46c2-9510-8ef0083c9620')
- def test_config_create(self):
- self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- self._config_create('e')
-
- @rbac_rule_validation.action(service="heat",
- rule="software_configs:delete")
- @decorators.idempotent_id('f4f784ea-9878-4306-bc5f-041ba5307ce5')
- def test_config_delete(self):
- configuration = self._config_create('d')
- self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- self.client.delete_software_config(configuration['id'])
-
- def _config_create(self, suffix):
- configuration = {'group': 'script',
- 'inputs': [],
- 'outputs': [],
- 'options': {}}
- configuration['name'] = 'heat_soft_config_%s' % suffix
- configuration['config'] = '#!/bin/bash echo init-%s' % suffix
- api_config = self.client.create_software_config(**configuration)
- self.addCleanup(
- test_utils.call_and_ignore_notfound_exc,
- self.client.delete_software_config,
- api_config['software_config']['id'])
- configuration['id'] = api_config['software_config']['id']
- return configuration
-
- def _deployment_create(self, config_id):
- self.server_id = data_utils.rand_name('dummy-server')
- self.action = 'ACTION_0'
- self.status = 'STATUS_0'
- self.input_values = {}
- self.output_values = []
- self.status_reason = 'REASON_0'
- self.signal_transport = 'NO_SIGNAL'
- self.deployment = self.client.create_software_deploy(
- self.server_id, config_id, self.action, self.status,
- self.input_values, self.output_values, self.status_reason,
- self.signal_transport)
- self.addCleanup(
- test_utils.call_and_ignore_notfound_exc,
- self.client.delete_software_deploy,
- self.deployment['software_deployment']['id'])
- self.deployment_id = self.deployment['software_deployment']['id']
- return self.deployment_id
diff --git a/patrole_tempest_plugin/tests/api/volume/rbac_base.py b/patrole_tempest_plugin/tests/api/volume/rbac_base.py
index c78a3e4..1d390b7 100644
--- a/patrole_tempest_plugin/tests/api/volume/rbac_base.py
+++ b/patrole_tempest_plugin/tests/api/volume/rbac_base.py
@@ -16,7 +16,7 @@
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
+from patrole_tempest_plugin import rbac_utils
CONF = config.CONF
@@ -37,8 +37,7 @@
super(BaseVolumeRbacTest, 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.rbac_utils = rbac_utils.RbacUtils(cls)
version_checker = {
2: [cls.os_primary.volume_hosts_v2_client,
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 60484f1..219acb4 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
@@ -36,8 +36,10 @@
def _create_user_message(self):
"""Trigger a 'no valid host' situation to generate a message."""
- bad_protocol = data_utils.rand_name('storage_protocol')
- bad_vendor = data_utils.rand_name('vendor_name')
+ bad_protocol = data_utils.rand_name(
+ self.__class__.__name__ + '-storage_protocol')
+ bad_vendor = data_utils.rand_name(
+ self.__class__.__name__ + '-vendor_name')
extra_specs = {'storage_protocol': bad_protocol,
'vendor_name': bad_vendor}
vol_type_name = data_utils.rand_name(
diff --git a/patrole_tempest_plugin/tests/api/volume/test_volume_basic_crud_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_volume_basic_crud_rbac.py
index b98c39a..d780de7 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_volume_basic_crud_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_volume_basic_crud_rbac.py
@@ -13,18 +13,20 @@
# 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 VolumesV2BasicCrudRbacTest(rbac_base.BaseVolumeRbacTest):
+ @classmethod
+ def resource_setup(cls):
+ super(VolumesV2BasicCrudRbacTest, cls).resource_setup()
+ cls.volume = cls.create_volume()
+
@rbac_rule_validation.action(service="cinder",
rule="volume:create")
@decorators.idempotent_id('426b08ef-6394-4d06-9128-965d5a6c38ef')
@@ -43,36 +45,32 @@
@rbac_rule_validation.action(service="cinder", rule="volume:get")
@decorators.idempotent_id('c4c3fdd5-b1b1-49c3-b977-a9f40ee9257a')
def test_get_volume(self):
- volume = self.create_volume()
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- self.volumes_client.show_volume(volume['id'])
+ self.volumes_client.show_volume(self.volume['id'])
@rbac_rule_validation.action(service="cinder",
rule="volume:get_all")
@decorators.idempotent_id('e3ab7906-b04b-4c45-aa11-1104d302f940')
def test_volume_list(self):
- # Get a list of Volumes
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.volumes_client.list_volumes()
+ @rbac_rule_validation.action(service="cinder", rule="volume:update")
+ @decorators.idempotent_id('b751b889-9a9b-40d8-ae7d-4b0f65e71ac7')
+ def test_update_volume(self):
+ update_name = data_utils.rand_name(self.__class__.__name__ + 'volume')
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.volumes_client.update_volume(self.volume['id'],
+ name=update_name)
+
@rbac_rule_validation.action(
service="cinder",
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
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.volumes_client.list_volumes(detail=True)
- @rbac_rule_validation.action(service="cinder", rule="volume:update")
- @decorators.idempotent_id('b751b889-9a9b-40d8-ae7d-4b0f65e71ac7')
- def test_update_volume(self):
- volume = self.create_volume()
- new_name = data_utils.rand_name('volume')
- self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- self.volumes_client.update_volume(volume['id'],
- name=new_name)
-
class VolumesV3BasicCrudRbacTest(VolumesV2BasicCrudRbacTest):
_api_version = 3
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 d07e5c6..8ee8713 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
@@ -23,6 +23,7 @@
class VolumeMetadataRbacTest(rbac_base.BaseVolumeRbacTest):
+
@classmethod
def setup_clients(cls):
super(VolumeMetadataRbacTest, cls).setup_clients()
@@ -31,36 +32,38 @@
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
@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):
+ def setUp(self):
+ super(VolumeMetadataRbacTest, self).setUp()
+ self._add_metadata(self.volume)
+
+ def tearDown(self):
+ self.volumes_client.update_volume_metadata(self.volume['id'], {})
+ super(VolumeMetadataRbacTest, self).tearDown()
+
+ def _add_metadata(self, volume):
# Create metadata for the volume
- metadata = {"key1": "value1",
- "key2": "value2",
- "key3": "value3",
- "key4": "<value&special_chars>"}
- cls.client.create_volume_metadata(cls.volume['id'],
- metadata)['metadata']
+ metadata = {"key1": "value1"}
+ self.client.create_volume_metadata(self.volume['id'], metadata)[
+ 'metadata']
@rbac_rule_validation.action(service="cinder",
- rule="volume:update_volume_metadata")
+ rule="volume:create_volume_metadata")
@decorators.idempotent_id('232bbb8b-4c29-44dc-9077-b1398c20b738')
def test_create_volume_metadata(self):
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self._add_metadata(self.volume)
@rbac_rule_validation.action(service="cinder",
- rule="volume:get")
+ rule="volume:get_volume_metadata")
@decorators.idempotent_id('87ea37d9-23ab-47b2-a59c-16fc4d2c6dfa')
- def test_get_volume_metadata(self):
+ def test_show_volume_metadata(self):
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.client.show_volume_metadata(self.volume['id'])['metadata']
@@ -85,21 +88,18 @@
rule="volume:update_volume_metadata")
@decorators.idempotent_id('8ce2ff80-99ba-49ae-9bb1-7e96729ee5af')
def test_update_volume_metadata_item(self):
- # Metadata to update
- update_item = {"key3": "value3_update"}
+ updated_metadata_item = {"key1": "value1_update"}
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- self.client.update_volume_metadata_item(self.volume['id'], "key3",
- update_item)['meta']
+ self.client.update_volume_metadata_item(
+ self.volume['id'], "key1", updated_metadata_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"}
+ updated_metadata = {"key1": "value1"}
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- self.client.update_volume_metadata(self.volume['id'], update)
+ self.client.update_volume_metadata(self.volume['id'], updated_metadata)
@decorators.idempotent_id('a9d9e825-5ea3-42e6-96f3-7ac4e97b2ed0')
@rbac_rule_validation.action(
@@ -107,9 +107,5 @@
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):
- _api_version = 3
+ self.client.update_volume_image_metadata(
+ self.volume['id'], image_id=self.image_id)
diff --git a/patrole_tempest_plugin/tests/api/volume/test_volume_services_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_volume_services_rbac.py
new file mode 100644
index 0000000..c1d8a65
--- /dev/null
+++ b/patrole_tempest_plugin/tests/api/volume/test_volume_services_rbac.py
@@ -0,0 +1,51 @@
+# 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 VolumeServicesRbacTest(rbac_base.BaseVolumeRbacTest):
+
+ # TODO(felipemonteiro): Implement a test to cover the policy action,
+ # "volume_extension:services:update", once the Tempest client endpoint
+ # is implemented.
+
+ @classmethod
+ def skip_checks(cls):
+ super(VolumeServicesRbacTest, cls).skip_checks()
+ if not test.is_extension_enabled('os-services', 'volume'):
+ msg = "%s skipped as os-services not enabled." % cls.__name__
+ raise cls.skipException(msg)
+
+ @classmethod
+ def setup_clients(cls):
+ super(VolumeServicesRbacTest, cls).setup_clients()
+ cls.client = cls.os_primary.volume_services_v2_client
+
+ @decorators.idempotent_id('b9134f01-97c0-4abd-9455-fe2f03e3f966')
+ @rbac_rule_validation.action(
+ service="cinder",
+ rule="volume_extension:services:index")
+ def test_list_services(self):
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.client.list_services()['services']
+
+
+class VolumeServicesV3RbacTest(VolumeServicesRbacTest):
+ _api_version = 3
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 8c04a8d..c39a376 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
@@ -43,7 +43,7 @@
cls.volume = cls.create_volume()
def _create_backup(self, volume_id):
- backup_name = data_utils.rand_name('backup')
+ backup_name = data_utils.rand_name(self.__class__.__name__ + 'backup')
backup = self.backups_client.create_backup(
volume_id=volume_id, name=backup_name)['backup']
self.addCleanup(
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 41af3b2..9d34a15 100644
--- a/patrole_tempest_plugin/tests/unit/test_rbac_rule_validation.py
+++ b/patrole_tempest_plugin/tests/unit/test_rbac_rule_validation.py
@@ -37,8 +37,7 @@
self.mock_args.auth_provider.credentials.user_id = \
mock.sentinel.user_id
- CONF.set_override('rbac_test_role', 'Member', group='rbac',
- enforce_type=True)
+ CONF.set_override('rbac_test_role', 'Member', group='rbac')
self.addCleanup(CONF.clear_override, 'rbac_test_role', group='rbac')
@mock.patch.object(rbac_rv, 'LOG', autospec=True)
@@ -255,14 +254,14 @@
"sentinel.action"), e.__str__())
mock_log.error.assert_called_once_with(
- "Role Member was allowed to perform sentinel.action")
+ 'Role %s was allowed to perform %s', ('Member',
+ mock.sentinel.action))
@mock.patch.object(rbac_rv, 'rbac_policy_parser', autospec=True)
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)
+ CONF.set_override('strict_policy_check', True, group='rbac')
self.addCleanup(CONF.clear_override, 'strict_policy_check',
group='rbac')
diff --git a/patrole_tempest_plugin/tests/unit/test_rbac_utils.py b/patrole_tempest_plugin/tests/unit/test_rbac_utils.py
index 057ce20..0f38b1e 100644
--- a/patrole_tempest_plugin/tests/unit/test_rbac_utils.py
+++ b/patrole_tempest_plugin/tests/unit/test_rbac_utils.py
@@ -17,6 +17,7 @@
import testtools
from tempest import config
+from tempest.lib import base as lib_base
from tempest.lib import exceptions as lib_exc
from tempest.tests import base
@@ -28,35 +29,45 @@
class RBACUtilsTest(base.TestCase):
- def setUp(self):
+ available_roles = {
+ 'roles': [
+ {'name': 'admin', 'id': 'admin_id'},
+ {'name': 'Member', 'id': 'member_id'}
+ ]
+ }
+
+ @mock.patch.object(rbac_utils, 'credentials', autospec=True,
+ **{'is_admin_available.return_value': True})
+ @mock.patch.object(rbac_utils.RbacUtils, '_clear_user_roles',
+ autospec=True, return_value=False)
+ def setUp(self, *args):
super(RBACUtilsTest, self).setUp()
- available_roles = {
- 'roles': [
- {'name': 'admin', 'id': 'admin_id'},
- {'name': 'Member', 'id': 'member_id'}
- ]
- }
- # Because rbac_utils is a singleton, reset all of its role-related
- # parameters to the correct values for each test run.
- self.rbac_utils = rbac_utils.rbac_utils()
- self.rbac_utils.switch_role_history = {}
- self.rbac_utils.admin_role_id = 'admin_id'
- self.rbac_utils.rbac_role_id = 'member_id'
-
- self.mock_test_obj = mock.Mock()
+ self.mock_test_obj = mock.Mock(spec=lib_base.BaseTestCase)
self.mock_test_obj.auth_provider = mock.Mock(
**{'credentials.user_id': mock.sentinel.user_id,
'credentials.tenant_id': mock.sentinel.project_id})
self.mock_test_obj.os_admin = mock.Mock(
- **{'roles_v3_client.list_roles.return_value': available_roles})
+ **{'roles_v3_client.list_roles.return_value': self.available_roles}
+ )
+ self.mock_test_obj.get_identity_version = mock.Mock(return_value=3)
- CONF.set_override('rbac_test_role', 'Member', group='rbac',
- enforce_type=True)
- CONF.set_override('auth_version', 'v3', group='identity',
- enforce_type=True)
+ with mock.patch.object(rbac_utils.RbacUtils, '_validate_switch_role'):
+ self.rbac_utils = rbac_utils.RbacUtils(self.mock_test_obj)
+ self.rbac_utils.switch_role_history = {}
+ self.rbac_utils.admin_role_id = 'admin_id'
+ self.rbac_utils.rbac_role_id = 'member_id'
+
+ CONF.set_override('admin_role', 'admin', group='identity')
+ CONF.set_override('auth_version', 'v3', group='identity')
+ CONF.set_override('rbac_test_role', 'Member', group='rbac')
+
+ roles_client = self.mock_test_obj.os_admin.roles_v3_client
+ roles_client.create_user_role_on_project.reset_mock()
+ self.mock_test_obj.auth_provider.reset_mock()
self.addCleanup(CONF.clear_override, 'rbac_test_role', group='rbac')
+ self.addCleanup(CONF.clear_override, 'admin_role', group='identity')
self.addCleanup(CONF.clear_override, 'auth_version', group='identity')
self.addCleanup(mock.patch.stopall)
@@ -65,7 +76,7 @@
**{'roles_client.list_user_roles_on_project.'
'return_value': {'roles': [{'id': return_value}]}})
- @mock.patch.object(rbac_utils.rbac_utils, '_clear_user_roles',
+ @mock.patch.object(rbac_utils.RbacUtils, '_clear_user_roles',
autospec=True, return_value=False)
def test_initialization_with_missing_admin_role(self, _):
self.mock_test_obj.os_admin = mock.Mock(
@@ -79,7 +90,7 @@
self.assertIn("Role with name 'admin' does not exist in the system.",
e.__str__())
- @mock.patch.object(rbac_utils.rbac_utils, '_clear_user_roles',
+ @mock.patch.object(rbac_utils.RbacUtils, '_clear_user_roles',
autospec=True, return_value=False)
def test_initialization_with_missing_rbac_role(self, _):
self.mock_test_obj.os_admin = mock.Mock(
@@ -116,43 +127,33 @@
'member_id'),
])
- @mock.patch.object(rbac_utils.rbac_utils, '_clear_user_roles',
+ @mock.patch.object(rbac_utils.RbacUtils, '_clear_user_roles',
autospec=True, return_value=False)
@mock.patch.object(rbac_utils, 'time', autospec=True)
- def test_rbac_utils_switch_role_to_admin_role(self, mock_time,
- mock_clear_user_roles):
+ def test_rbac_utils_switch_role_to_admin_role(self, mock_time, _):
self.rbac_utils.prev_switch_role = True
self._mock_list_user_roles_on_project('admin_id')
roles_client = self.mock_test_obj.os_admin.roles_v3_client
self.rbac_utils.switch_role(self.mock_test_obj, False)
- roles_client.create_user_role_on_project.\
- assert_called_once_with(mock.sentinel.project_id,
- mock.sentinel.user_id,
- 'admin_id')
- mock_clear_user_roles.assert_called_once_with(
- self.rbac_utils, 'admin_id')
+ roles_client.create_user_role_on_project.assert_called_once_with(
+ mock.sentinel.project_id, mock.sentinel.user_id, 'admin_id')
self.mock_test_obj.auth_provider.clear_auth.assert_called_once_with()
self.mock_test_obj.auth_provider.set_auth.assert_called_once_with()
mock_time.sleep.assert_called_once_with(1)
- @mock.patch.object(rbac_utils.rbac_utils, '_clear_user_roles',
+ @mock.patch.object(rbac_utils.RbacUtils, '_clear_user_roles',
autospec=True, return_value=False)
@mock.patch.object(rbac_utils, 'time', autospec=True)
- def test_rbac_utils_switch_role_to_rbac_role(self, mock_time,
- mock_clear_user_roles):
+ def test_rbac_utils_switch_role_to_rbac_role(self, mock_time, _):
self._mock_list_user_roles_on_project('member_id')
roles_client = self.mock_test_obj.os_admin.roles_v3_client
self.rbac_utils.switch_role(self.mock_test_obj, True)
- roles_client.create_user_role_on_project.\
- assert_called_once_with(mock.sentinel.project_id,
- mock.sentinel.user_id,
- 'member_id')
- mock_clear_user_roles.assert_called_once_with(
- self.rbac_utils, 'member_id')
+ roles_client.create_user_role_on_project.assert_called_once_with(
+ mock.sentinel.project_id, mock.sentinel.user_id, 'member_id')
self.mock_test_obj.auth_provider.clear_auth.assert_called_once_with()
self.mock_test_obj.auth_provider.set_auth.assert_called_once_with()
mock_time.sleep.assert_called_once_with(1)
@@ -165,7 +166,7 @@
self.rbac_utils.switch_role, self.mock_test_obj,
None)
- @mock.patch.object(rbac_utils.rbac_utils, '_clear_user_roles',
+ @mock.patch.object(rbac_utils.RbacUtils, '_clear_user_roles',
autospec=True, return_value=False)
def test_rbac_utils_switch_roles_with_false_value_twice(self, _):
self._mock_list_user_roles_on_project('admin_id')
@@ -178,7 +179,7 @@
'twice. Make sure that you included a rbac_utils.switch_role '
'method call inside the test.', str(e))
- @mock.patch.object(rbac_utils.rbac_utils, '_clear_user_roles',
+ @mock.patch.object(rbac_utils.RbacUtils, '_clear_user_roles',
autospec=True, return_value=False)
def test_rbac_utils_switch_roles_with_true_value_twice(self, _):
self._mock_list_user_roles_on_project('admin_id')
@@ -191,7 +192,7 @@
'twice. Make sure that you included a rbac_utils.switch_role '
'method call inside the test.', str(e))
- @mock.patch.object(rbac_utils.rbac_utils, '_clear_user_roles',
+ @mock.patch.object(rbac_utils.RbacUtils, '_clear_user_roles',
autospec=True, return_value=False)
@mock.patch.object(rbac_utils, 'LOG', autospec=True)
@mock.patch.object(rbac_utils, 'sys', autospec=True)
@@ -228,7 +229,7 @@
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',
+ @mock.patch.object(rbac_utils.RbacUtils, '_clear_user_roles',
autospec=True, return_value=False)
def test_rbac_utils_switch_role_except_exception(self,
mock_clear_user_roles):
diff --git a/releasenotes/notes/add-extra-hypervisor-tests-9374e5fcdb0266e2.yaml b/releasenotes/notes/add-extra-hypervisor-tests-9374e5fcdb0266e2.yaml
new file mode 100644
index 0000000..0c46435
--- /dev/null
+++ b/releasenotes/notes/add-extra-hypervisor-tests-9374e5fcdb0266e2.yaml
@@ -0,0 +1,11 @@
+---
+features:
+ - |
+ Add additional compute hypervisor RBAC tests, so that the previously
+ missing hypervisor endpoints are covered. Tests for the following
+ endpoints were written:
+ * show_hypervisor
+ * list_servers_on_hypervisor
+ * show_hypervisor_statistics
+ * show_hypervisor_uptime
+ * search_hypervisor
diff --git a/releasenotes/notes/domain-config-rbac-tests-8806ca7c159ddf94.yaml b/releasenotes/notes/domain-config-rbac-tests-8806ca7c159ddf94.yaml
new file mode 100644
index 0000000..8108cf4
--- /dev/null
+++ b/releasenotes/notes/domain-config-rbac-tests-8806ca7c159ddf94.yaml
@@ -0,0 +1,5 @@
+---
+features:
+ - |
+ Adds RBAC tests for the domain configuration Keystone v3 extension
+ API.
diff --git a/releasenotes/notes/nova_volume_client-75e153a1c84e4ff8.yaml b/releasenotes/notes/nova_volume_client-75e153a1c84e4ff8.yaml
new file mode 100644
index 0000000..0562137
--- /dev/null
+++ b/releasenotes/notes/nova_volume_client-75e153a1c84e4ff8.yaml
@@ -0,0 +1,5 @@
+---
+features:
+ - |
+ Adds RBAC tests for the Nova os-volumes API which is deprecated
+ from microversion 2.36 onward.
diff --git a/releasenotes/notes/volume-services-rbac-test-57e69f9952c8746e.yaml b/releasenotes/notes/volume-services-rbac-test-57e69f9952c8746e.yaml
new file mode 100644
index 0000000..5b6f0cd
--- /dev/null
+++ b/releasenotes/notes/volume-services-rbac-test-57e69f9952c8746e.yaml
@@ -0,0 +1,5 @@
+---
+features:
+ - |
+ Added RBAC test for the volume services API, which covers the following
+ policy action: "volume_extension:services:index".
diff --git a/requirements.txt b/requirements.txt
index ffc6abe..6d2c7f1 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,7 +1,7 @@
# The order of packages is significant, because pip processes them in the order
# of appearance. Changing the order has an impact on the overall integration
# process, which may cause wedges in the gate later.
-
+hacking!=0.13.0,<0.14,>=0.12.0 # Apache-2.0
pbr>=1.8 # Apache-2.0
urllib3>=1.15.1 # MIT
oslo.log>=3.11.0 # Apache-2.0
diff --git a/tox.ini b/tox.ini
index a004c6e..d2e83e9 100644
--- a/tox.ini
+++ b/tox.ini
@@ -53,9 +53,12 @@
commands = oslo_debug_helper -t patrole_tempest_plugin/tests {posargs}
[flake8]
-# E123, E125 skipped as they are invalid PEP-8.
-
+enable-extensions = H106,H203,H904
show-source = True
+# E123, E125 skipped as they are invalid PEP-8.
ignore = E123,E125
builtins = _
exclude=.venv,.git,.tox,dist,doc,*lib/python*,*egg,build
+
+[hacking]
+local-check-factory = patrole_tempest_plugin.hacking.checks.factory