Merge "Use tempest.common.identity.identity_utils for project management"
diff --git a/.zuul.yaml b/.zuul.yaml
index 5e6deeb..fb110f0 100644
--- a/.zuul.yaml
+++ b/.zuul.yaml
@@ -2,8 +2,8 @@
name: patrole-base
parent: devstack-tempest
description: |
- Patrole base job for admin and member roles. This job executes RBAC tests
- for all the "core" services that Tempest covers, excluding Swift.
+ Patrole base job for admin and member roles. This job executes RBAC tests
+ for all the "core" services that Tempest covers, excluding Swift.
required-projects:
- name: openstack/tempest
- name: openstack/patrole
@@ -87,6 +87,11 @@
RBAC_TEST_ROLE: member
- job:
+ name: patrole-member-rocky
+ parent: patrole-member
+ override-checkout: stable/rocky
+
+- job:
name: patrole-member-queens
parent: patrole-member
override-checkout: stable/queens
@@ -134,16 +139,15 @@
name: patrole-plugin-base
parent: patrole-base
description: |
- Patrole plugin job for admin and member roles which
- runs RBAC tests for neutron-tempest-plugin APIs (if the plugin is installed).
+ Patrole plugin job for admin and member roles which
+ runs RBAC tests for neutron-tempest-plugin APIs (if the plugin is installed).
required-projects:
- name: openstack/tempest
- name: openstack/patrole
- name: openstack/neutron-tempest-plugin
vars:
devstack_localrc:
- TEMPEST_PLUGINS: "'/opt/stack/patrole
- /opt/stack/neutron-tempest-plugin'"
+ TEMPEST_PLUGINS: "'/opt/stack/patrole /opt/stack/neutron-tempest-plugin'"
devstack_plugins:
neutron: git://git.openstack.org/openstack/neutron.git
patrole: git://git.openstack.org/openstack/patrole.git
@@ -152,6 +156,7 @@
tempest: true
neutron: true
neutron-segments: true
+ neutron-qos: true
- job:
name: patrole-plugin-member
@@ -173,20 +178,32 @@
- project:
templates:
+ - openstack-cover-jobs
+ - openstack-lower-constraints-jobs
- openstack-python36-jobs
+ - openstack-python-jobs
+ - openstack-python35-jobs
+ - check-requirements
+ - publish-openstack-docs-pti
+ - release-notes-jobs-python3
check:
jobs:
- patrole-admin
- patrole-member
+ - patrole-member-rocky
- patrole-member-queens
- patrole-member-pike
- patrole-py35-member
- patrole-multinode-admin
- patrole-multinode-member
- - openstack-tox-lower-constraints
- patrole-plugin-admin
- patrole-plugin-member
gate:
jobs:
- patrole-admin
- patrole-member
+ periodic-stable:
+ jobs:
+ - patrole-member-rocky
+ - patrole-member-queens
+ - patrole-member-pike
diff --git a/devstack/plugin.sh b/devstack/plugin.sh
index 4826d21..a6259f4 100644
--- a/devstack/plugin.sh
+++ b/devstack/plugin.sh
@@ -29,6 +29,9 @@
# These policies were removed in Stein but are available in Pike.
iniset $TEMPEST_CONFIG policy-feature-enabled removed_nova_policies_stein False
+
+ # TODO(cl566n): Policies used by Patrole testing. Remove these once stable/pike becomes EOL.
+ iniset $TEMPEST_CONFIG policy-feature-enabled added_cinder_policies_stein False
fi
if [[ ${DEVSTACK_SERIES} == 'queens' ]]; then
@@ -38,9 +41,16 @@
# These policies were removed in Stein but are available in Queens.
iniset $TEMPEST_CONFIG policy-feature-enabled removed_nova_policies_stein False
+
+ # TODO(cl566n): Policies used by Patrole testing. Remove these once stable/queens becomes EOL.
+ iniset $TEMPEST_CONFIG policy-feature-enabled added_cinder_policies_stein False
fi
- iniset $TEMPEST_CONFIG patrole enable_rbac True
+ if [[ ${DEVSTACK_SERIES} == 'rocky' ]]; then
+ # TODO(cl566n): Policies used by Patrole testing. Remove these once stable/rocky becomes EOL.
+ iniset $TEMPEST_CONFIG policy-feature-enabled added_cinder_policies_stein False
+ fi
+
iniset $TEMPEST_CONFIG patrole rbac_test_role $RBAC_TEST_ROLE
}
diff --git a/doc/source/framework/overview.rst b/doc/source/framework/overview.rst
index 4902f7b..8e04082 100644
--- a/doc/source/framework/overview.rst
+++ b/doc/source/framework/overview.rst
@@ -1,9 +1,11 @@
RBAC Testing Validation
=======================
---------
-Overview
---------
+.. _validation-workflow-overview:
+
+----------------------------
+Validation Workflow Overview
+----------------------------
RBAC testing validation is broken up into 3 stages:
@@ -36,6 +38,16 @@
``oslo.policy`` or a 403 from the API call and a ``True`` result from
``oslo.policy`` are failing results.
+.. warning::
+
+ Note that Patrole cannot currently derive the expected policy result for
+ service-specific ``oslo.policy`` `checks`_, like Neutron's `FieldCheck`_,
+ because such checks are contained within the service's code base itself,
+ which Patrole cannot import.
+
+.. _checks: https://docs.openstack.org/oslo.policy/latest/reference/api/oslo_policy.policy.html#generic-checks
+.. _FieldCheck: https://docs.openstack.org/neutron/pike/contributor/internals/policy.html#fieldcheck-verify-resource-attributes
+
-------------------------------
The RBAC Rule Validation Module
-------------------------------
diff --git a/doc/source/framework/policy_authority.rst b/doc/source/framework/policy_authority.rst
index 822c7b6..37b698c 100644
--- a/doc/source/framework/policy_authority.rst
+++ b/doc/source/framework/policy_authority.rst
@@ -60,3 +60,4 @@
.. automodule:: patrole_tempest_plugin.policy_authority
:members:
:undoc-members:
+ :special-members:
diff --git a/doc/source/framework/rbac_authority.rst b/doc/source/framework/rbac_authority.rst
index 84c372b..40f2a8d 100644
--- a/doc/source/framework/rbac_authority.rst
+++ b/doc/source/framework/rbac_authority.rst
@@ -35,3 +35,4 @@
.. automodule:: patrole_tempest_plugin.rbac_authority
:members:
:undoc-members:
+ :special-members:
diff --git a/doc/source/framework/rbac_utils.rst b/doc/source/framework/rbac_utils.rst
index 7143928..b13a4a3 100644
--- a/doc/source/framework/rbac_utils.rst
+++ b/doc/source/framework/rbac_utils.rst
@@ -23,156 +23,14 @@
and test execution, respectively. This is especially true when considering
custom policy rule definitions, which can be arbitrarily complex.
-.. _role-overriding:
-
-Role Overriding
-^^^^^^^^^^^^^^^
-
-Role overriding is the way Patrole is able to create resources and delete
-resources -- including those that require admin credentials -- while still
-being able to exercise the same set of Tempest credentials to perform the API
-action that authorizes the policy under test, by manipulating the role of
-the Tempest credentials.
-
-Patrole implicitly splits up each test into 3 stages: set up, test execution,
-and teardown.
-
-The role workflow is as follows:
-
-#. Setup: Admin role is used automatically. The primary credentials are
- overridden with the admin role.
-#. Test execution: ``[patrole] rbac_test_role`` is used manually via the
- call to ``with rbac_utils.override_role(self)``. Everything that
- is executed within this contextmanager uses the primary
- credentials overridden with the ``[patrole] rbac_test_role``.
-#. Teardown: Admin role is used automatically. The primary credentials have
- been overridden with the admin role.
-
-.. _Tempest credentials: https://docs.openstack.org/tempest/latest/library/credential_providers.html
-.. _dynamic credentials: https://docs.openstack.org/tempest/latest/configuration.html#dynamic-credentials
-
-Test Setup
-----------
-
-Automatic role override in background.
-
-Resources can be set up inside the ``resource_setup`` class method that Tempest
-provides. These resources are typically reserved for "expensive" resources
-in terms of memory or storage requirements, like volumes and VMs. These
-resources are **always** created via the admin role; Patrole automatically
-handles this.
-
-Like Tempest, however, Patrole must also create resources inside tests
-themselves. At the beginning of each test, the primary credentials have already
-been overridden with the admin role. One can create whatever test-level
-resources one needs, without having to worry about permissions.
-
-Test Execution
---------------
-
-Manual role override required.
-
-"Test execution" here means calling the API endpoint that enforces the policy
-action expected by the ``rbac_rule_validation`` decorator. Test execution
-should be performed *only after* calling
-``with rbac_utils.override_role(self)``.
-
-Immediately after that call, the API endpoint that enforces the policy should
-be called.
-
-Examples
-^^^^^^^^
-
-Always use the contextmanager before calling the API that enforces the
-expected policy action.
-
-Example::
-
- @rbac_rule_validation.action(
- service="nova",
- rule="os_compute_api:os-aggregates:show")
- def test_show_aggregate_rbac(self):
- # Do test setup before the ``override_role`` call.
- aggregate_id = self._create_aggregate()
- # Call the ``override_role`` method so that the primary credentials
- # have the test role needed for test execution.
- with self.rbac_utils.override_role(self):
- self.aggregates_client.show_aggregate(aggregate_id)
-
-When using a waiter, do the wait outside the contextmanager. "Waiting" always
-entails executing a ``GET`` request to the server, until the state of the
-returned resource matches a desired state. These ``GET`` requests enforce
-a different policy than the one expected. This is undesirable because
-Patrole should only test policies in isolation from one another.
-
-Otherwise, the test result will be tainted, because instead of only the
-expected policy getting enforced with the ``os_primary`` role, at least
-two policies get enforced.
-
-Example using waiter::
-
- @rbac_rule_validation.action(
- service="nova",
- rule="os_compute_api:os-admin-password")
- def test_change_server_password(self):
- original_password = self.servers_client.show_password(
- self.server['id'])
- self.addCleanup(self.servers_client.change_password, self.server['id'],
- adminPass=original_password)
-
- with self.rbac_utils.override_role(self):
- self.servers_client.change_password(
- self.server['id'], adminPass=data_utils.rand_password())
- # Call the waiter outside the ``override_role`` contextmanager, so that
- # it is executed with admin role.
- waiters.wait_for_server_status(
- self.servers_client, self.server['id'], 'ACTIVE')
-
-Below is an example of a method that enforces multiple policies getting
-called inside the contextmanager. The ``_complex_setup_method`` below
-performs the correct API that enforces the expected policy -- in this
-case ``self.resources_client.create_resource`` -- but then proceeds to
-use a waiter.
-
-Incorrect::
-
- def _complex_setup_method(self):
- resource = self.resources_client.create_resource(
- **kwargs)['resource']
- self.addCleanup(test_utils.call_and_ignore_notfound_exc,
- self._delete_resource, resource)
- waiters.wait_for_resource_status(
- self.resources_client, resource['id'], 'available')
- return resource
-
- @rbac_rule_validation.action(
- service="example-service",
- rule="example-rule")
- def test_change_server_password(self):
- # Never call a helper function inside the contextmanager that calls a
- # bunch of APIs. Only call the API that enforces the policy action
- # contained in the decorator above.
- with self.rbac_utils.override_role(self):
- self._complex_setup_method()
-
-To fix this test, see the "Example using waiter" section above. It is
-recommended to re-implement the logic in a helper method inside a test such
-that only the relevant API is called inside the contextmanager, with
-everything extraneous outside.
-
-Test Cleanup
-------------
-
-Automatic role override in background.
-
-After the test -- no matter whether it ended successfully or in failure --
-the credentials are overridden with the admin role by the Patrole framework,
-*before* ``tearDown`` or ``tearDownClass`` are called. This means that
-resources are always cleaned up using the admin role.
-
Implementation
--------------
.. automodule:: patrole_tempest_plugin.rbac_utils
:members:
:private-members:
+ :special-members:
+
+.. _Tempest credentials: https://docs.openstack.org/tempest/latest/library/credential_providers.html
+.. _dynamic credentials: https://docs.openstack.org/tempest/latest/configuration.html#dynamic-credentials
+
diff --git a/doc/source/framework/rbac_validation.rst b/doc/source/framework/rbac_validation.rst
index 186dfe2..6cd1534 100644
--- a/doc/source/framework/rbac_validation.rst
+++ b/doc/source/framework/rbac_validation.rst
@@ -17,3 +17,4 @@
.. automodule:: patrole_tempest_plugin.rbac_rule_validation
:members:
:private-members:
+ :special-members:
diff --git a/doc/source/framework/requirements_authority.rst b/doc/source/framework/requirements_authority.rst
index 6c4fcc0..628f0c0 100644
--- a/doc/source/framework/requirements_authority.rst
+++ b/doc/source/framework/requirements_authority.rst
@@ -103,3 +103,4 @@
.. automodule:: patrole_tempest_plugin.requirements_authority
:members:
:undoc-members:
+ :special-members:
diff --git a/doc/source/index.rst b/doc/source/index.rst
index 2dbf63b..c03aac6 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -54,6 +54,7 @@
HACKING
REVIEWING
+ test_writing_guide
Framework
---------
diff --git a/doc/source/rbac-overview.rst b/doc/source/rbac-overview.rst
index 5eefa5c..09ab17d 100644
--- a/doc/source/rbac-overview.rst
+++ b/doc/source/rbac-overview.rst
@@ -57,7 +57,7 @@
services are secure, from an RBAC perspective, for each release.
Patrole strives to validate RBAC by using the policy in code documentation,
-wherever possible.
+wherever possible. See :ref:`validation-workflow-overview` for more details.
.. _custom-policies:
@@ -85,8 +85,7 @@
This has implications on Patrole's :ref:`design-principles`: validating custom
overrides requires the ability to handle arbitrary roles, which requires logic
-capable of dynamically determining expected test behavior. See
-:ref:`rbac-validation` for more details.
+capable of dynamically determining expected test behavior.
Note that support for custom policies is limited. This is because custom
policies can be arbitrarily complex, requiring that tests be very robust
@@ -140,6 +139,39 @@
as well. See Neutron's `authorization policy enforcement`_ documentation
for more details.
+Admin Context Policy
+--------------------
+
+The so-called "admin context" policy refers to the following policy definition
+(using the legacy policy file syntax):
+
+.. code-block:: javascript
+
+ {
+ "context_is_admin": "role:admin"
+ ...
+ }
+
+Which is unfortunately used to bypass ``oslo.policy`` authorization checks,
+for example:
+
+.. code-block:: python
+
+ # This function is responsible for calling oslo.policy to check whether
+ # requests are authorized to perform an API action.
+ def enforce(context, action, target, [...]):
+ # Here this condition, if True, skips over the enforce call below which
+ # is what calls oslo.policy.
+ if context.is_admin:
+ return True
+ _ENFORCER.enforce([...]) # This is what can be skipped over.
+ [...]
+
+This type of behavior is currently present in many services. Unless such
+logic is removed in the future for services that implement it, Patrole
+won't really be able to validate that admin role works from an ``oslo.policy``
+perspective.
+
Glossary
--------
diff --git a/doc/source/test_writing_guide.rst b/doc/source/test_writing_guide.rst
new file mode 100644
index 0000000..1291201
--- /dev/null
+++ b/doc/source/test_writing_guide.rst
@@ -0,0 +1,166 @@
+Patrole Test Writing Overview
+=============================
+
+Introduction
+------------
+
+Patrole tests are broken up into 3 stages:
+
+#. :ref:`rbac-test-setup`
+#. :ref:`rbac-test-execution`
+#. :ref:`rbac-test-cleanup`
+
+See the :ref:`framework overview documentation <validation-workflow-overview>`
+for a high-level explanation of the entire testing work flow and framework
+implementation. The guide that follows is concerned with helping developers
+know how to write Patrole tests.
+
+.. _role-overriding:
+
+Role Overriding
+---------------
+
+Role overriding is the way Patrole is able to create resources and delete
+resources -- including those that require admin credentials -- while still
+being able to exercise the same set of Tempest credentials to perform the API
+action that authorizes the policy under test, by manipulating the role of
+the Tempest credentials.
+
+Patrole implicitly splits up each test into 3 stages: set up, test execution,
+and teardown.
+
+The role workflow is as follows:
+
+#. Setup: Admin role is used automatically. The primary credentials are
+ overridden with the admin role.
+#. Test execution: ``[patrole] rbac_test_role`` is used manually via the
+ call to ``with rbac_utils.override_role(self)``. Everything that
+ is executed within this contextmanager uses the primary
+ credentials overridden with the ``[patrole] rbac_test_role``.
+#. Teardown: Admin role is used automatically. The primary credentials have
+ been overridden with the admin role.
+
+.. _rbac-test-setup:
+
+Test Setup
+----------
+
+Automatic role override in background.
+
+Resources can be set up inside the ``resource_setup`` class method that Tempest
+provides. These resources are typically reserved for "expensive" resources
+in terms of memory or storage requirements, like volumes and VMs. These
+resources are **always** created via the admin role; Patrole automatically
+handles this.
+
+Like Tempest, however, Patrole must also create resources inside tests
+themselves. At the beginning of each test, the primary credentials have already
+been overridden with the admin role. One can create whatever test-level
+resources one needs, without having to worry about permissions.
+
+.. _rbac-test-execution:
+
+Test Execution
+--------------
+
+Manual role override required.
+
+"Test execution" here means calling the API endpoint that enforces the policy
+action expected by the ``rbac_rule_validation`` decorator. Test execution
+should be performed *only after* calling
+``with rbac_utils.override_role(self)``.
+
+Immediately after that call, the API endpoint that enforces the policy should
+be called.
+
+Examples
+^^^^^^^^
+
+Always use the contextmanager before calling the API that enforces the
+expected policy action.
+
+Example::
+
+ @rbac_rule_validation.action(
+ service="nova",
+ rules=["os_compute_api:os-aggregates:show"])
+ def test_show_aggregate_rbac(self):
+ # Do test setup before the ``override_role`` call.
+ aggregate_id = self._create_aggregate()
+ # Call the ``override_role`` method so that the primary credentials
+ # have the test role needed for test execution.
+ with self.rbac_utils.override_role(self):
+ self.aggregates_client.show_aggregate(aggregate_id)
+
+When using a waiter, do the wait outside the contextmanager. "Waiting" always
+entails executing a ``GET`` request to the server, until the state of the
+returned resource matches a desired state. These ``GET`` requests enforce
+a different policy than the one expected. This is undesirable because
+Patrole should only test policies in isolation from one another.
+
+Otherwise, the test result will be tainted, because instead of only the
+expected policy getting enforced with the ``os_primary`` role, at least
+two policies get enforced.
+
+Example using waiter::
+
+ @rbac_rule_validation.action(
+ service="nova",
+ rules=["os_compute_api:os-admin-password"])
+ def test_change_server_password(self):
+ original_password = self.servers_client.show_password(
+ self.server['id'])
+ self.addCleanup(self.servers_client.change_password, self.server['id'],
+ adminPass=original_password)
+
+ with self.rbac_utils.override_role(self):
+ self.servers_client.change_password(
+ self.server['id'], adminPass=data_utils.rand_password())
+ # Call the waiter outside the ``override_role`` contextmanager, so that
+ # it is executed with admin role.
+ waiters.wait_for_server_status(
+ self.servers_client, self.server['id'], 'ACTIVE')
+
+Below is an example of a method that enforces multiple policies getting
+called inside the contextmanager. The ``_complex_setup_method`` below
+performs the correct API that enforces the expected policy -- in this
+case ``self.resources_client.create_resource`` -- but then proceeds to
+use a waiter.
+
+Incorrect::
+
+ def _complex_setup_method(self):
+ resource = self.resources_client.create_resource(
+ **kwargs)['resource']
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self._delete_resource, resource)
+ waiters.wait_for_resource_status(
+ self.resources_client, resource['id'], 'available')
+ return resource
+
+ @rbac_rule_validation.action(
+ service="example-service",
+ rules=["example-rule"])
+ def test_change_server_password(self):
+ # Never call a helper function inside the contextmanager that calls a
+ # bunch of APIs. Only call the API that enforces the policy action
+ # contained in the decorator above.
+ with self.rbac_utils.override_role(self):
+ self._complex_setup_method()
+
+To fix this test, see the "Example using waiter" section above. It is
+recommended to re-implement the logic in a helper method inside a test such
+that only the relevant API is called inside the contextmanager, with
+everything extraneous outside.
+
+.. _rbac-test-cleanup:
+
+Test Cleanup
+------------
+
+Automatic role override in background.
+
+After the test -- no matter whether it ended successfully or in failure --
+the credentials are overridden with the admin role by the Patrole framework,
+*before* ``tearDown`` or ``tearDownClass`` are called. This means that
+resources are always cleaned up using the admin role.
diff --git a/patrole_tempest_plugin/config.py b/patrole_tempest_plugin/config.py
index 47b76d4..56a786b 100644
--- a/patrole_tempest_plugin/config.py
+++ b/patrole_tempest_plugin/config.py
@@ -24,23 +24,14 @@
default='admin',
help="""The current RBAC role against which to run
Patrole tests."""),
- cfg.BoolOpt('enable_rbac',
- default=True,
- deprecated_for_removal=True,
- deprecated_reason="""This is a legacy option that was
-meaningful when Patrole existed downstream as a suite of tests inside Tempest.
-Installing the Patrole plugin necessarily means that RBAC tests should be run.
-This option is paradoxical with the Tempest plugin architecture.
-""",
- deprecated_since='R',
- help="Enables Patrole RBAC tests."),
cfg.ListOpt('custom_policy_files',
default=['/etc/%s/policy.json'],
help="""List of the paths to search for policy files. Each
policy path assumes that the service name is included in the path once. Also
assumes Patrole is on the same host as the policy files. The paths should be
-ordered by precedence, with high-priority paths before low-priority paths. The
-first path that is found to contain the service's policy file will be used.
+ordered by precedence, with high-priority paths before low-priority paths. All
+the paths that are found to contain the service's policy file will be used and
+all policy files will be merged. Allowed ``json`` or ``yaml`` formats.
"""),
cfg.BoolOpt('test_custom_requirements',
default=False,
@@ -171,6 +162,11 @@
help="""Are the Nova API extension policies available in the
cloud (e.g. os_compute_api:os-extended-availability-zone)? These policies were
removed in Stein because Nova API extension concept was removed in Pike."""),
+ cfg.BoolOpt('added_cinder_policies_stein',
+ default=True,
+ help="""Are the Cinder API extension policies available in the
+cloud (e.g. [create|update|get|delete]_encryption_policy)? These policies are
+added in Stein.""")
]
diff --git a/patrole_tempest_plugin/policy_authority.py b/patrole_tempest_plugin/policy_authority.py
index 3339a5d..2a49b6c 100644
--- a/patrole_tempest_plugin/policy_authority.py
+++ b/patrole_tempest_plugin/policy_authority.py
@@ -13,8 +13,9 @@
# License for the specific language governing permissions and limitations
# under the License.
+import collections
import copy
-import json
+import glob
import os
from oslo_log import log as logging
@@ -103,17 +104,14 @@
if extra_target_data is None:
extra_target_data = {}
- self.validate_service(service)
+ self.service = self.validate_service(service)
# Prioritize dynamically searching for policy files over relying on
# deprecated service-specific policy file locations.
- self.path = None
if CONF.patrole.custom_policy_files:
self.discover_policy_files()
- self.path = self.policy_files.get(service)
- self.rules = policy.Rules.load(self._get_policy_data(service),
- 'default')
+ self.rules = self.get_rules()
self.project_id = project_id
self.user_id = user_id
self.extra_target_data = extra_target_data
@@ -139,19 +137,22 @@
raise rbac_exceptions.RbacInvalidServiceException(
"%s is NOT a valid service." % service)
+ return service
+
@classmethod
def discover_policy_files(cls):
"""Dynamically discover the policy file for each service in
- ``cls.available_services``. Pick the first candidate path found
+ ``cls.available_services``. Pick all candidate paths found
out of the potential paths in ``[patrole] custom_policy_files``.
"""
if not hasattr(cls, 'policy_files'):
- cls.policy_files = {}
+ cls.policy_files = collections.defaultdict(list)
for service in cls.available_services:
for candidate_path in CONF.patrole.custom_policy_files:
- if os.path.isfile(candidate_path % service):
- cls.policy_files.setdefault(service,
- candidate_path % service)
+ path = candidate_path % service
+ for filename in glob.iglob(path):
+ if os.path.isfile(filename):
+ cls.policy_files[service].append(filename)
def allowed(self, rule_name, role):
"""Checks if a given rule in a policy is allowed with given role.
@@ -168,71 +169,60 @@
is_admin=is_admin_context)
return is_allowed
- def _get_policy_data(self, service):
- file_policy_data = {}
- mgr_policy_data = {}
- policy_data = {}
-
+ def get_rules(self):
+ rules = policy.Rules()
# Check whether policy file exists and attempt to read it.
- if self.path and os.path.isfile(self.path):
+ for path in self.policy_files[self.service]:
try:
- with open(self.path, 'r') as policy_file:
- file_policy_data = policy_file.read()
- file_policy_data = json.loads(file_policy_data)
- except (IOError, ValueError) as e:
- msg = "Failed to read policy file for service. "
- if isinstance(e, IOError):
- msg += "Please check that policy path exists."
- else:
- msg += "JSON may be improperly formatted."
- LOG.debug(msg)
- file_policy_data = {}
+ with open(path, 'r') as fp:
+ for k, v in policy.Rules.load(fp.read()).items():
+ if k not in rules:
+ rules[k] = v
+ # If the policy name and rule are the same, no
+ # ambiguity, so no reason to warn.
+ elif str(v) != str(rules[k]):
+ msg = ("The same policy name: %s was found in "
+ "multiple policies files for service %s. "
+ "This can lead to policy rule ambiguity. "
+ "Using rule: %s; Rule from file: %s")
+ LOG.warning(msg, k, self.service, rules[k], v)
+ except (ValueError, IOError):
+ LOG.warning("Failed to read policy file '%s' for service %s.",
+ path, self.service)
# Check whether policy actions are defined in code. Nova and Keystone,
# for example, define their default policy actions in code.
mgr = stevedore.named.NamedExtensionManager(
'oslo.policy.policies',
- names=[service],
- on_load_failure_callback=None,
+ names=[self.service],
invoke_on_load=True,
warn_on_missing_entrypoint=False)
if mgr:
- policy_generator = {policy.name: policy.obj for policy in mgr}
- if policy_generator and service in policy_generator:
- for rule in policy_generator[service]:
- mgr_policy_data[rule.name] = str(rule.check)
+ policy_generator = {plc.name: plc.obj for plc in mgr}
+ if self.service in policy_generator:
+ for rule in policy_generator[self.service]:
+ if rule.name not in rules:
+ rules[rule.name] = rule.check
+ elif str(rule.check) != str(rules[rule.name]):
+ msg = ("The same policy name: %s was found in the "
+ "policies files and in the code for service "
+ "%s. This can lead to policy rule ambiguity. "
+ "Using rule: %s; Rule from code: %s")
+ LOG.warning(msg, rule.name, self.service,
+ rules[rule.name], rule.check)
- # If data from both file and code exist, combine both together.
- if file_policy_data and mgr_policy_data:
- # Add the policy actions from code first.
- for action, rule in mgr_policy_data.items():
- policy_data[action] = rule
- # Overwrite with any custom policy actions defined in policy.json.
- for action, rule in file_policy_data.items():
- policy_data[action] = rule
- elif file_policy_data:
- policy_data = file_policy_data
- elif mgr_policy_data:
- policy_data = mgr_policy_data
- else:
- error_message = (
- 'Policy file for {0} service was not found among the '
+ if not rules:
+ msg = (
+ 'Policy files for {0} service were not found among the '
'registered in-code policies or in any of the possible policy '
- 'files: {1}.'.format(service,
- [loc % service for loc in
- CONF.patrole.custom_policy_files])
- )
- raise rbac_exceptions.RbacParsingException(error_message)
+ 'files: {1}.'.format(
+ self.service,
+ [loc % self.service
+ for loc in CONF.patrole.custom_policy_files]))
+ raise rbac_exceptions.RbacParsingException(msg)
- try:
- policy_data = json.dumps(policy_data)
- except (TypeError, ValueError):
- error_message = 'Policy file for {0} service is invalid.'.format(
- service)
- raise rbac_exceptions.RbacParsingException(error_message)
-
- return policy_data
+ return rules
def _is_admin_context(self, role):
"""Checks whether a role has admin context.
@@ -296,9 +286,11 @@
def _try_rule(self, apply_rule, target, access_data, o):
if apply_rule not in self.rules:
- message = ("Policy action \"{0}\" not found in policy file: {1} or"
- " among registered policy in code defaults for service."
- ).format(apply_rule, self.path)
+ message = ('Policy action "{0}" not found in policy files: '
+ '{1} or among registered policy in code defaults for '
+ '{2} service.').format(apply_rule,
+ self.policy_files[self.service],
+ self.service)
LOG.debug(message)
raise rbac_exceptions.RbacParsingException(message)
else:
diff --git a/patrole_tempest_plugin/rbac_exceptions.py b/patrole_tempest_plugin/rbac_exceptions.py
index 809a7ed..6bdd7df 100644
--- a/patrole_tempest_plugin/rbac_exceptions.py
+++ b/patrole_tempest_plugin/rbac_exceptions.py
@@ -16,46 +16,41 @@
from tempest.lib import exceptions
-class RbacConflictingPolicies(exceptions.TempestException):
- message = ("Conflicting policies preventing this action from being "
- "performed.")
+class BasePatroleException(exceptions.TempestException):
+ message = "An unknown RBAC exception occurred"
-class RbacMalformedResponse(exceptions.TempestException):
+class RbacMalformedResponse(BasePatroleException):
message = ("The response body is missing the expected %(attribute)s due "
"to policy enforcement failure.")
- def __init__(self, empty=False, extra_attr=False, **kwargs):
+ def __init__(self, empty=False, **kwargs):
if empty:
self.message = ("The response body is empty due to policy "
"enforcement failure.")
kwargs = {}
- if extra_attr:
- self.message = ("The response body contained an unexpected "
- "attribute due to policy enforcement failure.")
- kwargs = {}
super(RbacMalformedResponse, self).__init__(**kwargs)
-class RbacResourceSetupFailed(exceptions.TempestException):
+class RbacResourceSetupFailed(BasePatroleException):
message = "RBAC resource setup failed"
-class RbacOverPermissionException(exceptions.TempestException):
+class RbacOverPermissionException(BasePatroleException):
"""Raised when the expected result is failure but the actual result is
pass.
"""
message = "Unauthorized action was allowed to be performed"
-class RbacUnderPermissionException(exceptions.TempestException):
+class RbacUnderPermissionException(BasePatroleException):
"""Raised when the expected result is pass but the actual result is
failure.
"""
message = "Authorized action was not allowed to be performed"
-class RbacExpectedWrongException(exceptions.TempestException):
+class RbacExpectedWrongException(BasePatroleException):
"""Raised when the expected exception does not match the actual exception
raised, when both are instances of Forbidden or NotFound, indicating
the test provides a wrong argument to `expected_error_codes`.
@@ -64,16 +59,30 @@
"instead. Actual exception: %(exception)s")
-class RbacInvalidServiceException(exceptions.TempestException):
+class RbacInvalidServiceException(BasePatroleException):
"""Raised when an invalid service is passed to ``rbac_rule_validation``
decorator.
"""
message = "Attempted to test an invalid service"
-class RbacParsingException(exceptions.TempestException):
+class RbacParsingException(BasePatroleException):
message = "Attempted to test an invalid policy file or action"
-class RbacInvalidErrorCode(exceptions.TempestException):
+class RbacInvalidErrorCode(BasePatroleException):
message = "Unsupported error code passed in test"
+
+
+class RbacOverrideRoleException(BasePatroleException):
+ """Raised when override_role is used incorrectly or fails somehow.
+
+ Used for safeguarding against false positives that might occur when the
+ expected exception isn't raised inside the ``override_role`` context.
+ Specifically, when:
+
+ * ``override_role`` isn't called
+ * an exception is raised before ``override_role`` context
+ * an exception is raised after ``override_role`` context
+ """
+ message = "Override role failure or incorrect usage"
diff --git a/patrole_tempest_plugin/rbac_rule_validation.py b/patrole_tempest_plugin/rbac_rule_validation.py
index 32deb9f..c85376f 100644
--- a/patrole_tempest_plugin/rbac_rule_validation.py
+++ b/patrole_tempest_plugin/rbac_rule_validation.py
@@ -17,7 +17,6 @@
import logging
import sys
-from oslo_log import versionutils
from oslo_utils import excutils
import six
@@ -38,8 +37,9 @@
RBACLOG = logging.getLogger('rbac_reporting')
-def action(service, rule='', rules=None,
- expected_error_code=_DEFAULT_ERROR_CODE, expected_error_codes=None,
+def action(service,
+ rules=None,
+ expected_error_codes=None,
extra_target_data=None):
"""A decorator for verifying OpenStack policy enforcement.
@@ -72,26 +72,15 @@
As such, negative and positive testing can be applied using this decorator.
:param str service: An OpenStack service. Examples: "nova" or "neutron".
- :param str rule: (DEPRECATED) A policy action defined in a policy.json file
- or in code.
- :param list rules: A list of policy actions defined in a policy.json file
- or in code. The rules are logical-ANDed together to derive the expected
- result.
+ :param list rules: A list of policy actions defined in a policy file or in
+ code. The rules are logical-ANDed together to derive the expected
+ result. Also accepts list of callables that return a policy action.
.. note::
Patrole currently only supports custom JSON policy files.
- :param int expected_error_code: (DEPRECATED) Overrides default value of 403
- (Forbidden) with endpoint-specific error code. Currently only supports
- 403 and 404. Support for 404 is needed because some services, like
- Neutron, intentionally throw a 404 for security reasons.
-
- .. warning::
-
- A 404 should not be provided *unless* the endpoint masks a
- ``Forbidden`` exception as a ``NotFound`` exception.
-
+ :type rules: list[str] or list[callable]
:param list expected_error_codes: When the ``rules`` list parameter is
used, then this list indicates the expected error code to use if one
of the rules does not allow the role being tested. This list must
@@ -112,6 +101,12 @@
If it is not passed, then it is defaulted to 403.
+ .. warning::
+
+ A 404 should not be provided *unless* the endpoint masks a
+ ``Forbidden`` exception as a ``NotFound`` exception.
+
+ :type expected_error_codes: list[int]
:param dict extra_target_data: Dictionary, keyed with ``oslo.policy``
generic check names, whose values are string literals that reference
nested ``tempest.test.BaseTestCase`` attributes. Used by
@@ -132,7 +127,8 @@
Examples::
@rbac_rule_validation.action(
- service="nova", rule="os_compute_api:os-agents")
+ service="nova",
+ rules=["os_compute_api:os-agents"])
def test_list_agents_rbac(self):
# The call to `override_role` is mandatory.
with self.rbac_utils.override_role(self):
@@ -142,8 +138,7 @@
if extra_target_data is None:
extra_target_data = {}
- rules, expected_error_codes = _prepare_multi_policy(rule, rules,
- expected_error_code,
+ rules, expected_error_codes = _prepare_multi_policy(rules,
expected_error_codes)
def decorator(test_func):
@@ -167,7 +162,6 @@
disallowed_rules.append(rule)
allowed = allowed and _allowed
- exp_error_code = expected_error_code
if disallowed_rules:
# Choose the first disallowed rule and expect the error
# code corresponding to it.
@@ -176,10 +170,13 @@
LOG.debug("%s: Expecting %d to be raised for policy name: %s",
test_func.__name__, exp_error_code,
disallowed_rules[0])
+ else:
+ exp_error_code = expected_error_codes[0]
expected_exception, irregular_msg = _get_exception_type(
exp_error_code)
+ caught_exception = None
test_status = 'Allowed'
try:
@@ -192,14 +189,16 @@
test_status = ('Error, %s' % (msg))
LOG.error(msg)
except (expected_exception,
- rbac_exceptions.RbacConflictingPolicies,
- rbac_exceptions.RbacMalformedResponse) as e:
+ rbac_exceptions.RbacMalformedResponse) as actual_exception:
+ caught_exception = actual_exception
test_status = 'Denied'
+
if irregular_msg:
LOG.warning(irregular_msg,
test_func.__name__,
', '.join(rules),
service)
+
if allowed:
msg = ("Role %s was not allowed to perform the following "
"actions: %s. Expected allowed actions: %s. "
@@ -209,8 +208,10 @@
sorted(disallowed_rules)))
LOG.error(msg)
raise rbac_exceptions.RbacUnderPermissionException(
- "%s Exception was: %s" % (msg, e))
+ "%s Exception was: %s" % (msg, actual_exception))
except Exception as actual_exception:
+ caught_exception = actual_exception
+
if _check_for_expected_mismatch_exception(expected_exception,
actual_exception):
LOG.error('Expected and actual exceptions do not match. '
@@ -249,11 +250,19 @@
"Allowed" if allowed else "Denied",
test_status)
+ # Sanity-check that ``override_role`` was called to eliminate
+ # false-positives and bad test flows resulting from exceptions
+ # getting raised too early, too late or not at all, within
+ # the scope of an RBAC test.
+ _validate_override_role_called(
+ test_obj,
+ actual_exception=caught_exception)
+
return wrapper
return decorator
-def _prepare_multi_policy(rule, rules, exp_error_code, exp_error_codes):
+def _prepare_multi_policy(rules, exp_error_codes):
if exp_error_codes:
if not rules:
msg = ("The `rules` list must be provided if using the "
@@ -263,34 +272,15 @@
msg = ("The `expected_error_codes` list is not the same length "
"as the `rules` list.")
raise ValueError(msg)
- if exp_error_code:
- deprecation_msg = (
- "The `exp_error_code` argument has been deprecated in favor "
- "of `exp_error_codes` and will be removed in a future "
- "version.")
- versionutils.report_deprecated_feature(LOG, deprecation_msg)
- LOG.debug("The `exp_error_codes` argument will be used instead of "
- "`exp_error_code`.")
if not isinstance(exp_error_codes, (tuple, list)):
exp_error_codes = [exp_error_codes]
else:
exp_error_codes = []
- if exp_error_code:
- exp_error_codes.append(exp_error_code)
if rules is None:
rules = []
elif not isinstance(rules, (tuple, list)):
rules = [rules]
- if rule:
- deprecation_msg = (
- "The `rule` argument has been deprecated in favor of `rules` "
- "and will be removed in a future version.")
- versionutils.report_deprecated_feature(LOG, deprecation_msg)
- if rules:
- LOG.debug("The `rules` argument will be used instead of `rule`.")
- else:
- rules.append(rule)
# Fill in the exp_error_codes if needed. This is needed for the scenarios
# where no exp_error_codes array is provided, so the error codes must be
@@ -302,7 +292,11 @@
for i in range(num_rules - num_ecs):
exp_error_codes.append(_DEFAULT_ERROR_CODE)
- return rules, exp_error_codes
+ evaluated_rules = [
+ r() if callable(r) else r for r in rules
+ ]
+
+ return evaluated_rules, exp_error_codes
def _is_authorized(test_obj, service, rule, extra_target_data):
@@ -389,7 +383,7 @@
irregular_msg = ("NotFound exception was caught for test %s. Expected "
"policies which may have caused the error: %s. The "
"service %s throws a 404 instead of a 403, which is "
- "irregular.")
+ "irregular")
return expected_exception, irregular_msg
@@ -431,8 +425,63 @@
def _check_for_expected_mismatch_exception(expected_exception,
actual_exception):
+ """Checks that ``expected_exception`` matches ``actual_exception``.
+
+ Since Patrole must handle 403/404 it is important that the expected and
+ actual error codes match.
+
+ :param excepted_exception: Expected exception for test.
+ :param actual_exception: Actual exception raised by test.
+ :returns: True if match, else False.
+ :rtype: boolean
+ """
permission_exceptions = (lib_exc.Forbidden, lib_exc.NotFound)
if isinstance(actual_exception, permission_exceptions):
if not isinstance(actual_exception, expected_exception.__class__):
return True
return False
+
+
+def _validate_override_role_called(test_obj, actual_exception):
+ """Validates that :func:`rbac_utils.RbacUtils.override_role` is called
+ during each Patrole test.
+
+ Useful for validating that the expected exception isn't raised too early
+ (before ``override_role`` call) or too late (after ``override_call``) or
+ at all (which is a bad test).
+
+ :param test_obj: An instance or subclass of ``tempest.test.BaseTestCase``.
+ :param actual_exception: Actual exception raised by test.
+ :raises RbacOverrideRoleException: If ``override_role`` isn't called, is
+ called too early, or is called too late.
+ """
+ called = test_obj._validate_override_role_called()
+ base_msg = ('This error is unrelated to RBAC and is due to either '
+ 'an API or override role failure. Exception: %s' %
+ actual_exception)
+
+ if not called:
+ if actual_exception is not None:
+ msg = ('Caught exception (%s) but it was raised before the '
+ '`override_role` context. ' % actual_exception.__class__)
+ else:
+ msg = 'Test missing required `override_role` call. '
+ msg += base_msg
+ LOG.error(msg)
+ raise rbac_exceptions.RbacOverrideRoleException(msg)
+ else:
+ exc_caught_in_ctx = test_obj._validate_override_role_caught_exc()
+ # This block is only executed if ``override_role`` is called. If
+ # an exception is raised and the exception wasn't raised in the
+ # ``override_role`` context and if the exception isn't a valid
+ # exception type (instance of ``BasePatroleException``), then this is
+ # a legitimate error.
+ if (not exc_caught_in_ctx and
+ actual_exception is not None and
+ not isinstance(actual_exception,
+ rbac_exceptions.BasePatroleException)):
+ msg = ('Caught exception (%s) but it was raised after the '
+ '`override_role` context. ' % actual_exception.__class__)
+ msg += base_msg
+ LOG.error(msg)
+ raise rbac_exceptions.RbacOverrideRoleException(msg)
diff --git a/patrole_tempest_plugin/rbac_utils.py b/patrole_tempest_plugin/rbac_utils.py
index 9a9f864..6db2199 100644
--- a/patrole_tempest_plugin/rbac_utils.py
+++ b/patrole_tempest_plugin/rbac_utils.py
@@ -14,10 +14,10 @@
# under the License.
from contextlib import contextmanager
+import sys
import time
from oslo_log import log as logging
-from oslo_log import versionutils
from oslo_utils import excutils
from tempest import clients
@@ -83,7 +83,7 @@
Example::
@rbac_rule_validation.action(service='test',
- rule='a:test:rule')
+ rules=['a:test:rule'])
def test_foo(self):
# Allocate test-level resources here.
with self.rbac_utils.override_role(self):
@@ -95,11 +95,17 @@
# if the API call above threw an exception, any code below this
# point in the test is not executed.
"""
+ test_obj._set_override_role_called()
self._override_role(test_obj, True)
try:
# Execute the test.
yield
finally:
+ # Check whether an exception was raised. If so, remember that
+ # for future validation.
+ exc = sys.exc_info()[0]
+ if exc is not None:
+ test_obj._set_override_role_caught_exc()
# This code block is always executed, no matter the result of the
# test. Automatically switch back to the admin role for test clean
# up.
@@ -222,6 +228,11 @@
cls.setup_rbac_utils()
"""
+ # Shows if override_role was called.
+ __override_role_called = False
+ # Shows if exception raised during override_role.
+ __override_role_caught_exc = False
+
@classmethod
def get_auth_providers(cls):
"""Returns list of auth_providers used within test.
@@ -232,21 +243,36 @@
return [cls.os_primary.auth_provider]
@classmethod
- def skip_rbac_checks(cls):
- if not CONF.patrole.enable_rbac:
- deprecation_msg = ("The `[patrole].enable_rbac` option is "
- "deprecated and will be removed in the S "
- "release. Patrole tests will always be enabled "
- "following installation of the Patrole Tempest "
- "plugin. Use a regex to skip tests.")
- versionutils.report_deprecated_feature(LOG, deprecation_msg)
- raise cls.skipException(
- 'Patrole testing not enabled so skipping %s.' % cls.__name__)
-
- @classmethod
def setup_rbac_utils(cls):
cls.rbac_utils = RbacUtils(cls)
+ def _set_override_role_called(self):
+ """Helper for tracking whether ``override_role`` was called."""
+ self.__override_role_called = True
+
+ def _set_override_role_caught_exc(self):
+ """Helper for tracking whether exception was thrown inside
+ ``override_role``.
+ """
+ self.__override_role_caught_exc = True
+
+ def _validate_override_role_called(self):
+ """Idempotently validate that ``override_role`` is called and reset
+ its value to False for sequential tests.
+ """
+ was_called = self.__override_role_called
+ self.__override_role_called = False
+ return was_called
+
+ def _validate_override_role_caught_exc(self):
+ """Idempotently validate that exception was caught inside
+ ``override_role``, so that, by process of elimination, it can be
+ determined whether one was thrown outside (which is invalid).
+ """
+ caught_exception = self.__override_role_caught_exc
+ self.__override_role_caught_exc = False
+ return caught_exception
+
def is_admin():
"""Verifies whether the current test role equals the admin role.
diff --git a/patrole_tempest_plugin/tests/api/README.rst b/patrole_tempest_plugin/tests/api/README.rst
new file mode 120000
index 0000000..e2853ec
--- /dev/null
+++ b/patrole_tempest_plugin/tests/api/README.rst
@@ -0,0 +1 @@
+../../../doc/source/field_guide/rbac.rst
\ No newline at end of file
diff --git a/patrole_tempest_plugin/tests/api/compute/rbac_base.py b/patrole_tempest_plugin/tests/api/compute/rbac_base.py
index 18d2f48..ab4551e 100644
--- a/patrole_tempest_plugin/tests/api/compute/rbac_base.py
+++ b/patrole_tempest_plugin/tests/api/compute/rbac_base.py
@@ -12,24 +12,16 @@
# under the License.
from tempest.api.compute import base as compute_base
-from tempest import config
from tempest.lib.common.utils import data_utils
from tempest.lib.common.utils import test_utils
from patrole_tempest_plugin import rbac_utils
-CONF = config.CONF
-
class BaseV2ComputeRbacTest(rbac_utils.RbacUtilsMixin,
compute_base.BaseV2ComputeTest):
@classmethod
- def skip_checks(cls):
- super(BaseV2ComputeRbacTest, cls).skip_checks()
- cls.skip_rbac_checks()
-
- @classmethod
def setup_clients(cls):
super(BaseV2ComputeRbacTest, cls).setup_clients()
cls.setup_rbac_utils()
diff --git a/patrole_tempest_plugin/tests/api/compute/test_agents_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_agents_rbac.py
index a046f96..617aa5b 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_agents_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_agents_rbac.py
@@ -42,7 +42,7 @@
return kwargs
@rbac_rule_validation.action(
- service="nova", rule="os_compute_api:os-agents")
+ service="nova", rules=["os_compute_api:os-agents"])
@decorators.idempotent_id('d1bc6d97-07f5-4f45-ac29-1c619a6a7e27')
def test_list_agents_rbac(self):
with self.rbac_utils.override_role(self):
@@ -50,7 +50,7 @@
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-agents")
+ rules=["os_compute_api:os-agents"])
@decorators.idempotent_id('77d6cae4-1ced-47f7-af2e-3d6a45958fd6')
def test_create_agent(self):
params = {'hypervisor': 'kvm', 'os': 'win', 'architecture': 'x86',
@@ -63,7 +63,7 @@
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-agents")
+ rules=["os_compute_api:os-agents"])
@decorators.idempotent_id('b22f2681-9ffb-439b-b240-dae503e41020')
def test_update_agent(self):
params = self._param_helper(
@@ -84,7 +84,7 @@
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-agents")
+ rules=["os_compute_api:os-agents"])
@decorators.idempotent_id('c5042af8-0682-43b0-abc4-bf33349e23dd')
def test_delete_agent(self):
params = self._param_helper(
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 b7cd392..dea8bb9 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_aggregates_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_aggregates_rbac.py
@@ -81,14 +81,14 @@
host=self.host)
@rbac_rule_validation.action(
- service="nova", rule="os_compute_api:os-aggregates:create")
+ service="nova", rules=["os_compute_api:os-aggregates:create"])
@decorators.idempotent_id('ba754393-896e-434a-9704-452ff4a84f3f')
def test_create_aggregate_rbac(self):
with self.rbac_utils.override_role(self):
self._create_aggregate()
@rbac_rule_validation.action(
- service="nova", rule="os_compute_api:os-aggregates:show")
+ service="nova", rules=["os_compute_api:os-aggregates:show"])
@decorators.idempotent_id('8fb0b749-b120-4727-b3fb-bcfa3fa6f55b')
def test_show_aggregate_rbac(self):
aggregate_id = self._create_aggregate()
@@ -96,14 +96,14 @@
self.aggregates_client.show_aggregate(aggregate_id)
@rbac_rule_validation.action(
- service="nova", rule="os_compute_api:os-aggregates:index")
+ service="nova", rules=["os_compute_api:os-aggregates:index"])
@decorators.idempotent_id('146284da-5dd6-4c97-b598-42b480f014c6')
def test_list_aggregate_rbac(self):
with self.rbac_utils.override_role(self):
self.aggregates_client.list_aggregates()
@rbac_rule_validation.action(
- service="nova", rule="os_compute_api:os-aggregates:update")
+ service="nova", rules=["os_compute_api:os-aggregates:update"])
@decorators.idempotent_id('c94e0d69-99b6-477e-b301-2cd0e9d0ad81')
def test_update_aggregate_rbac(self):
aggregate_id = self._create_aggregate()
@@ -113,7 +113,7 @@
name=new_name)
@rbac_rule_validation.action(
- service="nova", rule="os_compute_api:os-aggregates:delete")
+ service="nova", rules=["os_compute_api:os-aggregates:delete"])
@decorators.idempotent_id('5a50c5a6-0f12-4405-a1ce-2288ae895ea6')
def test_delete_aggregate_rbac(self):
aggregate_id = self._create_aggregate()
@@ -121,7 +121,7 @@
self.aggregates_client.delete_aggregate(aggregate_id)
@rbac_rule_validation.action(
- service="nova", rule="os_compute_api:os-aggregates:add_host")
+ service="nova", rules=["os_compute_api:os-aggregates:add_host"])
@decorators.idempotent_id('97e6e9df-5291-4faa-8147-755b2d1f1ce2')
def test_add_host_to_aggregate_rbac(self):
aggregate_id = self._create_aggregate()
@@ -129,7 +129,7 @@
self._add_host_to_aggregate(aggregate_id)
@rbac_rule_validation.action(
- service="nova", rule="os_compute_api:os-aggregates:remove_host")
+ service="nova", rules=["os_compute_api:os-aggregates:remove_host"])
@decorators.idempotent_id('5b035a25-75d2-4d72-b4d6-0f0337335628')
def test_remove_host_from_aggregate_rbac(self):
aggregate_id = self._create_aggregate()
@@ -138,7 +138,7 @@
self.aggregates_client.remove_host(aggregate_id, host=self.host)
@rbac_rule_validation.action(
- service="nova", rule="os_compute_api:os-aggregates:set_metadata")
+ service="nova", rules=["os_compute_api:os-aggregates:set_metadata"])
@decorators.idempotent_id('ed6f3849-065c-4ae9-a81e-6ad7ed0d3d9d')
def test_set_metadata_on_aggregate_rbac(self):
aggregate_id = self._create_aggregate()
diff --git a/patrole_tempest_plugin/tests/api/compute/test_availability_zone_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_availability_zone_rbac.py
index 66dce5c..d8b165c 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_availability_zone_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_availability_zone_rbac.py
@@ -28,15 +28,17 @@
"enabled." % cls.__name__)
raise cls.skipException(msg)
- @rbac_rule_validation.action(service="nova", rule="os_compute_api:"
- "os-availability-zone:list")
+ @rbac_rule_validation.action(
+ service="nova",
+ rules=["os_compute_api:os-availability-zone:list"])
@decorators.idempotent_id('cd34e7ea-d26e-4fa3-a8d0-f8883726ce3d')
def test_get_availability_zone_list_rbac(self):
with self.rbac_utils.override_role(self):
self.availability_zone_client.list_availability_zones()
- @rbac_rule_validation.action(service="nova", rule="os_compute_api:"
- "os-availability-zone:detail")
+ @rbac_rule_validation.action(
+ service="nova",
+ rules=["os_compute_api:os-availability-zone:detail"])
@decorators.idempotent_id('2f61c191-6ece-4f21-b487-39d749e3d38e')
def test_get_availability_zone_list_detail_rbac(self):
with self.rbac_utils.override_role(self):
diff --git a/patrole_tempest_plugin/tests/api/compute/test_fixed_ips_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_fixed_ips_rbac.py
index f426cf3..25f7d5f 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_fixed_ips_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_fixed_ips_rbac.py
@@ -56,7 +56,7 @@
@decorators.idempotent_id('c89391f7-4844-4a70-a116-37c1336efb99')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-fixed-ips")
+ rules=["os_compute_api:os-fixed-ips"])
def test_show_fixed_ip_details(self):
with self.rbac_utils.override_role(self):
self.fixed_ips_client.show_fixed_ip(self.ip)
@@ -64,7 +64,7 @@
@decorators.idempotent_id('f0314501-735d-4315-9856-959e01e82f0d')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-fixed-ips")
+ rules=["os_compute_api:os-fixed-ips"])
def test_set_reserve(self):
with self.rbac_utils.override_role(self):
self.fixed_ips_client.reserve_fixed_ip(self.ip, reserve="None")
@@ -72,7 +72,7 @@
@decorators.idempotent_id('866a6fdc-a237-4502-9bf2-52fe82aba356')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-fixed-ips")
+ rules=["os_compute_api:os-fixed-ips"])
def test_set_unreserve(self):
with self.rbac_utils.override_role(self):
self.fixed_ips_client.reserve_fixed_ip(self.ip, unreserve="None")
diff --git a/patrole_tempest_plugin/tests/api/compute/test_flavor_access_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_flavor_access_rbac.py
index a99ddbd..317c1ad 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_flavor_access_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_flavor_access_rbac.py
@@ -40,7 +40,7 @@
@decorators.idempotent_id('a2bd3740-765d-4c95-ac98-9e027378c75e')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-flavor-access")
+ rules=["os_compute_api:os-flavor-access"])
def test_show_flavor_contains_is_public_key(self):
public_flavor_id = CONF.compute.flavor_ref
@@ -58,7 +58,7 @@
@decorators.idempotent_id('dd388146-9750-4124-82ba-62deff1052bb')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-flavor-access")
+ rules=["os_compute_api:os-flavor-access"])
def test_list_flavors_details_contains_is_public_key(self):
expected_attr = 'os-flavor-access:is_public'
@@ -77,7 +77,7 @@
@decorators.idempotent_id('39cb5c8f-9990-436f-9282-fc76a41d9bac')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-flavor-access:add_tenant_access")
+ rules=["os_compute_api:os-flavor-access:add_tenant_access"])
def test_add_flavor_access(self):
with self.rbac_utils.override_role(self):
self.flavors_client.add_flavor_access(
@@ -88,7 +88,7 @@
@decorators.idempotent_id('61b8621f-52e4-473a-8d07-e228af8853d1')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-flavor-access:remove_tenant_access")
+ rules=["os_compute_api:os-flavor-access:remove_tenant_access"])
def test_remove_flavor_access(self):
self.flavors_client.add_flavor_access(
flavor_id=self.flavor_id, tenant_id=self.tenant_id)
@@ -103,7 +103,7 @@
@decorators.idempotent_id('e1cf59fb-7f32-40a1-96b9-248ab23dd581')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-flavor-access")
+ rules=["os_compute_api:os-flavor-access"])
def test_list_flavor_access(self):
# Add flavor access for os_primary so that it can access the flavor or
# else a NotFound is raised.
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 816492c..b781540 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
@@ -50,7 +50,7 @@
@decorators.idempotent_id('daee891d-dfe9-4501-a39c-29f2371bec3c')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-flavor-extra-specs:show")
+ rules=["os_compute_api:os-flavor-extra-specs:show"])
def test_show_flavor_extra_spec(self):
key = self._set_flavor_extra_spec()
with self.rbac_utils.override_role(self):
@@ -59,7 +59,7 @@
@decorators.idempotent_id('fcffeca2-ed04-4e85-bf93-02fb5643f22b')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-flavor-extra-specs:create")
+ rules=["os_compute_api:os-flavor-extra-specs:create"])
def test_set_flavor_extra_spec(self):
with self.rbac_utils.override_role(self):
self._set_flavor_extra_spec()
@@ -67,7 +67,7 @@
@decorators.idempotent_id('42b85279-6bfa-4f58-b7a2-258c284f03c5')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-flavor-extra-specs:update")
+ rules=["os_compute_api:os-flavor-extra-specs:update"])
def test_update_flavor_extra_spec(self):
key = self._set_flavor_extra_spec()
update_val = data_utils.rand_name(self.__class__.__name__ + '-val')
@@ -78,7 +78,7 @@
@decorators.idempotent_id('4b0e5471-e010-4c09-8965-80898e6760a3')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-flavor-extra-specs:delete")
+ rules=["os_compute_api:os-flavor-extra-specs:delete"])
def test_unset_flavor_extra_spec(self):
key = self._set_flavor_extra_spec()
with self.rbac_utils.override_role(self):
@@ -87,7 +87,7 @@
@decorators.idempotent_id('02c3831a-3ce9-476e-a722-d805ac2da621')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-flavor-extra-specs:index")
+ rules=["os_compute_api:os-flavor-extra-specs:index"])
def test_list_flavor_extra_specs(self):
self._set_flavor_extra_spec()
with self.rbac_utils.override_role(self):
diff --git a/patrole_tempest_plugin/tests/api/compute/test_flavor_manage_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_flavor_manage_rbac.py
index f0f267c..f968d4e 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_flavor_manage_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_flavor_manage_rbac.py
@@ -32,7 +32,7 @@
@decorators.idempotent_id('a4e7faec-7a4b-4809-9856-90d5b747ca35')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-flavor-manage:create")
+ rules=["os_compute_api:os-flavor-manage:create"])
def test_create_flavor_manage(self):
with self.rbac_utils.override_role(self):
self.create_flavor()
@@ -40,7 +40,7 @@
@decorators.idempotent_id('782e988e-061b-4c40-896f-a77c70c2b057')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-flavor-manage:delete")
+ rules=["os_compute_api:os-flavor-manage:delete"])
def test_delete_flavor_manage(self):
flavor_id = self.create_flavor()['id']
diff --git a/patrole_tempest_plugin/tests/api/compute/test_flavor_rxtx_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_flavor_rxtx_rbac.py
index b4531af..0748e67 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_flavor_rxtx_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_flavor_rxtx_rbac.py
@@ -40,7 +40,7 @@
@decorators.idempotent_id('5e1fd9f0-9a08-485a-ad9c-0fc66e4d64b7')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-flavor-rxtx")
+ rules=["os_compute_api:os-flavor-rxtx"])
def test_list_flavors_details_rxtx(self):
with self.rbac_utils.override_role(self):
result = self.flavors_client.list_flavors(detail=True)['flavors']
@@ -53,7 +53,7 @@
@decorators.idempotent_id('70c55a07-c843-4627-a29d-ba78673c1e63')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-flavor-rxtx")
+ rules=["os_compute_api:os-flavor-rxtx"])
def test_get_flavor_rxtx(self):
with self.rbac_utils.override_role(self):
result = self.flavors_client.show_flavor(
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 7467130..eef7943 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
@@ -48,7 +48,7 @@
@decorators.idempotent_id('c1a17153-b25d-4444-a721-5897d7737482')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-floating-ip-pools")
+ rules=["os_compute_api:os-floating-ip-pools"])
def test_list_floating_ip_pools(self):
with self.rbac_utils.override_role(self):
self.fip_pools_client.list_floating_ip_pools()
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 3ccef73..4a8426c 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
@@ -89,7 +89,7 @@
@decorators.idempotent_id('9a49e73f-96a0-4e93-830a-22c4e443b486')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-floating-ips-bulk")
+ rules=["os_compute_api:os-floating-ips-bulk"])
def test_create_floating_ips_bulk(self):
with self.rbac_utils.override_role(self):
self._create_floating_ips_bulk()
@@ -97,7 +97,7 @@
@decorators.idempotent_id('3b5c8a02-005d-4256-8a95-6fa2f389c6cf')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-floating-ips-bulk")
+ rules=["os_compute_api:os-floating-ips-bulk"])
def test_list_floating_ips_bulk(self):
with self.rbac_utils.override_role(self):
self.fip_bulk_client.list_floating_ips_bulk()
@@ -105,7 +105,7 @@
@decorators.idempotent_id('37c2b759-c494-4e20-9dba-6a67b2df9573')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-floating-ips-bulk")
+ rules=["os_compute_api:os-floating-ips-bulk"])
def test_delete_floating_ips_bulk(self):
self._create_floating_ips_bulk()
with self.rbac_utils.override_role(self):
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 1045512..0f37a80 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
@@ -44,7 +44,7 @@
@decorators.idempotent_id('ac1b3053-f755-4cda-85a0-30e88b88d7ba')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-floating-ips")
+ rules=["os_compute_api:os-floating-ips"])
def test_list_floating_ips(self):
with self.rbac_utils.override_role(self):
self.floating_ips_client.list_floating_ips()
@@ -52,7 +52,7 @@
@decorators.idempotent_id('bebe52b3-5269-4e72-80c8-5a4a39c3bfa6')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-floating-ips")
+ rules=["os_compute_api:os-floating-ips"])
def test_show_floating_ip(self):
body = self.floating_ips_client.create_floating_ip(
pool=CONF.network.floating_network_name)['floating_ip']
@@ -64,7 +64,7 @@
@decorators.idempotent_id('2bfb8745-c329-4ee9-95f6-c165a1989dbf')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-floating-ips")
+ rules=["os_compute_api:os-floating-ips"])
def test_create_floating_ips(self):
with self.rbac_utils.override_role(self):
body = self.floating_ips_client.create_floating_ip(
@@ -75,7 +75,7 @@
@decorators.idempotent_id('d3028373-5027-4e7a-b761-01c515403ecb')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-floating-ips")
+ rules=["os_compute_api:os-floating-ips"])
def test_delete_floating_ip(self):
body = self.floating_ips_client.create_floating_ip(
pool=CONF.network.floating_network_name)['floating_ip']
diff --git a/patrole_tempest_plugin/tests/api/compute/test_hosts_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_hosts_rbac.py
index 41d2656..f2d8113 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_hosts_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_hosts_rbac.py
@@ -36,7 +36,7 @@
@decorators.idempotent_id('035b7935-2fae-4218-8d37-27fa83097494')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-hosts")
+ rules=["os_compute_api:os-hosts"])
def test_list_hosts(self):
with self.rbac_utils.override_role(self):
self.hosts_client.list_hosts()
@@ -44,7 +44,7 @@
@decorators.idempotent_id('bc10d8b4-d2c3-4d4e-9d2b-31d1bd3e1b51')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-hosts")
+ rules=["os_compute_api:os-hosts"])
def test_show_host_details(self):
hosts = self.hosts_client.list_hosts()['hosts']
hosts = [host for host in hosts if host['service'] == 'compute']
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 33f40e7..5488556 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_hypervisor_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_hypervisor_rbac.py
@@ -39,7 +39,7 @@
@decorators.idempotent_id('17bbeb9a-e73e-445f-a771-c794448ef562')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-hypervisors")
+ rules=["os_compute_api:os-hypervisors"])
def test_list_hypervisors(self):
with self.rbac_utils.override_role(self):
self.hypervisor_client.list_hypervisors()
@@ -47,7 +47,7 @@
@decorators.idempotent_id('36b95c7d-1085-487a-a674-b7c1ca35f520')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-hypervisors")
+ rules=["os_compute_api:os-hypervisors"])
def test_list_hypervisors_with_details(self):
with self.rbac_utils.override_role(self):
self.hypervisor_client.list_hypervisors(detail=True)
@@ -55,7 +55,7 @@
@decorators.idempotent_id('8a7f6f9e-34a6-4480-8875-bba566c3a581')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-hypervisors")
+ rules=["os_compute_api:os-hypervisors"])
def test_show_hypervisor(self):
with self.rbac_utils.override_role(self):
self.hypervisor_client.show_hypervisor(self.hypervisor['id'])
@@ -63,7 +63,7 @@
@decorators.idempotent_id('ca0e465c-6365-4a7f-ae58-6f8ddbca06c2')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-hypervisors")
+ rules=["os_compute_api:os-hypervisors"])
def test_show_hypervisor_statistics(self):
with self.rbac_utils.override_role(self):
self.hypervisor_client.show_hypervisor_statistics()
@@ -71,7 +71,7 @@
@decorators.idempotent_id('109b37c5-91ba-4da5-b2a2-d7618d84406d')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-hypervisors")
+ rules=["os_compute_api:os-hypervisors"])
def test_show_hypervisor_uptime(self):
with self.rbac_utils.override_role(self):
self.hypervisor_client.show_hypervisor_uptime(
@@ -102,7 +102,7 @@
@decorators.idempotent_id('b86f03cf-2e79-4d88-9eea-62f761591413')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-hypervisors")
+ rules=["os_compute_api:os-hypervisors"])
def test_list_servers_on_hypervisor(self):
with self.rbac_utils.override_role(self):
self.hypervisor_client.list_servers_on_hypervisor(
@@ -111,7 +111,7 @@
@decorators.idempotent_id('3dbc71c1-8f04-4674-a67c-dcb2fd99b1b4')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-hypervisors")
+ rules=["os_compute_api:os-hypervisors"])
def test_search_hypervisor(self):
with self.rbac_utils.override_role(self):
self.hypervisor_client.search_hypervisor(
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 c988128..f6c1b67 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_images_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_images_rbac.py
@@ -79,7 +79,7 @@
@decorators.idempotent_id('b861f302-b72b-4055-81db-c62ff30b136d')
@rbac_rule_validation.action(
service="glance",
- rule="get_images")
+ rules=["get_images"])
def test_list_images(self):
with self.rbac_utils.override_role(self):
self.compute_images_client.list_images()
@@ -87,7 +87,7 @@
@decorators.idempotent_id('4365ae0f-15ee-4b54-a527-1679faaed140')
@rbac_rule_validation.action(
service="glance",
- rule="get_images")
+ rules=["get_images"])
def test_list_images_with_details(self):
with self.rbac_utils.override_role(self):
self.compute_images_client.list_images(detail=True)
@@ -95,7 +95,7 @@
@decorators.idempotent_id('886dfcae-51bf-4610-9e52-82d7189524c2')
@rbac_rule_validation.action(
service="glance",
- rule="get_image")
+ rules=["get_image"])
def test_show_image_details(self):
with self.rbac_utils.override_role(self):
self.compute_images_client.show_image(self.image['id'])
@@ -103,7 +103,7 @@
@decorators.idempotent_id('5888c7aa-0803-46d4-a3fb-5d4729465cd5')
@rbac_rule_validation.action(
service="glance",
- rule="delete_image")
+ rules=["delete_image"])
def test_delete_image(self):
image = self.glance_image_client.create_image(
name=data_utils.rand_name(self.__class__.__name__ + '-image'))
@@ -164,7 +164,7 @@
@decorators.idempotent_id('dbe09d4c-e615-48cb-b908-a06a0f410a8e')
@rbac_rule_validation.action(
service="glance",
- rule="get_image")
+ rules=["get_image"])
def test_show_image_metadata_item(self):
self.compute_images_client.set_image_metadata(self.image['id'],
meta={'foo': 'bar'})
@@ -178,7 +178,7 @@
@decorators.idempotent_id('59f66079-d564-47e8-81b0-03c2e84d339e')
@rbac_rule_validation.action(
service="glance",
- rule="get_image")
+ rules=["get_image"])
def test_list_image_metadata(self):
with self.rbac_utils.override_role(self):
self.compute_images_client.list_image_metadata(self.image['id'])
@@ -186,7 +186,7 @@
@decorators.idempotent_id('575604aa-909f-4b1b-a5a5-cfae1f63044b')
@rbac_rule_validation.action(
service="glance",
- rule="modify_image")
+ rules=["modify_image"])
def test_create_image_metadata(self):
with self.rbac_utils.override_role(self):
# NOTE(felipemonteiro): Although the name of the client function
@@ -200,7 +200,7 @@
@decorators.idempotent_id('fb8c4eb6-00e5-454c-b8bc-0e801ec369f1')
@rbac_rule_validation.action(
service="glance",
- rule="modify_image")
+ rules=["modify_image"])
def test_update_image_metadata(self):
with self.rbac_utils.override_role(self):
self.compute_images_client.set_image_metadata(self.image['id'],
@@ -211,7 +211,7 @@
@decorators.idempotent_id('9c7c2036-af9b-49a8-8ba1-09b027ee5def')
@rbac_rule_validation.action(
service="glance",
- rule="modify_image")
+ rules=["modify_image"])
def test_update_image_metadata_item(self):
with self.rbac_utils.override_role(self):
self.compute_images_client.set_image_metadata_item(
@@ -222,7 +222,7 @@
@decorators.idempotent_id('5f0dc4e6-0761-4613-9bde-0a6acdc78f46')
@rbac_rule_validation.action(
service="glance",
- rule="modify_image")
+ rules=["modify_image"])
def test_delete_image_metadata_item(self):
self.compute_images_client.set_image_metadata(self.image['id'],
meta={'foo': 'bar'})
@@ -286,7 +286,7 @@
@decorators.idempotent_id('fe34d2a6-5743-45bf-8f92-a1d703d7c7ab')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:image-size")
+ rules=["os_compute_api:image-size"])
def test_show_image_includes_image_size(self):
with self.rbac_utils.override_role(self):
body = self.compute_images_client.show_image(self.image['id'])[
@@ -302,7 +302,7 @@
@decorators.idempotent_id('08342c7d-297d-42ee-b398-90fce2443792')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:image-size")
+ rules=["os_compute_api:image-size"])
def test_list_images_with_details_includes_image_size(self):
with self.rbac_utils.override_role(self):
body = self.compute_images_client.list_images(detail=True)[
diff --git a/patrole_tempest_plugin/tests/api/compute/test_instance_usages_audit_log_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_instance_usages_audit_log_rbac.py
index 347b7df..163d29a 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_instance_usages_audit_log_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_instance_usages_audit_log_rbac.py
@@ -36,7 +36,7 @@
@decorators.idempotent_id('c80246c0-5c13-4ab0-97ba-91551cd53dc1')
@rbac_rule_validation.action(
- service="nova", rule="os_compute_api:os-instance-usage-audit-log")
+ service="nova", rules=["os_compute_api:os-instance-usage-audit-log"])
def test_list_instance_usage_audit_logs(self):
with self.rbac_utils.override_role(self):
(self.instance_usages_audit_log_client
@@ -44,7 +44,7 @@
@decorators.idempotent_id('ded8bfbd-5d90-4a58-aee0-d31231bf3c9b')
@rbac_rule_validation.action(
- service="nova", rule="os_compute_api:os-instance-usage-audit-log")
+ service="nova", rules=["os_compute_api:os-instance-usage-audit-log"])
def test_show_instance_usage_audit_log(self):
now = datetime.datetime.now()
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 b359ad2..c024a38 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_keypairs_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_keypairs_rbac.py
@@ -34,7 +34,7 @@
@decorators.idempotent_id('16e0ae81-e05f-48cd-b253-cf31ab0732f0')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-keypairs:create")
+ rules=["os_compute_api:os-keypairs:create"])
def test_create_keypair(self):
with self.rbac_utils.override_role(self):
self._create_keypair()
@@ -42,7 +42,7 @@
@decorators.idempotent_id('85a5eb99-40ec-4e77-9358-bee2cdf9d7df')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-keypairs:show")
+ rules=["os_compute_api:os-keypairs:show"])
def test_show_keypair(self):
kp_name = self._create_keypair()['keypair']['name']
with self.rbac_utils.override_role(self):
@@ -51,7 +51,7 @@
@decorators.idempotent_id('6bff9f1c-b809-43c1-8d63-61fbd19d49d3')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-keypairs:delete")
+ rules=["os_compute_api:os-keypairs:delete"])
def test_delete_keypair(self):
kp_name = self._create_keypair()['keypair']['name']
with self.rbac_utils.override_role(self):
@@ -60,7 +60,7 @@
@decorators.idempotent_id('6bb31346-ff7f-4b10-978e-170ac5fcfa3e')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-keypairs:index")
+ rules=["os_compute_api:os-keypairs:index"])
def test_index_keypair(self):
with self.rbac_utils.override_role(self):
self.keypairs_client.list_keypairs()
diff --git a/patrole_tempest_plugin/tests/api/compute/test_limits_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_limits_rbac.py
index 9442a5a..f1e0393 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_limits_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_limits_rbac.py
@@ -28,7 +28,7 @@
raise cls.skipException(msg)
@rbac_rule_validation.action(service="nova",
- rule="os_compute_api:limits")
+ rules=["os_compute_api:limits"])
@decorators.idempotent_id('3fb60f83-9a5f-4fdd-89d9-26c3710844a1')
def test_show_limits(self):
with self.rbac_utils.override_role(self):
diff --git a/patrole_tempest_plugin/tests/api/compute/test_migrations_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_migrations_rbac.py
index 1597a04..6596ac9 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_migrations_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_migrations_rbac.py
@@ -32,7 +32,7 @@
@decorators.idempotent_id('5795231c-3729-448c-a072-9a225db1a328')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-migrations:index")
+ rules=["os_compute_api:os-migrations:index"])
def test_list_services(self):
with self.rbac_utils.override_role(self):
self.migrations_client.list_migrations()
diff --git a/patrole_tempest_plugin/tests/api/compute/test_quota_class_sets_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_quota_class_sets_rbac.py
index 2bdd2f3..201922c 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_quota_class_sets_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_quota_class_sets_rbac.py
@@ -63,7 +63,7 @@
@decorators.idempotent_id('c10198ed-9df2-440e-a49b-367dadc6de94')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-quota-class-sets:show")
+ rules=["os_compute_api:os-quota-class-sets:show"])
def test_show_quota_class_set(self):
with self.rbac_utils.override_role(self):
self.quota_classes_client.show_quota_class_set('default')
@@ -71,7 +71,7 @@
@decorators.idempotent_id('81889e69-efd2-4e96-bb4c-ee3b646b9755')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-quota-class-sets:update")
+ rules=["os_compute_api:os-quota-class-sets:update"])
def test_update_quota_class_set(self):
# Update the pre-existing quotas for the project_id.
quota_class_set = self.quota_classes_client.show_quota_class_set(
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 2bc0893..2b05408 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
@@ -54,7 +54,7 @@
@decorators.idempotent_id('8229ceb0-db6a-4a2c-99c2-de226905d8b6')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-quota-sets:update")
+ rules=["os_compute_api:os-quota-sets:update"])
def test_update_quota_set(self):
default_quota_set = self.quotas_client.show_default_quota_set(
self.tenant_id)['quota_set']
@@ -71,7 +71,7 @@
@decorators.idempotent_id('58df5613-8f3c-400a-8b4b-2bae624d05e9')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-quota-sets:defaults")
+ rules=["os_compute_api:os-quota-sets:defaults"])
def test_show_default_quota_set(self):
with self.rbac_utils.override_role(self):
self.quotas_client.show_default_quota_set(self.tenant_id)
@@ -79,7 +79,7 @@
@decorators.idempotent_id('e8169ac4-c402-4864-894e-aba74e3a459c')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-quota-sets:show")
+ rules=["os_compute_api:os-quota-sets:show"])
def test_show_quota_set(self):
with self.rbac_utils.override_role(self):
self.quotas_client.show_quota_set(self.tenant_id)
@@ -87,7 +87,7 @@
@decorators.idempotent_id('4e240644-bf61-4872-9c32-8289ee2fdbbd')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-quota-sets:delete")
+ rules=["os_compute_api:os-quota-sets:delete"])
def test_delete_quota_set(self):
project_name = data_utils.rand_name(
self.__class__.__name__ + '-project')
@@ -105,7 +105,7 @@
@decorators.idempotent_id('ac9184b6-f3b3-4e17-a632-4b92c6500f86')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-quota-sets:detail")
+ rules=["os_compute_api:os-quota-sets:detail"])
def test_show_quota_set_details(self):
with self.rbac_utils.override_role(self):
self.quotas_client.show_quota_set(self.tenant_id,
diff --git a/patrole_tempest_plugin/tests/api/compute/test_security_groups_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_security_groups_rbac.py
index fa89a79..33d2ed1 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_security_groups_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_security_groups_rbac.py
@@ -55,7 +55,7 @@
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-security-groups")
+ rules=["os_compute_api:os-security-groups"])
@decorators.idempotent_id('3db159c6-a467-469f-9a25-574197885520')
def test_list_security_groups_by_server(self):
with self.rbac_utils.override_role(self):
@@ -64,7 +64,7 @@
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-security-groups")
+ rules=["os_compute_api:os-security-groups"])
@decorators.idempotent_id('ea1ca73f-2d1d-43cb-9a46-900d7927b357')
def test_create_security_group_for_server(self):
sg_name = self.create_security_group()['name']
@@ -78,7 +78,7 @@
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-security-groups")
+ rules=["os_compute_api:os-security-groups"])
@decorators.idempotent_id('0ad2e856-e2d3-4ac5-a620-f93d0d3d2626')
def test_remove_security_group_from_server(self):
sg_name = self.create_security_group()['name']
@@ -116,7 +116,7 @@
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-security-groups")
+ rules=["os_compute_api:os-security-groups"])
@decorators.idempotent_id('4ac58e49-48c1-4fca-a6c3-3f95fb99eb77')
def test_list_security_groups(self):
with self.rbac_utils.override_role(self):
@@ -124,7 +124,7 @@
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-security-groups")
+ rules=["os_compute_api:os-security-groups"])
@decorators.idempotent_id('e8fe7f5a-69ee-412d-81d3-a8c7a488b54d')
def test_create_security_groups(self):
with self.rbac_utils.override_role(self):
@@ -132,7 +132,7 @@
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-security-groups")
+ rules=["os_compute_api:os-security-groups"])
@decorators.idempotent_id('59127e8e-302d-11e7-93ae-92361f002671')
def test_delete_security_groups(self):
sec_group_id = self.create_security_group()['id']
@@ -141,7 +141,7 @@
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-security-groups")
+ rules=["os_compute_api:os-security-groups"])
@decorators.idempotent_id('3de5c6bc-b822-469e-a627-82427d38b067')
def test_update_security_groups(self):
sec_group_id = self.create_security_group()['id']
@@ -154,7 +154,7 @@
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-security-groups")
+ rules=["os_compute_api:os-security-groups"])
@decorators.idempotent_id('6edc0320-302d-11e7-93ae-92361f002671')
def test_show_security_groups(self):
sec_group_id = self.create_security_group()['id']
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 1fe52e9..a64bd20 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
@@ -119,7 +119,7 @@
'Pause is not available.')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-pause-server:pause")
+ rules=["os_compute_api:os-pause-server:pause"])
def test_pause_server(self):
with self.rbac_utils.override_role(self):
self._pause_server()
@@ -129,7 +129,7 @@
'Pause is not available.')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-pause-server:unpause")
+ rules=["os_compute_api:os-pause-server:unpause"])
def test_unpause_server(self):
self._pause_server()
with self.rbac_utils.override_role(self):
@@ -139,7 +139,7 @@
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:servers:stop")
+ rules=["os_compute_api:servers:stop"])
@decorators.idempotent_id('ab4a17d2-166f-4a6d-9944-f17baa576cf2')
def test_stop_server(self):
with self.rbac_utils.override_role(self):
@@ -148,7 +148,7 @@
@decorators.attr(type='slow')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:servers:start")
+ rules=["os_compute_api:servers:start"])
@decorators.idempotent_id('8876bfa9-4d10-406e-a335-a57e451abb12')
def test_start_server(self):
self._stop_server()
@@ -161,7 +161,7 @@
@decorators.attr(type='slow')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:servers:resize")
+ rules=["os_compute_api:servers:resize"])
@decorators.idempotent_id('0546fbdd-2d8f-4ce8-ac00-f1e2129d0765')
@testtools.skipUnless(CONF.compute_feature_enabled.resize,
'Resize is not available.')
@@ -172,7 +172,7 @@
@decorators.attr(type='slow')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:servers:revert_resize")
+ rules=["os_compute_api:servers:revert_resize"])
@decorators.idempotent_id('d41b64b8-a72d-414a-a4c5-94e1eb5e5a96')
@testtools.skipUnless(CONF.compute_feature_enabled.resize,
'Resize is not available.')
@@ -187,7 +187,7 @@
@decorators.attr(type='slow')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:servers:confirm_resize")
+ rules=["os_compute_api:servers:confirm_resize"])
@decorators.idempotent_id('f51620cb-dfcb-4e5d-b421-2e0edaa1316e')
@testtools.skipUnless(CONF.compute_feature_enabled.resize,
'Resize is not available.')
@@ -202,7 +202,7 @@
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:servers:rebuild")
+ rules=["os_compute_api:servers:rebuild"])
@decorators.idempotent_id('54b1a30b-c96c-472c-9c83-ccaf6ec7e20b')
def test_rebuild_server(self):
with self.rbac_utils.override_role(self):
@@ -212,7 +212,7 @@
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:servers:reboot")
+ rules=["os_compute_api:servers:reboot"])
@decorators.idempotent_id('19f27856-56e1-44f8-8615-7257f6b85cbb')
def test_reboot_server(self):
with self.rbac_utils.override_role(self):
@@ -222,7 +222,7 @@
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:servers:index")
+ rules=["os_compute_api:servers:index"])
@decorators.idempotent_id('631f0d86-7607-4198-8312-9da2f05464a4')
def test_server_index(self):
with self.rbac_utils.override_role(self):
@@ -230,7 +230,7 @@
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:servers:detail")
+ rules=["os_compute_api:servers:detail"])
@decorators.idempotent_id('96093480-3ce5-4a8b-b569-aed870379c24')
def test_server_detail(self):
with self.rbac_utils.override_role(self):
@@ -238,7 +238,7 @@
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:servers:detail:get_all_tenants")
+ rules=["os_compute_api:servers:detail:get_all_tenants"])
@decorators.idempotent_id('a9e5a1c0-acfe-49a2-b2b1-fd8b19d61f71')
def test_server_detail_all_tenants(self):
with self.rbac_utils.override_role(self):
@@ -246,7 +246,7 @@
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:servers:index:get_all_tenants")
+ rules=["os_compute_api:servers:index:get_all_tenants"])
@decorators.idempotent_id('4b93ba56-69e6-41f5-82c4-84a5c4c42091')
def test_server_index_all_tenants(self):
with self.rbac_utils.override_role(self):
@@ -254,7 +254,7 @@
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:servers:show")
+ rules=["os_compute_api:servers:show"])
@decorators.idempotent_id('eaaf4f51-31b5-497f-8f0f-f527e5f70b83')
def test_show_server(self):
with self.rbac_utils.override_role(self):
@@ -263,7 +263,7 @@
@utils.services('image')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:servers:create_image")
+ rules=["os_compute_api:servers:create_image"])
@decorators.idempotent_id('ba0ac859-99f4-4055-b5e0-e0905a44d331')
def test_create_image(self):
with self.rbac_utils.override_role(self):
@@ -273,7 +273,7 @@
@utils.services('image', 'volume')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:servers:create_image:allow_volume_backed")
+ rules=["os_compute_api:servers:create_image:allow_volume_backed"])
@decorators.idempotent_id('8b869f73-49b3-4cc4-a0ce-ef64f8e1d6f9')
def test_create_image_from_volume_backed_server(self):
# volume_backed=True creates a volume and create server will be
@@ -299,7 +299,7 @@
@utils.services('image')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-create-backup")
+ rules=["os_compute_api:os-create-backup"])
def test_create_backup(self):
# Prioritize glance v2 over v1 for deleting/waiting for image status.
if CONF.image_feature_enabled.api_v2:
@@ -334,7 +334,7 @@
@decorators.idempotent_id('0b70c527-af75-4bed-9ccf-4f1310a8b60f')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-shelve:shelve")
+ rules=["os_compute_api:os-shelve:shelve"])
def test_shelve_server(self):
with self.rbac_utils.override_role(self):
self._shelve_server()
@@ -343,7 +343,7 @@
@decorators.idempotent_id('4b6e849a-9182-49ff-9257-e97e751b475e')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-shelve:unshelve")
+ rules=["os_compute_api:os-shelve:unshelve"])
def test_unshelve_server(self):
self._shelve_server()
with self.rbac_utils.override_role(self):
@@ -364,7 +364,7 @@
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-evacuate")
+ rules=["os_compute_api:os-evacuate"])
@decorators.idempotent_id('78ecef3c-faff-412a-83be-47651963eb21')
def test_evacuate_server(self):
fake_host_name = data_utils.rand_name(
@@ -396,7 +396,7 @@
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:servers:show:host_status")
+ rules=["os_compute_api:servers:show:host_status"])
@decorators.idempotent_id('736da575-86f8-4b2a-9902-dd37dc9a409b')
def test_show_server_host_status(self):
with self.rbac_utils.override_role(self):
diff --git a/patrole_tempest_plugin/tests/api/compute/test_server_consoles_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_server_consoles_rbac.py
index fa2f359..4570ea1 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_server_consoles_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_server_consoles_rbac.py
@@ -37,7 +37,7 @@
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-console-output")
+ rules=["os_compute_api:os-console-output"])
@decorators.idempotent_id('90fd80f6-456c-11e7-a919-92ebcb67fe33')
def test_get_console_output(self):
with self.rbac_utils.override_role(self):
@@ -61,7 +61,7 @@
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-remote-consoles")
+ rules=["os_compute_api:os-remote-consoles"])
@decorators.idempotent_id('b0a72c02-9b15-4dcb-b186-efe8753370ab')
def test_get_vnc_console_output(self):
with self.rbac_utils.override_role(self):
@@ -86,7 +86,7 @@
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-remote-consoles")
+ rules=["os_compute_api:os-remote-consoles"])
@decorators.idempotent_id('879597de-87e0-4da9-a60a-28c8088dc508')
def test_get_remote_console_output(self):
with self.rbac_utils.override_role(self):
diff --git a/patrole_tempest_plugin/tests/api/compute/test_server_groups_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_server_groups_rbac.py
index 1674b1a..26ef0fe 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_server_groups_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_server_groups_rbac.py
@@ -31,7 +31,7 @@
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-server-groups:create")
+ rules=["os_compute_api:os-server-groups:create"])
@decorators.idempotent_id('7f3eae94-6130-47e9-81ac-34009f55be2f')
def test_create_server_group(self):
with self.rbac_utils.override_role(self):
@@ -39,7 +39,7 @@
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-server-groups:delete")
+ rules=["os_compute_api:os-server-groups:delete"])
@decorators.idempotent_id('832d9be3-632e-47b2-93d2-5897db43e3e2')
def test_delete_server_group(self):
server_group = self.create_test_server_group()
@@ -48,7 +48,7 @@
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-server-groups:index")
+ rules=["os_compute_api:os-server-groups:index"])
@decorators.idempotent_id('5eccd67f-5945-483b-b1c8-de851ebfc1c1')
def test_list_server_groups(self):
with self.rbac_utils.override_role(self):
@@ -56,7 +56,7 @@
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-server-groups:show")
+ rules=["os_compute_api:os-server-groups:show"])
@decorators.idempotent_id('62534e3f-7e99-4a3d-a08e-33e056460cf2')
def test_show_server_group(self):
server_group = self.create_test_server_group()
diff --git a/patrole_tempest_plugin/tests/api/compute/test_server_metadata_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_server_metadata_rbac.py
index 05b1758..6193938 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_server_metadata_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_server_metadata_rbac.py
@@ -35,7 +35,7 @@
@decorators.idempotent_id('b07bbc27-58e2-4581-869d-ad228cec5d9a')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:server-metadata:index")
+ rules=["os_compute_api:server-metadata:index"])
def test_list_server_metadata(self):
with self.rbac_utils.override_role(self):
self.servers_client.list_server_metadata(self.server['id'])
@@ -43,7 +43,7 @@
@decorators.idempotent_id('6e76748b-2417-4fa2-b41a-c0cc4bff356b')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:server-metadata:update_all")
+ rules=["os_compute_api:server-metadata:update_all"])
def test_set_server_metadata(self):
with self.rbac_utils.override_role(self):
self.servers_client.set_server_metadata(self.server['id'], {})
@@ -51,7 +51,7 @@
@decorators.idempotent_id('1060bac4-fe16-4a77-be64-d8e482a06eab')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:server-metadata:create")
+ rules=["os_compute_api:server-metadata:create"])
def test_update_server_metadata(self):
with self.rbac_utils.override_role(self):
self.servers_client.update_server_metadata(self.server['id'], {})
@@ -59,7 +59,7 @@
@decorators.idempotent_id('93dd8323-d3fa-48d1-8bd6-91c1b62fc341')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:server-metadata:show")
+ rules=["os_compute_api:server-metadata:show"])
def test_show_server_metadata_item(self):
with self.rbac_utils.override_role(self):
self.servers_client.show_server_metadata_item(
@@ -68,7 +68,7 @@
@decorators.idempotent_id('79511293-4bd7-447d-ba7e-634d0f4da70c')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:server-metadata:update")
+ rules=["os_compute_api:server-metadata:update"])
def test_set_server_metadata_item(self):
with self.rbac_utils.override_role(self):
self.servers_client.set_server_metadata_item(
@@ -77,7 +77,7 @@
@decorators.idempotent_id('feec5064-678d-40bc-a88f-c856e18d1e31')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:server-metadata:delete")
+ rules=["os_compute_api:server-metadata:delete"])
def test_delete_server_metadata_item(self):
with self.rbac_utils.override_role(self):
self.servers_client.delete_server_metadata_item(
diff --git a/patrole_tempest_plugin/tests/api/compute/test_server_migrations_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_server_migrations_rbac.py
index a867b81..8ae8bc0 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_server_migrations_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_server_migrations_rbac.py
@@ -62,7 +62,7 @@
'Cold migration not available.')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-migrate-server:migrate")
+ rules=["os_compute_api:os-migrate-server:migrate"])
@decorators.idempotent_id('c6f1607c-9fed-4c00-807e-9ba675b98b1b')
def test_cold_migration(self):
server = self.create_test_server(wait_until="ACTIVE")
@@ -76,7 +76,7 @@
'Live migration feature is not enabled.')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-migrate-server:migrate_live")
+ rules=["os_compute_api:os-migrate-server:migrate_live"])
@decorators.idempotent_id('33520834-72c8-4edb-a189-a2e0fc9eb0d3')
def test_migration_live(self):
server_id = self.create_test_server(wait_until="ACTIVE",
diff --git a/patrole_tempest_plugin/tests/api/compute/test_server_misc_policy_actions_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_server_misc_policy_actions_rbac.py
index 5681799..88bea25 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_server_misc_policy_actions_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_server_misc_policy_actions_rbac.py
@@ -81,7 +81,7 @@
@utils.requires_ext(extension='os-admin-actions', service='compute')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-admin-actions:reset_state")
+ rules=["os_compute_api:os-admin-actions:reset_state"])
@decorators.idempotent_id('ae84dd0b-f364-462e-b565-3457f9c019ef')
def test_reset_server_state(self):
"""Test reset server state, part of os-admin-actions."""
@@ -93,7 +93,7 @@
@utils.requires_ext(extension='os-admin-actions', service='compute')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-admin-actions:inject_network_info")
+ rules=["os_compute_api:os-admin-actions:inject_network_info"])
@decorators.idempotent_id('ce48c340-51c1-4cff-9b6e-0cc5ef008630')
def test_inject_network_info(self):
"""Test inject network info, part of os-admin-actions."""
@@ -103,7 +103,7 @@
@utils.requires_ext(extension='os-admin-actions', service='compute')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-admin-actions:reset_network")
+ rules=["os_compute_api:os-admin-actions:reset_network"])
@decorators.idempotent_id('2911a242-15c4-4fcb-80d5-80a8930661b0')
def test_reset_network(self):
"""Test reset network, part of os-admin-actions."""
@@ -114,7 +114,7 @@
'Change password not available.')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-admin-password")
+ rules=["os_compute_api:os-admin-password"])
@decorators.idempotent_id('908a7d59-3a66-441c-94cf-38e57ed14956')
def test_change_server_password(self):
"""Test change admin password, part of os-admin-password."""
@@ -135,7 +135,7 @@
@decorators.idempotent_id('2c82e819-382d-4d6f-87f0-a45954cbbc64')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-config-drive")
+ rules=["os_compute_api:os-config-drive"])
def test_list_servers_with_details_config_drive(self):
"""Test list servers with config_drive property in response body."""
with self.rbac_utils.override_role(self):
@@ -152,7 +152,7 @@
@decorators.idempotent_id('55c62ef7-b72b-4970-acc6-05b0a4316e5d')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-config-drive")
+ rules=["os_compute_api:os-config-drive"])
def test_show_server_config_drive(self):
"""Test show server with config_drive property in response body."""
with self.rbac_utils.override_role(self):
@@ -166,7 +166,7 @@
@decorators.idempotent_id('189bfed4-1e6d-475c-bb8c-d57e60895391')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-deferred-delete")
+ rules=["os_compute_api:os-deferred-delete"])
def test_force_delete_server(self):
"""Test force delete server, part of os-deferred-delete."""
with self.rbac_utils.override_role(self):
@@ -179,7 +179,7 @@
@utils.requires_ext(extension='OS-EXT-AZ', service='compute')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-extended-availability-zone")
+ rules=["os_compute_api:os-extended-availability-zone"])
def test_list_servers_with_details_extended_availability_zone(self):
"""Test list servers OS-EXT-AZ:availability_zone attr in resp body."""
expected_attr = 'OS-EXT-AZ:availability_zone'
@@ -197,7 +197,7 @@
@utils.requires_ext(extension='OS-EXT-AZ', service='compute')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-extended-availability-zone")
+ rules=["os_compute_api:os-extended-availability-zone"])
def test_show_server_extended_availability_zone(self):
"""Test show server OS-EXT-AZ:availability_zone attr in resp body."""
expected_attr = 'OS-EXT-AZ:availability_zone'
@@ -214,7 +214,7 @@
@utils.requires_ext(extension='OS-EXT-SRV-ATTR', service='compute')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-extended-server-attributes")
+ rules=["os_compute_api:os-extended-server-attributes"])
def test_list_servers_extended_server_attributes(self):
"""Test list servers with details, with extended server attributes in
response body.
@@ -238,7 +238,7 @@
@utils.requires_ext(extension='OS-EXT-SRV-ATTR', service='compute')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-extended-server-attributes")
+ rules=["os_compute_api:os-extended-server-attributes"])
def test_show_server_extended_server_attributes(self):
"""Test show server with extended server attributes in response
body.
@@ -262,7 +262,7 @@
@utils.requires_ext(extension='OS-EXT-STS', service='compute')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-extended-status")
+ rules=["os_compute_api:os-extended-status"])
def test_list_servers_extended_status(self):
"""Test list servers with extended properties in response body."""
with self.rbac_utils.override_role(self):
@@ -281,7 +281,7 @@
@utils.requires_ext(extension='OS-EXT-STS', service='compute')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-extended-status")
+ rules=["os_compute_api:os-extended-status"])
def test_show_server_extended_status(self):
"""Test show server with extended properties in response body."""
with self.rbac_utils.override_role(self):
@@ -300,7 +300,7 @@
@utils.requires_ext(extension='os-extended-volumes', service='compute')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-extended-volumes")
+ rules=["os_compute_api:os-extended-volumes"])
def test_list_servers_with_details_extended_volumes(self):
"""Test list servers os-extended-volumes:volumes_attached attr in resp
body.
@@ -319,7 +319,7 @@
@utils.requires_ext(extension='os-extended-volumes', service='compute')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-extended-volumes")
+ rules=["os_compute_api:os-extended-volumes"])
def test_show_server_extended_volumes(self):
"""Test show server os-extended-volumes:volumes_attached attr in resp
body.
@@ -336,7 +336,7 @@
@decorators.idempotent_id('9d1b131d-407e-4fa3-8eef-eb2c4526f1da')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-instance-actions")
+ rules=["os_compute_api:os-instance-actions"])
def test_list_instance_actions(self):
"""Test list instance actions, part of os-instance-actions."""
with self.rbac_utils.override_role(self):
@@ -346,7 +346,7 @@
@decorators.idempotent_id('eb04c439-4215-4029-9ccb-5b3c041bfc25')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-instance-actions:events")
+ rules=["os_compute_api:os-instance-actions:events"])
def test_show_instance_action(self):
"""Test show instance action, part of os-instance-actions.
@@ -372,7 +372,7 @@
"This API extension policy was removed in Stein")
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-keypairs")
+ rules=["os_compute_api:os-keypairs"])
@decorators.idempotent_id('81e6fa34-c06b-42ca-b195-82bf8699b940')
def test_show_server_keypair(self):
with self.rbac_utils.override_role(self):
@@ -386,7 +386,7 @@
"This API extension policy was removed in Stein")
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-keypairs")
+ rules=["os_compute_api:os-keypairs"])
@decorators.idempotent_id('41ca4280-ec59-4b80-a9b1-6bc6366faf39')
def test_list_servers_keypairs(self):
with self.rbac_utils.override_role(self):
@@ -397,7 +397,7 @@
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-lock-server:lock")
+ rules=["os_compute_api:os-lock-server:lock"])
@decorators.idempotent_id('b81e10fb-1864-498f-8c1d-5175c6fec5fb')
def test_lock_server(self):
"""Test lock server, part of os-lock-server."""
@@ -407,7 +407,7 @@
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-lock-server:unlock")
+ rules=["os_compute_api:os-lock-server:unlock"])
@decorators.idempotent_id('d50ef8e8-4bce-11e7-b114-b2f933d5fe66')
def test_unlock_server(self):
"""Test unlock server, part of os-lock-server."""
@@ -438,7 +438,7 @@
@utils.requires_ext(extension='os-rescue', service='compute')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-rescue")
+ rules=["os_compute_api:os-rescue"])
@decorators.idempotent_id('fbbb2afc-ed0e-4552-887d-ac00fb5d436e')
def test_rescue_server(self):
"""Test rescue server, part of os-rescue."""
@@ -451,7 +451,7 @@
@utils.requires_ext(extension='os-rescue', service='compute')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-rescue")
+ rules=["os_compute_api:os-rescue"])
def test_unrescue_server(self):
"""Test unrescue server, part of os-rescue."""
self.servers_client.rescue_server(self.server['id'])
@@ -466,7 +466,7 @@
@utils.requires_ext(extension='os-server-diagnostics', service='compute')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-server-diagnostics")
+ rules=["os_compute_api:os-server-diagnostics"])
@decorators.idempotent_id('5dabfcc4-bedb-417b-8247-b3ee7c5c0f3e')
def test_show_server_diagnostics(self):
"""Test show server diagnostics, part of os-server-diagnostics."""
@@ -477,7 +477,7 @@
@decorators.idempotent_id('aaf43f78-c178-4581-ac18-14afd3f1f6ba')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-server-password")
+ rules=["os_compute_api:os-server-password"])
def test_delete_server_password(self):
"""Test delete server password, part of os-server-password."""
with self.rbac_utils.override_role(self):
@@ -486,7 +486,7 @@
@utils.requires_ext(extension='os-server-password', service='compute')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-server-password")
+ rules=["os_compute_api:os-server-password"])
@decorators.idempotent_id('f677971a-7d20-493c-977f-6ff0a74b5b2c')
def test_get_server_password(self):
"""Test show server password, part of os-server-password."""
@@ -498,7 +498,7 @@
@utils.requires_ext(extension='OS-SRV-USG', service='compute')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-server-usage")
+ rules=["os_compute_api:os-server-usage"])
@decorators.idempotent_id('f0437ead-b9fb-462a-9f3d-ce53fac9d57a')
def test_show_server_usage(self):
"""Test show server usage, part of os-server-usage.
@@ -520,7 +520,7 @@
@utils.requires_ext(extension='os-simple-tenant-usage', service='compute')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-simple-tenant-usage:list")
+ rules=["os_compute_api:os-simple-tenant-usage:list"])
@decorators.idempotent_id('2aef094f-0452-4df6-a66a-0ec22a92b16e')
def test_list_simple_tenant_usages(self):
"""Test list tenant usages, part of os-simple-tenant-usage."""
@@ -530,7 +530,7 @@
@utils.requires_ext(extension='os-simple-tenant-usage', service='compute')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-simple-tenant-usage:show")
+ rules=["os_compute_api:os-simple-tenant-usage:show"])
@decorators.idempotent_id('fe7eacda-15c4-4bf7-93ef-1091c4546a9d')
def test_show_simple_tenant_usage(self):
"""Test show tenant usage, part of os-simple-tenant-usage."""
@@ -544,7 +544,7 @@
@decorators.idempotent_id('b775930f-237c-431c-83ae-d33ed1b9700b')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-suspend-server:suspend")
+ rules=["os_compute_api:os-suspend-server:suspend"])
def test_suspend_server(self):
"""Test suspend server, part of os-suspend-server."""
with self.rbac_utils.override_role(self):
@@ -558,7 +558,7 @@
@decorators.idempotent_id('4d90bd02-11f8-45b1-a8a1-534665584675')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-suspend-server:resume")
+ rules=["os_compute_api:os-suspend-server:resume"])
def test_resume_server(self):
"""Test resume server, part of os-suspend-server."""
self.servers_client.suspend_server(self.server['id'])
@@ -654,7 +654,7 @@
@decorators.idempotent_id('ddf53cb6-4a0a-4e5a-91e3-6c32aaa3b9b6')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-attach-interfaces")
+ rules=["os_compute_api:os-attach-interfaces"])
def test_list_interfaces(self):
"""Test list interfaces, part of os-attach-interfaces."""
with self.rbac_utils.override_role(self):
@@ -666,7 +666,7 @@
@utils.requires_ext(extension='os-attach-interfaces', service='compute')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-attach-interfaces")
+ rules=["os_compute_api:os-attach-interfaces"])
def test_show_interface(self):
"""Test show interfaces, part of os-attach-interfaces."""
interface = self._attach_interface_to_server()
@@ -680,7 +680,7 @@
@decorators.idempotent_id('d2d3a24d-4738-4bce-a287-36d664746cde')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-attach-interfaces:create")
+ rules=["os_compute_api:os-attach-interfaces:create"])
def test_create_interface(self):
"""Test create interface, part of os-attach-interfaces."""
network_id = self.network['id']
@@ -704,7 +704,7 @@
@decorators.idempotent_id('55b05692-ed44-4608-a84c-cd4219c82799')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-attach-interfaces:delete")
+ rules=["os_compute_api:os-attach-interfaces:delete"])
def test_delete_interface(self):
"""Test delete interface, part of os-attach-interfaces."""
interface = self._attach_interface_to_server()
@@ -719,7 +719,7 @@
@utils.requires_ext(extension='os-ips', service='compute')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:ips:index")
+ rules=["os_compute_api:ips:index"])
def test_list_addresses(self):
"""Test list server addresses, part of ips policy family."""
with self.rbac_utils.override_role(self):
@@ -729,7 +729,7 @@
@utils.requires_ext(extension='os-ips', service='compute')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:ips:show")
+ rules=["os_compute_api:ips:show"])
def test_list_addresses_by_network(self):
"""Test list server addresses by network, part of ips policy family."""
addresses = self.servers_client.list_addresses(self.server['id'])[
@@ -744,7 +744,7 @@
"Interface attachment is not available.")
@utils.requires_ext(extension='os-multinic', service='compute')
@rbac_rule_validation.action(
- service="nova", rule="os_compute_api:os-multinic")
+ service="nova", rules=["os_compute_api:os-multinic"])
@decorators.idempotent_id('bd3e2c74-130a-40f0-8085-124d93fe67da')
def test_add_fixed_ip(self):
"""Test add fixed ip to server network, part of os-multinic."""
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 cae31f6..826e469 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_server_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_server_rbac.py
@@ -21,9 +21,7 @@
from tempest.lib.common.utils import data_utils
from tempest.lib.common.utils import test_utils
from tempest.lib import decorators
-from tempest.lib import exceptions
-from patrole_tempest_plugin import rbac_exceptions
from patrole_tempest_plugin import rbac_rule_validation
from patrole_tempest_plugin.tests.api.compute import rbac_base as base
@@ -47,7 +45,7 @@
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:servers:create")
+ rules=["os_compute_api:servers:create"])
@decorators.idempotent_id('4f34c73a-6ddc-4677-976f-71320fa855bd')
def test_create_server(self):
with self.rbac_utils.override_role(self):
@@ -61,7 +59,7 @@
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:servers:create:forced_host")
+ rules=["os_compute_api:servers:create:forced_host"])
@decorators.idempotent_id('0ae3c401-52ab-41bc-ab96-c598a65d9ae5')
def test_create_server_forced_host(self):
# Retrieve 'nova' zone host information from availiability_zone_list
@@ -88,7 +86,7 @@
@utils.services('volume')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:servers:create:attach_volume")
+ rules=["os_compute_api:servers:create:attach_volume"])
@decorators.idempotent_id('eeddac5e-15aa-454f-838d-db608aae4dd8')
def test_create_server_attach_volume(self):
# To create a bootable volume, the UUID of the image from which
@@ -126,7 +124,7 @@
@utils.services('network')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:servers:create:attach_network")
+ rules=["os_compute_api:servers:create:attach_network"])
@decorators.idempotent_id('b44cd4ff-50a4-42ce-ada3-724e213cd540')
def test_create_server_attach_network(self):
def _create_network_resources():
@@ -165,7 +163,7 @@
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:servers:delete")
+ rules=["os_compute_api:servers:delete"])
@decorators.idempotent_id('062e3440-e873-4b41-9317-bf6d8be50c12')
def test_delete_server(self):
server = self.create_test_server(wait_until='ACTIVE')
@@ -177,18 +175,12 @@
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:servers:update")
+ rules=["os_compute_api:servers:update"])
@decorators.idempotent_id('077b17cb-5621-43b9-8adf-5725f0d7a863')
def test_update_server(self):
new_name = data_utils.rand_name(self.__class__.__name__ + '-server')
with self.rbac_utils.override_role(self):
- try:
- self.servers_client.update_server(self.server['id'],
- name=new_name)
- waiters.wait_for_server_status(self.servers_client,
- self.server['id'], 'ACTIVE')
- except exceptions.ServerFault as e:
- # Some other policy may have blocked it.
- LOG.info("ServerFault exception caught. Some other policy "
- "blocked updating of server")
- raise rbac_exceptions.RbacConflictingPolicies(e)
+ self.servers_client.update_server(self.server['id'],
+ name=new_name)
+ waiters.wait_for_server_status(self.servers_client,
+ self.server['id'], 'ACTIVE')
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 70e7da9..ac571b9 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
@@ -47,7 +47,7 @@
@decorators.idempotent_id('99e73dd3-adec-4044-b46c-84bdded35d09')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-server-tags:index")
+ rules=["os_compute_api:os-server-tags:index"])
def test_list_tags(self):
with self.rbac_utils.override_role(self):
self.servers_client.list_tags(self.server['id'])
@@ -55,7 +55,7 @@
@decorators.idempotent_id('9297c99e-94eb-429f-93cf-9b1838e33622')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-server-tags:show")
+ rules=["os_compute_api:os-server-tags:show"])
def test_check_tag_existence(self):
tag_name = self._add_tag_to_server()
with self.rbac_utils.override_role(self):
@@ -65,7 +65,7 @@
@decorators.idempotent_id('0d84ee94-d3ca-4635-8edf-b7f67ab8e4a3')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-server-tags:update")
+ rules=["os_compute_api:os-server-tags:update"])
def test_update_tag(self):
with self.rbac_utils.override_role(self):
self._add_tag_to_server()
@@ -73,7 +73,7 @@
@decorators.idempotent_id('115c2694-00aa-41ee-99f6-9eab4040c182')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-server-tags:delete")
+ rules=["os_compute_api:os-server-tags:delete"])
def test_delete_tag(self):
tag_name = self._add_tag_to_server()
with self.rbac_utils.override_role(self):
@@ -82,7 +82,7 @@
@decorators.idempotent_id('a8e19b87-6580-4bc8-9933-e62561ff667d')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-server-tags:update_all")
+ rules=["os_compute_api:os-server-tags:update_all"])
def test_update_all_tags(self):
new_tag_name = data_utils.rand_name(self.__class__.__name__ + '-tag')
with self.rbac_utils.override_role(self):
@@ -92,7 +92,7 @@
@decorators.idempotent_id('89d51936-e333-42f9-a045-132a4865ba1a')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-server-tags:delete_all")
+ rules=["os_compute_api:os-server-tags:delete_all"])
def test_delete_all_tags(self):
with self.rbac_utils.override_role(self):
self.servers_client.delete_all_tags(self.server['id'])
diff --git a/patrole_tempest_plugin/tests/api/compute/test_server_volume_attachments_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_server_volume_attachments_rbac.py
index a510d1e..cb76605 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_server_volume_attachments_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_server_volume_attachments_rbac.py
@@ -51,7 +51,7 @@
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-volumes-attachments:index")
+ rules=["os_compute_api:os-volumes-attachments:index"])
@decorators.idempotent_id('529b668b-6edb-41d5-8886-d7dbd0614678')
def test_list_volume_attachments(self):
with self.rbac_utils.override_role(self):
@@ -60,7 +60,7 @@
@decorators.attr(type='slow')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-volumes-attachments:create")
+ rules=["os_compute_api:os-volumes-attachments:create"])
@decorators.idempotent_id('21c2c3fd-fbe8-41b1-8ef8-115ec47d54c1')
def test_create_volume_attachment(self):
with self.rbac_utils.override_role(self):
@@ -69,7 +69,7 @@
@decorators.attr(type='slow')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-volumes-attachments:show")
+ rules=["os_compute_api:os-volumes-attachments:show"])
@decorators.idempotent_id('997df9c2-6e54-47b6-ab74-e4fdb500f385')
def test_show_volume_attachment(self):
attachment = self.attach_volume(self.server, self.volume)
@@ -83,7 +83,7 @@
'In-place swapping of volumes not supported.')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-volumes-attachments:update")
+ rules=["os_compute_api:os-volumes-attachments:update"])
@decorators.idempotent_id('bd667186-eca6-4b78-ab6a-3e2fabcb971f')
def test_update_volume_attachment(self):
attachment = self.attach_volume(self.server, self.volume)
@@ -108,7 +108,7 @@
@decorators.attr(type='slow')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-volumes-attachments:delete")
+ rules=["os_compute_api:os-volumes-attachments:delete"])
@decorators.idempotent_id('12b03e90-d087-46af-9c4d-507d021c4984')
def test_delete_volume_attachment(self):
self.attach_volume(self.server, self.volume)
diff --git a/patrole_tempest_plugin/tests/api/compute/test_services_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_services_rbac.py
index 183d990..f32e117 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_services_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_services_rbac.py
@@ -31,7 +31,7 @@
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-services")
+ rules=["os_compute_api:os-services"])
@decorators.idempotent_id('7472261b-9c6d-453a-bcb3-aecaa29ad281')
def test_list_services(self):
with self.rbac_utils.override_role(self):
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 49fb34c..a4ccc10 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
@@ -54,7 +54,7 @@
@decorators.idempotent_id('42b39ba1-14aa-4799-9518-34367d0da67a')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-tenant-networks")
+ rules=["os_compute_api:os-tenant-networks"])
def test_list_show_tenant_networks(self):
with self.rbac_utils.override_role(self):
self.tenant_networks_client.list_tenant_networks()
diff --git a/patrole_tempest_plugin/tests/api/compute/test_virtual_interfaces_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_virtual_interfaces_rbac.py
index ae77a34..8376be0 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_virtual_interfaces_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_virtual_interfaces_rbac.py
@@ -45,7 +45,7 @@
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-virtual-interfaces")
+ rules=["os_compute_api:os-virtual-interfaces"])
@decorators.idempotent_id('fc719ae3-0f73-4689-8378-1b841f0f2818')
def test_list_virtual_interfaces(self):
"""Test list virtual interfaces, part of os-virtual-interfaces.
diff --git a/patrole_tempest_plugin/tests/api/compute/test_volume_rbac.py b/patrole_tempest_plugin/tests/api/compute/test_volume_rbac.py
index b07fb3f..3c693ab 100644
--- a/patrole_tempest_plugin/tests/api/compute/test_volume_rbac.py
+++ b/patrole_tempest_plugin/tests/api/compute/test_volume_rbac.py
@@ -60,7 +60,7 @@
@decorators.idempotent_id('2402013e-a624-43e3-9518-44a5d1dbb32d')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-volumes")
+ rules=["os_compute_api:os-volumes"])
def test_create_volume(self):
with self.rbac_utils.override_role(self):
volume = self.volumes_extensions_client.create_volume(
@@ -73,7 +73,7 @@
@decorators.idempotent_id('69b3888c-dff2-47b0-9fa4-0672619c9054')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-volumes")
+ rules=["os_compute_api:os-volumes"])
def test_list_volumes(self):
with self.rbac_utils.override_role(self):
self.volumes_extensions_client.list_volumes()
@@ -81,7 +81,7 @@
@decorators.idempotent_id('4ba0a820-040f-488b-86bb-be2e920ea12c')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-volumes")
+ rules=["os_compute_api:os-volumes"])
def test_show_volume(self):
with self.rbac_utils.override_role(self):
self.volumes_extensions_client.show_volume(self.volume['id'])
@@ -89,7 +89,7 @@
@decorators.idempotent_id('6e7870f2-1bb2-4b58-96f8-6782071ef327')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-volumes")
+ rules=["os_compute_api:os-volumes"])
def test_delete_volume(self):
volume = self.create_volume()
with self.rbac_utils.override_role(self):
@@ -98,7 +98,7 @@
@decorators.idempotent_id('0c3eaa4f-69d6-4a13-9dda-19585f36b1c1')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-volumes")
+ rules=["os_compute_api:os-volumes"])
def test_create_snapshot(self):
s_name = data_utils.rand_name(self.__class__.__name__ + '-Snapshot')
with self.rbac_utils.override_role(self):
@@ -110,7 +110,7 @@
@decorators.idempotent_id('e944e816-416c-11e7-a919-92ebcb67fe33')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-volumes")
+ rules=["os_compute_api:os-volumes"])
def test_list_snapshots(self):
with self.rbac_utils.override_role(self):
self.snapshots_extensions_client.list_snapshots()
@@ -118,7 +118,7 @@
@decorators.idempotent_id('19c2e6bd-585b-472f-a8d7-71ea9299c655')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-volumes")
+ rules=["os_compute_api:os-volumes"])
def test_show_snapshot(self):
s_name = data_utils.rand_name(self.__class__.__name__ + '-Snapshot')
snapshot = self.snapshots_extensions_client.create_snapshot(
@@ -131,7 +131,7 @@
@decorators.idempotent_id('f4f5635c-416c-11e7-a919-92ebcb67fe33')
@rbac_rule_validation.action(
service="nova",
- rule="os_compute_api:os-volumes")
+ rules=["os_compute_api:os-volumes"])
def test_delete_snapshot(self):
s_name = data_utils.rand_name(self.__class__.__name__ + '-Snapshot')
snapshot = self.snapshots_extensions_client.create_snapshot(
diff --git a/patrole_tempest_plugin/tests/api/identity/rbac_base.py b/patrole_tempest_plugin/tests/api/identity/rbac_base.py
index 91b3d1e..44f5962 100644
--- a/patrole_tempest_plugin/tests/api/identity/rbac_base.py
+++ b/patrole_tempest_plugin/tests/api/identity/rbac_base.py
@@ -16,13 +16,11 @@
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 import rbac_utils
-CONF = config.CONF
LOG = logging.getLogger(__name__)
@@ -30,11 +28,6 @@
base.BaseIdentityTest):
@classmethod
- def skip_checks(cls):
- super(BaseIdentityRbacTest, cls).skip_checks()
- cls.skip_rbac_checks()
-
- @classmethod
def setup_clients(cls):
super(BaseIdentityRbacTest, cls).setup_clients()
cls.setup_rbac_utils()
diff --git a/patrole_tempest_plugin/tests/api/identity/v3/test_application_credentials_rbac.py b/patrole_tempest_plugin/tests/api/identity/v3/test_application_credentials_rbac.py
index c7a6033..1d466f3 100644
--- a/patrole_tempest_plugin/tests/api/identity/v3/test_application_credentials_rbac.py
+++ b/patrole_tempest_plugin/tests/api/identity/v3/test_application_credentials_rbac.py
@@ -52,23 +52,26 @@
return application_credential
@decorators.idempotent_id('b53bee14-e9df-4929-b257-6def76c12e4d')
- @rbac_rule_validation.action(service="keystone",
- rule="identity:create_application_credential")
+ @rbac_rule_validation.action(
+ service="keystone",
+ rules=["identity:create_application_credential"])
def test_create_application_credential(self):
with self.rbac_utils.override_role(self):
self._create_application_credential()
@decorators.idempotent_id('58b3c3a0-5ad0-44f7-8da7-0736f71f7168')
- @rbac_rule_validation.action(service="keystone",
- rule="identity:list_application_credentials")
+ @rbac_rule_validation.action(
+ service="keystone",
+ rules=["identity:list_application_credentials"])
def test_list_application_credentials(self):
with self.rbac_utils.override_role(self):
self.application_credentials_client.list_application_credentials(
user_id=self.user_id)
@decorators.idempotent_id('d7b13968-a8a6-47fd-8e1d-7cc7f565c7f8')
- @rbac_rule_validation.action(service="keystone",
- rule="identity:get_application_credential")
+ @rbac_rule_validation.action(
+ service="keystone",
+ rules=["identity:get_application_credential"])
def test_show_application_credential(self):
app_cred = self._create_application_credential()
with self.rbac_utils.override_role(self):
@@ -76,8 +79,9 @@
user_id=self.user_id, application_credential_id=app_cred['id'])
@decorators.idempotent_id('521b7c0f-1dd5-47a6-ae95-95c0323d7735')
- @rbac_rule_validation.action(service="keystone",
- rule="identity:delete_application_credential")
+ @rbac_rule_validation.action(
+ service="keystone",
+ rules=["identity:delete_application_credential"])
def test_delete_application_credential(self):
app_cred = self._create_application_credential()
with self.rbac_utils.override_role(self):
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
index 8393696..a63192f 100644
--- a/patrole_tempest_plugin/tests/api/identity/v3/test_auth_rbac.py
+++ b/patrole_tempest_plugin/tests/api/identity/v3/test_auth_rbac.py
@@ -32,14 +32,14 @@
@decorators.idempotent_id('2a9fbf7f-6feb-4161-ae4b-faf7d6421b1a')
@rbac_rule_validation.action(service="keystone",
- rule="identity:get_auth_projects")
+ rules=["identity:get_auth_projects"])
def test_list_auth_projects(self):
with self.rbac_utils.override_role(self):
self.identity_client.list_auth_projects()
@decorators.idempotent_id('6a40af0d-7265-4657-b6b2-87a2828e263e')
@rbac_rule_validation.action(service="keystone",
- rule="identity:get_auth_domains")
+ rules=["identity:get_auth_domains"])
def test_list_auth_domain(self):
with self.rbac_utils.override_role(self):
self.identity_client.list_auth_domains()
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 af6feb6..977a830 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
@@ -29,7 +29,7 @@
return credential
@rbac_rule_validation.action(service="keystone",
- rule="identity:create_credential")
+ rules=["identity:create_credential"])
@decorators.idempotent_id('c1ab6d34-c59f-4ae1-bae9-bb3c1089b48e')
def test_create_credential(self):
project = self.setup_test_project()
@@ -38,7 +38,7 @@
self.setup_test_credential(user=user)
@rbac_rule_validation.action(service="keystone",
- rule="identity:update_credential")
+ rules=["identity:update_credential"])
@decorators.idempotent_id('cfb05ce3-bffb-496e-a3c2-9515d730da63')
def test_update_credential(self):
credential = self._create_user_project_and_credential()
@@ -54,7 +54,7 @@
project_id=credential['project_id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:delete_credential")
+ rules=["identity:delete_credential"])
@decorators.idempotent_id('87ab42af-8d41-401b-90df-21e72919fcde')
def test_delete_credential(self):
credential = self._create_user_project_and_credential()
@@ -63,7 +63,7 @@
self.creds_client.delete_credential(credential['id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:get_credential")
+ rules=["identity:get_credential"])
@decorators.idempotent_id('1b6eeae6-f1e8-4cdf-8903-1c002b1fc271')
def test_show_credential(self):
credential = self._create_user_project_and_credential()
@@ -72,7 +72,7 @@
self.creds_client.show_credential(credential['id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:list_credentials")
+ rules=["identity:list_credentials"])
@decorators.idempotent_id('3de303e2-12a7-4811-805a-f18906472038')
def test_list_credentials(self):
with self.rbac_utils.override_role(self):
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
index 8db8906..4fa3937 100644
--- 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
@@ -53,14 +53,14 @@
return domain_config
@rbac_rule_validation.action(service="keystone",
- rule="identity:create_domain_config")
+ rules=["identity:create_domain_config"])
@decorators.idempotent_id('6bdaecd4-0843-4ed6-ab64-3a57ab0cd115')
def test_create_domain_config(self):
with self.rbac_utils.override_role(self):
self._create_domain_config(self.domain_id)
@rbac_rule_validation.action(service="keystone",
- rule="identity:get_domain_config")
+ rules=["identity:get_domain_config"])
@decorators.idempotent_id('6bdaecd4-0843-4ed6-ab64-3a57ab0cd118')
def test_show_domain_config(self):
with self.rbac_utils.override_role(self):
@@ -68,7 +68,7 @@
@decorators.idempotent_id('1b539f95-4991-4e09-960f-fa771e1007d7')
@rbac_rule_validation.action(service="keystone",
- rule="identity:get_domain_config")
+ rules=["identity:get_domain_config"])
def test_show_domain_group_config(self):
with self.rbac_utils.override_role(self):
self.domain_config_client.show_domain_group_config(
@@ -76,7 +76,7 @@
@decorators.idempotent_id('590c774d-a294-44f8-866e-aac9f4ab3809')
@rbac_rule_validation.action(service="keystone",
- rule="identity:get_domain_config")
+ rules=["identity:get_domain_config"])
def test_show_domain_group_option_config(self):
with self.rbac_utils.override_role(self):
self.domain_config_client.show_domain_group_option_config(
@@ -85,7 +85,7 @@
@decorators.idempotent_id('21053885-1ce3-4167-b5e3-e470253481da')
@rbac_rule_validation.action(
service="keystone",
- rule="identity:get_security_compliance_domain_config")
+ rules=["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.
@@ -95,28 +95,28 @@
@decorators.idempotent_id('d1addd10-9ae4-4360-9961-47324fd22f23')
@rbac_rule_validation.action(service="keystone",
- rule="identity:get_domain_config_default")
+ rules=["identity:get_domain_config_default"])
def test_show_default_config_settings(self):
with self.rbac_utils.override_role(self):
self.domain_config_client.show_default_config_settings()
@decorators.idempotent_id('63183377-251f-4622-81f0-6b58a8a285c9')
@rbac_rule_validation.action(service="keystone",
- rule="identity:get_domain_config_default")
+ rules=["identity:get_domain_config_default"])
def test_show_default_group_config(self):
with self.rbac_utils.override_role(self):
self.domain_config_client.show_default_group_config('identity')
@decorators.idempotent_id('6440e9c1-e8da-474d-9118-89996fffe5f8')
@rbac_rule_validation.action(service="keystone",
- rule="identity:get_domain_config_default")
+ rules=["identity:get_domain_config_default"])
def test_show_default_group_option(self):
with self.rbac_utils.override_role(self):
self.domain_config_client.show_default_group_option('identity',
'driver')
@rbac_rule_validation.action(service="keystone",
- rule="identity:update_domain_config")
+ rules=["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()}}
@@ -126,7 +126,7 @@
@decorators.idempotent_id('6e32bf96-dbe9-4ac8-b814-0e79fa948285')
@rbac_rule_validation.action(service="keystone",
- rule="identity:update_domain_config")
+ rules=["identity:update_domain_config"])
def test_update_domain_group_config(self):
with self.rbac_utils.override_role(self):
self.domain_config_client.update_domain_group_config(
@@ -134,14 +134,14 @@
@decorators.idempotent_id('d2c510da-a077-4c67-9522-27745ef2812b')
@rbac_rule_validation.action(service="keystone",
- rule="identity:update_domain_config")
+ rules=["identity:update_domain_config"])
def test_update_domain_group_option_config(self):
with self.rbac_utils.override_role(self):
self.domain_config_client.update_domain_group_option_config(
self.domain_id, 'identity', 'driver', driver='ldap')
@rbac_rule_validation.action(service="keystone",
- rule="identity:delete_domain_config")
+ rules=["identity:delete_domain_config"])
@decorators.idempotent_id('6bdaecd4-0843-4ed6-ab64-3a57ab0cd117')
def test_delete_domain_config(self):
with self.rbac_utils.override_role(self):
@@ -149,7 +149,7 @@
@decorators.idempotent_id('f479694b-df02-4d5a-88b6-c8b52f9341eb')
@rbac_rule_validation.action(service="keystone",
- rule="identity:delete_domain_config")
+ rules=["identity:delete_domain_config"])
def test_delete_domain_group_config(self):
with self.rbac_utils.override_role(self):
self.domain_config_client.delete_domain_group_config(
@@ -157,7 +157,7 @@
@decorators.idempotent_id('f594bde3-31c9-414f-922d-0ddafdc0ca40')
@rbac_rule_validation.action(service="keystone",
- rule="identity:delete_domain_config")
+ rules=["identity:delete_domain_config"])
def test_delete_domain_group_option_config(self):
with self.rbac_utils.override_role(self):
self.domain_config_client.delete_domain_group_option_config(
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 3837051..ab38876 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
@@ -23,14 +23,14 @@
class IdentityDomainsV3RbacTest(rbac_base.BaseIdentityV3RbacTest):
@rbac_rule_validation.action(service="keystone",
- rule="identity:create_domain")
+ rules=["identity:create_domain"])
@decorators.idempotent_id('6bdaecd4-0843-4ed6-ab64-3a57ab0cd110')
def test_create_domain(self):
with self.rbac_utils.override_role(self):
self.setup_test_domain()
@rbac_rule_validation.action(service="keystone",
- rule="identity:update_domain")
+ rules=["identity:update_domain"])
@decorators.idempotent_id('6bdaecd4-0843-4ed6-ab64-3a57ab0cd111')
def test_update_domain(self):
domain = self.setup_test_domain()
@@ -42,7 +42,7 @@
name=new_domain_name)
@rbac_rule_validation.action(service="keystone",
- rule="identity:delete_domain")
+ rules=["identity:delete_domain"])
@decorators.idempotent_id('6bdaecd4-0843-4ed6-ab64-3a57ab0cd112')
def test_delete_domain(self):
domain = self.setup_test_domain()
@@ -54,7 +54,7 @@
self.domains_client.delete_domain(domain['id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:get_domain")
+ rules=["identity:get_domain"])
@decorators.idempotent_id('6bdaecd4-0843-4ed6-ab64-3a57ab0cd113')
def test_show_domain(self):
domain = self.setup_test_domain()
@@ -62,7 +62,7 @@
self.domains_client.show_domain(domain['id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:list_domains")
+ rules=["identity:list_domains"])
@decorators.idempotent_id('6bdaecd4-0843-4ed6-ab64-3a57ab0cd114')
def test_list_domains(self):
with self.rbac_utils.override_role(self):
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 ad1fd9b..ec5ffa3 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
@@ -23,7 +23,7 @@
class IdentityEndpointsV3RbacTest(rbac_base.BaseIdentityV3RbacTest):
@rbac_rule_validation.action(service="keystone",
- rule="identity:create_endpoint")
+ rules=["identity:create_endpoint"])
@decorators.idempotent_id('6bdaecd4-0843-4ed6-ab64-3a57ab0cd127')
def test_create_endpoint(self):
service = self.setup_test_service()
@@ -31,7 +31,7 @@
self.setup_test_endpoint(service=service)
@rbac_rule_validation.action(service="keystone",
- rule="identity:update_endpoint")
+ rules=["identity:update_endpoint"])
@decorators.idempotent_id('6bdaecd4-0843-4ed6-ab64-3a57ab0cd128')
def test_update_endpoint(self):
endpoint = self.setup_test_endpoint()
@@ -43,7 +43,7 @@
url=new_url)
@rbac_rule_validation.action(service="keystone",
- rule="identity:delete_endpoint")
+ rules=["identity:delete_endpoint"])
@decorators.idempotent_id('6bdaecd4-0843-4ed6-ab64-3a57ab0cd129')
def test_delete_endpoint(self):
endpoint = self.setup_test_endpoint()
@@ -52,7 +52,7 @@
self.endpoints_client.delete_endpoint(endpoint['id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:get_endpoint")
+ rules=["identity:get_endpoint"])
@decorators.idempotent_id('6bdaecd4-0843-4ed6-ab64-3a57ab0cd130')
def test_show_endpoint(self):
endpoint = self.setup_test_endpoint()
@@ -61,7 +61,7 @@
self.endpoints_client.show_endpoint(endpoint['id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:list_endpoints")
+ rules=["identity:list_endpoints"])
@decorators.idempotent_id('6bdaecd4-0843-4ed6-ab64-3a57ab0cd131')
def test_list_endpoints(self):
with self.rbac_utils.override_role(self):
diff --git a/patrole_tempest_plugin/tests/api/identity/v3/test_ep_filter_groups_rbac.py b/patrole_tempest_plugin/tests/api/identity/v3/test_ep_filter_groups_rbac.py
index 6e58289..be49d84 100644
--- a/patrole_tempest_plugin/tests/api/identity/v3/test_ep_filter_groups_rbac.py
+++ b/patrole_tempest_plugin/tests/api/identity/v3/test_ep_filter_groups_rbac.py
@@ -58,14 +58,14 @@
return endpoint_group['id']
@rbac_rule_validation.action(service="keystone",
- rule="identity:create_endpoint_group")
+ rules=["identity:create_endpoint_group"])
@decorators.idempotent_id('b4765906-52ec-477b-b441-a8508ced68e3')
def test_create_endpoint_group(self):
with self.rbac_utils.override_role(self):
self._create_endpoint_group(ignore_not_found=True)
@rbac_rule_validation.action(service="keystone",
- rule="identity:list_endpoint_groups")
+ rules=["identity:list_endpoint_groups"])
@decorators.idempotent_id('089aa3a7-ba1f-4f70-a1cf-f298a845058a')
def test_list_endpoint_groups(self):
with self.rbac_utils.override_role(self):
@@ -73,14 +73,14 @@
@decorators.idempotent_id('5c16368d-1485-4c28-9803-db3fa3510623')
@rbac_rule_validation.action(service="keystone",
- rule="identity:get_endpoint_group")
+ rules=["identity:get_endpoint_group"])
def test_check_endpoint_group(self):
with self.rbac_utils.override_role(self):
self.endpoint_groups_client.check_endpoint_group(
self.endpoint_group_id)
@rbac_rule_validation.action(service="keystone",
- rule="identity:get_endpoint_group")
+ rules=["identity:get_endpoint_group"])
@decorators.idempotent_id('bd2b6fb8-661f-4255-84b2-50fea4a1dc61')
def test_show_endpoint_group(self):
with self.rbac_utils.override_role(self):
@@ -88,7 +88,7 @@
self.endpoint_group_id)
@rbac_rule_validation.action(service="keystone",
- rule="identity:update_endpoint_group")
+ rules=["identity:update_endpoint_group"])
@decorators.idempotent_id('028b9198-ec35-4bd5-8f72-e23dfb7a0c8e')
def test_update_endpoint_group(self):
updated_name = data_utils.rand_name(
@@ -99,7 +99,7 @@
self.endpoint_group_id, name=updated_name)
@rbac_rule_validation.action(service="keystone",
- rule="identity:delete_endpoint_group")
+ rules=["identity:delete_endpoint_group"])
@decorators.idempotent_id('88cc105e-70d9-48ac-927e-200ef41e070c')
def test_delete_endpoint_group(self):
endpoint_group_id = self._create_endpoint_group(ignore_not_found=True)
diff --git a/patrole_tempest_plugin/tests/api/identity/v3/test_ep_filter_projects_rbac.py b/patrole_tempest_plugin/tests/api/identity/v3/test_ep_filter_projects_rbac.py
index 1045b9b..17e918d 100644
--- a/patrole_tempest_plugin/tests/api/identity/v3/test_ep_filter_projects_rbac.py
+++ b/patrole_tempest_plugin/tests/api/identity/v3/test_ep_filter_projects_rbac.py
@@ -44,7 +44,7 @@
@rbac_rule_validation.action(
service="keystone",
- rule="identity:add_endpoint_to_project")
+ rules=["identity:add_endpoint_to_project"])
@decorators.idempotent_id('9199ec13-816d-4efe-b8b1-e1cd026b9747')
def test_add_endpoint_to_project(self):
# Adding endpoints to projects
@@ -53,7 +53,7 @@
@rbac_rule_validation.action(
service="keystone",
- rule="identity:list_projects_for_endpoint")
+ rules=["identity:list_projects_for_endpoint"])
@decorators.idempotent_id('f53dca42-ec8a-48e9-924b-0bbe6c99727f')
def test_list_projects_for_endpoint(self):
with self.rbac_utils.override_role(self):
@@ -62,7 +62,7 @@
@rbac_rule_validation.action(
service="keystone",
- rule="identity:check_endpoint_in_project")
+ rules=["identity:check_endpoint_in_project"])
@decorators.idempotent_id('0c1425eb-833c-4aa1-a21d-52ffa41fdc6a')
def test_check_endpoint_in_project(self):
self._add_endpoint_to_project()
@@ -72,7 +72,7 @@
@rbac_rule_validation.action(
service="keystone",
- rule="identity:list_endpoints_for_project")
+ rules=["identity:list_endpoints_for_project"])
@decorators.idempotent_id('5d86c659-c6ad-41e0-854e-3823e95c7cc2')
def test_list_endpoints_in_project(self):
with self.rbac_utils.override_role(self):
@@ -81,7 +81,7 @@
@rbac_rule_validation.action(
service="keystone",
- rule="identity:remove_endpoint_from_project")
+ rules=["identity:remove_endpoint_from_project"])
@decorators.idempotent_id('b4e21c10-4f47-427b-9b8a-f5b5601adfda')
def test_remove_endpoint_from_project(self):
self._add_endpoint_to_project(ignore_not_found=True)
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 06148d9..9814e3b 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
@@ -30,14 +30,14 @@
return (group['id'], user['id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:create_group")
+ rules=["identity:create_group"])
@decorators.idempotent_id('88377f51-9074-4d64-a22f-f8931d048c9a')
def test_create_group(self):
with self.rbac_utils.override_role(self):
self.setup_test_group()
@rbac_rule_validation.action(service="keystone",
- rule="identity:update_group")
+ rules=["identity:update_group"])
@decorators.idempotent_id('790fb7be-a657-4a64-9b83-c43425cf180b')
def test_update_group(self):
group = self.setup_test_group()
@@ -48,7 +48,7 @@
self.groups_client.update_group(group['id'], name=new_group_name)
@rbac_rule_validation.action(service="keystone",
- rule="identity:delete_group")
+ rules=["identity:delete_group"])
@decorators.idempotent_id('646b52da-2a5f-486a-afb0-51fdc86a6c12')
def test_delete_group(self):
group = self.setup_test_group()
@@ -57,7 +57,7 @@
self.groups_client.delete_group(group['id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:get_group")
+ rules=["identity:get_group"])
@decorators.idempotent_id('d530f0ad-42b9-429b-ad05-e53ac95a040e')
def test_show_group(self):
group = self.setup_test_group()
@@ -66,14 +66,14 @@
self.groups_client.show_group(group['id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:list_groups")
+ rules=["identity:list_groups"])
@decorators.idempotent_id('c4d0f76b-735f-4fd0-868b-0006bc420ff4')
def test_list_groups(self):
with self.rbac_utils.override_role(self):
self.groups_client.list_groups()
@rbac_rule_validation.action(service="keystone",
- rule="identity:add_user_to_group")
+ rules=["identity:add_user_to_group"])
@decorators.idempotent_id('fdd49b74-3ed3-4736-9f0e-9027a32017ac')
def test_add_user_group(self):
group = self.setup_test_group()
@@ -83,7 +83,7 @@
self.groups_client.add_group_user(group['id'], user['id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:remove_user_from_group")
+ rules=["identity:remove_user_from_group"])
@decorators.idempotent_id('8a60d11c-7d2b-47e5-a0f3-9ea900ca66fe')
def test_remove_user_group(self):
group_id, user_id = self._create_user_and_add_to_new_group()
@@ -92,7 +92,7 @@
self.groups_client.delete_group_user(group_id, user_id)
@rbac_rule_validation.action(service="keystone",
- rule="identity:list_users_in_group")
+ rules=["identity:list_users_in_group"])
@decorators.idempotent_id('b3e394a7-079e-4a0d-a4ff-9b266293d1ee')
def test_list_user_group(self):
group = self.setup_test_group()
@@ -101,7 +101,7 @@
self.groups_client.list_group_users(group['id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:check_user_in_group")
+ rules=["identity:check_user_in_group"])
@decorators.idempotent_id('d3603241-fd87-4a2d-94f9-f32469d1aaba')
def test_check_user_group(self):
group_id, user_id = self._create_user_and_add_to_new_group()
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 f591e15..ecd534d 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
@@ -34,14 +34,14 @@
return consumer
@rbac_rule_validation.action(service="keystone",
- rule="identity:create_consumer")
+ rules=["identity:create_consumer"])
@decorators.idempotent_id('0f148510-63bf-11e6-4522-080044d0d970')
def test_create_consumer(self):
with self.rbac_utils.override_role(self):
self._create_consumer()
@rbac_rule_validation.action(service="keystone",
- rule="identity:delete_consumer")
+ rules=["identity:delete_consumer"])
@decorators.idempotent_id('0f148510-63bf-11e6-4522-080044d0d971')
def test_delete_consumer(self):
consumer = self._create_consumer()
@@ -50,7 +50,7 @@
self.consumers_client.delete_consumer(consumer['id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:update_consumer")
+ rules=["identity:update_consumer"])
@decorators.idempotent_id('0f148510-63bf-11e6-4522-080044d0d972')
def test_update_consumer(self):
consumer = self._create_consumer()
@@ -62,7 +62,7 @@
updated_description)
@rbac_rule_validation.action(service="keystone",
- rule="identity:get_consumer")
+ rules=["identity:get_consumer"])
@decorators.idempotent_id('0f148510-63bf-11e6-4522-080044d0d973')
def test_show_consumer(self):
consumer = self._create_consumer()
@@ -71,7 +71,7 @@
self.consumers_client.show_consumer(consumer['id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:list_consumers")
+ rules=["identity:list_consumers"])
@decorators.idempotent_id('0f148510-63bf-11e6-4522-080044d0d975')
def test_list_consumers(self):
with self.rbac_utils.override_role(self):
diff --git a/patrole_tempest_plugin/tests/api/identity/v3/test_oauth_tokens_rbac.py b/patrole_tempest_plugin/tests/api/identity/v3/test_oauth_tokens_rbac.py
index 13731d5..30b386f 100644
--- a/patrole_tempest_plugin/tests/api/identity/v3/test_oauth_tokens_rbac.py
+++ b/patrole_tempest_plugin/tests/api/identity/v3/test_oauth_tokens_rbac.py
@@ -80,7 +80,7 @@
return access_key
@rbac_rule_validation.action(service="keystone",
- rule="identity:authorize_request_token")
+ rules=["identity:authorize_request_token"])
@decorators.idempotent_id('0f148510-63bf-11e6-4522-080044d0d976')
def test_authorize_request_token(self):
_, request_token = self._create_consumer_and_request_token()
@@ -91,7 +91,7 @@
self.role_ids)
@rbac_rule_validation.action(service="keystone",
- rule="identity:get_access_token")
+ rules=["identity:get_access_token"])
@decorators.idempotent_id('0f148510-63bf-11e6-4522-080044d0d977')
def test_get_access_token(self):
access_token = self._create_access_token()
@@ -101,7 +101,7 @@
access_token)
@rbac_rule_validation.action(service="keystone",
- rule="identity:get_access_token_role")
+ rules=["identity:get_access_token_role"])
@decorators.idempotent_id('0f148510-63bf-11e6-4522-080044d0d980')
def test_get_access_token_role(self):
access_token = self._create_access_token()
@@ -111,14 +111,14 @@
self.user_id, access_token, self.role_ids[0])
@rbac_rule_validation.action(service="keystone",
- rule="identity:list_access_tokens")
+ rules=["identity:list_access_tokens"])
@decorators.idempotent_id('0f148510-63bf-11e6-4522-080044d0d979')
def test_list_access_tokens(self):
with self.rbac_utils.override_role(self):
self.oauth_token_client.list_access_tokens(self.user_id)
@rbac_rule_validation.action(service="keystone",
- rule="identity:list_access_token_roles")
+ rules=["identity:list_access_token_roles"])
@decorators.idempotent_id('0f148510-63bf-11e6-4522-080044d0d978')
def test_list_access_token_roles(self):
access_token = self._create_access_token()
@@ -128,7 +128,7 @@
self.user_id, access_token)
@rbac_rule_validation.action(service="keystone",
- rule="identity:delete_access_token")
+ rules=["identity:delete_access_token"])
@decorators.idempotent_id('0f148510-63bf-11e6-4522-080044d0d981')
def test_revoke_access_token(self):
access_token = self._create_access_token()
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 a8c10ca..b0a3087 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
@@ -23,14 +23,14 @@
class IdentityPoliciesV3RbacTest(rbac_base.BaseIdentityV3RbacTest):
@rbac_rule_validation.action(service="keystone",
- rule="identity:create_policy")
+ rules=["identity:create_policy"])
@decorators.idempotent_id('de2f7ecb-fbf0-41f3-abf4-b97b5e082fd5')
def test_create_policy(self):
with self.rbac_utils.override_role(self):
self.setup_test_policy()
@rbac_rule_validation.action(service="keystone",
- rule="identity:update_policy")
+ rules=["identity:update_policy"])
@decorators.idempotent_id('9cfed3c6-0b27-4d15-be67-e06e0cfb01b9')
def test_update_policy(self):
policy = self.setup_test_policy()
@@ -42,7 +42,7 @@
type=updated_policy_type)
@rbac_rule_validation.action(service="keystone",
- rule="identity:delete_policy")
+ rules=["identity:delete_policy"])
@decorators.idempotent_id('dcd93f75-1e1b-4fbe-bee0-9c4c7b201735')
def test_delete_policy(self):
policy = self.setup_test_policy()
@@ -51,7 +51,7 @@
self.policies_client.delete_policy(policy['id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:get_policy")
+ rules=["identity:get_policy"])
@decorators.idempotent_id('d7e415c2-945a-4504-9571-0e2d0dd8594b')
def test_show_policy(self):
policy = self.setup_test_policy()
@@ -60,7 +60,7 @@
self.policies_client.show_policy(policy['id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:list_policies")
+ rules=["identity:list_policies"])
@decorators.idempotent_id('35a56161-4054-4237-8a78-7ce805dce202')
def test_list_policies(self):
with self.rbac_utils.override_role(self):
diff --git a/patrole_tempest_plugin/tests/api/identity/v3/test_policy_association_rbac.py b/patrole_tempest_plugin/tests/api/identity/v3/test_policy_association_rbac.py
index 2a69224..f56b6e4 100644
--- a/patrole_tempest_plugin/tests/api/identity/v3/test_policy_association_rbac.py
+++ b/patrole_tempest_plugin/tests/api/identity/v3/test_policy_association_rbac.py
@@ -58,7 +58,7 @@
@rbac_rule_validation.action(
service="keystone",
- rule="identity:create_policy_association_for_endpoint")
+ rules=["identity:create_policy_association_for_endpoint"])
@decorators.idempotent_id('1b3f4f62-4f4a-4d27-be27-9a113058597f')
def test_update_policy_association_for_endpoint(self):
with self.rbac_utils.override_role(self):
@@ -67,7 +67,7 @@
@rbac_rule_validation.action(
service="keystone",
- rule="identity:check_policy_association_for_endpoint")
+ rules=["identity:check_policy_association_for_endpoint"])
@decorators.idempotent_id('25ce8c89-e751-465c-8d35-52bacd774beb')
def test_show_policy_association_for_endpoint(self):
self._update_policy_association_for_endpoint(
@@ -78,7 +78,7 @@
@rbac_rule_validation.action(
service="keystone",
- rule="identity:delete_policy_association_for_endpoint")
+ rules=["identity:delete_policy_association_for_endpoint"])
@decorators.idempotent_id('95cad2d8-bcd0-4c4e-a8f7-cc80601e43a1')
def test_delete_policy_association_for_endpoint(self):
self._update_policy_association_for_endpoint(
@@ -89,7 +89,7 @@
@rbac_rule_validation.action(
service="keystone",
- rule="identity:create_policy_association_for_service")
+ rules=["identity:create_policy_association_for_service"])
@decorators.idempotent_id('57fb80fe-6ce2-4995-b710-4692b3fc3cdc')
def test_update_policy_association_for_service(self):
with self.rbac_utils.override_role(self):
@@ -98,7 +98,7 @@
@rbac_rule_validation.action(
service="keystone",
- rule="identity:check_policy_association_for_service")
+ rules=["identity:check_policy_association_for_service"])
@decorators.idempotent_id('5cbe285f-4888-4f98-978f-30210ff28b74')
def test_show_policy_association_for_service(self):
self._update_policy_association_for_service(
@@ -109,7 +109,7 @@
@rbac_rule_validation.action(
service="keystone",
- rule="identity:delete_policy_association_for_service")
+ rules=["identity:delete_policy_association_for_service"])
@decorators.idempotent_id('f754455c-02a4-4fb6-8c73-64ef453f955f')
def test_delete_policy_association_for_service(self):
self._update_policy_association_for_service(
@@ -120,7 +120,7 @@
@rbac_rule_validation.action(
service="keystone",
- rule="identity:create_policy_association_for_region_and_service")
+ rules=["identity:create_policy_association_for_region_and_service"])
@decorators.idempotent_id('54d2a93e-c84d-4079-8ea9-2fb227c262a1')
def test_update_policy_association_for_region_and_service(self):
with self.rbac_utils.override_role(self):
@@ -129,7 +129,7 @@
@rbac_rule_validation.action(
service="keystone",
- rule="identity:check_policy_association_for_region_and_service")
+ rules=["identity:check_policy_association_for_region_and_service"])
@decorators.idempotent_id('0763b780-52c1-47bc-9316-1fe12a2ab0bc')
def test_show_policy_association_for_region_and_service(self):
self._update_policy_association_for_region_and_service(
@@ -141,7 +141,7 @@
@rbac_rule_validation.action(
service="keystone",
- rule="identity:delete_policy_association_for_region_and_service")
+ rules=["identity:delete_policy_association_for_region_and_service"])
@decorators.idempotent_id('9c956888-81d4-4a24-8203-bff7b8a7834c')
def test_delete_policy_association_for_region_and_service(self):
self._update_policy_association_for_region_and_service(
diff --git a/patrole_tempest_plugin/tests/api/identity/v3/test_project_tags_rbac.py b/patrole_tempest_plugin/tests/api/identity/v3/test_project_tags_rbac.py
index e0be9cb..debc2e9 100644
--- a/patrole_tempest_plugin/tests/api/identity/v3/test_project_tags_rbac.py
+++ b/patrole_tempest_plugin/tests/api/identity/v3/test_project_tags_rbac.py
@@ -42,7 +42,7 @@
@decorators.idempotent_id('acbd7b2d-0a4d-4990-9fab-eccad69d4238')
@rbac_rule_validation.action(service="keystone",
- rule="identity:create_project_tag")
+ rules=["identity:create_project_tag"])
def test_update_project_tag(self):
tag = data_utils.rand_name(self.__class__.__name__ + '-Tag')
with self.rbac_utils.override_role(self):
@@ -50,14 +50,14 @@
@decorators.idempotent_id('e122d7d1-bb6d-43af-b489-afa8c609b9ae')
@rbac_rule_validation.action(service="keystone",
- rule="identity:list_project_tags")
+ rules=["identity:list_project_tags"])
def test_list_project_tags(self):
with self.rbac_utils.override_role(self):
self.project_tags_client.list_project_tags(self.project_id)
@decorators.idempotent_id('716f9081-4626-4594-a82c-e7dc037464ac')
@rbac_rule_validation.action(service="keystone",
- rule="identity:update_project_tags")
+ rules=["identity:update_project_tags"])
def test_update_all_project_tags(self):
tags = [
data_utils.rand_name(self.__class__.__name__ + '-Tag')
@@ -69,7 +69,7 @@
@decorators.idempotent_id('974cb1da-d7d4-4863-99da-4a3f0c801729')
@rbac_rule_validation.action(service="keystone",
- rule="identity:get_project_tag")
+ rules=["identity:get_project_tag"])
def test_check_project_tag_existence(self):
tag = data_utils.rand_name(self.__class__.__name__ + '-Tag')
self.project_tags_client.update_project_tag(self.project_id, tag)
@@ -80,7 +80,7 @@
@decorators.idempotent_id('ffe0c8e1-f9eb-43c5-8097-1e938fc08e07')
@rbac_rule_validation.action(service="keystone",
- rule="identity:delete_project_tag")
+ rules=["identity:delete_project_tag"])
def test_delete_project_tag(self):
tag = data_utils.rand_name(self.__class__.__name__ + '-Tag')
self.project_tags_client.update_project_tag(self.project_id, tag)
@@ -90,7 +90,7 @@
@decorators.idempotent_id('94d0ef63-e9e3-4287-9c5e-bd5464467d77')
@rbac_rule_validation.action(service="keystone",
- rule="identity:delete_project_tags")
+ rules=["identity:delete_project_tags"])
def test_delete_all_project_tags(self):
with self.rbac_utils.override_role(self):
self.project_tags_client.delete_all_project_tags(self.project_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 0b394b4..e1e6f08 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
@@ -23,14 +23,14 @@
class IdentityProjectV3RbacTest(rbac_base.BaseIdentityV3RbacTest):
@rbac_rule_validation.action(service="keystone",
- rule="identity:create_project")
+ rules=["identity:create_project"])
@decorators.idempotent_id('0f148510-63bf-11e6-1564-080044d0d904')
def test_create_project(self):
with self.rbac_utils.override_role(self):
self.setup_test_project()
@rbac_rule_validation.action(service="keystone",
- rule="identity:update_project")
+ rules=["identity:update_project"])
@decorators.idempotent_id('0f148510-63bf-11e6-1564-080044d0d905')
def test_update_project(self):
project = self.setup_test_project()
@@ -42,7 +42,7 @@
description=new_desc)
@rbac_rule_validation.action(service="keystone",
- rule="identity:delete_project")
+ rules=["identity:delete_project"])
@decorators.idempotent_id('0f148510-63bf-11e6-1564-080044d0d906')
def test_delete_project(self):
project = self.setup_test_project()
@@ -51,7 +51,7 @@
self.projects_client.delete_project(project['id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:get_project")
+ rules=["identity:get_project"])
@decorators.idempotent_id('0f148510-63bf-11e6-1564-080044d0d907')
def test_show_project(self):
project = self.setup_test_project()
@@ -60,7 +60,7 @@
self.projects_client.show_project(project['id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:list_projects")
+ rules=["identity:list_projects"])
@decorators.idempotent_id('0f148510-63bf-11e6-1564-080044d0d908')
def test_list_projects(self):
with self.rbac_utils.override_role(self):
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 14b9de5..1d81319 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
@@ -23,14 +23,14 @@
class IdentityRegionsV3RbacTest(rbac_base.BaseIdentityV3RbacTest):
@rbac_rule_validation.action(service="keystone",
- rule="identity:create_region")
+ rules=["identity:create_region"])
@decorators.idempotent_id('6bdaecd4-0843-4ed6-ab64-3a57ab0cd119')
def test_create_region(self):
with self.rbac_utils.override_role(self):
self.setup_test_region()
@rbac_rule_validation.action(service="keystone",
- rule="identity:update_region")
+ rules=["identity:update_region"])
@decorators.idempotent_id('6bdaecd4-0843-4ed6-ab64-3a57ab0cd120')
def test_update_region(self):
region = self.setup_test_region()
@@ -42,7 +42,7 @@
description=new_description)
@rbac_rule_validation.action(service="keystone",
- rule="identity:delete_region")
+ rules=["identity:delete_region"])
@decorators.idempotent_id('6bdaecd4-0843-4ed6-ab64-3a57ab0cd121')
def test_delete_region(self):
region = self.setup_test_region()
@@ -51,7 +51,7 @@
self.regions_client.delete_region(region['id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:get_region")
+ rules=["identity:get_region"])
@decorators.idempotent_id('6bdaecd4-0843-4ed6-ab64-3a57ab0cd122')
def test_show_region(self):
region = self.setup_test_region()
@@ -60,7 +60,7 @@
self.regions_client.show_region(region['id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:list_regions")
+ rules=["identity:list_regions"])
@decorators.idempotent_id('6bdaecd4-0843-4ed6-ab64-3a57ab0cd123')
def test_list_regions(self):
with self.rbac_utils.override_role(self):
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 90cf255..3eabac8 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
@@ -23,7 +23,7 @@
@decorators.idempotent_id('afe57adb-1b9c-43d9-84a9-f0cf4c94e416')
@rbac_rule_validation.action(service="keystone",
- rule="identity:list_role_assignments")
+ rules=["identity:list_role_assignments"])
def test_list_role_assignments(self):
with self.rbac_utils.override_role(self):
self.role_assignments_client.list_role_assignments()
@@ -31,7 +31,7 @@
@decorators.idempotent_id('36c7a990-857e-415c-8717-38d7200a9894')
@rbac_rule_validation.action(
service="keystone",
- rule="identity:list_role_assignments_for_tree")
+ rules=["identity:list_role_assignments_for_tree"])
def test_list_role_assignments_for_tree(self):
project = self.setup_test_project()
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 099c702..8242194 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
@@ -34,14 +34,14 @@
cls.user = cls.setup_test_user()
@rbac_rule_validation.action(service="keystone",
- rule="identity:create_role")
+ rules=["identity:create_role"])
@decorators.idempotent_id('0f148510-63bf-11e6-1395-080044d0d904')
def test_create_role(self):
with self.rbac_utils.override_role(self):
self.setup_test_role()
@rbac_rule_validation.action(service="keystone",
- rule="identity:update_role")
+ rules=["identity:update_role"])
@decorators.idempotent_id('0f148510-63bf-11e6-1395-080044d0d905')
def test_update_role(self):
new_role_name = data_utils.rand_name(
@@ -52,7 +52,7 @@
name=new_role_name)
@rbac_rule_validation.action(service="keystone",
- rule="identity:delete_role")
+ rules=["identity:delete_role"])
@decorators.idempotent_id('0f148510-63bf-11e6-1395-080044d0d906')
def test_delete_role(self):
role = self.setup_test_role()
@@ -61,21 +61,21 @@
self.roles_client.delete_role(role['id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:get_role")
+ rules=["identity:get_role"])
@decorators.idempotent_id('0f148510-63bf-11e6-1395-080044d0d907')
def test_show_role(self):
with self.rbac_utils.override_role(self):
self.roles_client.show_role(self.role['id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:list_roles")
+ rules=["identity:list_roles"])
@decorators.idempotent_id('0f148510-63bf-11e6-1395-080044d0d908')
def test_list_roles(self):
with self.rbac_utils.override_role(self):
self.roles_client.list_roles()
@rbac_rule_validation.action(service="keystone",
- rule="identity:create_grant")
+ rules=["identity:create_grant"])
@decorators.idempotent_id('0f148510-63bf-11e6-1395-080044d0d909')
def test_create_user_role_on_project(self):
with self.rbac_utils.override_role(self):
@@ -90,7 +90,7 @@
self.role['id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:create_grant")
+ rules=["identity:create_grant"])
@decorators.idempotent_id('0f148510-63bf-11e6-1395-080044d0d90c')
def test_create_group_role_on_project(self):
with self.rbac_utils.override_role(self):
@@ -105,7 +105,7 @@
self.role['id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:create_grant")
+ rules=["identity:create_grant"])
@decorators.idempotent_id('0f148510-63bf-11e6-1395-080044d0d90f')
def test_create_user_role_on_domain(self):
with self.rbac_utils.override_role(self):
@@ -120,7 +120,7 @@
self.role['id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:create_grant")
+ rules=["identity:create_grant"])
@decorators.idempotent_id('0f148510-63bf-11e6-1395-080044d0d912')
def test_create_group_role_on_domain(self):
with self.rbac_utils.override_role(self):
@@ -135,7 +135,7 @@
self.role['id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:check_grant")
+ rules=["identity:check_grant"])
@decorators.idempotent_id('22921b1e-1a33-4026-bff9-f236d6dd149c')
def test_check_user_role_existence_on_project(self):
self.roles_client.create_user_role_on_project(
@@ -156,7 +156,7 @@
@decorators.idempotent_id('92f8e67d-85bf-407d-9814-edd5664abc47')
@rbac_rule_validation.action(service="keystone",
- rule="identity:check_grant")
+ rules=["identity:check_grant"])
def test_check_user_role_existence_on_domain(self):
self.roles_client.create_user_role_on_domain(
self.domain['id'],
@@ -176,7 +176,7 @@
@decorators.idempotent_id('8738d3d2-8c84-4423-b36c-7c59eaa08b73')
@rbac_rule_validation.action(service="keystone",
- rule="identity:check_grant")
+ rules=["identity:check_grant"])
def test_check_role_from_group_on_project_existence(self):
self.roles_client.create_group_role_on_project(
self.project['id'],
@@ -196,7 +196,7 @@
@decorators.idempotent_id('e7d73bd0-cf5e-4c0c-9c93-cf53e23232d6')
@rbac_rule_validation.action(service="keystone",
- rule="identity:check_grant")
+ rules=["identity:check_grant"])
def test_check_role_from_group_on_domain_existence(self):
self.roles_client.create_group_role_on_domain(
self.domain['id'],
@@ -215,7 +215,7 @@
self.role['id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:revoke_grant")
+ rules=["identity:revoke_grant"])
@decorators.idempotent_id('0f148510-63bf-11e6-1395-080044d0d90a')
def test_delete_role_from_user_on_project(self):
self.roles_client.create_user_role_on_project(
@@ -235,7 +235,7 @@
self.role['id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:revoke_grant")
+ rules=["identity:revoke_grant"])
@decorators.idempotent_id('0f148510-63bf-11e6-1395-080044d0d90d')
def test_delete_role_from_group_on_project(self):
self.roles_client.create_group_role_on_project(
@@ -255,7 +255,7 @@
self.role['id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:revoke_grant")
+ rules=["identity:revoke_grant"])
@decorators.idempotent_id('0f148510-63bf-11e6-1395-080044d0d910')
def test_delete_role_from_user_on_domain(self):
self.roles_client.create_user_role_on_domain(
@@ -275,7 +275,7 @@
self.role['id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:revoke_grant")
+ rules=["identity:revoke_grant"])
@decorators.idempotent_id('0f148510-63bf-11e6-1395-080044d0d913')
def test_delete_role_from_group_on_domain(self):
self.roles_client.create_group_role_on_domain(
@@ -295,7 +295,7 @@
self.role['id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:list_grants")
+ rules=["identity:list_grants"])
@decorators.idempotent_id('0f148510-63bf-11e6-1395-080044d0d90b')
def test_list_user_roles_on_project(self):
with self.rbac_utils.override_role(self):
@@ -304,7 +304,7 @@
self.user['id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:list_grants")
+ rules=["identity:list_grants"])
@decorators.idempotent_id('0f148510-63bf-11e6-1395-080044d0d90e')
def test_list_group_roles_on_project(self):
with self.rbac_utils.override_role(self):
@@ -313,7 +313,7 @@
self.group['id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:list_grants")
+ rules=["identity:list_grants"])
@decorators.idempotent_id('0f148510-63bf-11e6-1395-080044d0d911')
def test_list_user_roles_on_domain(self):
with self.rbac_utils.override_role(self):
@@ -322,7 +322,7 @@
self.user['id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:list_grants")
+ rules=["identity:list_grants"])
@decorators.idempotent_id('0f148510-63bf-11e6-1395-080044d0d914')
def test_list_group_roles_on_domain(self):
with self.rbac_utils.override_role(self):
@@ -332,7 +332,7 @@
@decorators.idempotent_id('2aef3eaa-8156-4962-a01d-c9bb0e499e15')
@rbac_rule_validation.action(service="keystone",
- rule="identity:create_implied_role")
+ rules=["identity:create_implied_role"])
def test_create_role_inference_rule(self):
with self.rbac_utils.override_role(self):
self.roles_client.create_role_inference_rule(
@@ -342,7 +342,7 @@
@decorators.idempotent_id('83f997b2-55c4-4894-b1f2-e175b19d1fa5')
@rbac_rule_validation.action(service="keystone",
- rule="identity:get_implied_role")
+ rules=["identity:get_implied_role"])
def test_show_role_inference_rule(self):
self.roles_client.create_role_inference_rule(
self.role['id'], self.implies_role['id'])
@@ -355,14 +355,14 @@
@decorators.idempotent_id('f7bb39bf-0b06-468e-a8b0-60a4fb1f258d')
@rbac_rule_validation.action(service="keystone",
- rule="identity:list_implied_roles")
+ rules=["identity:list_implied_roles"])
def test_list_role_inferences_rules(self):
with self.rbac_utils.override_role(self):
self.roles_client.list_role_inferences_rules(self.role['id'])
@decorators.idempotent_id('eca2d502-09bb-45cd-9773-bce2e7bcddd1')
@rbac_rule_validation.action(service="keystone",
- rule="identity:check_implied_role")
+ rules=["identity:check_implied_role"])
def test_check_role_inference_rule(self):
self.roles_client.create_role_inference_rule(
self.role['id'], self.implies_role['id'])
@@ -375,7 +375,7 @@
@decorators.idempotent_id('13a5db1e-dd4a-4ca1-81ec-d5452aaaf54b')
@rbac_rule_validation.action(service="keystone",
- rule="identity:delete_implied_role")
+ rules=["identity:delete_implied_role"])
def test_delete_role_inference_rule(self):
self.roles_client.create_role_inference_rule(
self.role['id'], self.implies_role['id'])
@@ -389,7 +389,7 @@
@decorators.idempotent_id('05869f2b-4dd4-425a-905e-eec9a6f06374')
@rbac_rule_validation.action(service="keystone",
- rule="identity:list_role_inference_rules")
+ rules=["identity:list_role_inference_rules"])
def test_list_all_role_inference_rules(self):
with self.rbac_utils.override_role(self):
self.roles_client.list_all_role_inference_rules()
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 6ab17ff..41ba5ba 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
@@ -23,14 +23,14 @@
class IdentitySericesV3RbacTest(rbac_base.BaseIdentityV3RbacTest):
@rbac_rule_validation.action(service="keystone",
- rule="identity:create_service")
+ rules=["identity:create_service"])
@decorators.idempotent_id('9a4bb317-f0bb-4005-8df0-4b672885b7c8')
def test_create_service(self):
with self.rbac_utils.override_role(self):
self.setup_test_service()
@rbac_rule_validation.action(service="keystone",
- rule="identity:update_service")
+ rules=["identity:update_service"])
@decorators.idempotent_id('b39447d1-2cf6-40e5-a899-46f287f2ecf0')
def test_update_service(self):
service = self.setup_test_service()
@@ -43,7 +43,7 @@
type=service['type'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:delete_service")
+ rules=["identity:delete_service"])
@decorators.idempotent_id('177b991a-438d-4bef-8e9f-9c6cc5a1c9e8')
def test_delete_service(self):
service = self.setup_test_service()
@@ -52,7 +52,7 @@
self.services_client.delete_service(service['id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:get_service")
+ rules=["identity:get_service"])
@decorators.idempotent_id('d89a9ac6-cd53-428d-84c0-5bc71f4a432d')
def test_show_service(self):
service = self.setup_test_service()
@@ -61,7 +61,7 @@
self.services_client.show_service(service['id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:list_services")
+ rules=["identity:list_services"])
@decorators.idempotent_id('706e6bea-3385-4718-919c-0b5121395806')
def test_list_services(self):
with self.rbac_utils.override_role(self):
diff --git a/patrole_tempest_plugin/tests/api/identity/v3/test_tokens_negative_rbac.py b/patrole_tempest_plugin/tests/api/identity/v3/test_tokens_negative_rbac.py
index 00d522c..c1c2934 100644
--- a/patrole_tempest_plugin/tests/api/identity/v3/test_tokens_negative_rbac.py
+++ b/patrole_tempest_plugin/tests/api/identity/v3/test_tokens_negative_rbac.py
@@ -13,7 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-from tempest import config
from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
@@ -21,8 +20,6 @@
from patrole_tempest_plugin import rbac_utils
from patrole_tempest_plugin.tests.api.identity import rbac_base
-CONF = config.CONF
-
class IdentityTokenV3RbacTest(rbac_base.BaseIdentityV3RbacTest):
@@ -46,7 +43,7 @@
@decorators.attr(type=['negative'])
@rbac_rule_validation.action(
service="keystone",
- rule="identity:validate_token",
+ rules=["identity:validate_token"],
extra_target_data={
"target.token.user_id":
"os_alt.auth_provider.credentials.user_id"
@@ -65,7 +62,7 @@
@decorators.attr(type=['negative'])
@rbac_rule_validation.action(
service="keystone",
- rule="identity:revoke_token",
+ rules=["identity:revoke_token"],
extra_target_data={
"target.token.user_id":
"os_alt.auth_provider.credentials.user_id"
@@ -84,7 +81,7 @@
@decorators.attr(type=['negative'])
@rbac_rule_validation.action(
service="keystone",
- rule="identity:check_token",
+ rules=["identity:check_token"],
extra_target_data={
"target.token.user_id":
"os_alt.auth_provider.credentials.user_id"
diff --git a/patrole_tempest_plugin/tests/api/identity/v3/test_tokens_rbac.py b/patrole_tempest_plugin/tests/api/identity/v3/test_tokens_rbac.py
index 23ee768..a648774 100644
--- a/patrole_tempest_plugin/tests/api/identity/v3/test_tokens_rbac.py
+++ b/patrole_tempest_plugin/tests/api/identity/v3/test_tokens_rbac.py
@@ -30,7 +30,7 @@
@decorators.idempotent_id('201e2fe5-2023-4bce-9189-78b51520a91e')
@rbac_rule_validation.action(
service="keystone",
- rule="identity:validate_token",
+ rules=["identity:validate_token"],
extra_target_data={
"target.token.user_id":
"os_primary.auth_provider.credentials.user_id"
@@ -43,7 +43,7 @@
@decorators.idempotent_id('42a299db-fe0a-4ea0-9824-0bfd13155886')
@rbac_rule_validation.action(
service="keystone",
- rule="identity:revoke_token",
+ rules=["identity:revoke_token"],
extra_target_data={
"target.token.user_id":
"os_primary.auth_provider.credentials.user_id"
@@ -56,7 +56,7 @@
@decorators.idempotent_id('3554d218-8cd6-4730-a1b2-0e22f9b78f45')
@rbac_rule_validation.action(
service="keystone",
- rule="identity:check_token",
+ rules=["identity:check_token"],
extra_target_data={
"target.token.user_id":
"os_primary.auth_provider.credentials.user_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 91dbb53..985b992 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
@@ -65,7 +65,7 @@
@decorators.idempotent_id('7ab595a7-9b71-45fe-91d8-2793b0292f72')
@rbac_rule_validation.action(
service="keystone",
- rule="identity:create_trust",
+ rules=["identity:create_trust"],
extra_target_data={
"trust.trustor_user_id": "os_primary.credentials.user_id"
})
@@ -78,7 +78,7 @@
@decorators.attr(type=['negative'])
@rbac_rule_validation.action(
service="keystone",
- rule="identity:create_trust",
+ rules=["identity:create_trust"],
extra_target_data={
"trust.trustor_user_id": "os_alt.credentials.user_id"
})
@@ -94,7 +94,7 @@
@decorators.idempotent_id('d9a6fd06-08f6-462c-a86c-ce009adf1230')
@rbac_rule_validation.action(
service="keystone",
- rule="identity:delete_trust")
+ rules=["identity:delete_trust"])
def test_delete_trust(self):
trust = self.setup_test_trust(trustor_user_id=self.trustor_user_id,
trustee_user_id=self.trustee_user_id)
@@ -105,7 +105,7 @@
@decorators.idempotent_id('f2e32896-bf66-4f4e-89cf-e7fba0ef1f38')
@rbac_rule_validation.action(
service="keystone",
- rule="identity:list_trusts")
+ rules=["identity:list_trusts"])
def test_list_trusts(self):
with self.rbac_utils.override_role(self):
self.trusts_client.list_trusts(
@@ -114,7 +114,7 @@
@decorators.idempotent_id('3c9ff92f-a73e-4f9b-8865-e017f38c70f5')
@rbac_rule_validation.action(
service="keystone",
- rule="identity:list_roles_for_trust")
+ rules=["identity:list_roles_for_trust"])
def test_list_roles_for_trust(self):
with self.rbac_utils.override_role(self):
self.trusts_client.list_trust_roles(self.trust['id'])
@@ -122,7 +122,7 @@
@decorators.idempotent_id('3bb4f97b-cecd-4c7d-ad10-b88ee6c5d573')
@rbac_rule_validation.action(
service="keystone",
- rule="identity:get_role_for_trust")
+ rules=["identity:get_role_for_trust"])
def test_show_trust_role(self):
with self.rbac_utils.override_role(self):
self.trusts_client.show_trust_role(
@@ -131,7 +131,7 @@
@decorators.idempotent_id('0184e0fb-641e-4b52-ab73-81c1ce6ca5c1')
@rbac_rule_validation.action(
service="keystone",
- rule="identity:get_trust")
+ rules=["identity:get_trust"])
def test_show_trust(self):
with self.rbac_utils.override_role(self):
self.trusts_client.show_trust(self.trust['id'])
diff --git a/patrole_tempest_plugin/tests/api/identity/v3/test_users_rbac.py b/patrole_tempest_plugin/tests/api/identity/v3/test_users_rbac.py
index bd97535..c633bb8 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
@@ -28,14 +28,14 @@
cls.default_user_id = cls.os_primary.credentials.user_id
@rbac_rule_validation.action(service="keystone",
- rule="identity:create_user")
+ rules=["identity:create_user"])
@decorators.idempotent_id('0f148510-63bf-11e6-4522-080044d0d904')
def test_create_user(self):
with self.rbac_utils.override_role(self):
self.setup_test_user()
@rbac_rule_validation.action(service="keystone",
- rule="identity:update_user")
+ rules=["identity:update_user"])
@decorators.idempotent_id('0f148510-63bf-11e6-4522-080044d0d905')
def test_update_user(self):
user = self.setup_test_user()
@@ -48,7 +48,7 @@
email=new_email)
@rbac_rule_validation.action(service="keystone",
- rule="identity:delete_user")
+ rules=["identity:delete_user"])
@decorators.idempotent_id('0f148510-63bf-11e6-4522-080044d0d906')
def test_delete_user(self):
user = self.setup_test_user()
@@ -57,28 +57,28 @@
self.users_client.delete_user(user['id'])
@rbac_rule_validation.action(service="keystone",
- rule="identity:list_users")
+ rules=["identity:list_users"])
@decorators.idempotent_id('0f148510-63bf-11e6-4522-080044d0d907')
def test_list_users(self):
with self.rbac_utils.override_role(self):
self.users_client.list_users()
@rbac_rule_validation.action(service="keystone",
- rule="identity:get_user")
+ rules=["identity:get_user"])
@decorators.idempotent_id('0f148510-63bf-11e6-4522-080044d0d908')
def test_show_own_user(self):
with self.rbac_utils.override_role(self):
self.users_client.show_user(self.default_user_id)
@rbac_rule_validation.action(service="keystone",
- rule="identity:list_groups_for_user")
+ rules=["identity:list_groups_for_user"])
@decorators.idempotent_id('bd5946d4-46d2-423d-a800-a3e7aabc18b3')
def test_list_own_user_group(self):
with self.rbac_utils.override_role(self):
self.users_client.list_user_groups(self.default_user_id)
@rbac_rule_validation.action(service="keystone",
- rule="identity:list_user_projects")
+ rules=["identity:list_user_projects"])
@decorators.idempotent_id('0f148510-63bf-11e6-1564-080044d0d909')
def test_list_own_user_projects(self):
with self.rbac_utils.override_role(self):
diff --git a/patrole_tempest_plugin/tests/api/image/rbac_base.py b/patrole_tempest_plugin/tests/api/image/rbac_base.py
index 954790d..becd564 100644
--- a/patrole_tempest_plugin/tests/api/image/rbac_base.py
+++ b/patrole_tempest_plugin/tests/api/image/rbac_base.py
@@ -12,22 +12,14 @@
# under the License.
from tempest.api.image import base as image_base
-from tempest import config
from patrole_tempest_plugin import rbac_utils
-CONF = config.CONF
-
class BaseV2ImageRbacTest(rbac_utils.RbacUtilsMixin,
image_base.BaseV2ImageTest):
@classmethod
- def skip_checks(cls):
- super(BaseV2ImageRbacTest, cls).skip_checks()
- cls.skip_rbac_checks()
-
- @classmethod
def setup_clients(cls):
super(BaseV2ImageRbacTest, cls).setup_clients()
cls.setup_rbac_utils()
diff --git a/patrole_tempest_plugin/tests/api/image/test_image_namespace_objects_rbac.py b/patrole_tempest_plugin/tests/api/image/test_image_namespace_objects_rbac.py
index 3ad5c74..24e5806 100644
--- a/patrole_tempest_plugin/tests/api/image/test_image_namespace_objects_rbac.py
+++ b/patrole_tempest_plugin/tests/api/image/test_image_namespace_objects_rbac.py
@@ -24,7 +24,7 @@
class ImageNamespacesObjectsRbacTest(rbac_base.BaseV2ImageRbacTest):
@rbac_rule_validation.action(service="glance",
- rule="add_metadef_object")
+ rules=["add_metadef_object"])
@decorators.idempotent_id("772156f2-e33d-432e-8521-12385746c2f0")
def test_create_metadef_object_in_namespace(self):
"""Create Metadef Object Namespace Test
@@ -45,7 +45,7 @@
namespace['namespace'], object_name)
@rbac_rule_validation.action(service="glance",
- rule="get_metadef_objects")
+ rules=["get_metadef_objects"])
@decorators.idempotent_id("48b50ecb-237d-4909-be62-b6a05c47b64d")
def test_list_metadef_objects_in_namespace(self):
"""List Metadef Object Namespace Test
@@ -59,7 +59,7 @@
namespace['namespace'])
@rbac_rule_validation.action(service="glance",
- rule="modify_metadef_object")
+ rules=["modify_metadef_object"])
@decorators.idempotent_id("cd130b1d-89fa-479c-a90e-498d895fb455")
def test_update_metadef_object_in_namespace(self):
"""Update Metadef Object Namespace Test
@@ -83,7 +83,7 @@
namespace['namespace'], object_name, name=new_name)
@rbac_rule_validation.action(service="glance",
- rule="get_metadef_object")
+ rules=["get_metadef_object"])
@decorators.idempotent_id("93c61420-5b80-4a0e-b6f3-4ccc6e90b865")
def test_show_metadef_object_in_namespace(self):
"""Show Metadef Object Namespace Test
diff --git a/patrole_tempest_plugin/tests/api/image/test_image_namespace_property_rbac.py b/patrole_tempest_plugin/tests/api/image/test_image_namespace_property_rbac.py
index 75cf66d..1059450 100644
--- a/patrole_tempest_plugin/tests/api/image/test_image_namespace_property_rbac.py
+++ b/patrole_tempest_plugin/tests/api/image/test_image_namespace_property_rbac.py
@@ -29,7 +29,7 @@
cls.resource_name = body['resource_types'][0]['name']
@rbac_rule_validation.action(service="glance",
- rule="add_metadef_property")
+ rules=["add_metadef_property"])
@decorators.idempotent_id('383555ca-677b-43e9-b809-acc2b5a0176c')
def test_add_md_properties(self):
"""Create Image Metadef Namespace Property Test
@@ -45,7 +45,7 @@
title=property_name, name=self.resource_name)
@rbac_rule_validation.action(service="glance",
- rule="get_metadef_properties")
+ rules=["get_metadef_properties"])
@decorators.idempotent_id('d5177611-c2b5-4000-bd9c-1987af9222ea')
def test_get_md_properties(self):
"""List Image Metadef Namespace Properties Test
@@ -58,7 +58,7 @@
namespace=namespace['namespace'])
@rbac_rule_validation.action(service="glance",
- rule="get_metadef_property")
+ rules=["get_metadef_property"])
@decorators.idempotent_id('cfeda2af-bcab-433e-80c7-4b40c774aed5')
def test_get_md_property(self):
"""Get Image Metadef Namespace Property Test
@@ -77,7 +77,7 @@
namespace['namespace'], self.resource_name)
@rbac_rule_validation.action(service="glance",
- rule="modify_metadef_property")
+ rules=["modify_metadef_property"])
@decorators.idempotent_id('fdaf9363-4010-4f2f-8192-1b28f6b22e69')
def test_modify_md_properties(self):
"""Modify Image Metadef Namespace Policy Test
diff --git a/patrole_tempest_plugin/tests/api/image/test_image_namespace_rbac.py b/patrole_tempest_plugin/tests/api/image/test_image_namespace_rbac.py
index 204263a..aade60f 100644
--- a/patrole_tempest_plugin/tests/api/image/test_image_namespace_rbac.py
+++ b/patrole_tempest_plugin/tests/api/image/test_image_namespace_rbac.py
@@ -24,7 +24,7 @@
class ImageNamespacesRbacTest(rbac_base.BaseV2ImageRbacTest):
@rbac_rule_validation.action(service="glance",
- rule="add_metadef_namespace")
+ rules=["add_metadef_namespace"])
@decorators.idempotent_id('e0730ead-b824-4ffc-b774-9469df0e4da6')
def test_create_metadef_namespace(self):
"""Create Image Metadef Namespace Test
@@ -43,7 +43,7 @@
namespace_name)
@rbac_rule_validation.action(service="glance",
- rule="get_metadef_namespaces")
+ rules=["get_metadef_namespaces"])
@decorators.idempotent_id('f0b12538-9047-489e-98a5-2d78f48ce789')
def test_list_metadef_namespaces(self):
"""List Image Metadef Namespace Test
@@ -54,7 +54,7 @@
self.namespaces_client.list_namespaces()
@rbac_rule_validation.action(service="glance",
- rule="modify_metadef_namespace")
+ rules=["modify_metadef_namespace"])
@decorators.idempotent_id('72c14a7e-927d-4f1a-9e1f-25475552922b')
def test_modify_metadef_namespace(self):
"""Modify Image Metadef Namespace Test
diff --git a/patrole_tempest_plugin/tests/api/image/test_image_namespace_tags_rbac.py b/patrole_tempest_plugin/tests/api/image/test_image_namespace_tags_rbac.py
index 1a85b74..bc387ee 100644
--- a/patrole_tempest_plugin/tests/api/image/test_image_namespace_tags_rbac.py
+++ b/patrole_tempest_plugin/tests/api/image/test_image_namespace_tags_rbac.py
@@ -67,14 +67,14 @@
@decorators.idempotent_id('50bedccb-9d0b-4138-8d95-31a89250edf6')
@rbac_rule_validation.action(service="glance",
- rule="add_metadef_tag")
+ rules=["add_metadef_tag"])
def test_create_namespace_tag(self):
with self.rbac_utils.override_role(self):
self._create_namespace_tag()
@decorators.idempotent_id('4acf70cc-05da-4b1e-87b2-d5e4475164e7')
@rbac_rule_validation.action(service="glance",
- rule="get_metadef_tag")
+ rules=["get_metadef_tag"])
def test_show_namespace_tag(self):
tag_name = self._create_namespace_tag()
with self.rbac_utils.override_role(self):
@@ -83,7 +83,7 @@
@decorators.idempotent_id('01593828-3edb-461e-8abc-8fdeb3927e37')
@rbac_rule_validation.action(service="glance",
- rule="modify_metadef_tag")
+ rules=["modify_metadef_tag"])
def test_update_namespace_tag(self):
tag_name = self._create_namespace_tag()
updated_tag_name = data_utils.rand_name(
@@ -95,14 +95,14 @@
@decorators.idempotent_id('20ffaf76-ebdc-4267-a1ad-194346f5cc91')
@rbac_rule_validation.action(service="glance",
- rule="add_metadef_tags")
+ rules=["add_metadef_tags"])
def test_create_namespace_tags(self):
with self.rbac_utils.override_role(self):
self._create_namespace_tag(multiple=True)
@decorators.idempotent_id('d37c1501-e787-449d-89b3-754a942a459a')
@rbac_rule_validation.action(service="glance",
- rule="get_metadef_tags")
+ rules=["get_metadef_tags"])
def test_list_namespace_tags(self):
with self.rbac_utils.override_role(self):
self.namespace_tags_client.list_namespace_tags(self.namespace)
diff --git a/patrole_tempest_plugin/tests/api/image/test_image_resource_types_rbac.py b/patrole_tempest_plugin/tests/api/image/test_image_resource_types_rbac.py
index 7b03158..94f9cd4 100644
--- a/patrole_tempest_plugin/tests/api/image/test_image_resource_types_rbac.py
+++ b/patrole_tempest_plugin/tests/api/image/test_image_resource_types_rbac.py
@@ -36,7 +36,7 @@
cls.namespaces_client.delete_namespace, cls.namespace_name)
@rbac_rule_validation.action(service="glance",
- rule="list_metadef_resource_types")
+ rules=["list_metadef_resource_types"])
@decorators.idempotent_id('0416fc4d-cfdc-447b-88b6-d9f1dd0382f7')
def test_list_metadef_resource_types(self):
"""List Metadef Resource Type Image Test
@@ -47,7 +47,7 @@
self.resource_types_client.list_resource_types()
@rbac_rule_validation.action(service="glance",
- rule="get_metadef_resource_type")
+ rules=["get_metadef_resource_type"])
@decorators.idempotent_id('3698d53c-71ae-4803-a2c3-c272c054f25c')
def test_get_metadef_resource_type(self):
"""Get Metadef Resource Type Image Test
@@ -58,8 +58,9 @@
self.resource_types_client.list_resource_type_association(
self.namespace_name)
- @rbac_rule_validation.action(service="glance",
- rule="add_metadef_resource_type_association")
+ @rbac_rule_validation.action(
+ service="glance",
+ rules=["add_metadef_resource_type_association"])
@decorators.idempotent_id('ef9fbc60-3e28-4164-a25c-d30d892f7939')
def test_add_metadef_resource_type(self):
type_name = data_utils.rand_name()
diff --git a/patrole_tempest_plugin/tests/api/image/test_images_member_rbac.py b/patrole_tempest_plugin/tests/api/image/test_images_member_rbac.py
index 4b5fd08..656703a 100644
--- a/patrole_tempest_plugin/tests/api/image/test_images_member_rbac.py
+++ b/patrole_tempest_plugin/tests/api/image/test_images_member_rbac.py
@@ -36,7 +36,7 @@
cls.image_member_client = cls.os_primary.image_member_client_v2
@rbac_rule_validation.action(service="glance",
- rule="add_member")
+ rules=["add_member"])
@decorators.idempotent_id('b1b85ace-6484-11e6-881e-080027d0d606')
def test_add_image_member(self):
@@ -51,7 +51,7 @@
image_id, member=self.alt_tenant_id)
@rbac_rule_validation.action(service="glance",
- rule="delete_member")
+ rules=["delete_member"])
@decorators.idempotent_id('ba075234-6484-11e6-881e-080027d0d606')
def test_delete_image_member(self):
@@ -88,7 +88,7 @@
self.alt_tenant_id)
@rbac_rule_validation.action(service="glance",
- rule="modify_member")
+ rules=["modify_member"])
@decorators.idempotent_id('ca448bb2-6484-11e6-881e-080027d0d606')
def test_update_image_member(self):
@@ -110,7 +110,7 @@
status='pending')
@rbac_rule_validation.action(service="glance",
- rule="get_members")
+ rules=["get_members"])
@decorators.idempotent_id('d0a2dc20-6484-11e6-881e-080027d0d606')
def test_list_image_members(self):
diff --git a/patrole_tempest_plugin/tests/api/image/test_images_rbac.py b/patrole_tempest_plugin/tests/api/image/test_images_rbac.py
index e97e803..aa96112 100644
--- a/patrole_tempest_plugin/tests/api/image/test_images_rbac.py
+++ b/patrole_tempest_plugin/tests/api/image/test_images_rbac.py
@@ -42,7 +42,7 @@
return self.image_client.store_image_file(image_id, image_file)
@rbac_rule_validation.action(service="glance",
- rule="add_image")
+ rules=["add_image"])
@decorators.idempotent_id('0f148510-63bf-11e6-b348-080027d0d606')
def test_create_image(self):
@@ -54,7 +54,7 @@
self._create_image()
@rbac_rule_validation.action(service="glance",
- rule="upload_image")
+ rules=["upload_image"])
@decorators.idempotent_id('fdc0c7e2-ad58-4c5a-ba9d-1f6046a5b656')
def test_upload_image(self):
@@ -69,7 +69,7 @@
@decorators.idempotent_id('f0c268f3-cb51-49aa-9bd5-d30cf647322f')
@rbac_rule_validation.action(service="glance",
- rule="download_image")
+ rules=["download_image"])
def test_download_image(self):
"""Download Image Test
@@ -83,7 +83,7 @@
self.image_client.show_image_file(image['id'])
@rbac_rule_validation.action(service="glance",
- rule="delete_image")
+ rules=["delete_image"])
@decorators.idempotent_id('3b5c341e-645b-11e6-ac4f-080027d0d606')
def test_delete_image(self):
@@ -98,7 +98,7 @@
self.image_client.wait_for_resource_deletion(image['id'])
@rbac_rule_validation.action(service="glance",
- rule="get_image")
+ rules=["get_image"])
@decorators.idempotent_id('3085c7c6-645b-11e6-ac4f-080027d0d606')
def test_show_image(self):
@@ -112,7 +112,7 @@
self.image_client.show_image(image['id'])
@rbac_rule_validation.action(service="glance",
- rule="get_images")
+ rules=["get_images"])
@decorators.idempotent_id('bf1a4e94-645b-11e6-ac4f-080027d0d606')
def test_list_images(self):
@@ -124,7 +124,7 @@
self.image_client.list_images()['images']
@rbac_rule_validation.action(service="glance",
- rule="modify_image")
+ rules=["modify_image"])
@decorators.idempotent_id('32ecf48c-645e-11e6-ac4f-080027d0d606')
def test_update_image(self):
@@ -142,7 +142,7 @@
@decorators.idempotent_id('244050d9-1b9a-446a-b3c5-f26f3ba8eb75')
@rbac_rule_validation.action(service="glance",
- rule="modify_image")
+ rules=["modify_image"])
def test_create_image_tag(self):
"""Create image tag
@@ -158,7 +158,7 @@
@decorators.idempotent_id('c4a0bf9c-b78b-48c6-a31f-72c95f943c6e')
@rbac_rule_validation.action(service="glance",
- rule="modify_image")
+ rules=["modify_image"])
def test_delete_image_tag(self):
"""Delete image tag
@@ -173,7 +173,7 @@
self.image_client.delete_image_tag(image['id'], tag_name)
@rbac_rule_validation.action(service="glance",
- rule="publicize_image")
+ rules=["publicize_image"])
@decorators.idempotent_id('0ea4809c-6461-11e6-ac4f-080027d0d606')
def test_publicize_image(self):
@@ -186,7 +186,7 @@
@decorators.idempotent_id('0f2d8427-134a-4d3c-a102-5fcdf5443d09')
@rbac_rule_validation.action(service="glance",
- rule="communitize_image")
+ rules=["communitize_image"])
def test_communitize_image(self):
"""Communitize Image Test
@@ -197,7 +197,7 @@
self._create_image(visibility='community')
@rbac_rule_validation.action(service="glance",
- rule="deactivate")
+ rules=["deactivate"])
@decorators.idempotent_id('b488458c-65df-11e6-9947-080027824017')
def test_deactivate_image(self):
@@ -212,7 +212,7 @@
self.image_client.deactivate_image(image['id'])
@rbac_rule_validation.action(service="glance",
- rule="reactivate")
+ rules=["reactivate"])
@decorators.idempotent_id('d3fa28b8-65df-11e6-9947-080027824017')
def test_reactivate_image(self):
diff --git a/patrole_tempest_plugin/tests/api/network/README.rst b/patrole_tempest_plugin/tests/api/network/README.rst
new file mode 100644
index 0000000..20d6196
--- /dev/null
+++ b/patrole_tempest_plugin/tests/api/network/README.rst
@@ -0,0 +1,49 @@
+.. _network-rbac-tests:
+
+Network RBAC Tests
+==================
+
+What are these tests?
+---------------------
+
+These tests are RBAC tests for Neutron and its associated plugins. They are
+broken up into the following categories:
+
+* :ref:`neutron-rbac-tests`
+* :ref:`neutron-plugin-rbac-tests`
+
+.. _neutron-rbac-tests:
+
+Neutron tests
+^^^^^^^^^^^^^
+
+Neutron RBAC tests inherit from the base class ``BaseNetworkRbacTest``. They
+test many of the Neutron policies found in the service's `policy.json file`_.
+These tests are gated in many `Zuul jobs`_ (master, n-1, n-2) against many
+roles (member, admin).
+
+.. _neutron-plugin-rbac-tests:
+
+Neutron plugin tests
+^^^^^^^^^^^^^^^^^^^^
+
+The Neutron RBAC plugin tests focus on testing RBAC for various Neutron
+extensions and plugins, or, stated differently:
+
+* tests that rely on `neutron-tempest-plugin`_
+* external Neutron plugins
+
+These tests inherit from the base class ``BaseNetworkPluginRbacTest``. If an
+extension or plugin is not enabled in the cloud, the corresponding tests are
+gracefully skipped.
+
+.. note::
+
+ Patrole should import as few dependencies from ``neutron_tempest_plugin`` as
+ possible (such as ``neutron_tempest_plugin.api.clients`` for the service
+ clients) because the module is not a `stable interface`_.
+
+.. _policy.json file: https://github.com/openstack/neutron/blob/master/etc/policy.json
+.. _Zuul jobs: https://github.com/openstack/patrole/blob/master/.zuul.yaml
+.. _neutron-tempest-plugin: https://github.com/openstack/neutron-tempest-plugin
+.. _stable interface: https://github.com/openstack/neutron-tempest-plugin/tree/master/neutron_tempest_plugin#warning
diff --git a/patrole_tempest_plugin/tests/api/network/rbac_base.py b/patrole_tempest_plugin/tests/api/network/rbac_base.py
index 9d3e28b..6102347 100644
--- a/patrole_tempest_plugin/tests/api/network/rbac_base.py
+++ b/patrole_tempest_plugin/tests/api/network/rbac_base.py
@@ -14,22 +14,14 @@
# under the License.
from tempest.api.network import base as network_base
-from tempest import config
from patrole_tempest_plugin import rbac_utils
-CONF = config.CONF
-
class BaseNetworkRbacTest(rbac_utils.RbacUtilsMixin,
network_base.BaseNetworkTest):
@classmethod
- def skip_checks(cls):
- super(BaseNetworkRbacTest, cls).skip_checks()
- cls.skip_rbac_checks()
-
- @classmethod
def setup_clients(cls):
super(BaseNetworkRbacTest, cls).setup_clients()
cls.setup_rbac_utils()
diff --git a/patrole_tempest_plugin/tests/api/network/test_address_scope_rbac.py b/patrole_tempest_plugin/tests/api/network/test_address_scope_rbac.py
new file mode 100644
index 0000000..cf73669
--- /dev/null
+++ b/patrole_tempest_plugin/tests/api/network/test_address_scope_rbac.py
@@ -0,0 +1,139 @@
+# Copyright 2018 AT&T Corporation.
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+
+from tempest.common import utils
+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.network import rbac_base as base
+
+
+class AddressScopeRbacTest(base.BaseNetworkPluginRbacTest):
+
+ @classmethod
+ def skip_checks(cls):
+ super(AddressScopeRbacTest, cls).skip_checks()
+ if not utils.is_extension_enabled('address-scope', 'network'):
+ msg = "address-scope extension not enabled."
+ raise cls.skipException(msg)
+
+ @classmethod
+ def resource_setup(cls):
+ super(AddressScopeRbacTest, cls).resource_setup()
+ cls.network = cls.create_network()
+
+ def _create_address_scope(self, name=None, **kwargs):
+ name = name or data_utils.rand_name(self.__class__.__name__)
+ address_scope = self.ntp_client.create_address_scope(name=name,
+ ip_version=6,
+ **kwargs)
+ address_scope = address_scope['address_scope']
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.ntp_client.delete_address_scope,
+ address_scope['id'])
+ return address_scope
+
+ @rbac_rule_validation.action(service="neutron",
+ rules=["create_address_scope"],
+ expected_error_codes=[403])
+ @decorators.idempotent_id('8cb2d6b5-23c2-4648-997b-7a6ae55be3ad')
+ def test_create_address_scope(self):
+
+ """Create Address Scope
+
+ RBAC test for the neutron create_address_scope policy
+ """
+ with self.rbac_utils.override_role(self):
+ self._create_address_scope()
+
+ @rbac_rule_validation.action(service="neutron",
+ rules=["create_address_scope",
+ "create_address_scope:shared"],
+ expected_error_codes=[403, 403])
+ @decorators.idempotent_id('0c3f55c0-6ebe-4251-afca-62c5cb4632ca')
+ def test_create_address_scope_shared(self):
+
+ """Create Shared Address Scope
+
+ RBAC test for the neutron create_address_scope:shared policy
+ """
+ with self.rbac_utils.override_role(self):
+ self._create_address_scope(shared=True)
+
+ @rbac_rule_validation.action(service="neutron",
+ rules=["get_address_scope"],
+ expected_error_codes=[404])
+ @decorators.idempotent_id('a53f741b-46f6-412f-936f-ac920d449da8')
+ def test_get_address_scope(self):
+
+ """Get Address Scope
+
+ RBAC test for the neutron get_address_scope policy
+ """
+ address_scope = self._create_address_scope()
+ with self.rbac_utils.override_role(self):
+ self.ntp_client.show_address_scope(address_scope['id'])
+
+ @rbac_rule_validation.action(service="neutron",
+ rules=["get_address_scope",
+ "update_address_scope"],
+ expected_error_codes=[404, 403])
+ @decorators.idempotent_id('3ce4d606-e067-4ef5-840f-96c680226e73')
+ def test_update_address_scope(self):
+
+ """Update Address Scope
+
+ RBAC test for neutron update_address_scope policy
+ """
+ address_scope = self._create_address_scope()
+ name = data_utils.rand_name(self.__class__.__name__)
+ with self.rbac_utils.override_role(self):
+ self.ntp_client.update_address_scope(address_scope['id'],
+ name=name)
+
+ @rbac_rule_validation.action(service="neutron",
+ rules=["get_address_scope",
+ "update_address_scope",
+ "update_address_scope:shared"],
+ expected_error_codes=[404, 403, 403])
+ @decorators.idempotent_id('77d3a9d2-721a-4d9f-9654-6b52f113df85')
+ def test_update_address_scope_shared(self):
+
+ """Update Shared Address Scope
+
+ RBAC test for neutron update_address_scope:shared policy
+ """
+ address_scope = self._create_address_scope(shared=True)
+ with self.rbac_utils.override_role(self):
+ self.ntp_client.update_address_scope(address_scope['id'],
+ shared=False)
+
+ @rbac_rule_validation.action(service="neutron",
+ rules=["get_address_scope",
+ "delete_address_scope"],
+ expected_error_codes=[404, 403])
+ @decorators.idempotent_id('277d8e47-e498-4452-b969-a91f747296ba')
+ def test_delete_address_scope(self):
+
+ """Delete Address Scope
+
+ RBAC test for neutron delete_address_scope policy
+ """
+ address_scope = self._create_address_scope()
+ with self.rbac_utils.override_role(self):
+ self.ntp_client.delete_address_scope(address_scope['id'])
diff --git a/patrole_tempest_plugin/tests/api/network/test_agents_rbac.py b/patrole_tempest_plugin/tests/api/network/test_agents_rbac.py
index 7567275..c778d9c 100644
--- a/patrole_tempest_plugin/tests/api/network/test_agents_rbac.py
+++ b/patrole_tempest_plugin/tests/api/network/test_agents_rbac.py
@@ -14,6 +14,7 @@
# under the License.
from tempest.common import utils
+from tempest.lib.common.utils import data_utils
from tempest.lib.common.utils import test_utils
from tempest.lib import decorators
@@ -99,7 +100,7 @@
@decorators.idempotent_id('5d2bbdbc-40a5-43d2-828a-84dc93fcc453')
@rbac_rule_validation.action(service="neutron",
- rule="get_l3-routers")
+ rules=["get_l3-routers"])
def test_list_routers_on_l3_agent(self):
"""List routers on L3 agent test.
@@ -110,7 +111,7 @@
@decorators.idempotent_id('466b2a10-8747-4c09-855a-bd90a1c86ce7')
@rbac_rule_validation.action(service="neutron",
- rule="create_l3-router")
+ rules=["create_l3-router"])
def test_create_router_on_l3_agent(self):
"""Create router on L3 agent test.
@@ -126,7 +127,7 @@
@decorators.idempotent_id('8138cfc9-3e48-4a34-adf6-894077aa1be4')
@rbac_rule_validation.action(service="neutron",
- rule="delete_l3-router")
+ rules=["delete_l3-router"])
def test_delete_router_from_l3_agent(self):
"""Delete router from L3 agent test.
@@ -192,7 +193,7 @@
@decorators.idempotent_id('dc84087b-4c2a-4878-8ed0-40370e19da17')
@rbac_rule_validation.action(service="neutron",
- rule="get_dhcp-networks")
+ rules=["get_dhcp-networks"])
def test_list_networks_hosted_by_one_dhcp_agent(self):
"""List networks hosted by one DHCP agent test.
@@ -204,7 +205,7 @@
@decorators.idempotent_id('14e014ac-f355-46d3-b6d8-98f2c9ec1610')
@rbac_rule_validation.action(service="neutron",
- rule="create_dhcp-network")
+ rules=["create_dhcp-network"])
def test_add_dhcp_agent_to_network(self):
"""Add DHCP agent to network test.
@@ -220,7 +221,7 @@
@decorators.idempotent_id('937a4302-4b49-407d-9980-5843d7badc38')
@rbac_rule_validation.action(service="neutron",
- rule="delete_dhcp-network")
+ rules=["delete_dhcp-network"])
def test_delete_network_from_dhcp_agent(self):
"""Delete DHCP agent from network test.
@@ -235,3 +236,32 @@
with self.rbac_utils.override_role(self):
self.agents_client.delete_network_from_dhcp_agent(
self.agent['id'], network_id=network_id)
+
+
+class L3AgentsPluginRbacTest(base.BaseNetworkPluginRbacTest):
+
+ @classmethod
+ def skip_checks(cls):
+ super(L3AgentsPluginRbacTest, cls).skip_checks()
+ if not utils.is_extension_enabled('l3_agent_scheduler', 'network'):
+ msg = "l3_agent_scheduler extension not enabled."
+ raise cls.skipException(msg)
+
+ @classmethod
+ def resource_setup(cls):
+ super(L3AgentsPluginRbacTest, cls).resource_setup()
+ name = data_utils.rand_name(cls.__name__ + '-Router')
+ cls.router = cls.ntp_client.create_router(name)['router']
+
+ @decorators.idempotent_id('5d2bbdbc-40a5-43d2-828a-84dc93bcd321')
+ @rbac_rule_validation.action(service="neutron",
+ rules=["get_l3-agents"])
+ def test_list_l3_agents_on_router(self):
+ """List L3 agents on router test.
+
+ RBAC test for the neutron get_l3-agents policy
+ """
+ with self.rbac_utils.override_role(self):
+ # NOTE: It is not empty list since it's a special case where
+ # policy.enforce is called from the controller.
+ self.ntp_client.list_l3_agents_hosting_router(self.router['id'])
diff --git a/patrole_tempest_plugin/tests/api/network/test_dscp_marking_rule_rbac.py b/patrole_tempest_plugin/tests/api/network/test_dscp_marking_rule_rbac.py
new file mode 100644
index 0000000..b9f8365
--- /dev/null
+++ b/patrole_tempest_plugin/tests/api/network/test_dscp_marking_rule_rbac.py
@@ -0,0 +1,106 @@
+# Copyright 2018 AT&T Corporation.
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from tempest.common import utils
+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.network import rbac_base as base
+
+
+class DscpMarkingRulePluginRbacTest(base.BaseNetworkPluginRbacTest):
+
+ @classmethod
+ def skip_checks(cls):
+ super(DscpMarkingRulePluginRbacTest, cls).skip_checks()
+ if not utils.is_extension_enabled('qos', 'network'):
+ msg = "qos extension not enabled."
+ raise cls.skipException(msg)
+
+ @classmethod
+ def resource_setup(cls):
+ super(DscpMarkingRulePluginRbacTest, cls).resource_setup()
+ name = data_utils.rand_name(cls.__class__.__name__ + '-qos')
+ cls.policy_id = cls.ntp_client.create_qos_policy(
+ name=name)["policy"]["id"]
+ cls.addClassResourceCleanup(
+ cls.ntp_client.delete_qos_policy, cls.policy_id)
+
+ def create_policy_dscp_marking_rule(cls):
+ rule = cls.ntp_client.create_dscp_marking_rule(cls.policy_id, 10)
+ rule_id = rule['dscp_marking_rule']['id']
+ cls.addCleanup(
+ test_utils.call_and_ignore_notfound_exc,
+ cls.ntp_client.delete_dscp_marking_rule, cls.policy_id, rule_id)
+ return rule_id
+
+ @decorators.idempotent_id('2717AB75-E4CF-4CA4-AF04-5BEC0C808AA5')
+ @rbac_rule_validation.action(service="neutron",
+ rules=["create_policy_dscp_marking_rule"])
+ def test_create_policy_dscp_marking_rule(self):
+ """Create policy_dscp_marking_rule.
+
+ RBAC test for the neutron "create_policy_dscp_marking_rule" policy
+ """
+
+ with self.rbac_utils.override_role(self):
+ self.create_policy_dscp_marking_rule()
+
+ @decorators.idempotent_id('3D68F50E-B948-4B25-8A72-F6F4890BBC6F')
+ @rbac_rule_validation.action(service="neutron",
+ rules=["get_policy_dscp_marking_rule"],
+ expected_error_codes=[404])
+ def test_show_policy_dscp_marking_rule(self):
+ """Show policy_dscp_marking_rule.
+
+ RBAC test for the neutron "get_policy_dscp_marking_rule" policy
+ """
+ rule_id = self.create_policy_dscp_marking_rule()
+
+ with self.rbac_utils.override_role(self):
+ self.ntp_client.show_dscp_marking_rule(self.policy_id, rule_id)
+
+ @decorators.idempotent_id('33830794-8731-45C3-BC97-17718555DD7C')
+ @rbac_rule_validation.action(service="neutron",
+ rules=["get_policy_dscp_marking_rule",
+ "update_policy_dscp_marking_rule"],
+ expected_error_codes=[404, 403])
+ def test_update_policy_dscp_marking_rule(self):
+ """Update policy_dscp_marking_rule.
+
+ RBAC test for the neutron "update_policy_dscp_marking_rule" policy
+ """
+ rule_id = self.create_policy_dscp_marking_rule()
+
+ with self.rbac_utils.override_role(self):
+ self.ntp_client.update_dscp_marking_rule(
+ self.policy_id, rule_id, dscp_mark=16)
+
+ @decorators.idempotent_id('7BF564DD-3648-4D12-8A8B-6D5E576D1843')
+ @rbac_rule_validation.action(service="neutron",
+ rules=["get_policy_dscp_marking_rule",
+ "delete_policy_dscp_marking_rule"],
+ expected_error_codes=[404, 403])
+ def test_delete_policy_dscp_marking_rule(self):
+ """Delete policy_dscp_marking_rule.
+
+ RBAC test for the neutron "delete_policy_dscp_marking_rule" policy
+ """
+ rule_id = self.create_policy_dscp_marking_rule()
+
+ with self.rbac_utils.override_role(self):
+ self.ntp_client.delete_dscp_marking_rule(self.policy_id, rule_id)
diff --git a/patrole_tempest_plugin/tests/api/network/test_floating_ips_rbac.py b/patrole_tempest_plugin/tests/api/network/test_floating_ips_rbac.py
index 8a02149..336490a 100644
--- a/patrole_tempest_plugin/tests/api/network/test_floating_ips_rbac.py
+++ b/patrole_tempest_plugin/tests/api/network/test_floating_ips_rbac.py
@@ -63,7 +63,7 @@
return floating_ip
@rbac_rule_validation.action(service="neutron",
- rule="create_floatingip")
+ rules=["create_floatingip"])
@decorators.idempotent_id('f8f7474c-b8a5-4174-af84-73097d6ced38')
def test_create_floating_ip(self):
"""Create floating IP.
diff --git a/patrole_tempest_plugin/tests/api/network/test_metering_label_rules_rbac.py b/patrole_tempest_plugin/tests/api/network/test_metering_label_rules_rbac.py
index db099a1..bf49053 100644
--- a/patrole_tempest_plugin/tests/api/network/test_metering_label_rules_rbac.py
+++ b/patrole_tempest_plugin/tests/api/network/test_metering_label_rules_rbac.py
@@ -63,7 +63,7 @@
return label_rule
@rbac_rule_validation.action(service="neutron",
- rule="create_metering_label_rule")
+ rules=["create_metering_label_rule"])
@decorators.idempotent_id('81e81776-9d41-4d5e-b5c4-59d5c54a31ad')
def test_create_metering_label_rule(self):
"""Create metering label rule.
diff --git a/patrole_tempest_plugin/tests/api/network/test_metering_labels_rbac.py b/patrole_tempest_plugin/tests/api/network/test_metering_labels_rbac.py
index 0e10f5b..ed6e316 100644
--- a/patrole_tempest_plugin/tests/api/network/test_metering_labels_rbac.py
+++ b/patrole_tempest_plugin/tests/api/network/test_metering_labels_rbac.py
@@ -47,7 +47,7 @@
return label
@rbac_rule_validation.action(service="neutron",
- rule="create_metering_label")
+ rules=["create_metering_label"])
@decorators.idempotent_id('e8cfc8b8-c159-48f0-93b3-591625a02f8b')
def test_create_metering_label(self):
"""Create metering label.
diff --git a/patrole_tempest_plugin/tests/api/network/test_networks_rbac.py b/patrole_tempest_plugin/tests/api/network/test_networks_rbac.py
index 2e69f89..96ba378 100644
--- a/patrole_tempest_plugin/tests/api/network/test_networks_rbac.py
+++ b/patrole_tempest_plugin/tests/api/network/test_networks_rbac.py
@@ -97,7 +97,7 @@
return updated_network
@rbac_rule_validation.action(service="neutron",
- rule="create_network")
+ rules=["create_network"])
@decorators.idempotent_id('95b9baab-1ece-4e2b-89c8-8d671d974e54')
def test_create_network(self):
@@ -447,7 +447,7 @@
@utils.requires_ext(extension='dhcp_agent_scheduler', service='network')
@decorators.idempotent_id('b524f19f-fbb4-4d11-a85d-03bfae17bf0e')
@rbac_rule_validation.action(service="neutron",
- rule="get_dhcp-agents")
+ rules=["get_dhcp-agents"])
def test_list_dhcp_agents_on_hosting_network(self):
"""List DHCP Agents on Hosting Network Test
diff --git a/patrole_tempest_plugin/tests/api/network/test_policy_bandwidth_limit_rule_rbac.py b/patrole_tempest_plugin/tests/api/network/test_policy_bandwidth_limit_rule_rbac.py
new file mode 100644
index 0000000..8f9635d
--- /dev/null
+++ b/patrole_tempest_plugin/tests/api/network/test_policy_bandwidth_limit_rule_rbac.py
@@ -0,0 +1,109 @@
+# Copyright 2017 AT&T Corporation.
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from tempest.common import utils
+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.network import rbac_base as base
+
+
+class PolicyBandwidthLimitRulePluginRbacTest(base.BaseNetworkPluginRbacTest):
+
+ @classmethod
+ def skip_checks(cls):
+ super(PolicyBandwidthLimitRulePluginRbacTest, cls).skip_checks()
+ if not utils.is_extension_enabled('qos', 'network'):
+ msg = "qos extension not enabled."
+ raise cls.skipException(msg)
+
+ @classmethod
+ def resource_setup(cls):
+ super(PolicyBandwidthLimitRulePluginRbacTest, cls).resource_setup()
+ name = data_utils.rand_name(cls.__class__.__name__ + '-qos-policy')
+ cls.policy_id = cls.ntp_client.create_qos_policy(
+ name=name)["policy"]["id"]
+ cls.addClassResourceCleanup(cls.ntp_client.delete_qos_policy,
+ cls.policy_id)
+
+ def _create_bandwidth_limit_rule(self):
+ rule = self.ntp_client.create_bandwidth_limit_rule(
+ self.policy_id, max_kbps=1000, max_burst_kbps=1000,
+ direction="egress")
+ rule_id = rule['bandwidth_limit_rule']['id']
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.ntp_client.delete_bandwidth_limit_rule,
+ self.policy_id, rule_id)
+ return rule_id
+
+ @decorators.idempotent_id('E0FDCB39-E16D-4AF5-9165-3FEFD116E69D')
+ @rbac_rule_validation.action(
+ service="neutron", rules=["create_policy_bandwidth_limit_rule"])
+ def test_create_policy_bandwidth_limit_rule(self):
+ """Create bandwidth_limit_rule.
+
+ RBAC test for the neutron "create_policy_bandwidth_limit_rule" policy
+ """
+
+ with self.rbac_utils.override_role(self):
+ self._create_bandwidth_limit_rule()
+
+ @decorators.idempotent_id('A092BD50-364F-4F55-B81A-37DAD6E77B95')
+ @rbac_rule_validation.action(service="neutron",
+ rules=["get_policy_bandwidth_limit_rule"],
+ expected_error_codes=[404])
+ def test_show_policy_bandwidth_limit_rule(self):
+ """Show bandwidth_limit_rule.
+
+ RBAC test for the neutron "get_policy_bandwidth_limit_rule" policy
+ """
+ rule_id = self._create_bandwidth_limit_rule()
+
+ with self.rbac_utils.override_role(self):
+ self.ntp_client.show_bandwidth_limit_rule(self.policy_id, rule_id)
+
+ @decorators.idempotent_id('CAA27599-082B-44B9-AF09-8C9B8E777ED7')
+ @rbac_rule_validation.action(service="neutron",
+ rules=["get_policy_bandwidth_limit_rule",
+ "update_policy_bandwidth_limit_rule"],
+ expected_error_codes=[404, 403])
+ def test_update_policy_bandwidth_limit_rule(self):
+ """Update bandwidth_limit_rule.
+
+ RBAC test for the neutron "update_policy_bandwidth_limit_rule" policy
+ """
+ rule_id = self._create_bandwidth_limit_rule()
+
+ with self.rbac_utils.override_role(self):
+ self.ntp_client.update_bandwidth_limit_rule(
+ self.policy_id, rule_id, max_kbps=2000)
+
+ @decorators.idempotent_id('BF6D9ED7-4B04-423D-857D-455DB0705852')
+ @rbac_rule_validation.action(service="neutron",
+ rules=["get_policy_bandwidth_limit_rule",
+ "delete_policy_bandwidth_limit_rule"],
+ expected_error_codes=[404, 403])
+ def test_delete_policy_bandwidth_limit_rule(self):
+ """Delete bandwidth_limit_rule.
+
+ RBAC test for the neutron "delete_policy_bandwidth_limit_rule" policy
+ """
+ rule_id = self._create_bandwidth_limit_rule()
+
+ with self.rbac_utils.override_role(self):
+ self.ntp_client.delete_bandwidth_limit_rule(self.policy_id,
+ rule_id)
diff --git a/patrole_tempest_plugin/tests/api/network/test_policy_minimum_bandwidth_rule_rbac.py b/patrole_tempest_plugin/tests/api/network/test_policy_minimum_bandwidth_rule_rbac.py
new file mode 100644
index 0000000..4f85cb6
--- /dev/null
+++ b/patrole_tempest_plugin/tests/api/network/test_policy_minimum_bandwidth_rule_rbac.py
@@ -0,0 +1,112 @@
+# Copyright 2017 AT&T Corporation.
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from tempest.common import utils
+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.network import rbac_base as base
+
+
+class PolicyMinimumBandwidthRulePluginRbacTest(base.BaseNetworkPluginRbacTest):
+
+ @classmethod
+ def skip_checks(cls):
+ super(PolicyMinimumBandwidthRulePluginRbacTest, cls).skip_checks()
+ if not utils.is_extension_enabled('qos', 'network'):
+ msg = "qos extension not enabled."
+ raise cls.skipException(msg)
+
+ @classmethod
+ def resource_setup(cls):
+ super(PolicyMinimumBandwidthRulePluginRbacTest, cls).resource_setup()
+ name = data_utils.rand_name(cls.__class__.__name__ + '-qos')
+ cls.policy_id = cls.ntp_client.create_qos_policy(
+ name=name)["policy"]["id"]
+ cls.addClassResourceCleanup(test_utils.call_and_ignore_notfound_exc,
+ cls.ntp_client.delete_qos_policy,
+ cls.policy_id)
+
+ def create_minimum_bandwidth_rule(self):
+ rule = self.ntp_client.create_minimum_bandwidth_rule(
+ self.policy_id, direction="egress", min_kbps=1000)
+ rule_id = rule['minimum_bandwidth_rule']['id']
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.ntp_client.delete_minimum_bandwidth_rule,
+ self.policy_id, rule_id)
+ return rule_id
+
+ @decorators.idempotent_id('25B5EF3A-DF2A-4C80-A498-3BE14A321D97')
+ @rbac_rule_validation.action(
+ service="neutron", rules=["create_policy_minimum_bandwidth_rule"])
+ def test_create_policy_minimum_bandwidth_rule(self):
+ """Create policy_minimum_bandwidth_rule.
+
+ RBAC test for the neutron "create_policy_minimum_bandwidth_rule" policy
+ """
+
+ with self.rbac_utils.override_role(self):
+ self.create_minimum_bandwidth_rule()
+
+ @decorators.idempotent_id('01DD902C-47C5-45D2-9A0E-7AF05981DF21')
+ @rbac_rule_validation.action(service="neutron",
+ rules=["get_policy_minimum_bandwidth_rule"],
+ expected_error_codes=[404])
+ def test_show_policy_minimum_bandwidth_rule(self):
+ """Show policy_minimum_bandwidth_rule.
+
+ RBAC test for the neutron "get_policy_minimum_bandwidth_rule" policy
+ """
+ rule_id = self.create_minimum_bandwidth_rule()
+
+ with self.rbac_utils.override_role(self):
+ self.ntp_client.show_minimum_bandwidth_rule(
+ self.policy_id, rule_id)
+
+ @decorators.idempotent_id('50AFE69B-455C-413A-BDC6-26B42DC8D55D')
+ @rbac_rule_validation.action(
+ service="neutron",
+ rules=["get_policy_minimum_bandwidth_rule",
+ "update_policy_minimum_bandwidth_rule"],
+ expected_error_codes=[404, 403])
+ def test_update_policy_minimum_bandwidth_rule(self):
+ """Update policy_minimum_bandwidth_rule.
+
+ RBAC test for the neutron "update_policy_minimum_bandwidth_rule" policy
+ """
+ rule_id = self.create_minimum_bandwidth_rule()
+
+ with self.rbac_utils.override_role(self):
+ self.ntp_client.update_minimum_bandwidth_rule(
+ self.policy_id, rule_id, min_kbps=2000)
+
+ @decorators.idempotent_id('2112E325-C3B2-4071-8A93-B218F275A83B')
+ @rbac_rule_validation.action(
+ service="neutron",
+ rules=["get_policy_minimum_bandwidth_rule",
+ "delete_policy_minimum_bandwidth_rule"],
+ expected_error_codes=[404, 403])
+ def test_delete_policy_minimum_bandwidth_rule(self):
+ """Delete policy_minimum_bandwidth_rule.
+
+ RBAC test for the neutron "delete_policy_minimum_bandwidth_rule" policy
+ """
+ rule_id = self.create_minimum_bandwidth_rule()
+
+ with self.rbac_utils.override_role(self):
+ self.ntp_client.delete_minimum_bandwidth_rule(
+ self.policy_id, rule_id)
diff --git a/patrole_tempest_plugin/tests/api/network/test_ports_rbac.py b/patrole_tempest_plugin/tests/api/network/test_ports_rbac.py
index 175d051..b65bd73 100644
--- a/patrole_tempest_plugin/tests/api/network/test_ports_rbac.py
+++ b/patrole_tempest_plugin/tests/api/network/test_ports_rbac.py
@@ -59,7 +59,7 @@
return ip_list
@rbac_rule_validation.action(service="neutron",
- rule="create_port")
+ rules=["create_port"])
@decorators.idempotent_id('0ec8c551-625c-4864-8a52-85baa7c40f22')
def test_create_port(self):
diff --git a/patrole_tempest_plugin/tests/api/network/test_qos_rbac.py b/patrole_tempest_plugin/tests/api/network/test_qos_rbac.py
new file mode 100644
index 0000000..20f9e61
--- /dev/null
+++ b/patrole_tempest_plugin/tests/api/network/test_qos_rbac.py
@@ -0,0 +1,100 @@
+# Copyright 2018 AT&T Corporation.
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from tempest.common import utils
+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.network import rbac_base as base
+
+
+class QosRbacTest(base.BaseNetworkPluginRbacTest):
+
+ @classmethod
+ def skip_checks(cls):
+ super(QosRbacTest, cls).skip_checks()
+ if not utils.is_extension_enabled('qos', 'network'):
+ msg = "qos extension not enabled."
+ raise cls.skipException(msg)
+
+ @classmethod
+ def resource_setup(cls):
+ super(QosRbacTest, cls).resource_setup()
+ cls.network = cls.create_network()
+
+ def create_policy(self, name=None):
+ name = name or data_utils.rand_name(self.__class__.__name__)
+ policy = self.ntp_client.create_qos_policy(name)['policy']
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.ntp_client.delete_qos_policy, policy['id'])
+ return policy
+
+ @rbac_rule_validation.action(service="neutron",
+ rules=["create_policy"],
+ expected_error_codes=[403])
+ @decorators.idempotent_id('2ade2e48-7f82-4650-a69c-933d8d594636')
+ def test_create_policy(self):
+
+ """Create Policy Test
+
+ RBAC test for the neutron create_policy policy
+ """
+ with self.rbac_utils.override_role(self):
+ self.create_policy()
+
+ @rbac_rule_validation.action(service="neutron",
+ rules=["get_policy"],
+ expected_error_codes=[404])
+ @decorators.idempotent_id('d004a8de-b226-4eb4-9fdc-8202a7f64c56')
+ def test_get_policy(self):
+
+ """Show Policy Test
+
+ RBAC test for the neutron get_policy policy
+ """
+ policy = self.create_policy()
+ with self.rbac_utils.override_role(self):
+ self.ntp_client.show_qos_policy(policy['id'])
+
+ @rbac_rule_validation.action(service="neutron",
+ rules=["get_policy", "update_policy"],
+ expected_error_codes=[404, 403])
+ @decorators.idempotent_id('fb74d56f-1dfc-490b-a9e1-454af583eefb')
+ def test_update_policy(self):
+
+ """Update Policy Test
+
+ RBAC test for the neutron update_policy policy
+ """
+ policy = self.create_policy()
+ with self.rbac_utils.override_role(self):
+ self.ntp_client.update_qos_policy(policy['id'],
+ description='updated')
+
+ @rbac_rule_validation.action(service="neutron",
+ rules=["get_policy", "delete_policy"],
+ expected_error_codes=[404, 403])
+ @decorators.idempotent_id('ef4c23a6-4095-47a6-958e-1df585f7d8db')
+ def test_delete_policy(self):
+
+ """Delete Policy Test
+
+ RBAC test for the neutron delete_policy policy
+ """
+ policy = self.create_policy()
+ with self.rbac_utils.override_role(self):
+ self.ntp_client.delete_qos_policy(policy['id'])
diff --git a/patrole_tempest_plugin/tests/api/network/test_rbac_policies_rbac.py b/patrole_tempest_plugin/tests/api/network/test_rbac_policies_rbac.py
index a8813e7..9c88bc0 100644
--- a/patrole_tempest_plugin/tests/api/network/test_rbac_policies_rbac.py
+++ b/patrole_tempest_plugin/tests/api/network/test_rbac_policies_rbac.py
@@ -30,9 +30,9 @@
def create_rbac_policy(self, tenant_id, network_id):
policy = self.ntp_client.create_rbac_policy(
- target_tenant=self.tenant_id,
+ target_tenant=tenant_id,
object_type="network",
- object_id=self.network_id,
+ object_id=network_id,
action="access_as_shared"
)
self.addCleanup(
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 3d7631a..f850a3e 100644
--- a/patrole_tempest_plugin/tests/api/network/test_routers_rbac.py
+++ b/patrole_tempest_plugin/tests/api/network/test_routers_rbac.py
@@ -56,7 +56,7 @@
return unused_ip[0]
@rbac_rule_validation.action(service="neutron",
- rule="create_router")
+ rules=["create_router"])
@decorators.idempotent_id('acc5005c-bdb6-4192-bc9f-ece9035bb488')
def test_create_router(self):
"""Create Router
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 4536fdb..9112bf6 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
@@ -70,7 +70,7 @@
return sec_group_rule
@rbac_rule_validation.action(service="neutron",
- rule="create_security_group")
+ rules=["create_security_group"])
@decorators.idempotent_id('db7003ce-5717-4e5b-afc7-befa35e8c67f')
def test_create_security_group(self):
@@ -116,7 +116,7 @@
description="test description")
@rbac_rule_validation.action(service="neutron",
- rule="get_security_group")
+ rules=["get_security_group"])
@decorators.idempotent_id('fbaf8d96-ed3e-49af-b24c-5fb44f05bbb7')
def test_list_security_groups(self):
@@ -129,7 +129,7 @@
raise rbac_exceptions.RbacMalformedResponse(empty=True)
@rbac_rule_validation.action(service="neutron",
- rule="create_security_group_rule")
+ rules=["create_security_group_rule"])
@decorators.idempotent_id('953d78df-00cd-416f-9cbd-b7cb4ea65772')
def test_create_security_group_rule(self):
@@ -160,7 +160,7 @@
sec_group_rule['id'])
@rbac_rule_validation.action(service="neutron",
- rule="get_security_group_rule")
+ rules=["get_security_group_rule"])
@decorators.idempotent_id('05739ab6-fa35-11e6-bc64-92361f002671')
def test_list_security_group_rules(self):
diff --git a/patrole_tempest_plugin/tests/api/network/test_service_providers_rbac.py b/patrole_tempest_plugin/tests/api/network/test_service_providers_rbac.py
index fd85444..561a72c 100644
--- a/patrole_tempest_plugin/tests/api/network/test_service_providers_rbac.py
+++ b/patrole_tempest_plugin/tests/api/network/test_service_providers_rbac.py
@@ -22,7 +22,7 @@
class ServiceProvidersRbacTest(base.BaseNetworkRbacTest):
@rbac_rule_validation.action(service="neutron",
- rule="get_service_provider")
+ rules=["get_service_provider"])
@decorators.idempotent_id('15f573b7-474a-4b37-8629-7fac86553ce5')
def test_list_service_providers(self):
with self.rbac_utils.override_role(self):
diff --git a/patrole_tempest_plugin/tests/api/network/test_subnetpools_rbac.py b/patrole_tempest_plugin/tests/api/network/test_subnetpools_rbac.py
index 7d02271..bc6b923 100644
--- a/patrole_tempest_plugin/tests/api/network/test_subnetpools_rbac.py
+++ b/patrole_tempest_plugin/tests/api/network/test_subnetpools_rbac.py
@@ -53,7 +53,7 @@
return subnetpool
@rbac_rule_validation.action(service="neutron",
- rule="create_subnetpool")
+ rules=["create_subnetpool"])
@decorators.idempotent_id('1b5509fd-2c32-44a8-a786-1b6ca162dbd1')
def test_create_subnetpool(self):
"""Create subnetpool.
@@ -65,7 +65,33 @@
@rbac_rule_validation.action(service="neutron",
rules=["create_subnetpool",
- "create_subnetpool:shared"])
+ "create_subnetpool:is_default"],
+ expected_error_codes=[403, 403])
+ @decorators.idempotent_id('1b5509fd-2c32-44a8-a786-1b6ca162dbd2')
+ def test_create_subnetpool_default(self):
+ """Create default subnetpool.
+
+ RBAC test for the neutron create_subnetpool:is_default policy
+ """
+ # Most likely we already have default subnetpools for ipv4 and ipv6,
+ # so we temporary mark them as is_default=False, to let this test pass.
+ def_pools = self.subnetpools_client.list_subnetpools(is_default=True)
+ for default_pool in def_pools["subnetpools"]:
+ self.subnetpools_client.update_subnetpool(default_pool["id"],
+ is_default=False)
+
+ self.addCleanup(self.subnetpools_client.update_subnetpool,
+ default_pool["id"], is_default=True)
+
+ with self.rbac_utils.override_role(self):
+ # It apparently only enforces the policy for is_default=True.
+ # It does nothing for is_default=False
+ self._create_subnetpool(is_default=True)
+
+ @rbac_rule_validation.action(service="neutron",
+ rules=["create_subnetpool",
+ "create_subnetpool:shared"],
+ expected_error_codes=[403, 403])
@decorators.idempotent_id('cf730989-0d47-40bc-b39a-99e7de484723')
def test_create_subnetpool_shared(self):
"""Create subnetpool shared.
diff --git a/patrole_tempest_plugin/tests/api/network/test_subnets_rbac.py b/patrole_tempest_plugin/tests/api/network/test_subnets_rbac.py
index 93d79a9..9a5ebe4 100644
--- a/patrole_tempest_plugin/tests/api/network/test_subnets_rbac.py
+++ b/patrole_tempest_plugin/tests/api/network/test_subnets_rbac.py
@@ -39,7 +39,7 @@
@decorators.idempotent_id('0481adeb-4301-44d5-851c-35910cc18a6b')
@rbac_rule_validation.action(service="neutron",
- rule="create_subnet")
+ rules=["create_subnet"])
def test_create_subnet(self):
"""Create subnet.
@@ -62,7 +62,7 @@
@decorators.idempotent_id('e2ddc415-5cab-43f4-9b61-166aed65d637')
@rbac_rule_validation.action(service="neutron",
- rule="get_subnet")
+ rules=["get_subnet"])
def test_list_subnets(self):
"""List subnets.
diff --git a/patrole_tempest_plugin/tests/api/volume/rbac_base.py b/patrole_tempest_plugin/tests/api/volume/rbac_base.py
index bac173e..14b3151 100644
--- a/patrole_tempest_plugin/tests/api/volume/rbac_base.py
+++ b/patrole_tempest_plugin/tests/api/volume/rbac_base.py
@@ -13,14 +13,11 @@
from tempest.api.volume import base as vol_base
from tempest.common import waiters
-from tempest import config
from tempest.lib.common.utils import data_utils
from tempest.lib.common.utils import test_utils
from patrole_tempest_plugin import rbac_utils
-CONF = config.CONF
-
class BaseVolumeRbacTest(rbac_utils.RbacUtilsMixin,
vol_base.BaseVolumeTest):
@@ -32,11 +29,6 @@
_api_version = 3
@classmethod
- def skip_checks(cls):
- super(BaseVolumeRbacTest, cls).skip_checks()
- cls.skip_rbac_checks()
-
- @classmethod
def setup_clients(cls):
super(BaseVolumeRbacTest, cls).setup_clients()
cls.setup_rbac_utils()
diff --git a/patrole_tempest_plugin/tests/api/volume/test_capabilities_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_capabilities_rbac.py
index 82b89ab..fa1157a 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_capabilities_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_capabilities_rbac.py
@@ -36,7 +36,7 @@
cls.hosts_client = cls.os_primary.volume_hosts_v2_client
@rbac_rule_validation.action(service="cinder",
- rule="volume_extension:capabilities")
+ rules=["volume_extension:capabilities"])
@decorators.idempotent_id('40928b74-2141-11e7-93ae-92361f002671')
def test_show_back_end_capabilities(self):
host = self.hosts_client.list_hosts()['hosts'][0]['host_name']
diff --git a/patrole_tempest_plugin/tests/api/volume/test_encryption_types_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_encryption_types_rbac.py
index f10e41b..0eb0244 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_encryption_types_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_encryption_types_rbac.py
@@ -13,12 +13,36 @@
# License for the specific language governing permissions and limitations
# under the License.
+import functools
+
from tempest.common import utils
+from tempest import config
from tempest.lib import decorators
from patrole_tempest_plugin import rbac_rule_validation
from patrole_tempest_plugin.tests.api.volume import rbac_base
+CONF = config.CONF
+
+
+def _get_volume_type_encryption_policy(action):
+ feature_flag = CONF.policy_feature_enabled.added_cinder_policies_stein
+
+ if feature_flag:
+ return "volume_extension:volume_type_encryption:%s" % action
+
+ return "volume_extension:volume_type_encryption"
+
+
+_CREATE_VOLUME_TYPE_ENCRYPTION = functools.partial(
+ _get_volume_type_encryption_policy, "create")
+_SHOW_VOLUME_TYPE_ENCRYPTION = functools.partial(
+ _get_volume_type_encryption_policy, "get")
+_UPDATE_VOLUME_TYPE_ENCRYPTION = functools.partial(
+ _get_volume_type_encryption_policy, "update")
+_DELETE_VOLUME_TYPE_ENCRYPTION = functools.partial(
+ _get_volume_type_encryption_policy, "delete")
+
class EncryptionTypesV3RbacTest(rbac_base.BaseVolumeRbacTest):
@@ -45,7 +69,7 @@
@decorators.idempotent_id('ffd94ce5-c24b-4b6c-84c9-c5aad8c3010c')
@rbac_rule_validation.action(
service="cinder",
- rule="volume_extension:volume_type_encryption")
+ rules=[_CREATE_VOLUME_TYPE_ENCRYPTION])
def test_create_volume_type_encryption(self):
vol_type_id = self.create_volume_type()['id']
with self.rbac_utils.override_role(self):
@@ -57,7 +81,7 @@
@decorators.idempotent_id('6599e72e-acef-4c0d-a9b2-463fca30d1da')
@rbac_rule_validation.action(
service="cinder",
- rule="volume_extension:volume_type_encryption")
+ rules=[_DELETE_VOLUME_TYPE_ENCRYPTION])
def test_delete_volume_type_encryption(self):
vol_type_id = self._create_volume_type_encryption()
with self.rbac_utils.override_role(self):
@@ -66,7 +90,7 @@
@decorators.idempotent_id('42da9fec-32fd-4dca-9242-8a53b2fed25a')
@rbac_rule_validation.action(
service="cinder",
- rule="volume_extension:volume_type_encryption")
+ rules=[_UPDATE_VOLUME_TYPE_ENCRYPTION])
def test_update_volume_type_encryption(self):
vol_type_id = self._create_volume_type_encryption()
with self.rbac_utils.override_role(self):
@@ -77,7 +101,7 @@
@decorators.idempotent_id('1381a3dc-248f-4282-b231-c9399018c804')
@rbac_rule_validation.action(
service="cinder",
- rule="volume_extension:volume_type_encryption")
+ rules=[_SHOW_VOLUME_TYPE_ENCRYPTION])
def test_show_volume_type_encryption(self):
vol_type_id = self._create_volume_type_encryption()
with self.rbac_utils.override_role(self):
@@ -86,7 +110,7 @@
@decorators.idempotent_id('d4ed3cf8-52b2-4fa2-910d-e405361f0881')
@rbac_rule_validation.action(
service="cinder",
- rule="volume_extension:volume_type_encryption")
+ rules=[_SHOW_VOLUME_TYPE_ENCRYPTION])
def test_show_encryption_specs_item(self):
vol_type_id = self._create_volume_type_encryption()
with self.rbac_utils.override_role(self):
diff --git a/patrole_tempest_plugin/tests/api/volume/test_group_snapshots_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_group_snapshots_rbac.py
index 73d7bf2..1d59f9b 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_group_snapshots_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_group_snapshots_rbac.py
@@ -89,7 +89,7 @@
@decorators.idempotent_id('653df0e8-d90a-474a-a5ce-3c2339aff7ba')
@rbac_rule_validation.action(
service="cinder",
- rule="group:create_group_snapshot"
+ rules=["group:create_group_snapshot"]
)
def test_create_group_snapshot(self):
with self.rbac_utils.override_role(self):
@@ -112,7 +112,7 @@
@decorators.idempotent_id('8b966844-4421-4f73-940b-9157cb878331')
@rbac_rule_validation.action(
service="cinder",
- rule="group:get_group_snapshot"
+ rules=["group:get_group_snapshot"]
)
def test_show_group_snapshot_rbac(self):
group_snapshot_name = data_utils.rand_name('group_snapshot')
@@ -125,7 +125,7 @@
@decorators.idempotent_id('e9de6dae-1efb-47cd-a3a8-d1f4b8f9f3ff')
@rbac_rule_validation.action(
service="cinder",
- rule="group:get_all_group_snapshots"
+ rules=["group:get_all_group_snapshots"]
)
def test_list_group_snapshot_rbac(self):
with self.rbac_utils.override_role(self):
@@ -134,7 +134,7 @@
@decorators.idempotent_id('cf2e25ee-ca58-4ad6-b98d-33235c77db7b')
@rbac_rule_validation.action(
service="cinder",
- rule="group:delete_group_snapshot"
+ rules=["group:delete_group_snapshot"]
)
def test_delete_group_snapshot_rbac(self):
group_snapshot_name = data_utils.rand_name('group_snapshot')
@@ -186,7 +186,7 @@
@decorators.idempotent_id('3f0c842e-0c72-4f5e-a9c2-281070be3e2c')
@rbac_rule_validation.action(
service="cinder",
- rule="group:reset_group_snapshot_status"
+ rules=["group:reset_group_snapshot_status"]
)
def test_reset_group_snapshot_rbac(self):
group_snapshot_name = data_utils.rand_name('group_snapshot')
diff --git a/patrole_tempest_plugin/tests/api/volume/test_group_type_specs.py b/patrole_tempest_plugin/tests/api/volume/test_group_type_specs.py
index a34a55d..9c41dfc 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_group_type_specs.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_group_type_specs.py
@@ -27,7 +27,7 @@
@decorators.idempotent_id('b2859734-00ad-4a22-88ee-541698e90d12')
@rbac_rule_validation.action(
service="cinder",
- rule="group:group_types_specs"
+ rules=["group:group_types_specs"]
)
def test_group_type_specs_create(self):
# Create new group type
@@ -47,7 +47,7 @@
@decorators.idempotent_id('469d0253-aa13-423f-8264-231ac17effbf')
@rbac_rule_validation.action(
service="cinder",
- rule="group:group_types_specs"
+ rules=["group:group_types_specs"]
)
def test_group_type_specs_show(self):
group_type = self.create_group_type()
@@ -65,7 +65,7 @@
@decorators.idempotent_id('2e706a4e-dec9-46bf-9426-1c5b6f3ce102')
@rbac_rule_validation.action(
service="cinder",
- rule="group:group_types_specs"
+ rules=["group:group_types_specs"]
)
def test_group_type_specs_update(self):
group_type = self.create_group_type()
@@ -81,7 +81,7 @@
@decorators.idempotent_id('fd5e332b-fb2c-4957-ace9-11d60ddd5472')
@rbac_rule_validation.action(
service="cinder",
- rule="group:group_types_specs"
+ rules=["group:group_types_specs"]
)
def test_group_type_specs_list(self):
group_type = self.create_group_type()
@@ -92,7 +92,7 @@
@decorators.idempotent_id('d9639a07-e441-4576-baf6-7ec732b16572')
@rbac_rule_validation.action(
service="cinder",
- rule="group:group_types_specs"
+ rules=["group:group_types_specs"]
)
def test_group_type_specs_delete(self):
group_type = self.create_group_type()
diff --git a/patrole_tempest_plugin/tests/api/volume/test_groups_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_groups_rbac.py
index ecd193b..c117d23 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_groups_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_groups_rbac.py
@@ -63,7 +63,7 @@
@decorators.idempotent_id('43235328-66ae-424f-bc7f-f709c0ca268c')
@rbac_rule_validation.action(
service="cinder",
- rule="group:create")
+ rules=["group:create"])
def test_create_group(self, name=None):
group_name = name or data_utils.rand_name(
@@ -80,7 +80,7 @@
@decorators.idempotent_id('9dc34a62-ae3e-439e-92b6-9389ea4c2863')
@rbac_rule_validation.action(
service="cinder",
- rule="group:get")
+ rules=["group:get"])
def test_show_group(self):
group = self._create_group(group_type=self.group_type_id,
volume_types=[self.volume_type_id])
@@ -91,7 +91,7 @@
@decorators.idempotent_id('db43841b-a173-4317-acfc-f83e4e48e4ee')
@rbac_rule_validation.action(
service="cinder",
- rule="group:get_all")
+ rules=["group:get_all"])
def test_list_groups(self):
with self.rbac_utils.override_role(self):
self.groups_client.list_groups()['groups']
@@ -99,7 +99,7 @@
@decorators.idempotent_id('5378da93-9c26-4ad4-b039-0555e2b8f668')
@rbac_rule_validation.action(
service="cinder",
- rule="group:get_all")
+ rules=["group:get_all"])
def test_list_groups_with_details(self):
with self.rbac_utils.override_role(self):
self.groups_client.list_groups(detail=True)['groups']
@@ -107,7 +107,7 @@
@decorators.idempotent_id('f499fc48-df83-4917-bf8d-783ebf6f080b')
@rbac_rule_validation.action(
service="cinder",
- rule="group:update")
+ rules=["group:update"])
def test_update_group(self):
group = self._create_group(group_type=self.group_type_id,
volume_types=[self.volume_type_id])
@@ -119,7 +119,7 @@
@decorators.idempotent_id('66fda391-5774-42a9-a018-80b34e57ab76')
@rbac_rule_validation.action(
service="cinder",
- rule="group:delete")
+ rules=["group:delete"])
def test_delete_group(self):
group = self._create_group(ignore_notfound=True,
@@ -146,7 +146,7 @@
@decorators.idempotent_id('b849c1d4-3215-4f9d-b1e6-0aeb4b2b65ac')
@rbac_rule_validation.action(
service="cinder",
- rule="group:reset_status")
+ rules=["group:reset_status"])
def test_reset_group_status(self):
group = self._create_group(ignore_notfound=False,
group_type=self.group_type_id,
@@ -166,7 +166,7 @@
@decorators.idempotent_id('2820f12c-4681-4c7f-b28d-e6925637dff6')
@rbac_rule_validation.action(
service="cinder",
- rule="group:group_types_manage")
+ rules=["group:group_types_manage"])
def test_create_group_type(self):
with self.rbac_utils.override_role(self):
self.create_group_type(ignore_notfound=True)
@@ -174,7 +174,7 @@
@decorators.idempotent_id('f77f8156-4fc9-4f02-be15-8930f748e10c')
@rbac_rule_validation.action(
service="cinder",
- rule="group:group_types_manage")
+ rules=["group:group_types_manage"])
def test_delete_group_type(self):
group_type = self.create_group_type(ignore_notfound=True)
@@ -184,7 +184,7 @@
@decorators.idempotent_id('67929954-4551-4d22-b15a-27fb6e56b711')
@rbac_rule_validation.action(
service="cinder",
- rule="group:group_types_manage")
+ rules=["group:group_types_manage"])
def test_update_group_type(self):
group_type = self.create_group_type()
update_params = {
@@ -199,7 +199,7 @@
@decorators.idempotent_id('a5f88c26-df7c-4f21-a3ae-7a4c2d6212b4')
@rbac_rule_validation.action(
service="cinder",
- rule="group:access_group_types_specs")
+ rules=["group:access_group_types_specs"])
def test_create_group_type_group_specs(self):
# TODO(felipemonteiro): Combine with ``test_create_group_type``
# once multiple policy testing is supported. This policy is
@@ -214,7 +214,7 @@
@decorators.idempotent_id('8d9e2831-24c3-47b7-a76a-2e563287f12f')
@rbac_rule_validation.action(
service="cinder",
- rule="group:access_group_types_specs")
+ rules=["group:access_group_types_specs"])
def test_show_group_type(self):
group_type = self.create_group_type()
with self.rbac_utils.override_role(self):
diff --git a/patrole_tempest_plugin/tests/api/volume/test_limits_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_limits_rbac.py
index aec5cb1..3127d83 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_limits_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_limits_rbac.py
@@ -33,7 +33,7 @@
'"limits_extension:used_limits" must be available in the cloud.')
@decorators.idempotent_id('dab04510-5b86-4479-a633-6e496ff405af')
@rbac_rule_validation.action(service="cinder",
- rule="limits_extension:used_limits")
+ rules=["limits_extension:used_limits"])
def test_show_limits(self):
# It is enough to check whether any of the following keys below
# are in the response body under ['limits']['absolute'], but no harm
diff --git a/patrole_tempest_plugin/tests/api/volume/test_qos_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_qos_rbac.py
index a62bbda..5664bf9 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_qos_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_qos_rbac.py
@@ -39,31 +39,32 @@
return qos_specs
@rbac_rule_validation.action(
- service="cinder", rule="volume_extension:qos_specs_manage:create")
+ service="cinder", rules=["volume_extension:qos_specs_manage:create"])
@decorators.idempotent_id('4f9f45f0-b379-4577-a279-cec3e917cbec')
def test_create_qos_with_consumer(self):
with self.rbac_utils.override_role(self):
self._create_test_qos_specs()
@rbac_rule_validation.action(
- service="cinder", rule="volume_extension:qos_specs_manage:delete")
+ service="cinder", rules=["volume_extension:qos_specs_manage:delete"])
@decorators.idempotent_id('fbc8a77e-6b6d-45ae-bebe-c496eb8f06f7')
def test_delete_qos_with_consumer(self):
qos = self._create_test_qos_specs()
with self.rbac_utils.override_role(self):
self.qos_client.delete_qos(qos['id'])
- @rbac_rule_validation.action(service="cinder",
- rule="volume_extension:qos_specs_manage:get")
+ @rbac_rule_validation.action(
+ service="cinder",
+ rules=["volume_extension:qos_specs_manage:get"])
@decorators.idempotent_id('22aff0dd-0343-408d-ae80-e77551956e14')
def test_show_qos(self):
qos = self._create_test_qos_specs()
with self.rbac_utils.override_role(self):
self.qos_client.show_qos(qos['id'])['qos_specs']
- @rbac_rule_validation.action(service="cinder",
- rule="volume_extension:"
- "qos_specs_manage:get_all")
+ @rbac_rule_validation.action(
+ service="cinder",
+ rules=["volume_extension:qos_specs_manage:get_all"])
@decorators.idempotent_id('ff1e98f3-d456-40a9-96d4-c7e4a55dcffa')
def test_get_association_qos(self):
qos = self._create_test_qos_specs()
@@ -76,14 +77,14 @@
@rbac_rule_validation.action(
service="cinder",
- rule="volume_extension:qos_specs_manage:get_all")
+ rules=["volume_extension:qos_specs_manage:get_all"])
@decorators.idempotent_id('546b8bb1-04a4-4387-9506-a538a7f3cd6a')
def test_list_qos(self):
with self.rbac_utils.override_role(self):
self.qos_client.list_qos()['qos_specs']
@rbac_rule_validation.action(
- service="cinder", rule="volume_extension:qos_specs_manage:update")
+ service="cinder", rules=["volume_extension:qos_specs_manage:update"])
@decorators.idempotent_id('89b630b7-c170-47c3-ac80-50ed425c2d98')
def test_set_qos_key(self):
qos = self._create_test_qos_specs()
@@ -92,7 +93,7 @@
qos['id'], iops_bytes='500')['qos_specs']
@rbac_rule_validation.action(
- service="cinder", rule="volume_extension:qos_specs_manage:update")
+ service="cinder", rules=["volume_extension:qos_specs_manage:update"])
@decorators.idempotent_id('6c50c837-de77-4dae-a2ec-30e05c62969c')
def test_unset_qos_key(self):
qos = self._create_test_qos_specs()
@@ -104,7 +105,7 @@
'qos-key-unset', args=['iops_bytes'])
@rbac_rule_validation.action(
- service="cinder", rule="volume_extension:qos_specs_manage:update")
+ service="cinder", rules=["volume_extension:qos_specs_manage:update"])
@decorators.idempotent_id('2047b347-8bbe-405e-bf5a-c75a0d7e3930')
def test_associate_qos(self):
qos = self._create_test_qos_specs()
@@ -117,7 +118,7 @@
self.qos_client.disassociate_qos, qos['id'], vol_type)
@rbac_rule_validation.action(
- service="cinder", rule="volume_extension:qos_specs_manage:update")
+ service="cinder", rules=["volume_extension:qos_specs_manage:update"])
@decorators.idempotent_id('f12aeca1-0c02-4f33-b805-014171e5b2d4')
def test_disassociate_qos(self):
qos = self._create_test_qos_specs()
@@ -132,7 +133,7 @@
'disassociate', args=vol_type)
@rbac_rule_validation.action(
- service="cinder", rule="volume_extension:qos_specs_manage:update")
+ service="cinder", rules=["volume_extension:qos_specs_manage:update"])
@decorators.idempotent_id('9f6e664d-a5d9-4e71-b122-73a3086be1b9')
def test_disassociate_all_qos(self):
qos = self._create_test_qos_specs()
diff --git a/patrole_tempest_plugin/tests/api/volume/test_quota_classes_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_quota_classes_rbac.py
index dace257..dcc67f6 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_quota_classes_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_quota_classes_rbac.py
@@ -39,7 +39,7 @@
@decorators.idempotent_id('1a060def-2b43-4534-97f5-5eadbbe8c726')
@rbac_rule_validation.action(service="cinder",
- rule="volume_extension:quota_classes")
+ rules=["volume_extension:quota_classes"])
def test_show_quota_class_set(self):
with self.rbac_utils.override_role(self):
self.quota_classes_client.show_quota_class_set(
@@ -47,7 +47,7 @@
@decorators.idempotent_id('72159478-23a7-4c75-989f-6bac609eca62')
@rbac_rule_validation.action(service="cinder",
- rule="volume_extension:quota_classes")
+ rules=["volume_extension:quota_classes"])
def test_update_quota_class_set(self):
quota_class_set = self.quota_classes_client.show_quota_class_set(
self.quota_name)['quota_class_set']
diff --git a/patrole_tempest_plugin/tests/api/volume/test_scheduler_stats_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_scheduler_stats_rbac.py
index a243587..efcfdaf 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_scheduler_stats_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_scheduler_stats_rbac.py
@@ -37,7 +37,7 @@
@rbac_rule_validation.action(
service="cinder",
- rule="scheduler_extension:scheduler_stats:get_pools")
+ rules=["scheduler_extension:scheduler_stats:get_pools"])
@decorators.idempotent_id('5f800441-4d30-48ec-9e5b-0d55bc86acbb')
def test_list_back_end_storage_pools(self):
with self.rbac_utils.override_role(self):
diff --git a/patrole_tempest_plugin/tests/api/volume/test_snapshot_manage_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_snapshot_manage_rbac.py
index d238045..e2887e0 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_snapshot_manage_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_snapshot_manage_rbac.py
@@ -51,7 +51,7 @@
@decorators.idempotent_id('bd7d62f2-e485-4626-87ef-03b7f19ee1d0')
@rbac_rule_validation.action(
service="cinder",
- rule="snapshot_extension:snapshot_manage")
+ rules=["snapshot_extension:snapshot_manage"])
def test_manage_snapshot_rbac(self):
name = data_utils.rand_name(self.__class__.__name__ +
'-Managed-Snapshot')
@@ -73,7 +73,7 @@
@decorators.idempotent_id('4a2e8934-9c0b-434e-8f0b-e18b9aff126f')
@rbac_rule_validation.action(
service="cinder",
- rule="snapshot_extension:snapshot_unmanage")
+ rules=["snapshot_extension:snapshot_unmanage"])
def test_unmanage_snapshot_rbac(self):
with self.rbac_utils.override_role(self):
self.snapshots_client.unmanage_snapshot(self.snapshot['id'])
diff --git a/patrole_tempest_plugin/tests/api/volume/test_snapshots_actions_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_snapshots_actions_rbac.py
index 65b7526..ed42b2d 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_snapshots_actions_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_snapshots_actions_rbac.py
@@ -49,7 +49,7 @@
@rbac_rule_validation.action(
service="cinder",
- rule="volume_extension:snapshot_admin_actions:reset_status")
+ rules=["volume_extension:snapshot_admin_actions:reset_status"])
@decorators.idempotent_id('ea430145-34ef-408d-b678-95d5ae5f46eb')
def test_reset_snapshot_status(self):
status = 'error'
@@ -61,7 +61,7 @@
@rbac_rule_validation.action(
service="cinder",
- rule="volume_extension:snapshot_admin_actions:force_delete")
+ rules=["volume_extension:snapshot_admin_actions:force_delete"])
@decorators.idempotent_id('a8b0f7d8-4c00-4645-b8d5-33ab4eecc6cb')
def test_snapshot_force_delete(self):
temp_snapshot = self.create_snapshot(self.volume['id'])
@@ -73,7 +73,7 @@
@decorators.idempotent_id('a95eab2a-c441-4609-9235-f7478627da88')
@rbac_rule_validation.action(
service="cinder",
- rule="snapshot_extension:snapshot_actions:update_snapshot_status")
+ rules=["snapshot_extension:snapshot_actions:update_snapshot_status"])
def test_update_snapshot_status(self):
status = 'creating'
self.snapshots_client.reset_snapshot_status(
diff --git a/patrole_tempest_plugin/tests/api/volume/test_snapshots_metadata_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_snapshots_metadata_rbac.py
index 1c5fb2e..1141b7e 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_snapshots_metadata_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_snapshots_metadata_rbac.py
@@ -48,7 +48,7 @@
self.snapshot_id, metadata)['metadata']
@rbac_rule_validation.action(service="cinder",
- rule="volume:get_snapshot_metadata")
+ rules=["volume:get_snapshot_metadata"])
@decorators.idempotent_id('f6912bb1-62e6-483d-bcd0-e98c1641f4c3')
def test_get_snapshot_metadata(self):
# Create volume and snapshot metadata
@@ -60,7 +60,7 @@
@rbac_rule_validation.action(
service="cinder",
- rule="volume_extension:volume_tenant_attribute")
+ rules=["volume_extension:volume_tenant_attribute"])
@decorators.idempotent_id('e2c73b00-0c19-4bb7-8c61-d84b1a223ed1')
def test_get_snapshot_metadata_for_volume_tenant(self):
# Create volume and snapshot metadata
@@ -72,7 +72,7 @@
@decorators.idempotent_id('7ea597f6-c544-4b10-aab0-ff68f595fb06')
@rbac_rule_validation.action(service="cinder",
- rule="volume:update_snapshot_metadata")
+ rules=["volume:update_snapshot_metadata"])
def test_update_snapshot_metadata(self):
self._create_test_snapshot_metadata()
with self.rbac_utils.override_role(self):
@@ -83,7 +83,7 @@
@decorators.idempotent_id('93068d02-0131-4dd3-af16-fc40d7128d93')
@rbac_rule_validation.action(service="cinder",
- rule="volume:get_snapshot_metadata")
+ rules=["volume:get_snapshot_metadata"])
def test_show_snapshot_metadata_item(self):
self._create_test_snapshot_metadata()
with self.rbac_utils.override_role(self):
@@ -92,7 +92,7 @@
@decorators.idempotent_id('1f8f43e7-da31-4128-bb3c-73fc548650e3')
@rbac_rule_validation.action(service="cinder",
- rule="volume:update_snapshot_metadata")
+ rules=["volume:update_snapshot_metadata"])
def test_update_snapshot_metadata_item(self):
update_item = {"key3": "value3_update"}
self._create_test_snapshot_metadata()
@@ -102,7 +102,7 @@
@decorators.idempotent_id('3ec32516-f7cd-4f88-b78a-ddee67492071')
@rbac_rule_validation.action(service="cinder",
- rule="volume:delete_snapshot_metadata")
+ rules=["volume:delete_snapshot_metadata"])
def test_delete_snapshot_metadata_item(self):
self._create_test_snapshot_metadata()
with self.rbac_utils.override_role(self):
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 56ee1e0..962a9b1 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
@@ -65,7 +65,7 @@
@decorators.idempotent_id('bf7f31a1-509b-4a7d-a8a8-ad6ce68229c7')
@rbac_rule_validation.action(
service="cinder",
- rule="message:get_all")
+ rules=["message:get_all"])
def test_list_messages(self):
with self.rbac_utils.override_role(self):
self.messages_client.list_messages()['messages']
@@ -73,7 +73,7 @@
@decorators.idempotent_id('9cc1ad1e-68a2-4407-8b60-ea77909bce08')
@rbac_rule_validation.action(
service="cinder",
- rule="message:get")
+ rules=["message:get"])
def test_show_message(self):
message_id = self._create_user_message()
@@ -83,7 +83,7 @@
@decorators.idempotent_id('65ca7fb7-7f2c-443e-b144-ac86973a97be')
@rbac_rule_validation.action(
service="cinder",
- rule="message:delete")
+ rules=["message:delete"])
def test_delete_message(self):
message_id = self._create_user_message()
diff --git a/patrole_tempest_plugin/tests/api/volume/test_volume_actions_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_volume_actions_rbac.py
index a4fc3fd..2a5b9fe 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_volume_actions_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_volume_actions_rbac.py
@@ -76,7 +76,7 @@
@decorators.attr(type='slow')
@rbac_rule_validation.action(
service="cinder",
- rule="volume_extension:volume_actions:attach")
+ rules=["volume_extension:volume_actions:attach"])
@decorators.idempotent_id('f97b10e4-2eed-4f8b-8632-71c02cb9fe42')
def test_attach_volume_to_instance(self):
server = self._create_server()
@@ -94,7 +94,7 @@
@decorators.attr(type='slow')
@rbac_rule_validation.action(
service="cinder",
- rule="volume_extension:volume_actions:detach")
+ rules=["volume_extension:volume_actions:detach"])
@decorators.idempotent_id('5a042f6a-688b-42e6-a02e-fe5c47b89b07')
def test_detach_volume_from_instance(self):
server = self._create_server()
@@ -107,7 +107,7 @@
self.volumes_client, volume_id, 'available')
@rbac_rule_validation.action(service="cinder",
- rule="volume:update_readonly_flag")
+ rules=["volume:update_readonly_flag"])
@decorators.idempotent_id('2750717a-f250-4e41-9e09-02624aad6ff8')
def test_volume_readonly_update(self):
with self.rbac_utils.override_role(self):
@@ -118,7 +118,7 @@
@decorators.idempotent_id('59b783c0-f4ef-430c-8a90-1bad97d4ec5c')
@rbac_rule_validation.action(service="cinder",
- rule="volume:update")
+ rules=["volume:update"])
def test_volume_set_bootable(self):
with self.rbac_utils.override_role(self):
self.volumes_client.set_bootable_volume(self.volume['id'],
@@ -132,7 +132,7 @@
@decorators.idempotent_id('41566922-75a1-4484-99c7-9c8782ee99ac')
@rbac_rule_validation.action(
service="cinder",
- rule="volume_extension:volume_actions:reserve")
+ rules=["volume_extension:volume_actions:reserve"])
def test_volume_reserve(self):
with self.rbac_utils.override_role(self):
self.volumes_client.reserve_volume(self.volume['id'])
@@ -145,14 +145,14 @@
@decorators.idempotent_id('e5fa9564-77d9-4e57-b0c0-3e0ae4d08535')
@rbac_rule_validation.action(
service="cinder",
- rule="volume_extension:volume_actions:unreserve")
+ rules=["volume_extension:volume_actions:unreserve"])
def test_volume_unreserve(self):
with self.rbac_utils.override_role(self):
self.volumes_client.unreserve_volume(self.volume['id'])
@decorators.idempotent_id('c015c82f-7010-48cc-bd71-4ef542046f20')
@rbac_rule_validation.action(service="cinder",
- rule="volume:retype")
+ rules=["volume:retype"])
def test_volume_retype(self):
vol_type = self.create_volume_type()['name']
volume = self.create_volume()
@@ -164,7 +164,7 @@
@rbac_rule_validation.action(
service="cinder",
- rule="volume_extension:volume_admin_actions:reset_status")
+ rules=["volume_extension:volume_admin_actions:reset_status"])
@decorators.idempotent_id('4b3dad7d-0e73-4839-8781-796dd3d7af1d')
def test_volume_reset_status(self):
volume = self.create_volume()
@@ -175,7 +175,7 @@
@rbac_rule_validation.action(
service="cinder",
- rule="volume_extension:volume_admin_actions:force_delete")
+ rules=["volume_extension:volume_admin_actions:force_delete"])
@decorators.idempotent_id('a312a937-6abf-4b91-a950-747086cbce48')
def test_volume_force_delete(self):
volume = self.create_volume()
@@ -189,7 +189,7 @@
@utils.services('compute')
@rbac_rule_validation.action(
service="cinder",
- rule="volume_extension:volume_admin_actions:force_detach")
+ rules=["volume_extension:volume_admin_actions:force_detach"])
def test_force_detach_volume_from_instance(self):
volume = self.create_volume()
server = self._create_server()
@@ -227,7 +227,7 @@
@utils.services('image')
@rbac_rule_validation.action(
service="cinder",
- rule="volume_extension:volume_actions:upload_image")
+ rules=["volume_extension:volume_actions:upload_image"])
@decorators.idempotent_id('b0d0da46-903c-4445-893e-20e680d68b50')
def test_volume_upload_image(self):
# TODO(felipemonteiro): The ``upload_volume`` endpoint also enforces
@@ -251,7 +251,7 @@
@utils.services('image')
@rbac_rule_validation.action(
service="cinder",
- rule="volume_extension:volume_actions:upload_public")
+ rules=["volume_extension:volume_actions:upload_public"])
@decorators.idempotent_id('578a84dd-a6bd-4f97-a418-4a0c3c272c08')
def test_volume_upload_public(self):
# This also enforces "volume_extension:volume_actions:upload_image".
@@ -277,7 +277,7 @@
max_microversion = 'latest'
@decorators.idempotent_id('a654833d-4811-4acd-93ef-5ac4a34c75bc')
- @rbac_rule_validation.action(service="cinder", rule="volume:get_all")
+ @rbac_rule_validation.action(service="cinder", rules=["volume:get_all"])
def test_show_volume_summary(self):
with self.rbac_utils.override_role(self):
self.volumes_client.show_volume_summary()
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 a6ded52..ac2255a 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
@@ -32,7 +32,7 @@
cls.volume = cls.create_volume()
@rbac_rule_validation.action(service="cinder",
- rule="volume:create")
+ rules=["volume:create"])
@decorators.idempotent_id('426b08ef-6394-4d06-9128-965d5a6c38ef')
def test_create_volume(self):
name = data_utils.rand_name(self.__class__.__name__ + '-Volume')
@@ -41,12 +41,29 @@
with self.rbac_utils.override_role(self):
volume = self.volumes_client.create_volume(name=name, size=size)[
'volume']
+ # Use helper in base Tempest volume class which waits for deletion.
+ self.addCleanup(self.delete_volume, self.volumes_client, volume['id'])
+ waiters.wait_for_volume_resource_status(self.volumes_client,
+ volume['id'], 'available')
+
+ @decorators.idempotent_id('a009e6dc-e8bf-4412-99f5-8e45cffcffec')
+ @rbac_rule_validation.action(service="cinder",
+ rules=["volume:create_from_image"])
+ def test_create_volume_from_image(self):
+ name = data_utils.rand_name(self.__class__.__name__ + '-Volume')
+ size = CONF.volume.volume_size
+ img_uuid = CONF.compute.image_ref
+
+ with self.rbac_utils.override_role(self):
+ volume = self.volumes_client.create_volume(
+ name=name, size=size, imageRef=img_uuid)['volume']
+ # Use helper in base Tempest volume class which waits for deletion.
self.addCleanup(self.delete_volume, self.volumes_client, volume['id'])
waiters.wait_for_volume_resource_status(self.volumes_client,
volume['id'], 'available')
@rbac_rule_validation.action(service="cinder",
- rule="volume:delete")
+ rules=["volume:delete"])
@decorators.idempotent_id('6de9f9c2-509f-4558-867b-af21c7163be4')
def test_delete_volume(self):
volume = self.create_volume()
@@ -54,14 +71,14 @@
self.volumes_client.delete_volume(volume['id'])
self.volumes_client.wait_for_resource_deletion(volume['id'])
- @rbac_rule_validation.action(service="cinder", rule="volume:get")
+ @rbac_rule_validation.action(service="cinder", rules=["volume:get"])
@decorators.idempotent_id('c4c3fdd5-b1b1-49c3-b977-a9f40ee9257a')
def test_show_volume(self):
with self.rbac_utils.override_role(self):
self.volumes_client.show_volume(self.volume['id'])
@rbac_rule_validation.action(service="cinder",
- rule="volume:get_all")
+ rules=["volume:get_all"])
@decorators.idempotent_id('e3ab7906-b04b-4c45-aa11-1104d302f940')
def test_list_volumes(self):
with self.rbac_utils.override_role(self):
@@ -69,12 +86,12 @@
@decorators.idempotent_id('9b6d5beb-254f-4f1b-9906-0bdce4042f53')
@rbac_rule_validation.action(service="cinder",
- rule="volume:get_all")
+ rules=["volume:get_all"])
def test_list_volumes_with_details(self):
with self.rbac_utils.override_role(self):
self.volumes_client.list_volumes(detail=True)
- @rbac_rule_validation.action(service="cinder", rule="volume:update")
+ @rbac_rule_validation.action(service="cinder", rules=["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')
diff --git a/patrole_tempest_plugin/tests/api/volume/test_volume_hosts_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_volume_hosts_rbac.py
index c21c40e..8e2e264 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_volume_hosts_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_volume_hosts_rbac.py
@@ -22,7 +22,7 @@
class VolumeHostsV3RbacTest(rbac_base.BaseVolumeRbacTest):
@rbac_rule_validation.action(service="cinder",
- rule="volume_extension:hosts")
+ rules=["volume_extension:hosts"])
@decorators.idempotent_id('64e837f5-5452-4e26-b934-c721ea7a8644')
def test_list_hosts(self):
with self.rbac_utils.override_role(self):
@@ -30,7 +30,7 @@
@decorators.idempotent_id('9ddf321e-788f-4787-b8cc-dfa59e264143')
@rbac_rule_validation.action(service="cinder",
- rule="volume_extension:hosts")
+ rules=["volume_extension:hosts"])
def test_show_host(self):
hosts = self.volume_hosts_client.list_hosts()['hosts']
host_names = [host['host_name'] for host in hosts]
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 8a50141..6c2c84d 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
@@ -42,14 +42,14 @@
self.volume['id'], "key1")
@rbac_rule_validation.action(service="cinder",
- rule="volume:create_volume_metadata")
+ rules=["volume:create_volume_metadata"])
@decorators.idempotent_id('232bbb8b-4c29-44dc-9077-b1398c20b738')
def test_create_volume_metadata(self):
with self.rbac_utils.override_role(self):
self._add_metadata(self.volume)
@rbac_rule_validation.action(service="cinder",
- rule="volume:get_volume_metadata")
+ rules=["volume:get_volume_metadata"])
@decorators.idempotent_id('87ea37d9-23ab-47b2-a59c-16fc4d2c6dfa')
def test_show_volume_metadata(self):
with self.rbac_utils.override_role(self):
@@ -58,7 +58,7 @@
@decorators.idempotent_id('5c0f4c19-b448-4f51-9224-dad5faddc3bb')
@rbac_rule_validation.action(service="cinder",
- rule="volume:get_volume_metadata")
+ rules=["volume:get_volume_metadata"])
def test_show_volume_metadata_item(self):
self._add_metadata(self.volume)
@@ -67,7 +67,7 @@
self.volume['id'], "key1")
@rbac_rule_validation.action(service="cinder",
- rule="volume:delete_volume_metadata")
+ rules=["volume:delete_volume_metadata"])
@decorators.idempotent_id('7498dfc1-9db2-4423-ad20-e6dcb25d1beb')
def test_delete_volume_metadata_item(self):
self._add_metadata(self.volume)
@@ -77,7 +77,7 @@
"key1")
@rbac_rule_validation.action(service="cinder",
- rule="volume:update_volume_metadata")
+ rules=["volume:update_volume_metadata"])
@decorators.idempotent_id('8ce2ff80-99ba-49ae-9bb1-7e96729ee5af')
def test_update_volume_metadata_item(self):
self._add_metadata(self.volume)
@@ -88,7 +88,7 @@
@decorators.idempotent_id('a231b445-97a5-4657-b05f-245895e88da9')
@rbac_rule_validation.action(service="cinder",
- rule="volume:update_volume_metadata")
+ rules=["volume:update_volume_metadata"])
def test_update_volume_metadata(self):
self._add_metadata(self.volume)
updated_metadata = {"key1": "value1"}
@@ -99,7 +99,7 @@
@decorators.idempotent_id('39e8f82c-f1fc-4905-bf47-177ce2f71bb9')
@rbac_rule_validation.action(
service="cinder",
- rule="volume_extension:volume_image_metadata")
+ rules=["volume_extension:volume_image_metadata"])
def test_list_volumes_details_image_metadata(self):
self.volumes_client.update_volume_image_metadata(
self.volume['id'], image_id=self.image_id)
@@ -117,7 +117,7 @@
@decorators.idempotent_id('53f94d52-0dd5-42cf-a3a4-59b35150b3d5')
@rbac_rule_validation.action(
service="cinder",
- rule="volume_extension:volume_image_metadata")
+ rules=["volume_extension:volume_image_metadata"])
def test_show_volume_details_image_metadata(self):
self.volumes_client.update_volume_image_metadata(
self.volume['id'], image_id=self.image_id)
@@ -135,7 +135,7 @@
@decorators.idempotent_id('a9d9e825-5ea3-42e6-96f3-7ac4e97b2ed0')
@rbac_rule_validation.action(
service="cinder",
- rule="volume_extension:volume_image_metadata")
+ rules=["volume_extension:volume_image_metadata"])
def test_update_volume_image_metadata(self):
with self.rbac_utils.override_role(self):
self.volumes_client.update_volume_image_metadata(
@@ -146,7 +146,7 @@
@decorators.idempotent_id('a41c8eed-2051-4a25-b401-df036faacbdc')
@rbac_rule_validation.action(
service="cinder",
- rule="volume_extension:volume_image_metadata")
+ rules=["volume_extension:volume_image_metadata"])
def test_delete_volume_image_metadata(self):
self.volumes_client.update_volume_image_metadata(
self.volume['id'], image_id=self.image_id)
diff --git a/patrole_tempest_plugin/tests/api/volume/test_volume_quotas_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_volume_quotas_rbac.py
index 32cc48c..cd1fb6e 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_volume_quotas_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_volume_quotas_rbac.py
@@ -45,21 +45,21 @@
@decorators.idempotent_id('427c9f0c-982e-403d-ae45-c05f4d6322ff')
@rbac_rule_validation.action(service="cinder",
- rule="volume_extension:quotas:show")
+ rules=["volume_extension:quotas:show"])
def test_list_quotas(self):
with self.rbac_utils.override_role(self):
self.quotas_client.show_quota_set(self.demo_tenant_id)
@decorators.idempotent_id('e47cf444-2753-4983-be6d-fc0d6523720f')
@rbac_rule_validation.action(service="cinder",
- rule="volume_extension:quotas:show")
+ rules=["volume_extension:quotas:show"])
def test_list_quotas_usage_true(self):
with self.rbac_utils.override_role(self):
self.quotas_client.show_quota_set(self.demo_tenant_id,
params={'usage': True})
@rbac_rule_validation.action(service="cinder",
- rule="volume_extension:quotas:show")
+ rules=["volume_extension:quotas:show"])
@decorators.idempotent_id('b3c7177e-b6b1-4d0f-810a-fc95606964dd')
def test_list_default_quotas(self):
with self.rbac_utils.override_role(self):
@@ -67,7 +67,7 @@
self.demo_tenant_id)
@rbac_rule_validation.action(service="cinder",
- rule="volume_extension:quotas:update")
+ rules=["volume_extension:quotas:update"])
@decorators.idempotent_id('60f8f421-1630-4953-b449-b22af32265c7')
def test_update_quota_set(self):
self._restore_default_quota_set()
@@ -81,7 +81,7 @@
@decorators.idempotent_id('329bdb88-5132-4810-b1fc-350d181577e3')
@rbac_rule_validation.action(service="cinder",
- rule="volume_extension:quotas:delete")
+ rules=["volume_extension:quotas:delete"])
def test_delete_quota_set(self):
self._restore_default_quota_set()
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
index 1711c88..9f97a82 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_volume_services_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_volume_services_rbac.py
@@ -41,7 +41,7 @@
@decorators.idempotent_id('b9134f01-97c0-4abd-9455-fe2f03e3f966')
@rbac_rule_validation.action(
service="cinder",
- rule="volume_extension:services:index")
+ rules=["volume_extension:services:index"])
def test_list_services(self):
with self.rbac_utils.override_role(self):
self.services_client.list_services()['services']
diff --git a/patrole_tempest_plugin/tests/api/volume/test_volume_transfers_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_volume_transfers_rbac.py
index ad0d031..a18a370 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_volume_transfers_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_volume_transfers_rbac.py
@@ -49,14 +49,14 @@
return transfer
@rbac_rule_validation.action(service="cinder",
- rule="volume:create_transfer")
+ rules=["volume:create_transfer"])
@decorators.idempotent_id('25413af4-468d-48ff-94ca-4436f8526b3e')
def test_create_volume_transfer(self):
with self.rbac_utils.override_role(self):
self._create_transfer()
@rbac_rule_validation.action(service="cinder",
- rule="volume:get_transfer")
+ rules=["volume:get_transfer"])
@decorators.idempotent_id('7a0925d3-ed97-4c25-8299-e5cdabe2eb55')
def test_get_volume_transfer(self):
transfer = self._create_transfer()
@@ -64,7 +64,7 @@
self.transfers_client.show_volume_transfer(transfer['id'])
@rbac_rule_validation.action(service="cinder",
- rule="volume:get_all_transfers")
+ rules=["volume:get_all_transfers"])
@decorators.idempotent_id('02a06f2b-5040-49e2-b2b7-619a7db59603')
def test_list_volume_transfers(self):
with self.rbac_utils.override_role(self):
@@ -72,13 +72,13 @@
@decorators.idempotent_id('e84e45b0-9872-40bf-bf44-971266161a86')
@rbac_rule_validation.action(service="cinder",
- rule="volume:get_all_transfers")
+ rules=["volume:get_all_transfers"])
def test_list_volume_transfers_details(self):
with self.rbac_utils.override_role(self):
self.transfers_client.list_volume_transfers(detail=True)
@rbac_rule_validation.action(service="cinder",
- rule="volume:accept_transfer")
+ rules=["volume:accept_transfer"])
@decorators.idempotent_id('987f2a11-d657-4984-a6c9-28f06c1cd014')
def test_accept_volume_transfer(self):
transfer = self._create_transfer()
@@ -87,7 +87,7 @@
transfer['id'], auth_key=transfer['auth_key'])
@rbac_rule_validation.action(service="cinder",
- rule="volume:delete_transfer")
+ rules=["volume:delete_transfer"])
@decorators.idempotent_id('4672187e-7fff-454b-832a-5c8865dda868')
def test_delete_volume_transfer(self):
transfer = self._create_transfer()
diff --git a/patrole_tempest_plugin/tests/api/volume/test_volume_types_access_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_volume_types_access_rbac.py
index 89dc0a2..3aed54d 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_volume_types_access_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_volume_types_access_rbac.py
@@ -52,7 +52,7 @@
@decorators.idempotent_id('af70e6ad-e931-419f-9200-8bcc284e4e47')
@rbac_rule_validation.action(
service="cinder",
- rule="volume_extension:volume_type_access")
+ rules=["volume_extension:volume_type_access"])
def test_list_type_access(self):
self._add_type_access()
@@ -63,7 +63,7 @@
@decorators.idempotent_id('b462eeba-45d0-4d6e-945a-a1d27708d367')
@rbac_rule_validation.action(
service="cinder",
- rule="volume_extension:volume_type_access:addProjectAccess")
+ rules=["volume_extension:volume_type_access:addProjectAccess"])
def test_add_type_access(self):
with self.rbac_utils.override_role(self):
self._add_type_access(ignore_not_found=True)
@@ -71,7 +71,7 @@
@decorators.idempotent_id('8f848aeb-636a-46f1-aeeb-e2a60e9d2bfe')
@rbac_rule_validation.action(
service="cinder",
- rule="volume_extension:volume_type_access:removeProjectAccess")
+ rules=["volume_extension:volume_type_access:removeProjectAccess"])
def test_remove_type_access(self):
self._add_type_access(ignore_not_found=True)
diff --git a/patrole_tempest_plugin/tests/api/volume/test_volume_types_extra_specs_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_volume_types_extra_specs_rbac.py
index 8d4c265..b610dde 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_volume_types_extra_specs_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_volume_types_extra_specs_rbac.py
@@ -55,7 +55,7 @@
@decorators.idempotent_id('76c36be2-2b6c-4acf-9aac-c9dc5c17cdbe')
@rbac_rule_validation.action(
service="cinder",
- rule="volume_extension:types_extra_specs:index")
+ rules=["volume_extension:types_extra_specs:index"])
def test_list_volume_types_extra_specs(self):
with self.rbac_utils.override_role(self):
self.volume_types_client.list_volume_types_extra_specs(
@@ -63,7 +63,7 @@
@rbac_rule_validation.action(
service="cinder",
- rule="volume_extension:types_extra_specs:create")
+ rules=["volume_extension:types_extra_specs:create"])
@decorators.idempotent_id('eea40251-990b-49b0-99ae-10e4585b479b')
def test_create_volume_type_extra_specs(self):
with self.rbac_utils.override_role(self):
@@ -72,7 +72,7 @@
@decorators.idempotent_id('e2dcc9c6-2fef-431d-afaf-92b45bc76d1a')
@rbac_rule_validation.action(
service="cinder",
- rule="volume_extension:types_extra_specs:show")
+ rules=["volume_extension:types_extra_specs:show"])
def test_show_volume_type_extra_specs(self):
self._create_volume_type_extra_specs()
@@ -83,7 +83,7 @@
@decorators.idempotent_id('93001912-f938-41c7-8787-62dc7010fd52')
@rbac_rule_validation.action(
service="cinder",
- rule="volume_extension:types_extra_specs:delete")
+ rules=["volume_extension:types_extra_specs:delete"])
def test_delete_volume_type_extra_specs(self):
self._create_volume_type_extra_specs(ignore_not_found=True)
@@ -94,7 +94,7 @@
@decorators.idempotent_id('0a444437-7402-4fbe-a18a-93af2ee00618')
@rbac_rule_validation.action(
service="cinder",
- rule="volume_extension:types_extra_specs:update")
+ rules=["volume_extension:types_extra_specs:update"])
def test_update_volume_type_extra_specs(self):
self._create_volume_type_extra_specs()
update_extra_specs = {self.spec_key: "val2"}
diff --git a/patrole_tempest_plugin/tests/api/volume/test_volume_types_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_volume_types_rbac.py
index a37661e..a5bec1f 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_volume_types_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_volume_types_rbac.py
@@ -24,7 +24,7 @@
@decorators.idempotent_id('e2bbf968-d947-4a15-a4da-a98c3069731e')
@rbac_rule_validation.action(
service="cinder",
- rule="volume_extension:types_manage")
+ rules=["volume_extension:types_manage"])
def test_create_volume_type(self):
with self.rbac_utils.override_role(self):
self.create_volume_type()
@@ -32,7 +32,7 @@
@decorators.idempotent_id('2b74ac82-e03e-4801-86f3-d05c9acfd66b')
@rbac_rule_validation.action(
service="cinder",
- rule="volume_extension:types_manage")
+ rules=["volume_extension:types_manage"])
def test_update_volume_type(self):
volume_type = self.create_volume_type()
with self.rbac_utils.override_role(self):
@@ -42,7 +42,7 @@
@decorators.idempotent_id('90aec0ef-4f9b-4170-be6b-a392c12540be')
@rbac_rule_validation.action(
service="cinder",
- rule="volume_extension:types_manage")
+ rules=["volume_extension:types_manage"])
def test_delete_volume_type(self):
volume_type = self.create_volume_type()
with self.rbac_utils.override_role(self):
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 1e0a17d..bf22341 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_volumes_backup_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_volumes_backup_rbac.py
@@ -57,7 +57,7 @@
@decorators.attr(type='slow')
@rbac_rule_validation.action(service="cinder",
- rule="backup:create")
+ rules=["backup:create"])
@decorators.idempotent_id('6887ec94-0bcf-4ab7-b30f-3808a4b5a2a5')
def test_create_backup(self):
backup_name = data_utils.rand_name(self.__class__.__name__ + '-Backup')
@@ -73,14 +73,14 @@
@decorators.attr(type='slow')
@rbac_rule_validation.action(service="cinder",
- rule="backup:get")
+ rules=["backup:get"])
@decorators.idempotent_id('abd92bdd-b0fb-4dc4-9cfc-de9e968f8c8a')
def test_show_backup(self):
with self.rbac_utils.override_role(self):
self.backups_client.show_backup(self.backup['id'])
@rbac_rule_validation.action(service="cinder",
- rule="backup:get_all")
+ rules=["backup:get_all"])
@decorators.idempotent_id('4d18f0f0-7e01-4007-b622-dedc859b22f6')
def test_list_backups(self):
with self.rbac_utils.override_role(self):
@@ -88,7 +88,7 @@
@decorators.idempotent_id('dbd69865-876f-4835-b70e-7341153fb162')
@rbac_rule_validation.action(service="cinder",
- rule="backup:get_all")
+ rules=["backup:get_all"])
def test_list_backups_with_details(self):
with self.rbac_utils.override_role(self):
self.backups_client.list_backups(detail=True)
@@ -97,7 +97,7 @@
@decorators.idempotent_id('50f43bde-205e-438e-9a05-5eac07fc3d63')
@rbac_rule_validation.action(
service="cinder",
- rule="volume_extension:backup_admin_actions:reset_status")
+ rules=["volume_extension:backup_admin_actions:reset_status"])
def test_reset_backup_status(self):
# Use instance-level create_backup for easier debugging.
backup = self.create_backup(volume_id=self.volume['id'])
@@ -112,7 +112,7 @@
@decorators.attr(type='slow')
@rbac_rule_validation.action(service="cinder",
- rule="backup:restore")
+ rules=["backup:restore"])
@decorators.idempotent_id('9c794bf9-2446-4f41-8fe0-80b71e757f9d')
def test_restore_backup(self):
with self.rbac_utils.override_role(self):
@@ -125,7 +125,7 @@
@decorators.attr(type='slow')
@rbac_rule_validation.action(service="cinder",
- rule="backup:delete")
+ rules=["backup:delete"])
@decorators.idempotent_id('d5d0c6a2-413d-437e-a73f-4bf2b41a20ed')
def test_delete_backup(self):
# Do not call the create_backup in Tempest's base volume class, because
@@ -147,7 +147,7 @@
@decorators.attr(type='slow')
@rbac_rule_validation.action(service="cinder",
- rule="backup:export-import")
+ rules=["backup:export-import"])
@decorators.idempotent_id('e984ec8d-e8eb-485c-98bc-f1856020303c')
def test_export_backup(self):
with self.rbac_utils.override_role(self):
@@ -156,7 +156,7 @@
@decorators.attr(type='slow')
@rbac_rule_validation.action(service="cinder",
- rule="backup:backup-import")
+ rules=["backup:backup-import"])
@decorators.idempotent_id('1e70f039-4556-44cc-9cc1-edf2b7ed648b')
def test_import_backup(self):
export_backup = self.backups_client.export_backup(
@@ -202,7 +202,7 @@
@decorators.idempotent_id('69801485-d5be-4e75-bbb4-168d50b5a8c2')
@rbac_rule_validation.action(service="cinder",
- rule="backup:backup_project_attribute")
+ rules=["backup:backup_project_attribute"])
def test_show_backup_project_attribute(self):
with self.rbac_utils.override_role(self):
body = self.backups_client.show_backup(self.backup['id'])['backup']
@@ -215,7 +215,7 @@
@decorators.idempotent_id('aa40b7c0-5974-48be-8cbc-e23cc61c4c68')
@rbac_rule_validation.action(service="cinder",
- rule="backup:backup_project_attribute")
+ rules=["backup:backup_project_attribute"])
def test_list_backup_details_project_attribute(self):
with self.rbac_utils.override_role(self):
body = self.backups_client.list_backups(detail=True)['backups']
@@ -246,7 +246,7 @@
@decorators.idempotent_id('b45b0e98-6eb8-4c62-aa53-0f8c7c09faa6')
@rbac_rule_validation.action(
service="cinder",
- rule="backup:update")
+ rules=["backup:update"])
def test_backup_update(self):
update_kwargs = {
'name': data_utils.rand_name(self.__class__.__name__ + '-Backup'),
diff --git a/patrole_tempest_plugin/tests/api/volume/test_volumes_extend_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_volumes_extend_rbac.py
index 18883c9..ec6cf66 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_volumes_extend_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_volumes_extend_rbac.py
@@ -28,7 +28,7 @@
# Create a test shared volume for tests
cls.volume = cls.create_volume()
- @rbac_rule_validation.action(service="cinder", rule="volume:extend")
+ @rbac_rule_validation.action(service="cinder", rules=["volume:extend"])
@decorators.idempotent_id('1627b065-4081-4e14-8340-8e4fb02ceaf2')
def test_volume_extend(self):
# Extend volume test
diff --git a/patrole_tempest_plugin/tests/api/volume/test_volumes_manage_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_volumes_manage_rbac.py
index 852d81e..2782e22 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_volumes_manage_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_volumes_manage_rbac.py
@@ -66,7 +66,7 @@
@rbac_rule_validation.action(
service="cinder",
- rule="volume_extension:volume_manage")
+ rules=["volume_extension:volume_manage"])
@decorators.idempotent_id('114f9708-939b-407e-aeac-d21ebfabaad3')
def test_volume_manage(self):
volume_id = self.create_volume()['id']
@@ -108,7 +108,7 @@
@rbac_rule_validation.action(
service="cinder",
- rule="volume_extension:volume_unmanage")
+ rules=["volume_extension:volume_unmanage"])
@decorators.idempotent_id('d5d72abe-60bc-45ac-a8f2-c21b24f0b5d6')
def test_volume_unmanage(self):
volume_id = self.create_volume()['id']
diff --git a/patrole_tempest_plugin/tests/api/volume/test_volumes_snapshots_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_volumes_snapshots_rbac.py
index 7d721c4..40469a2 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_volumes_snapshots_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_volumes_snapshots_rbac.py
@@ -46,7 +46,7 @@
detail=with_detail, **params)['snapshots']
@rbac_rule_validation.action(service="cinder",
- rule="volume:create_snapshot")
+ rules=["volume:create_snapshot"])
@decorators.idempotent_id('ac7b2ee5-fbc0-4360-afc2-de8fa4881ede')
def test_create_snapshot(self):
# Create a temp snapshot
@@ -54,7 +54,7 @@
self.create_snapshot(self.volume['id'])
@rbac_rule_validation.action(service="cinder",
- rule="volume:get_snapshot")
+ rules=["volume:get_snapshot"])
@decorators.idempotent_id('93a11b40-1ba8-44d6-a196-f8d97220f796')
def test_show_snapshot(self):
# Get the snapshot
@@ -65,7 +65,7 @@
@decorators.idempotent_id('5d6f5f21-9293-4f2a-8f44-cabdc24d92cb')
@rbac_rule_validation.action(
service="cinder",
- rule="volume_extension:extended_snapshot_attributes")
+ rules=["volume_extension:extended_snapshot_attributes"])
def test_show_snapshot_with_extended_attributes(self):
"""List snapshots with extended attributes."""
expected_attrs = ('os-extended-snapshot-attributes:project_id',
@@ -80,7 +80,7 @@
attribute=expected_attr)
@rbac_rule_validation.action(service="cinder",
- rule="volume:update_snapshot")
+ rules=["volume:update_snapshot"])
@decorators.idempotent_id('53fe8ee3-3bea-4ae8-a979-3c98ea72f620')
def test_update_snapshot(self):
new_desc = 'This is the new description of snapshot.'
@@ -93,7 +93,7 @@
self.snapshots_client, self.snapshot['id'], 'available')
@rbac_rule_validation.action(service="cinder",
- rule="volume:delete_snapshot")
+ rules=["volume:delete_snapshot"])
@decorators.idempotent_id('c7fe54ec-3b70-4772-ba11-f166d95888a3')
def test_delete_snapshot(self):
# Create a temp snapshot
@@ -105,7 +105,7 @@
temp_snapshot['id'])
@rbac_rule_validation.action(service="cinder",
- rule="volume:get_all_snapshots")
+ rules=["volume:get_all_snapshots"])
@decorators.idempotent_id('e4edf0c0-2cd3-420f-b8ab-4d98a0718608')
def test_list_snapshots(self):
"""List snapshots with params."""
@@ -115,7 +115,7 @@
@decorators.idempotent_id('f3155d8e-45ee-45c9-910d-18c0242229e1')
@rbac_rule_validation.action(service="cinder",
- rule="volume:get_all_snapshots")
+ rules=["volume:get_all_snapshots"])
def test_list_snapshots_details(self):
"""List snapshots details with params."""
params = {'name': self.snapshot['name']}
@@ -125,7 +125,7 @@
@decorators.idempotent_id('dd37f388-2731-446d-a78f-676997ebb04a')
@rbac_rule_validation.action(
service="cinder",
- rule="volume_extension:extended_snapshot_attributes")
+ rules=["volume_extension:extended_snapshot_attributes"])
def test_list_snapshots_details_with_extended_attributes(self):
"""List snapshots details with extended attributes."""
expected_attrs = ('os-extended-snapshot-attributes:project_id',
diff --git a/patrole_tempest_plugin/tests/unit/fixtures.py b/patrole_tempest_plugin/tests/unit/fixtures.py
index 1c47985..4552224 100644
--- a/patrole_tempest_plugin/tests/unit/fixtures.py
+++ b/patrole_tempest_plugin/tests/unit/fixtures.py
@@ -16,6 +16,7 @@
"""Fixtures for Patrole tests."""
from __future__ import absolute_import
+from contextlib import contextmanager
import fixtures
import mock
import time
@@ -117,6 +118,17 @@
new_role = 'member' if role_toggle else 'admin'
self.set_roles(['admin', 'member'], [new_role])
+ @contextmanager
+ def real_override_role(self, test_obj):
+ """Actual call to ``override_role``.
+
+ Useful for ensuring all the necessary mocks are performed before
+ the method in question is called.
+ """
+ _rbac_utils = rbac_utils.RbacUtils(test_obj)
+ with _rbac_utils.override_role(test_obj):
+ yield
+
def set_roles(self, roles, roles_on_project=None):
"""Set the list of available roles in the system.
diff --git a/patrole_tempest_plugin/tests/unit/resources/custom_rbac_policy.yaml b/patrole_tempest_plugin/tests/unit/resources/custom_rbac_policy.yaml
new file mode 100644
index 0000000..444bd2e
--- /dev/null
+++ b/patrole_tempest_plugin/tests/unit/resources/custom_rbac_policy.yaml
@@ -0,0 +1,13 @@
+---
+even_rule: role:two or role:four or role:six or role:eight
+odd_rule: role:one or role:three or role:five or role:seven or role:nine
+zero_rule: role:zero
+prime_rule: role:one or role:two or role:three or role:five or role:seven
+all_rule: ''
+
+policy_action_1: rule:even_rule
+policy_action_2: rule:odd_rule
+policy_action_3: rule:zero_rule
+policy_action_4: rule:prime_rule
+policy_action_5: rule:all_rule
+policy_action_6: role:eight
diff --git a/patrole_tempest_plugin/tests/unit/test_policy_authority.py b/patrole_tempest_plugin/tests/unit/test_policy_authority.py
index d396a29..624c0c5 100644
--- a/patrole_tempest_plugin/tests/unit/test_policy_authority.py
+++ b/patrole_tempest_plugin/tests/unit/test_policy_authority.py
@@ -13,7 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
import mock
import os
@@ -61,11 +60,14 @@
self.tenant_policy_file = os.path.join(current_directory,
'resources',
'tenant_rbac_policy.json')
- self.conf_policy_path = os.path.join(
+ self.conf_policy_path_json = os.path.join(
current_directory, 'resources', '%s.json')
+ self.conf_policy_path_yaml = os.path.join(
+ current_directory, 'resources', '%s.yaml')
+
self.useFixture(fixtures.ConfPatcher(
- custom_policy_files=[self.conf_policy_path], group='patrole'))
+ custom_policy_files=[self.conf_policy_path_json], group='patrole'))
self.useFixture(fixtures.ConfPatcher(
api_v3=True, api_v2=False, group='identity-feature-enabled'))
@@ -74,13 +76,18 @@
if attr in dir(policy_authority.PolicyAuthority):
delattr(policy_authority.PolicyAuthority, attr)
- def _get_fake_policy_rule(self, name, rule):
- fake_rule = mock.Mock(check=rule, __name__='foo')
- fake_rule.name = name
- return fake_rule
+ @staticmethod
+ def _get_fake_policies(rules):
+ fake_rules = []
+ rules = policy_authority.policy.Rules.from_dict(rules)
+ for name, check in rules.items():
+ fake_rule = mock.Mock(check=check, __name__='foo')
+ fake_rule.name = name
+ fake_rules.append(fake_rule)
+ return fake_rules
@mock.patch.object(policy_authority, 'LOG', autospec=True)
- def test_custom_policy(self, m_log):
+ def _test_custom_policy(self, *args):
default_roles = ['zero', 'one', 'two', 'three', 'four',
'five', 'six', 'seven', 'eight', 'nine']
@@ -105,6 +112,16 @@
for role in set(default_roles) - set(role_list):
self.assertFalse(authority.allowed(rule, role))
+ def test_custom_policy_json(self):
+ # The CONF.patrole.custom_policy_files has a path to JSON file by
+ # default, so we don't need to use ConfPatcher here.
+ self._test_custom_policy()
+
+ def test_custom_policy_yaml(self):
+ self.useFixture(fixtures.ConfPatcher(
+ custom_policy_files=[self.conf_policy_path_yaml], group='patrole'))
+ self._test_custom_policy()
+
def test_admin_policy_file_with_admin_role(self):
test_tenant_id = mock.sentinel.tenant_id
test_user_id = mock.sentinel.user_id
@@ -270,9 +287,9 @@
fake_rule = 'fake_rule'
expected_message = (
- "Policy action \"{0}\" not found in policy file: {1} or among "
- "registered policy in code defaults for service.").format(
- fake_rule, self.custom_policy_file)
+ 'Policy action "{0}" not found in policy files: {1} or among '
+ 'registered policy in code defaults for {2} service.').format(
+ fake_rule, [self.custom_policy_file], "custom_rbac_policy")
e = self.assertRaises(rbac_exceptions.RbacParsingException,
authority.allowed, fake_rule, None)
@@ -292,9 +309,10 @@
mock.sentinel.error)})
expected_message = (
- "Policy action \"{0}\" not found in policy file: {1} or among "
- "registered policy in code defaults for service.").format(
- mock.sentinel.rule, self.custom_policy_file)
+ 'Policy action "{0}" not found in policy files: {1} or among '
+ 'registered policy in code defaults for {2} service.').format(
+ mock.sentinel.rule, [self.custom_policy_file],
+ "custom_rbac_policy")
e = self.assertRaises(rbac_exceptions.RbacParsingException,
authority.allowed, mock.sentinel.rule, None)
@@ -302,18 +320,15 @@
m_log.debug.assert_called_once_with(expected_message)
@mock.patch.object(policy_authority, 'stevedore', autospec=True)
- def test_get_policy_data_from_file_and_from_code(self, mock_stevedore):
- fake_policy_rules = [
- self._get_fake_policy_rule('code_policy_action_1',
- 'rule:code_rule_1'),
- self._get_fake_policy_rule('code_policy_action_2',
- 'rule:code_rule_2'),
- self._get_fake_policy_rule('code_policy_action_3',
- 'rule:code_rule_3'),
- ]
+ def test_get_rules_from_file_and_from_code(self, mock_stevedore):
+ fake_policy_rules = self._get_fake_policies({
+ 'code_policy_action_1': 'rule:code_rule_1',
+ 'code_policy_action_2': 'rule:code_rule_2',
+ 'code_policy_action_3': 'rule:code_rule_3',
+ })
mock_manager = mock.Mock(obj=fake_policy_rules, __name__='foo')
- mock_manager.configure_mock(name='fake_service')
+ mock_manager.configure_mock(name='tenant_rbac_policy')
mock_stevedore.named.NamedExtensionManager.return_value = [
mock_manager
]
@@ -323,10 +338,10 @@
authority = policy_authority.PolicyAuthority(
test_tenant_id, test_user_id, "tenant_rbac_policy")
- policy_data = authority._get_policy_data('fake_service')
- self.assertIsInstance(policy_data, str)
+ rules = authority.get_rules()
+ self.assertIsInstance(rules, policy_authority.policy.Rules)
- actual_policy_data = json.loads(policy_data)
+ actual_policy_data = {k: str(v) for k, v in rules.items()}
expected_policy_data = {
"code_policy_action_1": "rule:code_rule_1",
"code_policy_action_2": "rule:code_rule_2",
@@ -335,26 +350,25 @@
"rule2": "tenant_id:%(tenant_id)s",
"rule3": "project_id:%(project_id)s",
"rule4": "user_id:%(user_id)s",
- "admin_tenant_rule": "role:admin and tenant_id:%(tenant_id)s",
- "admin_user_rule": "role:admin and user_id:%(user_id)s"
+ "admin_tenant_rule": "(role:admin and tenant_id:%(tenant_id)s)",
+ "admin_user_rule": "(role:admin and user_id:%(user_id)s)"
}
self.assertEqual(expected_policy_data, actual_policy_data)
@mock.patch.object(policy_authority, 'stevedore', autospec=True)
- def test_get_policy_data_from_file_and_from_code_with_overwrite(
+ def test_get_rules_from_file_and_from_code_with_overwrite(
self, mock_stevedore):
# The custom policy file should overwrite default rules rule1 and rule2
# that are defined in code.
- fake_policy_rules = [
- self._get_fake_policy_rule('rule1', 'rule:code_rule_1'),
- self._get_fake_policy_rule('rule2', 'rule:code_rule_2'),
- self._get_fake_policy_rule('code_policy_action_3',
- 'rule:code_rule_3'),
- ]
+ fake_policy_rules = self._get_fake_policies({
+ 'rule1': 'rule:code_rule_1',
+ 'rule2': 'rule:code_rule_2',
+ 'code_policy_action_3': 'rule:code_rule_3',
+ })
mock_manager = mock.Mock(obj=fake_policy_rules, __name__='foo')
- mock_manager.configure_mock(name='fake_service')
+ mock_manager.configure_mock(name='tenant_rbac_policy')
mock_stevedore.named.NamedExtensionManager.return_value = [
mock_manager
]
@@ -364,81 +378,51 @@
authority = policy_authority.PolicyAuthority(
test_tenant_id, test_user_id, 'tenant_rbac_policy')
- policy_data = authority._get_policy_data('fake_service')
- self.assertIsInstance(policy_data, str)
+ rules = authority.get_rules()
+ self.assertIsInstance(rules, policy_authority.policy.Rules)
- actual_policy_data = json.loads(policy_data)
+ actual_policy_data = {k: str(v) for k, v in rules.items()}
expected_policy_data = {
"code_policy_action_3": "rule:code_rule_3",
"rule1": "tenant_id:%(network:tenant_id)s",
"rule2": "tenant_id:%(tenant_id)s",
"rule3": "project_id:%(project_id)s",
"rule4": "user_id:%(user_id)s",
- "admin_tenant_rule": "role:admin and tenant_id:%(tenant_id)s",
- "admin_user_rule": "role:admin and user_id:%(user_id)s"
+ "admin_tenant_rule": "(role:admin and tenant_id:%(tenant_id)s)",
+ "admin_user_rule": "(role:admin and user_id:%(user_id)s)"
}
self.assertEqual(expected_policy_data, actual_policy_data)
@mock.patch.object(policy_authority, 'stevedore', autospec=True)
- def test_get_policy_data_cannot_find_policy(self, mock_stevedore):
+ def test_get_rules_cannot_find_policy(self, mock_stevedore):
mock_stevedore.named.NamedExtensionManager.return_value = None
e = self.assertRaises(rbac_exceptions.RbacParsingException,
policy_authority.PolicyAuthority,
None, None, 'test_service')
expected_error = (
- 'Policy file for {0} service was not found among the registered '
+ 'Policy files for {0} service were not found among the registered '
'in-code policies or in any of the possible policy files: {1}.'
.format('test_service',
[CONF.patrole.custom_policy_files[0] % 'test_service']))
self.assertIn(expected_error, str(e))
- @mock.patch.object(policy_authority, 'json', autospec=True)
+ @mock.patch.object(policy_authority.policy, 'parse_file_contents',
+ autospec=True)
@mock.patch.object(policy_authority, 'stevedore', autospec=True)
- def test_get_policy_data_without_valid_policy(self, mock_stevedore,
- mock_json):
- test_policy_action = mock.Mock(check='rule:bar', __name__='foo')
- test_policy_action.configure_mock(name='foo')
-
- test_policy = mock.Mock(obj=[test_policy_action], __name__='foo')
- test_policy.configure_mock(name='test_service')
-
- mock_stevedore.named.NamedExtensionManager\
- .return_value = [test_policy]
-
- mock_json.dumps.side_effect = ValueError
-
- e = self.assertRaises(rbac_exceptions.RbacParsingException,
- policy_authority.PolicyAuthority,
- None, None, 'test_service')
-
- expected_error = "Policy file for {0} service is invalid."\
- .format("test_service")
- self.assertIn(expected_error, str(e))
-
- mock_stevedore.named.NamedExtensionManager.assert_called_once_with(
- 'oslo.policy.policies',
- names=['test_service'],
- on_load_failure_callback=None,
- invoke_on_load=True,
- warn_on_missing_entrypoint=False)
-
- @mock.patch.object(policy_authority, 'json', autospec=True)
- @mock.patch.object(policy_authority, 'stevedore', autospec=True)
- def test_get_policy_data_from_file_not_json(self, mock_stevedore,
- mock_json):
+ def test_get_rules_without_valid_policy(self, mock_stevedore,
+ mock_parse_file_contents):
mock_stevedore.named.NamedExtensionManager.return_value = None
- mock_json.loads.side_effect = ValueError
+ mock_parse_file_contents.side_effect = ValueError
e = self.assertRaises(rbac_exceptions.RbacParsingException,
policy_authority.PolicyAuthority,
None, None, 'tenant_rbac_policy')
expected_error = (
- 'Policy file for {0} service was not found among the registered '
- 'in-code policies or in any of the possible policy files: {1}.'
- .format('tenant_rbac_policy', [CONF.patrole.custom_policy_files[0]
- % 'tenant_rbac_policy']))
+ 'Policy files for {0} service were not found among the registered '
+ 'in-code policies or in any of the possible policy files:'
+ .format('tenant_rbac_policy'))
self.assertIn(expected_error, str(e))
def test_discover_policy_files(self):
@@ -450,56 +434,62 @@
dir(policy_authority.PolicyAuthority))
self.assertIn('policy_files', dir(policy_parser))
self.assertIn('tenant_rbac_policy', policy_parser.policy_files)
- self.assertEqual(self.conf_policy_path % 'tenant_rbac_policy',
+ self.assertEqual([self.conf_policy_path_json % 'tenant_rbac_policy'],
policy_parser.policy_files['tenant_rbac_policy'])
@mock.patch.object(policy_authority, 'policy', autospec=True)
- @mock.patch.object(policy_authority.PolicyAuthority, '_get_policy_data',
+ @mock.patch.object(policy_authority.PolicyAuthority, 'get_rules',
autospec=True)
@mock.patch.object(policy_authority, 'clients', autospec=True)
@mock.patch.object(policy_authority, 'os', autospec=True)
- def test_discover_policy_files_with_many_invalid_one_valid(self, m_os,
- m_creds, *args):
+ @mock.patch.object(policy_authority, 'glob', autospec=True)
+ def test_discover_policy_files_with_many_invalid_one_valid(self, m_glob,
+ m_os, m_creds,
+ *args):
+ service = 'test_service'
+ custom_policy_files = ['foo/%s', 'bar/%s', 'baz/%s']
+ m_glob.iglob.side_effect = [iter([path % service])
+ for path in custom_policy_files]
# Only the 3rd path is valid.
- m_os.path.isfile.side_effect = [False, False, True, False]
+ m_os.path.isfile.side_effect = [False, False, True]
# Ensure the outer for loop runs only once in `discover_policy_files`.
m_creds.Manager().identity_services_v3_client.\
list_services.return_value = {
- 'services': [{'name': 'test_service'}]}
+ 'services': [{'name': service}]}
# The expected policy will be 'baz/test_service'.
self.useFixture(fixtures.ConfPatcher(
- custom_policy_files=['foo/%s', 'bar/%s', 'baz/%s'],
+ custom_policy_files=custom_policy_files,
group='patrole'))
policy_parser = policy_authority.PolicyAuthority(
- None, None, 'test_service')
+ None, None, service)
# Ensure that "policy_files" is set at class and instance levels.
- self.assertIn('policy_files',
- dir(policy_authority.PolicyAuthority))
- self.assertIn('policy_files', dir(policy_parser))
- self.assertIn('test_service', policy_parser.policy_files)
- self.assertEqual('baz/test_service',
- policy_parser.policy_files['test_service'])
+ self.assertTrue(hasattr(policy_authority.PolicyAuthority,
+ 'policy_files'))
+ self.assertTrue(hasattr(policy_parser, 'policy_files'))
+ self.assertEqual(['baz/%s' % service],
+ policy_parser.policy_files[service])
def test_discover_policy_files_with_no_valid_files(self):
expected_error = (
- 'Policy file for {0} service was not found among the registered '
+ 'Policy files for {0} service were not found among the registered '
'in-code policies or in any of the possible policy files: {1}.'
- .format('test_service', [self.conf_policy_path % 'test_service']))
+ .format('test_service',
+ [self.conf_policy_path_json % 'test_service']))
e = self.assertRaises(rbac_exceptions.RbacParsingException,
policy_authority.PolicyAuthority,
None, None, 'test_service')
self.assertIn(expected_error, str(e))
- self.assertIn('policy_files',
- dir(policy_authority.PolicyAuthority))
- self.assertNotIn(
- 'test_service',
- policy_authority.PolicyAuthority.policy_files.keys())
+ self.assertTrue(hasattr(policy_authority.PolicyAuthority,
+ 'policy_files'))
+ self.assertEqual(
+ [],
+ policy_authority.PolicyAuthority.policy_files['test_service'])
def _test_validate_service(self, v2_services, v3_services,
expected_failure=False, expected_services=None):
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 1bf5510..1a2c691 100644
--- a/patrole_tempest_plugin/tests/unit/test_rbac_rule_validation.py
+++ b/patrole_tempest_plugin/tests/unit/test_rbac_rule_validation.py
@@ -12,9 +12,13 @@
# License for the specific language governing permissions and limitations
# under the License.
+from __future__ import absolute_import
+
+import functools
import mock
from oslo_config import cfg
+import fixtures
from tempest.lib import exceptions
from tempest import manager
from tempest import test
@@ -23,7 +27,7 @@
from patrole_tempest_plugin import rbac_exceptions
from patrole_tempest_plugin import rbac_rule_validation as rbac_rv
from patrole_tempest_plugin import rbac_utils
-from patrole_tempest_plugin.tests.unit import fixtures
+from patrole_tempest_plugin.tests.unit import fixtures as patrole_fixtures
CONF = cfg.CONF
@@ -43,10 +47,12 @@
setattr(self.mock_test_args.os_primary, 'credentials', mock_creds)
self.useFixture(
- fixtures.ConfPatcher(rbac_test_role='Member', group='patrole'))
+ patrole_fixtures.ConfPatcher(rbac_test_role='Member',
+ group='patrole'))
# Disable patrole log for unit tests.
self.useFixture(
- fixtures.ConfPatcher(enable_reporting=False, group='patrole_log'))
+ patrole_fixtures.ConfPatcher(enable_reporting=False,
+ group='patrole_log'))
class RBACRuleValidationTest(BaseRBACRuleValidationTest):
@@ -54,6 +60,12 @@
``rbac_rule_validation`` decorator.
"""
+ def setUp(self):
+ super(RBACRuleValidationTest, self).setUp()
+ # This behavior is tested in separate test class below.
+ self.useFixture(fixtures.MockPatchObject(
+ rbac_rv, '_validate_override_role_called'))
+
@mock.patch.object(rbac_rv, 'LOG', autospec=True)
@mock.patch.object(rbac_rv, 'policy_authority', autospec=True)
def test_rule_validation_have_permission_no_exc(self, mock_authority,
@@ -69,7 +81,6 @@
pass
test_policy(self.mock_test_args)
- mock_log.warning.assert_not_called()
mock_log.error.assert_not_called()
@mock.patch.object(rbac_rv, 'LOG', autospec=True)
@@ -88,7 +99,6 @@
raise exceptions.Forbidden()
test_policy(self.mock_test_args)
- mock_log.warning.assert_not_called()
mock_log.error.assert_not_called()
@mock.patch.object(rbac_rv, 'LOG', autospec=True)
@@ -119,7 +129,8 @@
@mock.patch.object(rbac_rv, 'policy_authority', autospec=True)
def test_rule_validation_rbac_malformed_response_positive(
self, mock_authority, mock_log):
- """Test RbacMalformedResponse error is thrown without permission passes.
+ """Test RbacMalformedResponse error is thrown without permission
+ passes.
Positive test case: if RbacMalformedResponse is thrown and the user is
not allowed to perform the action, then this is a success.
@@ -132,7 +143,6 @@
raise rbac_exceptions.RbacMalformedResponse()
mock_log.error.assert_not_called()
- mock_log.warning.assert_not_called()
@mock.patch.object(rbac_rv, 'LOG', autospec=True)
@mock.patch.object(rbac_rv, 'policy_authority', autospec=True)
@@ -158,48 +168,6 @@
@mock.patch.object(rbac_rv, 'LOG', autospec=True)
@mock.patch.object(rbac_rv, 'policy_authority', autospec=True)
- def test_rule_validation_rbac_conflicting_policies_positive(
- self, mock_authority, mock_log):
- """Test RbacConflictingPolicies error is thrown without permission passes.
-
- Positive test case: if RbacConflictingPolicies is thrown and the user
- is not allowed to perform the action, then this is a success.
- """
- mock_authority.PolicyAuthority.return_value.allowed.return_value =\
- False
-
- @rbac_rv.action(mock.sentinel.service, rules=[mock.sentinel.action])
- def test_policy(*args):
- raise rbac_exceptions.RbacConflictingPolicies()
-
- mock_log.error.assert_not_called()
- mock_log.warning.assert_not_called()
-
- @mock.patch.object(rbac_rv, 'LOG', autospec=True)
- @mock.patch.object(rbac_rv, 'policy_authority', autospec=True)
- def test_rule_validation_rbac_conflicting_policies_negative(self,
- mock_authority,
- mock_log):
- """Test RbacConflictingPolicies error is thrown with permission fails.
-
- Negative test case: if RbacConflictingPolicies is thrown and the user
- is allowed to perform the action, then this is an expected failure.
- """
- mock_authority.PolicyAuthority.return_value.allowed.return_value = True
-
- @rbac_rv.action(mock.sentinel.service, rules=[mock.sentinel.action])
- def test_policy(*args):
- raise rbac_exceptions.RbacConflictingPolicies()
-
- test_re = ("Role Member was not allowed to perform the following "
- "actions: \[%s\].*" % (mock.sentinel.action))
- self.assertRaisesRegex(
- rbac_exceptions.RbacUnderPermissionException, test_re, test_policy,
- self.mock_test_args)
- self.assertRegex(mock_log.error.mock_calls[0][1][0], test_re)
-
- @mock.patch.object(rbac_rv, 'LOG', autospec=True)
- @mock.patch.object(rbac_rv, 'policy_authority', autospec=True)
def test_expect_not_found_but_raises_forbidden(self, mock_authority,
mock_log):
"""Test that expecting 404 but getting 403 works for all scenarios.
@@ -211,7 +179,7 @@
exception.
"""
@rbac_rv.action(mock.sentinel.service, rules=[mock.sentinel.action],
- expected_error_code=404)
+ expected_error_codes=[404])
def test_policy(*args):
raise exceptions.Forbidden('Test message')
@@ -241,7 +209,7 @@
policy_names = ['foo:bar']
@rbac_rv.action(mock.sentinel.service, rules=policy_names,
- expected_error_code=404)
+ expected_error_codes=[404])
def test_policy(*args):
raise exceptions.NotFound()
@@ -269,7 +237,7 @@
mock_log.warning.assert_called_with(
"NotFound exception was caught for test %s. Expected policies "
"which may have caused the error: %s. The service %s throws a "
- "404 instead of a 403, which is irregular.",
+ "404 instead of a 403, which is irregular",
test_policy.__name__,
', '.join(policy_names),
mock.sentinel.service)
@@ -294,7 +262,7 @@
pass
@rbac_rv.action(mock.sentinel.service, rules=[mock.sentinel.action],
- expected_error_code=404)
+ expected_error_codes=[404])
def test_policy_expect_not_found(*args):
pass
@@ -334,7 +302,7 @@
expected_irregular_msg = (
"NotFound exception was caught for test %s. Expected policies "
"which may have caused the error: %s. The service %s throws a "
- "404 instead of a 403, which is irregular.")
+ "404 instead of a 403, which is irregular")
actual_exception, actual_irregular_msg = \
rbac_rv._get_exception_type(404)
@@ -385,6 +353,12 @@
Patrole RBAC validation work flows.
"""
+ def setUp(self):
+ super(RBACRuleValidationLoggingTest, self).setUp()
+ # This behavior is tested in separate test class below.
+ self.useFixture(fixtures.MockPatchObject(
+ rbac_rv, '_validate_override_role_called'))
+
@mock.patch.object(rbac_rv, 'RBACLOG', autospec=True)
@mock.patch.object(rbac_rv, 'policy_authority', autospec=True)
def test_rbac_report_logging_disabled(self, mock_authority, mock_rbaclog):
@@ -392,7 +366,8 @@
is False
"""
self.useFixture(
- fixtures.ConfPatcher(enable_reporting=False, group='patrole_log'))
+ patrole_fixtures.ConfPatcher(enable_reporting=False,
+ group='patrole_log'))
mock_authority.PolicyAuthority.return_value.allowed.return_value = True
@@ -410,7 +385,8 @@
True
"""
self.useFixture(
- fixtures.ConfPatcher(enable_reporting=True, group='patrole_log'))
+ patrole_fixtures.ConfPatcher(enable_reporting=True,
+ group='patrole_log'))
mock_authority.PolicyAuthority.return_value.allowed.return_value = True
policy_names = ['foo:bar', 'baz:qux']
@@ -429,9 +405,75 @@
"Allowed",
"Allowed")
+ @mock.patch.object(rbac_rv, 'LOG', autospec=True)
+ @mock.patch.object(rbac_rv, 'policy_authority', autospec=True)
+ def test_rule_validation_with_callable_rule(self, mock_authority,
+ mock_log):
+ """Test that a callable as the rule is evaluated correctly."""
+ mock_authority.PolicyAuthority.return_value.allowed.return_value = True
+
+ @rbac_rv.action(mock.sentinel.service,
+ rules=[lambda: mock.sentinel.action])
+ def test_policy(*args):
+ pass
+
+ test_policy(self.mock_test_args)
+
+ policy_authority = mock_authority.PolicyAuthority.return_value
+ policy_authority.allowed.assert_called_with(
+ mock.sentinel.action,
+ CONF.patrole.rbac_test_role)
+
+ mock_log.error.assert_not_called()
+
+ @mock.patch.object(rbac_rv, 'LOG', autospec=True)
+ @mock.patch.object(rbac_rv, 'policy_authority', autospec=True)
+ def test_rule_validation_with_conditional_callable_rule(
+ self, mock_authority, mock_log):
+ """Test that a complex callable with conditional logic as the rule is
+ evaluated correctly.
+ """
+ mock_authority.PolicyAuthority.return_value.allowed.return_value = True
+
+ def partial_func(x):
+ return "foo" if x == "bar" else "qux"
+ foo_callable = functools.partial(partial_func, "bar")
+ bar_callable = functools.partial(partial_func, "baz")
+
+ @rbac_rv.action(mock.sentinel.service,
+ rules=[foo_callable])
+ def test_foo_policy(*args):
+ pass
+
+ @rbac_rv.action(mock.sentinel.service,
+ rules=[bar_callable])
+ def test_bar_policy(*args):
+ pass
+
+ test_foo_policy(self.mock_test_args)
+ policy_authority = mock_authority.PolicyAuthority.return_value
+ policy_authority.allowed.assert_called_with(
+ "foo",
+ CONF.patrole.rbac_test_role)
+ policy_authority.allowed.reset_mock()
+
+ test_bar_policy(self.mock_test_args)
+ policy_authority = mock_authority.PolicyAuthority.return_value
+ policy_authority.allowed.assert_called_with(
+ "qux",
+ CONF.patrole.rbac_test_role)
+
+ mock_log.error.assert_not_called()
+
class RBACRuleValidationNegativeTest(BaseRBACRuleValidationTest):
+ def setUp(self):
+ super(RBACRuleValidationNegativeTest, self).setUp()
+ # This behavior is tested in separate test class below.
+ self.useFixture(fixtures.MockPatchObject(
+ rbac_rv, '_validate_override_role_called'))
+
@mock.patch.object(rbac_rv, 'policy_authority', autospec=True)
def test_rule_validation_invalid_service_raises_exc(self, mock_authority):
"""Test that invalid service raises the appropriate exception."""
@@ -451,6 +493,12 @@
``rbac_rule_validation`` decorator.
"""
+ def setUp(self):
+ super(RBACRuleValidationTestMultiPolicy, self).setUp()
+ # This behavior is tested in separate test class below.
+ self.useFixture(fixtures.MockPatchObject(
+ rbac_rv, '_validate_override_role_called'))
+
def _assert_policy_authority_called_with(self, rules, mock_authority):
m_authority = mock_authority.PolicyAuthority.return_value
m_authority.allowed.assert_has_calls([
@@ -641,31 +689,24 @@
_do_test([True, False, False, True], 'mock.sentinel.action2')
_do_test([True, False, True, False], 'mock.sentinel.action2')
- @mock.patch.object(rbac_rv, 'LOG', autospec=True)
- def test_prepare_multi_policy_allowed_usages(self, mock_log):
+ def test_prepare_multi_policy_allowed_usages(self):
- def _do_test(rule, rules, ecode, ecodes, exp_rules, exp_ecodes):
- rule_list, ec_list = rbac_rv._prepare_multi_policy(rule, rules,
- ecode, ecodes)
+ def _do_test(rules, ecodes, exp_rules, exp_ecodes):
+ rule_list, ec_list = rbac_rv._prepare_multi_policy(rules, ecodes)
self.assertEqual(rule_list, exp_rules)
self.assertEqual(ec_list, exp_ecodes)
- # Validate that using deprecated values: rule and expected_error_code
- # are converted into rules = [rule] and expected_error_codes =
- # [expected_error_code]
- _do_test("rule1", None, 403, None, ["rule1"], [403])
-
- # Validate that rules = [rule] and expected_error_codes defaults to
- # 403 when no values are provided.
- _do_test("rule1", None, None, None, ["rule1"], [403])
+ # Validate that expected_error_codes defaults to 403 when no values
+ # are provided.
+ _do_test(["rule1"], None, ["rule1"], [403])
# Validate that `len(rules) == len(expected_error_codes)` works when
# both == 1.
- _do_test(None, ["rule1"], None, [403], ["rule1"], [403])
+ _do_test(["rule1"], [403], ["rule1"], [403])
# Validate that `len(rules) == len(expected_error_codes)` works when
# both are > 1.
- _do_test(None, ["rule1", "rule2"], None, [403, 404],
+ _do_test(["rule1", "rule2"], [403, 404],
["rule1", "rule2"], [403, 404])
# Validate that when only a default expected_error_code argument is
@@ -675,36 +716,210 @@
# @rbac_rv.action(service, rules=[<rule>, <rule>])
# def test_policy(*args):
# ...
- _do_test(None, ["rule1", "rule2"], 403, None,
+ _do_test(["rule1", "rule2"], None,
["rule1", "rule2"], [403, 403])
- # Validate that the deprecated values are ignored when new values are
- # provided.
- _do_test("rule3", ["rule1", "rule2"], 404, [403, 403],
- ["rule1", "rule2"], [403, 403])
- mock_log.debug.assert_any_call(
- "The `rules` argument will be used instead of `rule`.")
- mock_log.debug.assert_any_call(
- "The `exp_error_codes` argument will be used instead of "
- "`exp_error_code`.")
-
@mock.patch.object(rbac_rv, 'LOG', autospec=True)
def test_prepare_multi_policy_disallowed_usages(self, mock_log):
- def _do_test(rule, rules, ecode, ecodes):
- rule_list, ec_list = rbac_rv._prepare_multi_policy(rule, rules,
- ecode, ecodes)
+ def _do_test(rules, ecodes):
+ rule_list, ec_list = rbac_rv._prepare_multi_policy(rules, ecodes)
error_re = ("The `expected_error_codes` list is not the same length"
" as the `rules` list.")
# When len(rules) > 1 then len(expected_error_codes) must be same len.
self.assertRaisesRegex(ValueError, error_re, _do_test,
- None, ["rule1", "rule2"], None, [403])
+ ["rule1", "rule2"], [403])
# When len(expected_error_codes) > 1 len(rules) must be same len.
- self.assertRaisesRegex(ValueError, error_re, _do_test,
- None, ["rule1"], None, [403, 404])
+ self.assertRaisesRegex(ValueError, error_re, _do_test, ["rule1"],
+ [403, 404])
error_re = ("The `rules` list must be provided if using the "
"`expected_error_codes` list.")
# When expected_error_codes is provided rules must be as well.
- self.assertRaisesRegex(ValueError, error_re, _do_test,
- None, None, None, [404])
+ self.assertRaisesRegex(ValueError, error_re, _do_test, None, [404])
+
+
+class RBACOverrideRoleValidationTest(BaseRBACRuleValidationTest):
+ """Class for validating that untimely exceptions (outside
+ ``override_role`` is called) result in test failures.
+
+ This regression tests false positives caused by test exceptions matching
+ the expected exception before or after the ``override_role`` context is
+ called. Also tests case where ``override_role`` is never called which is
+ an invalid Patrole test.
+
+ """
+
+ def setUp(self):
+ super(RBACOverrideRoleValidationTest, self).setUp()
+
+ # Mixin automatically initializes __override_role_called to False.
+ class FakeRbacTest(rbac_utils.RbacUtilsMixin, test.BaseTestCase):
+ def runTest(self):
+ pass
+
+ # Stub out problematic function calls.
+ FakeRbacTest.os_primary = mock.Mock(spec=manager.Manager)
+ FakeRbacTest.rbac_utils = self.useFixture(
+ patrole_fixtures.RbacUtilsFixture())
+ mock_creds = mock.Mock(user_id=mock.sentinel.user_id,
+ project_id=mock.sentinel.project_id)
+ setattr(FakeRbacTest.os_primary, 'credentials', mock_creds)
+ setattr(FakeRbacTest.os_primary, 'auth_provider', mock.Mock())
+
+ self.parent_class = FakeRbacTest
+
+ @mock.patch.object(rbac_rv, 'policy_authority', autospec=True)
+ def test_rule_validation_override_role_called_inside_ctx(self,
+ mock_authority):
+ """Test success case when the expected exception is raised within the
+ override_role context.
+ """
+ mock_authority.PolicyAuthority.return_value.allowed.return_value =\
+ False
+
+ class ChildRbacTest(self.parent_class):
+
+ @rbac_rv.action(mock.sentinel.service, rules=["fake:rule"],
+ expected_error_codes=[404])
+ def test_called(self_):
+ with self_.rbac_utils.real_override_role(self_):
+ raise exceptions.NotFound()
+
+ child_test = ChildRbacTest()
+ child_test.test_called()
+
+ @mock.patch.object(rbac_rv, 'policy_authority', autospec=True)
+ def test_rule_validation_override_role_patrole_exception_ignored(
+ self, mock_authority):
+ """Test success case where Patrole exception is raised (which is
+ valid in case of e.g. RbacMalformedException) after override_role
+ passes.
+ """
+ mock_authority.PolicyAuthority.return_value.allowed.return_value =\
+ True
+
+ class ChildRbacTest(self.parent_class):
+
+ @rbac_rv.action(mock.sentinel.service, rules=["fake:rule"],
+ expected_error_codes=[404])
+ def test_called(self_):
+ with self_.rbac_utils.real_override_role(self_):
+ pass
+ # Instances of BasePatroleException don't count as they are
+ # part of the validation work flow.
+ raise rbac_exceptions.BasePatroleException()
+
+ child_test = ChildRbacTest()
+ self.assertRaises(rbac_exceptions.BasePatroleException,
+ child_test.test_called)
+
+ @mock.patch.object(rbac_rv, 'policy_authority', autospec=True)
+ def test_rule_validation_override_role_called_before_ctx(self,
+ mock_authority):
+ """Test failure case when an exception that happens before
+ ``override_role`` context, even if it is the expected exception,
+ raises ``RbacOverrideRoleException``.
+ """
+ mock_authority.PolicyAuthority.return_value.allowed.return_value =\
+ False
+
+ # This behavior should work for supported (NotFound/Forbidden) and
+ # miscellaneous exceptions alike.
+ for exception_type in (exceptions.NotFound,
+ Exception):
+ class ChildRbacTest(self.parent_class):
+
+ @rbac_rv.action(mock.sentinel.service, rules=["fake:rule"],
+ expected_error_codes=[404])
+ def test_called_before(self_):
+ raise exception_type()
+
+ child_test = ChildRbacTest()
+ test_re = ".*before.*"
+ self.assertRaisesRegex(rbac_exceptions.RbacOverrideRoleException,
+ test_re, child_test.test_called_before)
+
+ @mock.patch.object(rbac_rv, 'policy_authority', autospec=True)
+ def test_rule_validation_override_role_called_after_ctx(self,
+ mock_authority):
+ """Test failure case when an exception that happens before
+ ``override_role`` context, even if it is the expected exception,
+ raises ``RbacOverrideRoleException``.
+ """
+ mock_authority.PolicyAuthority.return_value.allowed.return_value =\
+ False
+
+ # This behavior should work for supported (NotFound/Forbidden) and
+ # miscellaneous exceptions alike.
+ for exception_type in (exceptions.NotFound,
+ Exception):
+ class ChildRbacTest(self.parent_class):
+
+ @rbac_rv.action(mock.sentinel.service, rules=["fake:rule"],
+ expected_error_codes=[404])
+ def test_called_after(self_):
+ with self_.rbac_utils.real_override_role(self_):
+ pass
+ # Simulates a test tearDown failure or some such.
+ raise exception_type()
+
+ child_test = ChildRbacTest()
+ test_re = ".*after.*"
+ self.assertRaisesRegex(rbac_exceptions.RbacOverrideRoleException,
+ test_re, child_test.test_called_after)
+
+ @mock.patch.object(rbac_rv, 'policy_authority', autospec=True)
+ def test_rule_validation_override_role_never_called(self, mock_authority):
+ """Test failure case where override_role is **never** called."""
+ mock_authority.PolicyAuthority.return_value.allowed.return_value =\
+ False
+
+ class ChildRbacTest(self.parent_class):
+
+ @rbac_rv.action(mock.sentinel.service, rules=["fake:rule"],
+ expected_error_codes=[404])
+ def test_never_called(self_):
+ pass
+
+ child_test = ChildRbacTest()
+ test_re = ".*missing required `override_role` call.*"
+ self.assertRaisesRegex(rbac_exceptions.RbacOverrideRoleException,
+ test_re, child_test.test_never_called)
+
+ @mock.patch.object(rbac_rv, 'policy_authority', autospec=True)
+ def test_rule_validation_override_role_sequential_test_calls(
+ self, mock_authority):
+ """Test success/failure scenarios above across sequential test calls.
+ """
+ mock_authority.PolicyAuthority.return_value.allowed.return_value =\
+ False
+
+ class ChildRbacTest(self.parent_class):
+
+ @rbac_rv.action(mock.sentinel.service, rules=["fake:rule1"],
+ expected_error_codes=[404])
+ def test_called(self_):
+ with self_.rbac_utils.real_override_role(self_):
+ raise exceptions.NotFound()
+
+ @rbac_rv.action(mock.sentinel.service, rules=["fake:rule2"],
+ expected_error_codes=[404])
+ def test_called_before(self_):
+ raise exceptions.NotFound()
+
+ test_re = ".*before.*"
+
+ # Test case where override role is called in first test but *not* in
+ # second test.
+ child_test1 = ChildRbacTest()
+ child_test1.test_called()
+ self.assertRaisesRegex(rbac_exceptions.RbacOverrideRoleException,
+ test_re, child_test1.test_called_before)
+
+ # Test case where override role is *not* called in first test but is
+ # in second test.
+ child_test2 = ChildRbacTest()
+ self.assertRaisesRegex(rbac_exceptions.RbacOverrideRoleException,
+ test_re, child_test2.test_called_before)
+ child_test2.test_called()
diff --git a/patrole_tempest_plugin/tests/unit/test_rbac_utils.py b/patrole_tempest_plugin/tests/unit/test_rbac_utils.py
index c5264aa..5132079 100644
--- a/patrole_tempest_plugin/tests/unit/test_rbac_utils.py
+++ b/patrole_tempest_plugin/tests/unit/test_rbac_utils.py
@@ -208,11 +208,6 @@
class FakeRbacTest(rbac_utils.RbacUtilsMixin, test.BaseTestCase):
@classmethod
- def skip_checks(cls):
- super(FakeRbacTest, cls).skip_checks()
- cls.skip_rbac_checks()
-
- @classmethod
def setup_clients(cls):
super(FakeRbacTest, cls).setup_clients()
cls.setup_rbac_utils()
@@ -237,21 +232,3 @@
self.assertTrue(hasattr(child_test, 'rbac_utils'))
self.assertIsInstance(child_test.rbac_utils, rbac_utils.RbacUtils)
-
- def test_skip_rbac_checks(self):
- """Validate that the child class is skipped if `[patrole] enable_rbac`
- is False and that the child class's name is in the skip message.
- """
- self.useFixture(patrole_fixtures.ConfPatcher(enable_rbac=False,
- group='patrole'))
-
- class ChildRbacTest(self.parent_class):
- pass
-
- child_test = ChildRbacTest()
-
- with testtools.ExpectedException(
- testtools.TestCase.skipException,
- value_re=('Patrole testing not enabled so skipping %s.'
- % ChildRbacTest.__name__)):
- child_test.setUpClass()
diff --git a/releasenotes/notes/check-expected-errors-only-in-override-role-f7109a73f5ff70e2.yaml b/releasenotes/notes/check-expected-errors-only-in-override-role-f7109a73f5ff70e2.yaml
new file mode 100644
index 0000000..e0ac744
--- /dev/null
+++ b/releasenotes/notes/check-expected-errors-only-in-override-role-f7109a73f5ff70e2.yaml
@@ -0,0 +1,19 @@
+---
+features:
+ - |
+ Add new exception called ``RbacOverrideRoleException``. Used for
+ safeguarding against false positives that might occur when the expected
+ exception isn't raised inside the ``override_role`` context. Specifically,
+ when:
+
+ * ``override_role`` isn't called
+ * an exception is raised before ``override_role`` context
+ * an exception is raised after ``override_role`` context
+fixes:
+ - |
+ Previously, the ``rbac_rule_validation.action`` decorator could catch
+ expected exceptions with no regard to where the error happened. Such
+ behavior could cause false-positive results. To prevent this from
+ happening from now on, if an exception happens outside of the
+ ``override_role`` context, it will cause
+ ``rbac_exceptions.RbacOverrideRoleException`` to be raised.
diff --git a/releasenotes/notes/multiple-policy-files-9aa7f7583283739e.yaml b/releasenotes/notes/multiple-policy-files-9aa7f7583283739e.yaml
new file mode 100644
index 0000000..a3555e6
--- /dev/null
+++ b/releasenotes/notes/multiple-policy-files-9aa7f7583283739e.yaml
@@ -0,0 +1,17 @@
+---
+features:
+ - |
+ In order to implement the tests for plugins which do not maintain the
+ ``policy.json`` with full list of the policy rules and provide policy file
+ with only their own policy rules, the Patrole should be able to load and
+ merge multiple policy files for any of the services.
+
+ - Discovery all policy files for each of the services.
+ The updated ``discover_policy_files`` function picks all candidate paths
+ found out of the potential paths in the ``[patrole].custom_policy_files``
+ config option. Using ``glob.glob()`` function makes it possible to use
+ the patterns like '\*.json' to discover the policy files.
+
+ - Loading and merging a data from multiple policy files.
+ Patrole loads a data from each of the discovered policy files for a
+ service and merge the data from all files.
diff --git a/releasenotes/notes/remove-deprecated-enable-rbac-config-option-a5e46ce1053b7dea.yaml b/releasenotes/notes/remove-deprecated-enable-rbac-config-option-a5e46ce1053b7dea.yaml
new file mode 100644
index 0000000..53b1710
--- /dev/null
+++ b/releasenotes/notes/remove-deprecated-enable-rbac-config-option-a5e46ce1053b7dea.yaml
@@ -0,0 +1,5 @@
+---
+upgrade:
+ - |
+ Remove deprecated ``[patrole].enable_rbac`` configuration option. To skip
+ Patrole tests going forward, use an appropriate regex.
diff --git a/releasenotes/notes/remove-deprecated-rules-expected-error-codes-params-52071a83113934fd.yaml b/releasenotes/notes/remove-deprecated-rules-expected-error-codes-params-52071a83113934fd.yaml
new file mode 100644
index 0000000..16b2e03
--- /dev/null
+++ b/releasenotes/notes/remove-deprecated-rules-expected-error-codes-params-52071a83113934fd.yaml
@@ -0,0 +1,13 @@
+---
+upgrade:
+ - |
+ The following deprecated parameters in ``rbac_rule_validation.action``
+ decorator:
+
+ * ``rule``
+ * ``expected_error_code``
+
+ have been removed. Use the non-deprecated versions instead:
+
+ * ``rules``
+ * ``expected_error_codes``
diff --git a/releasenotes/notes/volume-type-encryption-policy-granularity-141ac283b9c0778e.yaml b/releasenotes/notes/volume-type-encryption-policy-granularity-141ac283b9c0778e.yaml
new file mode 100644
index 0000000..4aeb107
--- /dev/null
+++ b/releasenotes/notes/volume-type-encryption-policy-granularity-141ac283b9c0778e.yaml
@@ -0,0 +1,19 @@
+---
+features:
+ - |
+ Added new Cinder feature flag (``CONF.policy_feature_enabled.added_cinder_policies_stein``)
+ for the following newly introduced granular Cinder policies:
+
+ - ``volume_extension:volume_type_encryption:create``
+ - ``volume_extension:volume_type_encryption:get``
+ - ``volume_extension:volume_type_encryption:update``
+ - ``volume_extension:volume_type_encryption:delete``
+
+ The corresponding Patrole test cases are modified to support
+ the granularity. The test cases also support backward
+ compatibility with the old single rule:
+ ``volume_extension:volume_type_encryption``
+
+ The ``rules`` parameter in ``rbac_rule_validation.action``
+ decorator now also accepts a list of callables; each callable
+ should return a policy action (str).
diff --git a/releasenotes/notes/yaml-policy-file-support-278d3edf64f98d69.yaml b/releasenotes/notes/yaml-policy-file-support-278d3edf64f98d69.yaml
new file mode 100644
index 0000000..e333377
--- /dev/null
+++ b/releasenotes/notes/yaml-policy-file-support-278d3edf64f98d69.yaml
@@ -0,0 +1,7 @@
+---
+features:
+- |
+ Patrole now supports parsing custom YAML policy files, the new policy file
+ extension since Ocata. The function ``_get_policy_data`` has been renamed to
+ ``get_rules`` and been changed to re-use ``oslo_policy.policy.Rules.load``
+ function.