Merge "RBAC test for Keystone v3 OS-ENDPOINT-POLICY API"
diff --git a/.zuul.yaml b/.zuul.yaml
index 387c042..089ba6e 100644
--- a/.zuul.yaml
+++ b/.zuul.yaml
@@ -1,7 +1,13 @@
- job:
name: patrole-base
- parent: legacy-dsvm-base
+ parent: devstack-tempest
+ description: Patrole base job for admin and Member roles.
+ required-projects:
+ - name: openstack/tempest
+ - name: openstack/patrole
timeout: 7800
+ roles:
+ - zuul: openstack-dev/devstack
irrelevant-files:
- ^(test-|)requirements.txt$
- ^.*\.rst$
@@ -9,10 +15,17 @@
- ^patrole/patrole_tempest_plugin/tests/unit/.*$
- ^releasenotes/.*
- ^setup.cfg$
- required-projects:
- - openstack-infra/devstack-gate
- - openstack/patrole
- - openstack/tempest
+ vars:
+ devstack_localrc:
+ TEMPEST_PLUGINS: "'{{ ansible_user_dir }}/src/git.openstack.org/openstack/patrole'"
+ devstack_plugins:
+ patrole: git://git.openstack.org/openstack/patrole.git
+ devstack_services:
+ tempest: true
+ neutron: true
+ tempest_concurrency: 2
+ tempest_test_regex: (?!.*\[.*\bslow\b.*\])(^patrole_tempest_plugin\.tests\.api)
+ tox_envlist: all-plugin
- job:
name: patrole-base-multinode
@@ -33,14 +46,18 @@
- job:
name: patrole-admin
parent: patrole-base
- run: playbooks/patrole-admin/run.yaml
- post-run: playbooks/patrole-admin/post.yaml
+ description: Patrole job for admin role.
+ vars:
+ devstack_localrc:
+ RBAC_TEST_ROLE: admin
- job:
name: patrole-member
parent: patrole-base
- run: playbooks/patrole-member/run.yaml
- post-run: playbooks/patrole-member/post.yaml
+ description: Patrole job for Member role.
+ vars:
+ devstack_localrc:
+ RBAC_TEST_ROLE: Member
- job:
name: patrole-multinode-admin
@@ -61,8 +78,20 @@
- job:
name: patrole-py35-member
parent: patrole-base
- run: playbooks/patrole-py35-member/run.yaml
- post-run: playbooks/patrole-py35-member/post.yaml
+ description: Patrole py3 job for Member role.
+ vars:
+ devstack_localrc:
+ # Use Member for py3 because arguably negative testing is more
+ # important than admin, which is already covered by patrole-admin job.
+ RBAC_TEST_ROLE: Member
+ USE_PYTHON3: true
+ devstack_services:
+ s-account: false
+ s-container: false
+ s-object: false
+ s-proxy: false
+ # Without Swift, c-bak cannot run (in the gate at least).
+ c-bak: false
- project:
check:
@@ -72,8 +101,10 @@
- patrole-py35-member
- patrole-multinode-admin
- patrole-multinode-member
+ - openstack-tox-lower-constraints
gate:
jobs:
- patrole-admin
- patrole-member
- patrole-py35-member
+ - openstack-tox-lower-constraints
diff --git a/HACKING.rst b/HACKING.rst
index a94b47c..056c86a 100644
--- a/HACKING.rst
+++ b/HACKING.rst
@@ -39,25 +39,17 @@
- [P103] ``self.client`` must not be used as a client alias; this allows for
code that is more maintainable and easier to read
-Role Switching
---------------
+Role Overriding
+---------------
-Correct role switching is vital to correct RBAC testing within Patrole. If a
-test does not call ``rbac_utils.switch_role`` with ``toggle_rbac_role=True``
-within the RBAC test, then the test is *not* a valid RBAC test: The API
-endpoint under test will be performed with admin credentials, which is always
-wrong unless ``CONF.patrole.rbac_test_role`` is admin.
+Correct role overriding is vital to correct RBAC testing within Patrole. If a
+test does not call ``rbac_utils.override_role`` within the RBAC test, followed
+by the API endpoint that enforces the expected policy action, then the test is
+**not** a valid Patrole test: The API endpoint under test will be performed
+with admin role, which is always wrong unless ``CONF.patrole.rbac_test_role``
+is also admin.
-.. note::
+.. todo::
- Switching back to the admin role for setup and clean up is automatically
- performed. Toggling ``switch_role`` with ``toggle_rbac_role=False`` within
- the context of a test should *never* be performed and doing so will likely
- result in an error being thrown.
-..
-
-Patrole does not have a hacking check for role switching, but does use a
-built-in mechanism for verifying that role switching is being correctly
-executed across tests. If a test does not call ``switch_role`` with
-``toggle_rbac_role=True``, then an ``RbacResourceSetupFailed`` exception
-will be raised.
+ Patrole does not have a hacking check for role overriding, but one may be
+ added in the future.
diff --git a/doc/requirements.txt b/doc/requirements.txt
new file mode 100644
index 0000000..012efb2
--- /dev/null
+++ b/doc/requirements.txt
@@ -0,0 +1,6 @@
+# The order of packages is significant, because pip processes them in the order
+# of appearance. Changing the order has an impact on the overall integration
+# process, which may cause wedges in the gate later.
+sphinx!=1.6.6,!=1.6.7,>=1.6.2 # BSD
+openstackdocstheme>=1.18.1 # Apache-2.0
+reno>=2.5.0 # Apache-2.0
diff --git a/doc/source/configuration.rst b/doc/source/configuration.rst
index 8ec0013..ce799ad 100644
--- a/doc/source/configuration.rst
+++ b/doc/source/configuration.rst
@@ -35,21 +35,6 @@
Given the value of ``enable_rbac``, enables or disables Patrole tests. If
``enable_rbac`` is ``False``, then Patrole tests are skipped.
-Strict Policy Check
--------------------
-
-Currently, many services define their "default" rule to be "anyone allowed".
-If a policy action is not explicitly defined in a policy file, then
-``oslo.policy`` will fall back to the "default" rule. This implies that if
-there's a typo in a policy action specified in a Patrole test, ``oslo.policy``
-can report that the ``rbac_test_role`` will be able to perform the
-non-existent policy action. For a testing framework, this is undesirable
-behavior.
-
-Hence, ``strict_policy_check``, if ``True``, will throw an error in the event
-that a non-existent or bogus policy action is passed to a Patrole test. If
-``False``, however, a ``self.skipException`` will be raised.
-
Custom Policy Files
-------------------
@@ -70,4 +55,3 @@
Patrole currently does not support policy files located on a host different
than the one on which it is running.
-..
diff --git a/doc/source/index.rst b/doc/source/index.rst
index 308c12c..be3264e 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -14,6 +14,7 @@
installation
configuration
usage
+ testing
sampleconf
Developer's Guide
diff --git a/doc/source/installation.rst b/doc/source/installation.rst
index c244152..b9cc924 100644
--- a/doc/source/installation.rst
+++ b/doc/source/installation.rst
@@ -10,12 +10,13 @@
At the command line::
$ git clone http://git.openstack.org/openstack/patrole
- $ sudo pip install patrole
+ $ sudo pip install ./patrole
Or, if you have virtualenvwrapper installed::
- $ mkvirtualenv patrole
- $ sudo pip install patrole
+ $ mkvirtualenv patrole_env
+ $ workon patrole_env
+ $ pip install ./patrole
Or to install from the source::
diff --git a/doc/source/testing.rst b/doc/source/testing.rst
new file mode 100644
index 0000000..d61c78d
--- /dev/null
+++ b/doc/source/testing.rst
@@ -0,0 +1,51 @@
+.. _patrole-testing:
+
+===============
+Patrole Testing
+===============
+
+Testing Scope
+=============
+
+Patrole testing scope is strictly confined to Role-Based Access Control
+(RBAC). In OpenStack, ``oslo.policy`` is the RBAC library used by all
+major services. Thus, Patrole is concerned with validating that public API
+endpoints are correctly using ``oslo.policy`` for authorization.
+
+In other words, all tests in Patrole are RBAC tests.
+
+Stable Tests
+============
+
+In the discussion below, "correct" means that a test is consistent with
+a service's API-to-policy mapping and "stable" means that a test should
+require minimal maintenance for the supported releases.
+
+Present
+-------
+
+During the Queens release, a `governance spec`_ was pushed to support policy
+in code, which documents the mapping between APIs and each of their policies.
+
+This documentation is an important prerequisite for ensuring that Patrole
+tests for a given service are correct. This mapping can be referenced to
+confirm that Patrole's assumed mapping for a test is correct. For
+example, Nova has implemented policy in code which can be used to verify
+that Patrole's Nova RBAC tests use the same mapping.
+
+If a given service does not have policy in code, this implies that it is
+*more likely* that the RBAC tests for that service are inconsistent with the
+*intended* policy mapping. Until that service implements policy in code, it
+is difficult for Patrole maintainers to verify that tests for that service
+are correct.
+
+Future
+------
+
+Once all services that Patrole tests have implemented policy in code --
+and once Patrole has updated all its tests in accordance with the policy in
+code documentation -- then Patrole tests can guaranteed to be stable.
+
+This stability will be denoted with a 1.0 version release.
+
+.. _governance spec: https://governance.openstack.org/tc/goals/queens/policy-in-code.html
diff --git a/etc/patrole.conf.sample b/etc/patrole.conf.sample
index cafdf8a..ed2b07c 100644
--- a/etc/patrole.conf.sample
+++ b/etc/patrole.conf.sample
@@ -14,18 +14,6 @@
# Enables RBAC tests. (boolean value)
#enable_rbac = true
-# DEPRECATED: If true, throws RbacParsingException for policies which
-# don't exist or are not included in the service's policy file. If
-# false, throws
-# skipException. (boolean value)
-# This option is deprecated for removal.
-# Its value may be silently ignored in the future.
-# Reason: This option allows for the possibility
-# of false positives. As a testing framework, Patrole should fail any
-# test that
-# passes in an invalid policy.
-#strict_policy_check = true
-
# List of the paths to search for policy files. Each
# policy path assumes that the service name is included in the path
# once. Also
diff --git a/lower-constraints.txt b/lower-constraints.txt
new file mode 100644
index 0000000..a5ff1ca
--- /dev/null
+++ b/lower-constraints.txt
@@ -0,0 +1,84 @@
+alabaster==0.7.10
+appdirs==1.4.3
+asn1crypto==0.24.0
+Babel==2.5.3
+bcrypt==3.1.4
+certifi==2018.1.18
+cffi==1.11.5
+chardet==3.0.4
+cliff==2.11.0
+cmd2==0.8.1
+coverage==4.5.1
+cryptography==2.1.4
+debtcollector==1.19.0
+docutils==0.14
+dulwich==0.19.0
+extras==1.0.0
+fasteners==0.14.1
+fixtures==3.0.0
+flake8==2.5.5
+future==0.16.0
+hacking==1.0.0
+idna==2.6
+imagesize==1.0.0
+iso8601==0.1.12
+Jinja2==2.10
+jsonschema==2.6.0
+keystoneauth1==3.4.0
+linecache2==1.0.0
+MarkupSafe==1.0
+mccabe==0.2.1
+mock==2.0.0
+monotonic==1.4
+mox3==0.25.0
+msgpack==0.5.6
+netaddr==0.7.19
+netifaces==0.10.6
+nose==1.3.7
+nosexcover==1.0.11
+openstackdocstheme==1.20.0
+os-client-config==1.29.0
+oslo.concurrency==3.26.0
+oslo.config==5.2.0
+oslo.context==2.20.0
+oslo.i18n==3.20.0
+oslo.log==3.37.0
+oslo.policy==1.34.0
+oslo.serialization==2.25.0
+oslo.utils==3.36.0
+oslotest==3.3.0
+paramiko==2.4.1
+pbr==3.1.1
+pep8==1.5.7
+prettytable==0.7.2
+pyasn1==0.4.2
+pycparser==2.18
+pyflakes==0.8.1
+Pygments==2.2.0
+pyinotify==0.9.6
+PyNaCl==1.2.1
+pyparsing==2.2.0
+pyperclip==1.6.0
+python-dateutil==2.7.0
+python-mimeparse==1.6.0
+python-subunit==1.2.0
+pytz==2018.3
+PyYAML==3.12
+reno==2.7.0
+requests==2.18.4
+requestsexceptions==1.4.0
+rfc3986==1.1.0
+six==1.11.0
+snowballstemmer==1.2.1
+Sphinx==1.6.5
+sphinxcontrib-websupport==1.0.1
+stestr==2.0.0
+stevedore==1.28.0
+tempest==18.0.0
+testrepository==0.0.20
+testtools==2.3.0
+traceback2==1.4.0
+unittest2==1.1.0
+urllib3==1.22
+voluptuous==0.11.1
+wrapt==1.10.11
diff --git a/patrole_tempest_plugin/config.py b/patrole_tempest_plugin/config.py
index 8ac2a20..0077d19 100644
--- a/patrole_tempest_plugin/config.py
+++ b/patrole_tempest_plugin/config.py
@@ -27,15 +27,6 @@
cfg.BoolOpt('enable_rbac',
default=True,
help="Enables RBAC tests."),
- cfg.BoolOpt('strict_policy_check',
- default=True,
- deprecated_for_removal=True,
- deprecated_reason="""This option allows for the possibility
-of false positives. As a testing framework, Patrole should fail any test that
-passes in an invalid policy.""",
- help="""If true, throws RbacParsingException for policies which
-don't exist or are not included in the service's policy file. If false, throws
-skipException."""),
# TODO(rb560u): There needs to be support for reading these JSON files from
# other hosts. It may be possible to leverage the v3 identity policy API.
cfg.ListOpt('custom_policy_files',
diff --git a/patrole_tempest_plugin/policy_authority.py b/patrole_tempest_plugin/policy_authority.py
index 6851942..99348b9 100644
--- a/patrole_tempest_plugin/policy_authority.py
+++ b/patrole_tempest_plugin/policy_authority.py
@@ -158,6 +158,8 @@
:param string rule_name: Rule to be checked using ``oslo.policy``.
:param bool is_admin: Whether admin context is used.
+ :raises RbacParsingException: If `rule_name`` does not exist in the
+ cloud (in policy file or among registered in-code policy defaults).
"""
is_admin_context = self._is_admin_context(role)
is_allowed = self._allowed(
@@ -215,9 +217,11 @@
policy_data = mgr_policy_data
else:
error_message = (
- 'Policy file for {0} service neither found in code nor at {1}.'
- .format(service, [loc % service for loc in
- CONF.patrole.custom_policy_files])
+ 'Policy file for {0} service was 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)
diff --git a/patrole_tempest_plugin/rbac_rule_validation.py b/patrole_tempest_plugin/rbac_rule_validation.py
index 97d246f..d3213cf 100644
--- a/patrole_tempest_plugin/rbac_rule_validation.py
+++ b/patrole_tempest_plugin/rbac_rule_validation.py
@@ -13,9 +13,9 @@
# License for the specific language governing permissions and limitations
# under the License.
+import functools
import logging
import sys
-import testtools
from oslo_utils import excutils
import six
@@ -105,9 +105,9 @@
@rbac_rule_validation.action(
service="nova", rule="os_compute_api:os-agents")
def test_list_agents_rbac(self):
- # The call to `switch_role` is mandatory.
- self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- self.agents_client.list_agents()
+ # The call to `override_role` is mandatory.
+ with self.rbac_utils.override_role(self):
+ self.agents_client.list_agents()
"""
if extra_target_data is None:
@@ -116,6 +116,7 @@
def decorator(test_func):
role = CONF.patrole.rbac_test_role
+ @functools.wraps(test_func)
def wrapper(*args, **kwargs):
if args and isinstance(args[0], test.BaseTestCase):
test_obj = args[0]
@@ -163,8 +164,7 @@
LOG.error(msg)
else:
if not allowed:
- LOG.error("Role %s was allowed to perform %s",
- role, rule)
+ LOG.error("Role %s was allowed to perform %s", role, rule)
raise rbac_exceptions.RbacOverPermission(
"OverPermission: Role %s was allowed to perform %s" %
(role, rule))
@@ -177,8 +177,7 @@
"Allowed" if allowed else "Denied",
test_status)
- _wrapper = testtools.testcase.attr(role)(wrapper)
- return _wrapper
+ return wrapper
return decorator
@@ -200,10 +199,6 @@
:raises RbacResourceSetupFailed: If `project_id` or `user_id` are missing
from the `auth_provider` attribute in `test_obj`.
- :raises RbacParsingException: if ``[patrole] strict_policy_check`` is True
- and the ``rule`` does not exist in the system.
- :raises skipException: If ``[patrole] strict_policy_check`` is False and
- the ``rule`` does not exist in the system.
"""
try:
@@ -215,33 +210,27 @@
LOG.error(msg)
raise rbac_exceptions.RbacResourceSetupFailed(msg)
- try:
- role = CONF.patrole.rbac_test_role
- # Test RBAC against custom requirements. Otherwise use oslo.policy.
- if CONF.patrole.test_custom_requirements:
- authority = requirements_authority.RequirementsAuthority(
- CONF.patrole.custom_requirements_file, service)
- else:
- formatted_target_data = _format_extra_target_data(
- test_obj, extra_target_data)
- authority = policy_authority.PolicyAuthority(
- project_id, user_id, service,
- extra_target_data=formatted_target_data)
- is_allowed = authority.allowed(rule, role)
+ role = CONF.patrole.rbac_test_role
+ # Test RBAC against custom requirements. Otherwise use oslo.policy.
+ if CONF.patrole.test_custom_requirements:
+ authority = requirements_authority.RequirementsAuthority(
+ CONF.patrole.custom_requirements_file, service)
+ else:
+ formatted_target_data = _format_extra_target_data(
+ test_obj, extra_target_data)
+ authority = policy_authority.PolicyAuthority(
+ project_id, user_id, service,
+ extra_target_data=formatted_target_data)
+ is_allowed = authority.allowed(rule, role)
- if is_allowed:
- LOG.debug("[Action]: %s, [Role]: %s is allowed!", rule,
- role)
- else:
- LOG.debug("[Action]: %s, [Role]: %s is NOT allowed!",
- rule, role)
- return is_allowed
- except rbac_exceptions.RbacParsingException as e:
- if CONF.patrole.strict_policy_check:
- raise e
- else:
- raise testtools.TestCase.skipException(str(e))
- return False
+ if is_allowed:
+ LOG.debug("[Action]: %s, [Role]: %s is allowed!", rule,
+ role)
+ else:
+ LOG.debug("[Action]: %s, [Role]: %s is NOT allowed!",
+ rule, role)
+
+ return is_allowed
def _get_exception_type(expected_error_code=403):
diff --git a/patrole_tempest_plugin/rbac_utils.py b/patrole_tempest_plugin/rbac_utils.py
index 49cb5e1..1ada69b 100644
--- a/patrole_tempest_plugin/rbac_utils.py
+++ b/patrole_tempest_plugin/rbac_utils.py
@@ -15,7 +15,6 @@
import abc
from contextlib import contextmanager
-import debtcollector.removals
import six
import time
@@ -107,20 +106,6 @@
# up.
self._override_role(test_obj, False)
- @debtcollector.removals.remove(removal_version='Rocky')
- def switch_role(self, test_obj, toggle_rbac_role):
- """Switch the role used by `os_primary` Tempest credentials.
-
- Switch the role used by `os_primary` credentials to:
-
- * admin if `toggle_rbac_role` is False
- * `CONF.patrole.rbac_test_role` if `toggle_rbac_role` is True
-
- :param test_obj: instance of :py:class:`tempest.test.BaseTestCase`
- :param toggle_rbac_role: role to switch `os_primary` Tempest creds to
- """
- self._override_role(test_obj, toggle_rbac_role)
-
def _override_role(self, test_obj, toggle_rbac_role=False):
"""Private helper for overriding ``os_primary`` Tempest credentials.
diff --git a/patrole_tempest_plugin/tests/api/network/test_networks_multiprovider_rbac.py b/patrole_tempest_plugin/tests/api/network/test_network_segments_rbac.py
similarity index 76%
rename from patrole_tempest_plugin/tests/api/network/test_networks_multiprovider_rbac.py
rename to patrole_tempest_plugin/tests/api/network/test_network_segments_rbac.py
index 9c65c14..1dee46b 100644
--- a/patrole_tempest_plugin/tests/api/network/test_networks_multiprovider_rbac.py
+++ b/patrole_tempest_plugin/tests/api/network/test_network_segments_rbac.py
@@ -14,6 +14,7 @@
# under the License.
from oslo_log import log
+
from tempest.common import utils
from tempest.lib.common.utils import data_utils
from tempest.lib.common.utils import test_utils
@@ -26,18 +27,34 @@
LOG = log.getLogger(__name__)
-class NetworksMultiProviderRbacTest(base.BaseNetworkRbacTest):
+class NetworkSegmentsRbacTest(base.BaseNetworkRbacTest):
@classmethod
def skip_checks(cls):
- super(NetworksMultiProviderRbacTest, cls).skip_checks()
+ super(NetworkSegmentsRbacTest, cls).skip_checks()
if not utils.is_extension_enabled('multi-provider', 'network'):
msg = "multi-provider extension not enabled."
raise cls.skipException(msg)
+ @classmethod
+ def resource_setup(cls):
+ super(NetworkSegmentsRbacTest, cls).resource_setup()
+ # Find the network type that is supported by the current cloud by
+ # checking which network type other networks currently have. This is
+ # done because there is no tempest.conf option enumerating supported
+ # network types.
+ networks = cls.networks_client.list_networks()['networks']
+ network_types = [n['provider:network_type'] for n in networks
+ if n['provider:network_type'] != 'flat']
+ if not network_types:
+ raise cls.skipException(
+ 'Could not find network with provider:network_type that is '
+ 'not "flat".')
+ cls.network_type = network_types[0]
+
def _create_network_segments(self):
- segments = [{"provider:network_type": "gre"},
- {"provider:network_type": "gre"}]
+ segments = [{'provider:network_type': self.network_type},
+ {'provider:network_type': self.network_type}]
body = self.networks_client.create_network(
name=data_utils.rand_name(self.__class__.__name__),
@@ -68,7 +85,7 @@
RBAC test for the neutron update_network:segments policy
"""
network = self._create_network_segments()
- new_segments = [{"provider:network_type": "gre"}]
+ new_segments = [{'provider:network_type': self.network_type}]
with self.rbac_utils.override_role(self):
self.networks_client.update_network(network['id'],
@@ -92,7 +109,7 @@
# If user does not have access to the network segments attribute,
# no NotFound or Forbidden exception are thrown. Instead,
# the response will have an empty network body only.
- if len(response_network) == 0:
+ if not response_network:
LOG.info("NotFound or Forbidden exception are not thrown when "
"role doesn't have access to the endpoint. Instead, "
"the response will have an empty network body.")
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 226411f..1c5fb2e 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
@@ -47,15 +47,6 @@
self.snapshots_client.create_snapshot_metadata(
self.snapshot_id, metadata)['metadata']
- @rbac_rule_validation.action(
- service="cinder",
- rule="volume_extension:extended_snapshot_attributes")
- @decorators.idempotent_id('c9cbec1c-edfe-46b8-825b-7b6ac0a58c25')
- def test_create_snapshot_metadata(self):
- # Create metadata for the snapshot
- with self.rbac_utils.override_role(self):
- self._create_test_snapshot_metadata()
-
@rbac_rule_validation.action(service="cinder",
rule="volume:get_snapshot_metadata")
@decorators.idempotent_id('f6912bb1-62e6-483d-bcd0-e98c1641f4c3')
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 df4fd10..7d721c4 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
@@ -17,6 +17,7 @@
from tempest import config
from tempest.lib import decorators
+from patrole_tempest_plugin import rbac_exceptions
from patrole_tempest_plugin import rbac_rule_validation
from patrole_tempest_plugin.tests.api.volume import rbac_base
@@ -39,20 +40,15 @@
# Create a test shared snapshot for tests
cls.snapshot = cls.create_snapshot(cls.volume['id'])
- def _list_by_param_values(self, params, with_detail=False):
- # Perform list or list_details action with given params
- # and validates result.
- if with_detail:
- self.snapshots_client.list_snapshots(
- detail=True, params=params)['snapshots']
- else:
- self.snapshots_client.list_snapshots(
- params=params)['snapshots']
+ def _list_by_param_values(self, with_detail=False, **params):
+ # Perform list or list_details action with given params.
+ return self.snapshots_client.list_snapshots(
+ detail=with_detail, **params)['snapshots']
@rbac_rule_validation.action(service="cinder",
rule="volume:create_snapshot")
@decorators.idempotent_id('ac7b2ee5-fbc0-4360-afc2-de8fa4881ede')
- def test_snapshot_create(self):
+ def test_create_snapshot(self):
# Create a temp snapshot
with self.rbac_utils.override_role(self):
self.create_snapshot(self.volume['id'])
@@ -60,16 +56,33 @@
@rbac_rule_validation.action(service="cinder",
rule="volume:get_snapshot")
@decorators.idempotent_id('93a11b40-1ba8-44d6-a196-f8d97220f796')
- def test_snapshot_get(self):
+ def test_show_snapshot(self):
# Get the snapshot
with self.rbac_utils.override_role(self):
- self.snapshots_client.show_snapshot(self.snapshot
- ['id'])['snapshot']
+ self.snapshots_client.show_snapshot(
+ self.snapshot['id'])['snapshot']
+
+ @decorators.idempotent_id('5d6f5f21-9293-4f2a-8f44-cabdc24d92cb')
+ @rbac_rule_validation.action(
+ service="cinder",
+ rule="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',
+ 'os-extended-snapshot-attributes:progress')
+
+ with self.rbac_utils.override_role(self):
+ resp = self.snapshots_client.show_snapshot(
+ self.snapshot['id'])['snapshot']
+ for expected_attr in expected_attrs:
+ if expected_attr not in resp:
+ raise rbac_exceptions.RbacMalformedResponse(
+ attribute=expected_attr)
@rbac_rule_validation.action(service="cinder",
rule="volume:update_snapshot")
@decorators.idempotent_id('53fe8ee3-3bea-4ae8-a979-3c98ea72f620')
- def test_snapshot_update(self):
+ def test_update_snapshot(self):
new_desc = 'This is the new description of snapshot.'
params = {'description': new_desc}
# Updates snapshot with new values
@@ -80,19 +93,9 @@
self.snapshots_client, self.snapshot['id'], 'available')
@rbac_rule_validation.action(service="cinder",
- rule="volume:get_all_snapshots")
- @decorators.idempotent_id('e4edf0c0-2cd3-420f-b8ab-4d98a0718608')
- def test_snapshots_get_all(self):
- """list snapshots with params."""
- # Verify list snapshots by display_name filter
- params = {'name': self.snapshot['name']}
- with self.rbac_utils.override_role(self):
- self._list_by_param_values(params)
-
- @rbac_rule_validation.action(service="cinder",
rule="volume:delete_snapshot")
@decorators.idempotent_id('c7fe54ec-3b70-4772-ba11-f166d95888a3')
- def test_snapshot_delete(self):
+ def test_delete_snapshot(self):
# Create a temp snapshot
temp_snapshot = self.create_snapshot(self.volume['id'])
with self.rbac_utils.override_role(self):
@@ -100,3 +103,38 @@
self.snapshots_client.delete_snapshot(temp_snapshot['id'])
self.snapshots_client.wait_for_resource_deletion(
temp_snapshot['id'])
+
+ @rbac_rule_validation.action(service="cinder",
+ rule="volume:get_all_snapshots")
+ @decorators.idempotent_id('e4edf0c0-2cd3-420f-b8ab-4d98a0718608')
+ def test_list_snapshots(self):
+ """List snapshots with params."""
+ params = {'name': self.snapshot['name']}
+ with self.rbac_utils.override_role(self):
+ self._list_by_param_values(**params)
+
+ @decorators.idempotent_id('f3155d8e-45ee-45c9-910d-18c0242229e1')
+ @rbac_rule_validation.action(service="cinder",
+ rule="volume:get_all_snapshots")
+ def test_list_snapshots_details(self):
+ """List snapshots details with params."""
+ params = {'name': self.snapshot['name']}
+ with self.rbac_utils.override_role(self):
+ self._list_by_param_values(with_detail=True, **params)
+
+ @decorators.idempotent_id('dd37f388-2731-446d-a78f-676997ebb04a')
+ @rbac_rule_validation.action(
+ service="cinder",
+ rule="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',
+ 'os-extended-snapshot-attributes:progress')
+ params = {'name': self.snapshot['name']}
+
+ with self.rbac_utils.override_role(self):
+ resp = self._list_by_param_values(with_detail=True, **params)
+ for expected_attr in expected_attrs:
+ if expected_attr not in resp[0]:
+ raise rbac_exceptions.RbacMalformedResponse(
+ attribute=expected_attr)
diff --git a/patrole_tempest_plugin/tests/unit/test_policy_authority.py b/patrole_tempest_plugin/tests/unit/test_policy_authority.py
index d2074e7..3e2cc4c 100644
--- a/patrole_tempest_plugin/tests/unit/test_policy_authority.py
+++ b/patrole_tempest_plugin/tests/unit/test_policy_authority.py
@@ -387,12 +387,11 @@
policy_authority.PolicyAuthority,
None, None, 'test_service')
- expected_error = \
- 'Policy file for {0} service neither found in code '\
- 'nor at {1}.'.format(
- 'test_service',
- [CONF.patrole.custom_policy_files[0] % 'test_service'])
-
+ 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('test_service',
+ [CONF.patrole.custom_policy_files[0] % 'test_service']))
self.assertIn(expected_error, str(e))
@mock.patch.object(policy_authority, 'json', autospec=True)
@@ -436,7 +435,8 @@
None, None, 'tenant_rbac_policy')
expected_error = (
- 'Policy file for {0} service neither found in code nor at {1}.'
+ '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']))
self.assertIn(expected_error, str(e))
@@ -485,9 +485,10 @@
policy_parser.policy_files['test_service'])
def test_discover_policy_files_with_no_valid_files(self):
- expected_error = ("Policy file for test_service service neither found "
- "in code nor at %s." %
- [self.conf_policy_path % 'test_service'])
+ 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('test_service', [self.conf_policy_path % 'test_service']))
e = self.assertRaises(rbac_exceptions.RbacParsingException,
policy_authority.PolicyAuthority,
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 82f0428..85547e1 100644
--- a/patrole_tempest_plugin/tests/unit/test_rbac_rule_validation.py
+++ b/patrole_tempest_plugin/tests/unit/test_rbac_rule_validation.py
@@ -13,7 +13,6 @@
# under the License.
import mock
-import testtools
from tempest.lib import exceptions
from tempest import manager
@@ -297,12 +296,8 @@
@mock.patch.object(rbac_rv, 'policy_authority', autospec=True)
def test_invalid_policy_rule_raises_parsing_exception(
self, mock_authority):
- """Test that invalid policy action causes test to be fail with
- ``[patrole] strict_policy_check`` set to True.
+ """Test that invalid policy action causes test to raise an exception.
"""
- self.useFixture(
- fixtures.ConfPatcher(strict_policy_check=True, group='patrole'))
-
mock_authority.PolicyAuthority.return_value.allowed.\
side_effect = rbac_exceptions.RbacParsingException
@@ -319,30 +314,6 @@
mock.sentinel.service, extra_target_data={})
@mock.patch.object(rbac_rv, 'policy_authority', autospec=True)
- def test_invalid_policy_rule_raises_skip_exception(
- self, mock_authority):
- """Test that invalid policy action causes test to be skipped with
- ``[patrole] strict_policy_check`` set to False.
- """
- self.useFixture(
- fixtures.ConfPatcher(strict_policy_check=False, group='patrole'))
-
- mock_authority.PolicyAuthority.return_value.allowed.side_effect = (
- rbac_exceptions.RbacParsingException)
-
- @rbac_rv.action(mock.sentinel.service, mock.sentinel.action)
- def test_policy(*args):
- pass
-
- error_re = 'Attempted to test an invalid policy file or action'
- self.assertRaisesRegex(testtools.TestCase.skipException, error_re,
- test_policy, self.mock_test_args)
-
- mock_authority.PolicyAuthority.assert_called_once_with(
- mock.sentinel.project_id, mock.sentinel.user_id,
- mock.sentinel.service, extra_target_data={})
-
- @mock.patch.object(rbac_rv, 'policy_authority', autospec=True)
def test_get_exception_type_404(self, _):
"""Test that getting a 404 exception type returns NotFound."""
expected_exception = exceptions.NotFound
diff --git a/playbooks/patrole-admin/post.yaml b/playbooks/patrole-admin/post.yaml
deleted file mode 100644
index dac8753..0000000
--- a/playbooks/patrole-admin/post.yaml
+++ /dev/null
@@ -1,80 +0,0 @@
-- hosts: primary
- tasks:
-
- - name: Copy files from {{ ansible_user_dir }}/workspace/ on node
- synchronize:
- src: '{{ ansible_user_dir }}/workspace/'
- dest: '{{ zuul.executor.log_root }}'
- mode: pull
- copy_links: true
- verify_host: true
- rsync_opts:
- - --include=**/*nose_results.html
- - --include=*/
- - --exclude=*
- - --prune-empty-dirs
-
- - name: Copy files from {{ ansible_user_dir }}/workspace/ on node
- synchronize:
- src: '{{ ansible_user_dir }}/workspace/'
- dest: '{{ zuul.executor.log_root }}'
- mode: pull
- copy_links: true
- verify_host: true
- rsync_opts:
- - --include=**/*testr_results.html.gz
- - --include=*/
- - --exclude=*
- - --prune-empty-dirs
-
- - name: Copy files from {{ ansible_user_dir }}/workspace/ on node
- synchronize:
- src: '{{ ansible_user_dir }}/workspace/'
- dest: '{{ zuul.executor.log_root }}'
- mode: pull
- copy_links: true
- verify_host: true
- rsync_opts:
- - --include=/.testrepository/tmp*
- - --include=*/
- - --exclude=*
- - --prune-empty-dirs
-
- - name: Copy files from {{ ansible_user_dir }}/workspace/ on node
- synchronize:
- src: '{{ ansible_user_dir }}/workspace/'
- dest: '{{ zuul.executor.log_root }}'
- mode: pull
- copy_links: true
- verify_host: true
- rsync_opts:
- - --include=**/*testrepository.subunit.gz
- - --include=*/
- - --exclude=*
- - --prune-empty-dirs
-
- - name: Copy files from {{ ansible_user_dir }}/workspace/ on node
- synchronize:
- src: '{{ ansible_user_dir }}/workspace/'
- dest: '{{ zuul.executor.log_root }}/tox'
- mode: pull
- copy_links: true
- verify_host: true
- rsync_opts:
- - --include=/.tox/*/log/*
- - --include=*/
- - --exclude=*
- - --prune-empty-dirs
-
- - name: Copy files from {{ ansible_user_dir }}/workspace/ on node
- synchronize:
- src: '{{ ansible_user_dir }}/workspace/'
- dest: '{{ zuul.executor.log_root }}'
- mode: pull
- copy_links: true
- verify_host: true
- rsync_opts:
- - --include=/logs/**
- - --include=*/
- - --exclude=*
- - --prune-empty-dirs
diff --git a/playbooks/patrole-admin/run.yaml b/playbooks/patrole-admin/run.yaml
deleted file mode 100644
index 57f208d..0000000
--- a/playbooks/patrole-admin/run.yaml
+++ /dev/null
@@ -1,60 +0,0 @@
-- hosts: all
- name: Autoconverted job legacy-tempest-dsvm-patrole-admin from old job gate-tempest-dsvm-patrole-admin-ubuntu-xenial
- tasks:
-
- - name: Ensure legacy workspace directory
- file:
- path: '{{ ansible_user_dir }}/workspace'
- state: directory
-
- - shell:
- cmd: |
- set -e
- set -x
- cat > clonemap.yaml << EOF
- clonemap:
- - name: openstack-infra/devstack-gate
- dest: devstack-gate
- EOF
- /usr/zuul-env/bin/zuul-cloner -m clonemap.yaml --cache-dir /opt/git \
- git://git.openstack.org \
- openstack-infra/devstack-gate
- executable: /bin/bash
- chdir: '{{ ansible_user_dir }}/workspace'
- environment: '{{ zuul | zuul_legacy_vars }}'
-
- - shell:
- cmd: |
- set -e
- set -x
- cat << 'EOF' >>"/tmp/dg-local.conf"
- [[local|localrc]]
- enable_plugin patrole git://git.openstack.org/openstack/patrole
- TEMPEST_PLUGINS='/opt/stack/new/patrole'
- # Needed by Patrole devstack plugin
- RBAC_TEST_ROLE=admin
- EOF
- executable: /bin/bash
- chdir: '{{ ansible_user_dir }}/workspace'
- environment: '{{ zuul | zuul_legacy_vars }}'
-
- - shell:
- cmd: |
- set -e
- set -x
- export PYTHONUNBUFFERED=true
- export DEVSTACK_GATE_TEMPEST=1
- export DEVSTACK_GATE_NEUTRON=1
- export DEVSTACK_GATE_TEMPEST_REGEX='(?!.*\[.*\bslow\b.*\])(^patrole_tempest_plugin\.tests\.api)'
- export DEVSTACK_GATE_TEMPEST_ALL_PLUGINS=1
- export TEMPEST_CONCURRENCY=2
- export PROJECTS="openstack/patrole $PROJECTS"
- export BRANCH_OVERRIDE=default
- if [ "$BRANCH_OVERRIDE" != "default" ] ; then
- export OVERRIDE_ZUUL_BRANCH=$BRANCH_OVERRIDE
- fi
- cp devstack-gate/devstack-vm-gate-wrap.sh ./safe-devstack-vm-gate-wrap.sh
- ./safe-devstack-vm-gate-wrap.sh
- executable: /bin/bash
- chdir: '{{ ansible_user_dir }}/workspace'
- environment: '{{ zuul | zuul_legacy_vars }}'
diff --git a/playbooks/patrole-member/post.yaml b/playbooks/patrole-member/post.yaml
deleted file mode 100644
index dac8753..0000000
--- a/playbooks/patrole-member/post.yaml
+++ /dev/null
@@ -1,80 +0,0 @@
-- hosts: primary
- tasks:
-
- - name: Copy files from {{ ansible_user_dir }}/workspace/ on node
- synchronize:
- src: '{{ ansible_user_dir }}/workspace/'
- dest: '{{ zuul.executor.log_root }}'
- mode: pull
- copy_links: true
- verify_host: true
- rsync_opts:
- - --include=**/*nose_results.html
- - --include=*/
- - --exclude=*
- - --prune-empty-dirs
-
- - name: Copy files from {{ ansible_user_dir }}/workspace/ on node
- synchronize:
- src: '{{ ansible_user_dir }}/workspace/'
- dest: '{{ zuul.executor.log_root }}'
- mode: pull
- copy_links: true
- verify_host: true
- rsync_opts:
- - --include=**/*testr_results.html.gz
- - --include=*/
- - --exclude=*
- - --prune-empty-dirs
-
- - name: Copy files from {{ ansible_user_dir }}/workspace/ on node
- synchronize:
- src: '{{ ansible_user_dir }}/workspace/'
- dest: '{{ zuul.executor.log_root }}'
- mode: pull
- copy_links: true
- verify_host: true
- rsync_opts:
- - --include=/.testrepository/tmp*
- - --include=*/
- - --exclude=*
- - --prune-empty-dirs
-
- - name: Copy files from {{ ansible_user_dir }}/workspace/ on node
- synchronize:
- src: '{{ ansible_user_dir }}/workspace/'
- dest: '{{ zuul.executor.log_root }}'
- mode: pull
- copy_links: true
- verify_host: true
- rsync_opts:
- - --include=**/*testrepository.subunit.gz
- - --include=*/
- - --exclude=*
- - --prune-empty-dirs
-
- - name: Copy files from {{ ansible_user_dir }}/workspace/ on node
- synchronize:
- src: '{{ ansible_user_dir }}/workspace/'
- dest: '{{ zuul.executor.log_root }}/tox'
- mode: pull
- copy_links: true
- verify_host: true
- rsync_opts:
- - --include=/.tox/*/log/*
- - --include=*/
- - --exclude=*
- - --prune-empty-dirs
-
- - name: Copy files from {{ ansible_user_dir }}/workspace/ on node
- synchronize:
- src: '{{ ansible_user_dir }}/workspace/'
- dest: '{{ zuul.executor.log_root }}'
- mode: pull
- copy_links: true
- verify_host: true
- rsync_opts:
- - --include=/logs/**
- - --include=*/
- - --exclude=*
- - --prune-empty-dirs
diff --git a/playbooks/patrole-member/run.yaml b/playbooks/patrole-member/run.yaml
deleted file mode 100644
index b95467f..0000000
--- a/playbooks/patrole-member/run.yaml
+++ /dev/null
@@ -1,61 +0,0 @@
-- hosts: all
- name: Autoconverted job legacy-tempest-dsvm-patrole-member from old job gate-tempest-dsvm-patrole-member-ubuntu-xenial
- tasks:
-
- - name: Ensure legacy workspace directory
- file:
- path: '{{ ansible_user_dir }}/workspace'
- state: directory
-
- - shell:
- cmd: |
- set -e
- set -x
- cat > clonemap.yaml << EOF
- clonemap:
- - name: openstack-infra/devstack-gate
- dest: devstack-gate
- EOF
- /usr/zuul-env/bin/zuul-cloner -m clonemap.yaml --cache-dir /opt/git \
- git://git.openstack.org \
- openstack-infra/devstack-gate
- executable: /bin/bash
- chdir: '{{ ansible_user_dir }}/workspace'
- environment: '{{ zuul | zuul_legacy_vars }}'
-
- - shell:
- cmd: |
- set -e
- set -x
- cat << 'EOF' >>"/tmp/dg-local.conf"
- [[local|localrc]]
- enable_plugin patrole git://git.openstack.org/openstack/patrole
- TEMPEST_PLUGINS='/opt/stack/new/patrole'
- # Needed by Patrole devstack plugin
- RBAC_TEST_ROLE=member
- EOF
- executable: /bin/bash
- chdir: '{{ ansible_user_dir }}/workspace'
- environment: '{{ zuul | zuul_legacy_vars }}'
-
- - shell:
- cmd: |
- set -e
- set -x
- export PYTHONUNBUFFERED=true
- export DEVSTACK_GATE_TEMPEST=1
- export DEVSTACK_GATE_NEUTRON=1
- export DEVSTACK_GATE_TEMPEST_REGEX='(?!.*\[.*\bslow\b.*\])(^patrole_tempest_plugin\.tests\.api)'
- export DEVSTACK_GATE_TEMPEST_ALL_PLUGINS=1
- export TEMPEST_CONCURRENCY=2
- export PROJECTS="openstack/patrole $PROJECTS"
- export BRANCH_OVERRIDE=default
- if [ "$BRANCH_OVERRIDE" != "default" ] ; then
- export OVERRIDE_ZUUL_BRANCH=$BRANCH_OVERRIDE
- fi
- cp devstack-gate/devstack-vm-gate-wrap.sh ./safe-devstack-vm-gate-wrap.sh
- ./safe-devstack-vm-gate-wrap.sh
- executable: /bin/bash
- chdir: '{{ ansible_user_dir }}/workspace'
- environment: '{{ zuul | zuul_legacy_vars }}'
-
diff --git a/playbooks/patrole-py35-member/post.yaml b/playbooks/patrole-py35-member/post.yaml
deleted file mode 100644
index dac8753..0000000
--- a/playbooks/patrole-py35-member/post.yaml
+++ /dev/null
@@ -1,80 +0,0 @@
-- hosts: primary
- tasks:
-
- - name: Copy files from {{ ansible_user_dir }}/workspace/ on node
- synchronize:
- src: '{{ ansible_user_dir }}/workspace/'
- dest: '{{ zuul.executor.log_root }}'
- mode: pull
- copy_links: true
- verify_host: true
- rsync_opts:
- - --include=**/*nose_results.html
- - --include=*/
- - --exclude=*
- - --prune-empty-dirs
-
- - name: Copy files from {{ ansible_user_dir }}/workspace/ on node
- synchronize:
- src: '{{ ansible_user_dir }}/workspace/'
- dest: '{{ zuul.executor.log_root }}'
- mode: pull
- copy_links: true
- verify_host: true
- rsync_opts:
- - --include=**/*testr_results.html.gz
- - --include=*/
- - --exclude=*
- - --prune-empty-dirs
-
- - name: Copy files from {{ ansible_user_dir }}/workspace/ on node
- synchronize:
- src: '{{ ansible_user_dir }}/workspace/'
- dest: '{{ zuul.executor.log_root }}'
- mode: pull
- copy_links: true
- verify_host: true
- rsync_opts:
- - --include=/.testrepository/tmp*
- - --include=*/
- - --exclude=*
- - --prune-empty-dirs
-
- - name: Copy files from {{ ansible_user_dir }}/workspace/ on node
- synchronize:
- src: '{{ ansible_user_dir }}/workspace/'
- dest: '{{ zuul.executor.log_root }}'
- mode: pull
- copy_links: true
- verify_host: true
- rsync_opts:
- - --include=**/*testrepository.subunit.gz
- - --include=*/
- - --exclude=*
- - --prune-empty-dirs
-
- - name: Copy files from {{ ansible_user_dir }}/workspace/ on node
- synchronize:
- src: '{{ ansible_user_dir }}/workspace/'
- dest: '{{ zuul.executor.log_root }}/tox'
- mode: pull
- copy_links: true
- verify_host: true
- rsync_opts:
- - --include=/.tox/*/log/*
- - --include=*/
- - --exclude=*
- - --prune-empty-dirs
-
- - name: Copy files from {{ ansible_user_dir }}/workspace/ on node
- synchronize:
- src: '{{ ansible_user_dir }}/workspace/'
- dest: '{{ zuul.executor.log_root }}'
- mode: pull
- copy_links: true
- verify_host: true
- rsync_opts:
- - --include=/logs/**
- - --include=*/
- - --exclude=*
- - --prune-empty-dirs
diff --git a/playbooks/patrole-py35-member/run.yaml b/playbooks/patrole-py35-member/run.yaml
deleted file mode 100644
index e895702..0000000
--- a/playbooks/patrole-py35-member/run.yaml
+++ /dev/null
@@ -1,70 +0,0 @@
-- hosts: all
- name: Autoconverted job legacy-tempest-dsvm-patrole-py35-member from old job gate-tempest-dsvm-patrole-py35-member-ubuntu-xenial
- tasks:
-
- - name: Ensure legacy workspace directory
- file:
- path: '{{ ansible_user_dir }}/workspace'
- state: directory
-
- - shell:
- cmd: |
- set -e
- set -x
- cat > clonemap.yaml << EOF
- clonemap:
- - name: openstack-infra/devstack-gate
- dest: devstack-gate
- EOF
- /usr/zuul-env/bin/zuul-cloner -m clonemap.yaml --cache-dir /opt/git \
- git://git.openstack.org \
- openstack-infra/devstack-gate
- executable: /bin/bash
- chdir: '{{ ansible_user_dir }}/workspace'
- environment: '{{ zuul | zuul_legacy_vars }}'
-
- - shell:
- cmd: |
- set -e
- set -x
- cat << 'EOF' >>"/tmp/dg-local.conf"
- [[local|localrc]]
- enable_plugin patrole git://git.openstack.org/openstack/patrole
- TEMPEST_PLUGINS='/opt/stack/new/patrole'
- # Needed by Patrole devstack plugin
- RBAC_TEST_ROLE=member
- # Swift is not ready for python3 yet
- disable_service s-account
- disable_service s-container
- disable_service s-object
- disable_service s-proxy
- # Without Swift, c-bak cannot run (in the Gate at least)
- disable_service c-bak
- EOF
- executable: /bin/bash
- chdir: '{{ ansible_user_dir }}/workspace'
- environment: '{{ zuul | zuul_legacy_vars }}'
-
- - shell:
- cmd: |
- set -e
- set -x
- export PYTHONUNBUFFERED=true
- export DEVSTACK_GATE_USE_PYTHON3=True
- # Ensure that tempest set up is executed, but do not automatically
- # execute tempest tests; they are executed in post_test_hook.
- export DEVSTACK_GATE_TEMPEST=1
- export DEVSTACK_GATE_NEUTRON=1
- export DEVSTACK_GATE_TEMPEST_REGEX='(?!.*\[.*\bslow\b.*\])(^patrole_tempest_plugin\.tests\.api)'
- export DEVSTACK_GATE_TEMPEST_ALL_PLUGINS=1
- export TEMPEST_CONCURRENCY=2
- export PROJECTS="openstack/patrole $PROJECTS"
- export BRANCH_OVERRIDE=default
- if [ "$BRANCH_OVERRIDE" != "default" ] ; then
- export OVERRIDE_ZUUL_BRANCH=$BRANCH_OVERRIDE
- fi
- cp devstack-gate/devstack-vm-gate-wrap.sh ./safe-devstack-vm-gate-wrap.sh
- ./safe-devstack-vm-gate-wrap.sh
- executable: /bin/bash
- chdir: '{{ ansible_user_dir }}/workspace'
- environment: '{{ zuul | zuul_legacy_vars }}'
diff --git a/releasenotes/notes/remove-deprecated-switch-role-148c9a5c6796857f.yaml b/releasenotes/notes/remove-deprecated-switch-role-148c9a5c6796857f.yaml
new file mode 100644
index 0000000..b303d09
--- /dev/null
+++ b/releasenotes/notes/remove-deprecated-switch-role-148c9a5c6796857f.yaml
@@ -0,0 +1,6 @@
+---
+upgrade:
+ - |
+ The ``switch_role`` method in ``rbac_utils`` module has been removed
+ because it is a clunky way of manipulating Tempest roles to achieve
+ RBAC testing. Use ``override_role`` instead.
diff --git a/releasenotes/notes/remove-strict-policy-check-480e3d664f7b2d96.yaml b/releasenotes/notes/remove-strict-policy-check-480e3d664f7b2d96.yaml
new file mode 100644
index 0000000..37c5e1e
--- /dev/null
+++ b/releasenotes/notes/remove-strict-policy-check-480e3d664f7b2d96.yaml
@@ -0,0 +1,6 @@
+---
+upgrade:
+ - |
+ The ``[patrole].strict_policy_check`` was deprecated during the Queens
+ release cycle. It is removed in this release cycle because Patrole should
+ always fail on invalid policies.
diff --git a/requirements.txt b/requirements.txt
index 35c6038..cc13aa9 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -3,7 +3,7 @@
# process, which may cause wedges in the gate later.
pbr!=2.1.0,>=2.0.0 # Apache-2.0
oslo.log>=3.36.0 # Apache-2.0
-oslo.config>=5.1.0 # Apache-2.0
+oslo.config>=5.2.0 # Apache-2.0
oslo.policy>=1.30.0 # Apache-2.0
tempest>=17.1.0 # Apache-2.0
stevedore>=1.20.0 # Apache-2.0
diff --git a/setup.cfg b/setup.cfg
index 143d3aa..02ce831 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -23,12 +23,6 @@
packages =
patrole_tempest_plugin
-[build_sphinx]
-source-dir = doc/source
-build-dir = doc/build
-all_files = 1
-warning-is-error = 1
-
[upload_sphinx]
upload-dir = doc/build/html
diff --git a/test-requirements.txt b/test-requirements.txt
index add2388..d6e73bd 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -2,10 +2,6 @@
# of appearance. Changing the order has an impact on the overall integration
# process, which may cause wedges in the gate later.
hacking>=1.0.0 # Apache-2.0
-
-sphinx!=1.6.6,>=1.6.2 # BSD
-openstackdocstheme>=1.18.1 # Apache-2.0
-reno>=2.5.0 # Apache-2.0
fixtures>=3.0.0 # Apache-2.0/BSD
mock>=2.0.0 # BSD
coverage!=4.4,>=4.0 # Apache-2.0
diff --git a/tox.ini b/tox.ini
index d5e3b91..cca09d0 100644
--- a/tox.ini
+++ b/tox.ini
@@ -46,11 +46,24 @@
rm
[testenv:docs]
-commands = python setup.py build_sphinx
+deps =
+ -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt}
+ -r{toxinidir}/requirements.txt
+ -r{toxinidir}/doc/requirements.txt
+commands =
+ rm -rf doc/build
+ sphinx-build -W -b html doc/source doc/build/html
+whitelist_externals = rm
[testenv:releasenotes]
+deps =
+ -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt}
+ -r{toxinidir}/requirements.txt
+ -r{toxinidir}/doc/requirements.txt
commands =
+ rm -rf releasenotes/build
sphinx-build -a -E -W -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html
+whitelist_externals = rm
[testenv:debug]
commands = oslo_debug_helper -t patrole_tempest_plugin/tests {posargs}
@@ -78,3 +91,10 @@
[hacking]
local-check-factory = patrole_tempest_plugin.hacking.checks.factory
+
+[testenv:lower-constraints]
+basepython = python3
+deps =
+ -c{toxinidir}/lower-constraints.txt
+ -r{toxinidir}/test-requirements.txt
+ -r{toxinidir}/requirements.txt