Merge "Fix volume delete_group data race in clean up"
diff --git a/.gitignore b/.gitignore
index 963e589..6d47339 100644
--- a/.gitignore
+++ b/.gitignore
@@ -53,6 +53,10 @@
*~
.*.swp
.*sw?
+*.idea
# Files created by releasenotes build
-releasenotes/build
\ No newline at end of file
+releasenotes/build
+
+# Misc
+.stestr/
diff --git a/.mailmap b/.mailmap
index 516ae6f..47612b3 100644
--- a/.mailmap
+++ b/.mailmap
@@ -1,3 +1,5 @@
# Format is:
# <preferred e-mail> <other e-mail 1>
# <preferred e-mail> <other e-mail 2>
+Felipe Monteiro <felipe.carneiro.monteiro@gmail.com> <fm577c@att.com>
+Felipe Monteiro <felipe.carneiro.monteiro@gmail.com> <felipe.monteiro@att.com>
diff --git a/.zuul.yaml b/.zuul.yaml
new file mode 100644
index 0000000..313ce49
--- /dev/null
+++ b/.zuul.yaml
@@ -0,0 +1,80 @@
+- job:
+ name: patrole-dsvm-base
+ parent: legacy-dsvm-base
+ timeout: 7800
+ irrelevant-files:
+ - ^(test-|)requirements.txt$
+ - ^.*\.rst$
+ - ^doc/.*
+ - ^patrole/patrole_tempest_plugin/tests/unit/.*$
+ - ^releasenotes/.*
+ - ^setup.cfg$
+ required-projects:
+ - openstack-infra/devstack-gate
+ - openstack/patrole
+ - openstack/tempest
+
+- job:
+ name: patrole-dsvm-base-multinode
+ parent: legacy-dsvm-base-multinode
+ timeout: 7800
+ irrelevant-files:
+ - ^(test-|)requirements.txt$
+ - ^.*\.rst$
+ - ^doc/.*
+ - ^patrole/patrole_tempest_plugin/tests/unit/.*$
+ - ^releasenotes/.*
+ - ^setup.cfg$
+ required-projects:
+ - openstack-infra/devstack-gate
+ - openstack/patrole
+ - openstack/tempest
+
+- job:
+ name: tempest-dsvm-patrole-admin
+ parent: patrole-dsvm-base
+ run: playbooks/legacy/tempest-dsvm-patrole-admin/run.yaml
+ post-run: playbooks/legacy/tempest-dsvm-patrole-admin/post.yaml
+
+- job:
+ name: tempest-dsvm-patrole-member
+ parent: patrole-dsvm-base
+ run: playbooks/legacy/tempest-dsvm-patrole-member/run.yaml
+ post-run: playbooks/legacy/tempest-dsvm-patrole-member/post.yaml
+
+- job:
+ name: tempest-dsvm-patrole-multinode-admin
+ parent: patrole-dsvm-base-multinode
+ run: playbooks/legacy/tempest-dsvm-patrole-multinode-admin/run.yaml
+ post-run: playbooks/legacy/tempest-dsvm-patrole-multinode-admin/post.yaml
+ voting: false
+ nodeset: legacy-ubuntu-xenial-2-node
+
+- job:
+ name: tempest-dsvm-patrole-multinode-member
+ parent: patrole-dsvm-base-multinode
+ run: playbooks/legacy/tempest-dsvm-patrole-multinode-member/run.yaml
+ post-run: playbooks/legacy/tempest-dsvm-patrole-multinode-member/post.yaml
+ voting: false
+ nodeset: legacy-ubuntu-xenial-2-node
+
+- job:
+ name: tempest-dsvm-patrole-py35-member
+ parent: patrole-dsvm-base
+ run: playbooks/legacy/tempest-dsvm-patrole-py35-member/run.yaml
+ post-run: playbooks/legacy/tempest-dsvm-patrole-py35-member/post.yaml
+
+- project:
+ name: openstack/patrole
+ check:
+ jobs:
+ - tempest-dsvm-patrole-admin
+ - tempest-dsvm-patrole-member
+ - tempest-dsvm-patrole-py35-member
+ - tempest-dsvm-patrole-multinode-admin
+ - tempest-dsvm-patrole-multinode-member
+ gate:
+ jobs:
+ - tempest-dsvm-patrole-admin
+ - tempest-dsvm-patrole-member
+ - tempest-dsvm-patrole-py35-member
diff --git a/README.rst b/README.rst
index 6110dda..f4ab65c 100644
--- a/README.rst
+++ b/README.rst
@@ -16,6 +16,35 @@
Patrole currently offers testing for the following OpenStack services: Nova,
Neutron, Glance, Cinder and Keystone.
+Patrole is currently undergoing heavy development. As more projects move
+toward policy in code, Patrole will align its testing with the appropriate
+documentation.
+
+Design Principles
+-----------------
+
+Patrole borrows some design principles from Tempest, but not all, as its
+testing scope is confined to policies.
+
+* *Stability*. Patrole uses OpenStack public interfaces. Tests in Patrole
+ should only touch public OpenStack APIs.
+* *Atomicity*. Patrole tests should be atomic: they should test policies in
+ isolation. Unlike Tempest, a Patrole test strives to only call a single
+ endpoint at a time.
+* *Holistic coverage*. Patrole strives for complete coverage of the OpenStack
+ API. Additionally, Patrole strives to test the API-to-policy mapping
+ contained in each project's policy in code documentation.
+* *Self-contained*. Patrole should attempt to clean up after itself; whenever
+ possible we should tear down resources when done.
+
+ .. note::
+
+ Patrole modifies roles dynamically in the background, which affects
+ pre-provisioned credentials. Work is currently underway to clean up
+ modifications made to pre-provisioned credentials.
+
+* *Self-tested*. Patrole should be self-tested.
+
Features
--------
* Validation of default policy definitions located in policy.json files.
diff --git a/devstack/plugin.sh b/devstack/plugin.sh
index 1066136..1f666f2 100644
--- a/devstack/plugin.sh
+++ b/devstack/plugin.sh
@@ -20,7 +20,6 @@
iniset $TEMPEST_CONFIG rbac enable_rbac True
iniset $TEMPEST_CONFIG rbac rbac_test_role $RBAC_TEST_ROLE
- iniset $TEMPEST_CONFIG rbac strict_policy_check False
fi
}
diff --git a/patrole_tempest_plugin/config.py b/patrole_tempest_plugin/config.py
index d309d60..7966247 100644
--- a/patrole_tempest_plugin/config.py
+++ b/patrole_tempest_plugin/config.py
@@ -30,8 +30,12 @@
deprecated_group='rbac',
help="Enables RBAC tests."),
cfg.BoolOpt('strict_policy_check',
- default=False,
+ default=True,
deprecated_group='rbac',
+ 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."""),
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
new file mode 100644
index 0000000..dd32187
--- /dev/null
+++ b/patrole_tempest_plugin/tests/api/compute/test_fixed_ips_rbac.py
@@ -0,0 +1,78 @@
+# Copyright 2017 NEC Corporation.
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from tempest import config
+from tempest.lib import decorators
+
+from patrole_tempest_plugin import rbac_rule_validation
+from patrole_tempest_plugin.tests.api.compute import rbac_base
+
+CONF = config.CONF
+
+
+class FixedIpsRbacTest(rbac_base.BaseV2ComputeRbacTest):
+
+ # Tests will fail with a 404 starting from microversion 2.36:
+ # See the following link for details:
+ # https://developer.openstack.org/api-ref/compute/#fixed-ips-os-fixed-ips-deprecated
+ max_microversion = '2.35'
+
+ @classmethod
+ def skip_checks(cls):
+ super(FixedIpsRbacTest, cls).skip_checks()
+ if CONF.service_available.neutron:
+ msg = ("%s skipped as neutron is available" % cls.__name__)
+ raise cls.skipException(msg)
+
+ @classmethod
+ def resource_setup(cls):
+ super(FixedIpsRbacTest, cls).resource_setup()
+ server = cls.create_test_server(wait_until='ACTIVE')
+ server = cls.servers_client.show_server(server['id'])['server']
+ cls.ip = None
+ for ip_set in server['addresses']:
+ for ip in server['addresses'][ip_set]:
+ if ip['OS-EXT-IPS:type'] == 'fixed':
+ cls.ip = ip['addr']
+ break
+ if cls.ip:
+ break
+ if cls.ip is None:
+ raise cls.skipException("No fixed ip found for server: %s"
+ % server['id'])
+
+ @decorators.idempotent_id('c89391f7-4844-4a70-a116-37c1336efb99')
+ @rbac_rule_validation.action(
+ service="nova",
+ rule="os_compute_api:os-fixed-ips")
+ def test_show_fixed_ip_details(self):
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.fixed_ips_client.show_fixed_ip(self.ip)
+
+ @decorators.idempotent_id('f0314501-735d-4315-9856-959e01e82f0d')
+ @rbac_rule_validation.action(
+ service="nova",
+ rule="os_compute_api:os-fixed-ips")
+ def test_set_reserve(self):
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.fixed_ips_client.reserve_fixed_ip(self.ip, reserve="None")
+
+ @decorators.idempotent_id('866a6fdc-a237-4502-9bf2-52fe82aba356')
+ @rbac_rule_validation.action(
+ service="nova",
+ rule="os_compute_api:os-fixed-ips")
+ def test_set_unreserve(self):
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.fixed_ips_client.reserve_fixed_ip(self.ip, unreserve="None")
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 f28bf3c..2bc267b 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
@@ -72,6 +72,57 @@
waiters.wait_for_server_status(
self.os_admin.servers_client, self.server_id, 'ACTIVE')
+ def _shelve_server(self):
+ self.servers_client.shelve_server(self.server_id)
+ self.addCleanup(self._cleanup_server_actions,
+ self.servers_client.unshelve_server,
+ self.server_id)
+ offload_time = CONF.compute.shelved_offload_time
+ if offload_time >= 0:
+ waiters.wait_for_server_status(self.os_admin.servers_client,
+ self.server_id,
+ 'SHELVED_OFFLOADED',
+ extra_timeout=offload_time)
+ else:
+ waiters.wait_for_server_status(self.os_admin.servers_client,
+ self.server_id, 'SHELVED')
+
+ def _pause_server(self):
+ self.servers_client.pause_server(self.server_id)
+ self.addCleanup(self._cleanup_server_actions,
+ self.servers_client.unpause_server,
+ self.server_id)
+ waiters.wait_for_server_status(
+ self.os_admin.servers_client, self.server_id, 'PAUSED')
+
+ def _cleanup_server_actions(self, function, server_id, **kwargs):
+ server = self.servers_client.show_server(server_id)['server']
+ if server['status'] != 'ACTIVE':
+ function(server_id, **kwargs)
+
+ @decorators.idempotent_id('117f4ff2-8544-437b-824f-5e41cb6640ee')
+ @testtools.skipUnless(CONF.compute_feature_enabled.pause,
+ 'Pause is not available.')
+ @rbac_rule_validation.action(
+ service="nova",
+ rule="os_compute_api:os-pause-server:pause")
+ def test_pause_server(self):
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self._pause_server()
+
+ @decorators.idempotent_id('087008cf-82fa-4eeb-ae8b-32c4126456ad')
+ @testtools.skipUnless(CONF.compute_feature_enabled.pause,
+ 'Pause is not available.')
+ @rbac_rule_validation.action(
+ service="nova",
+ rule="os_compute_api:os-pause-server:unpause")
+ def test_unpause_server(self):
+ self._pause_server()
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.servers_client.unpause_server(self.server_id)
+ waiters.wait_for_server_status(
+ self.os_admin.servers_client, self.server_id, 'ACTIVE')
+
@rbac_rule_validation.action(
service="nova",
rule="os_compute_api:servers:stop")
@@ -267,6 +318,27 @@
glance_admin_client.delete_image, image_id)
waiters.wait_for_image_status(glance_admin_client, image_id, 'active')
+ @decorators.attr(type='slow')
+ @decorators.idempotent_id('0b70c527-af75-4bed-9ccf-4f1310a8b60f')
+ @rbac_rule_validation.action(
+ service="nova",
+ rule="os_compute_api:os-shelve:shelve")
+ def test_shelve_server(self):
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self._shelve_server()
+
+ @decorators.attr(type='slow')
+ @decorators.idempotent_id('4b6e849a-9182-49ff-9257-e97e751b475e')
+ @rbac_rule_validation.action(
+ service="nova",
+ rule="os_compute_api:os-shelve:unshelve")
+ def test_unshelve_server(self):
+ self._shelve_server()
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.servers_client.unshelve_server(self.server_id)
+ waiters.wait_for_server_status(
+ self.os_admin.servers_client, self.server_id, 'ACTIVE')
+
class ServerActionsV214RbacTest(rbac_base.BaseV2ComputeRbacTest):
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 bc096ce..6a26f2b 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
@@ -26,8 +26,8 @@
https://github.com/openstack/keystone/blob/master/keystone/common/policies/auth.py
"""
- # TODO(felipemonteiro): Add tests for identity:get_auth_catalog and
- # identity:get_auth_domains once the endpoints are implemented in Tempest's
+ # TODO(felipemonteiro): Add tests for identity:get_auth_catalog
+ # once the endpoints are implemented in Tempest's
# identity v3 client.
@decorators.idempotent_id('2a9fbf7f-6feb-4161-ae4b-faf7d6421b1a')
@@ -36,3 +36,10 @@
def test_list_auth_projects(self):
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.identity_client.list_auth_projects()['projects']
+
+ @decorators.idempotent_id('6a40af0d-7265-4657-b6b2-87a2828e263e')
+ @rbac_rule_validation.action(service="keystone",
+ rule="identity:get_auth_domains")
+ def test_list_auth_domain(self):
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.identity_client.list_auth_domains()
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 82feff9..3639520 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
@@ -127,3 +127,11 @@
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.trusts_client.show_trust_role(
self.trust['id'], self.delegated_role_id)['role']
+
+ @decorators.idempotent_id('0184e0fb-641e-4b52-ab73-81c1ce6ca5c1')
+ @rbac_rule_validation.action(
+ service="keystone",
+ rule="identity:get_trust")
+ def test_show_trust(self):
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.trusts_client.show_trust(self.trust['id'])
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 c3ed9e1..fff2ada 100644
--- a/patrole_tempest_plugin/tests/api/network/test_routers_rbac.py
+++ b/patrole_tempest_plugin/tests/api/network/test_routers_rbac.py
@@ -176,6 +176,27 @@
raise rbac_exceptions.RbacMalformedResponse(
attribute='distributed')
+ @decorators.idempotent_id('defc502c-4159-4824-b4d9-3cdcc39015b2')
+ @utils.requires_ext(extension='l3-ha', service='network')
+ @rbac_rule_validation.action(service="neutron",
+ rule="get_router:ha")
+ def test_show_high_availability_router(self):
+ """GET high-availability router
+
+ RBAC test for the neutron get_router:ha policy
+ """
+ router = self.routers_client.create_router(ha=True)['router']
+ self.addCleanup(self.routers_client.delete_router, router['id'])
+
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ retrieved_fields = self.routers_client.show_router(
+ router['id'], fields=['ha'])['router']
+
+ # Rather than throwing a 403, the field is not present, so raise exc.
+ if 'ha' not in retrieved_fields:
+ raise rbac_exceptions.RbacMalformedResponse(
+ attribute='ha')
+
@rbac_rule_validation.action(
service="neutron", rule="update_router")
@decorators.idempotent_id('3d182f4e-0023-4218-9aa0-ea2b0ae0bd7a')
diff --git a/patrole_tempest_plugin/tests/api/volume/rbac_base.py b/patrole_tempest_plugin/tests/api/volume/rbac_base.py
index f4531df..7e2ebad 100644
--- a/patrole_tempest_plugin/tests/api/volume/rbac_base.py
+++ b/patrole_tempest_plugin/tests/api/volume/rbac_base.py
@@ -22,6 +22,12 @@
class BaseVolumeRbacTest(vol_base.BaseVolumeTest):
+ # NOTE(felipemonteiro): Patrole currently only tests the v3 Cinder API
+ # because it is the current API and because policy enforcement does not
+ # change between API major versions. So, it is not necessary to specify
+ # the `_api_version` in any test class. However, specify microversions in
+ # subclasses if necessary.
+ _api_version = 3
@classmethod
def skip_checks(cls):
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 74ffe60..cfca14e 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_capabilities_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_capabilities_rbac.py
@@ -20,18 +20,18 @@
from patrole_tempest_plugin.tests.api.volume import rbac_base
-class CapabilitiesRbacTest(rbac_base.BaseVolumeRbacTest):
+class CapabilitiesV3RbacTest(rbac_base.BaseVolumeRbacTest):
@classmethod
def skip_checks(cls):
- super(CapabilitiesRbacTest, cls).skip_checks()
+ super(CapabilitiesV3RbacTest, cls).skip_checks()
if not utils.is_extension_enabled('capabilities', 'volume'):
msg = "%s skipped as capabilities not enabled." % cls.__name__
raise cls.skipException(msg)
@classmethod
def setup_clients(cls):
- super(CapabilitiesRbacTest, cls).setup_clients()
+ super(CapabilitiesV3RbacTest, cls).setup_clients()
cls.capabilities_client = cls.os_primary.volume_capabilities_v2_client
cls.hosts_client = cls.os_primary.volume_hosts_v2_client
@@ -42,7 +42,3 @@
host = self.hosts_client.list_hosts()['hosts'][0]['host_name']
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.capabilities_client.show_backend_capabilities(host)
-
-
-class CapabilitiesV3RbacTest(CapabilitiesRbacTest):
- _api_version = 3
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 2cae0bd..a78585f 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
@@ -20,18 +20,18 @@
from patrole_tempest_plugin.tests.api.volume import rbac_base
-class EncryptionTypesRbacTest(rbac_base.BaseVolumeRbacTest):
+class EncryptionTypesV3RbacTest(rbac_base.BaseVolumeRbacTest):
@classmethod
def skip_checks(cls):
- super(EncryptionTypesRbacTest, cls).skip_checks()
+ super(EncryptionTypesV3RbacTest, cls).skip_checks()
if not utils.is_extension_enabled('encryption', 'volume'):
msg = "%s skipped as encryption not enabled." % cls.__name__
raise cls.skipException(msg)
@classmethod
def setup_clients(cls):
- super(EncryptionTypesRbacTest, cls).setup_clients()
+ super(EncryptionTypesV3RbacTest, cls).setup_clients()
cls.encryption_types_client = cls.os_primary.encryption_types_v2_client
def _create_volume_type_encryption(self):
@@ -82,7 +82,3 @@
vol_type_id = self._create_volume_type_encryption()
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.encryption_types_client.show_encryption_type(vol_type_id)
-
-
-class EncryptionTypesV3RbacTest(EncryptionTypesRbacTest):
- _api_version = 3
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 b998d64..e1c0910 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_groups_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_groups_rbac.py
@@ -24,7 +24,6 @@
class GroupsV3RbacTest(rbac_base.BaseVolumeRbacTest):
- _api_version = 3
min_microversion = '3.14'
max_microversion = 'latest'
@@ -129,7 +128,6 @@
class GroupTypesV3RbacTest(rbac_base.BaseVolumeRbacTest):
- _api_version = 3
min_microversion = '3.11'
max_microversion = 'latest'
@@ -161,7 +159,21 @@
service="cinder",
rule="group:group_types_manage")
def test_delete_group_type(self):
- goup_type = self.create_group_type(ignore_notfound=True)
+ group_type = self.create_group_type(ignore_notfound=True)
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- self.group_types_client.delete_group_type(goup_type['id'])
+ self.group_types_client.delete_group_type(group_type['id'])
+
+ @decorators.idempotent_id('8d9e2831-24c3-47b7-a76a-2e563287f12f')
+ @rbac_rule_validation.action(
+ service="cinder",
+ rule="group:access_group_types_specs")
+ def test_show_group_type(self):
+ group_type = self.create_group_type()
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ resp_body = \
+ self.group_types_client.show_group_type(
+ group_type['id'])['group_type']
+ if 'group_specs' not in resp_body:
+ raise rbac_exceptions.RbacMalformedResponse(
+ attribute='group_specs')
diff --git a/patrole_tempest_plugin/tests/api/volume/test_limits_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_limits_rbac.py
new file mode 100644
index 0000000..fa92cad
--- /dev/null
+++ b/patrole_tempest_plugin/tests/api/volume/test_limits_rbac.py
@@ -0,0 +1,30 @@
+# Copyright 2017 AT&T Corporation.
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from tempest.lib import decorators
+
+from patrole_tempest_plugin import rbac_rule_validation
+from patrole_tempest_plugin.tests.api.volume import rbac_base
+
+
+class LimitsV3RbacTest(rbac_base.BaseVolumeRbacTest):
+ _api_version = 3
+
+ @decorators.idempotent_id('dab04510-5b86-4479-a633-6e496ff405af')
+ @rbac_rule_validation.action(service="cinder",
+ rule="limits_extension:used_limits")
+ def test_show_limits(self):
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.volume_limits_client.show_limits()
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 2327de8..3ac59be 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_qos_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_qos_rbac.py
@@ -22,13 +22,12 @@
from patrole_tempest_plugin.tests.api.volume import rbac_base
-class VolumeQOSRbacTest(rbac_base.BaseVolumeRbacTest):
-
+class VolumeQOSV3RbacTest(rbac_base.BaseVolumeRbacTest):
credentials = ['primary', 'admin']
@classmethod
def setup_clients(cls):
- super(VolumeQOSRbacTest, cls).setup_clients()
+ super(VolumeQOSV3RbacTest, cls).setup_clients()
cls.qos_client = cls.os_primary.volume_qos_v2_client
cls.admin_qos_client = cls.os_admin.volume_qos_v2_client
@@ -146,7 +145,3 @@
self.qos_client.disassociate_all_qos(qos['id'])
waiters.wait_for_qos_operations(self.admin_qos_client, qos['id'],
'disassociate-all')
-
-
-class VolumeQOSV3RbacTest(VolumeQOSRbacTest):
- _api_version = 3
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 d016498..a81f1b9 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
@@ -21,11 +21,11 @@
from patrole_tempest_plugin.tests.api.volume import rbac_base
-class QuotaClassesRbacTest(rbac_base.BaseVolumeRbacTest):
+class QuotaClassesV3RbacTest(rbac_base.BaseVolumeRbacTest):
@classmethod
def skip_checks(cls):
- super(QuotaClassesRbacTest, cls).skip_checks()
+ super(QuotaClassesV3RbacTest, cls).skip_checks()
if not utils.is_extension_enabled('os-quota-class-sets', 'volume'):
msg = ("%s skipped as os-quota-class-sets not enabled."
% cls.__name__)
@@ -33,7 +33,7 @@
@classmethod
def setup_clients(cls):
- super(QuotaClassesRbacTest, cls).setup_clients()
+ super(QuotaClassesV3RbacTest, cls).setup_clients()
cls.quota_classes_client = cls.os_primary.quota_classes_client
cls.quota_name = data_utils.rand_name(cls.__name__ + '-QuotaClass')
@@ -56,7 +56,3 @@
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.quota_classes_client.update_quota_class_set(self.quota_name,
**quota_class_set)
-
-
-class QuotaClassesV3RbacTest(QuotaClassesRbacTest):
- _api_version = 3
diff --git a/patrole_tempest_plugin/tests/api/volume/test_scheduler_stats_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_scheduler_stats_rbac.py
index 25562e8..8fded0a 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
@@ -20,18 +20,18 @@
from patrole_tempest_plugin.tests.api.volume import rbac_base
-class SchedulerStatsRbacTest(rbac_base.BaseVolumeRbacTest):
+class SchedulerStatsV3RbacTest(rbac_base.BaseVolumeRbacTest):
@classmethod
def skip_checks(cls):
- super(SchedulerStatsRbacTest, cls).skip_checks()
+ super(SchedulerStatsV3RbacTest, cls).skip_checks()
if not utils.is_extension_enabled('scheduler-stats', 'volume'):
msg = "%s skipped as scheduler-stats not enabled." % cls.__name__
raise cls.skipException(msg)
@classmethod
def setup_clients(cls):
- super(SchedulerStatsRbacTest, cls).setup_clients()
+ super(SchedulerStatsV3RbacTest, cls).setup_clients()
cls.scheduler_stats_client =\
cls.os_primary.volume_scheduler_stats_v2_client
@@ -42,7 +42,3 @@
def test_list_back_end_storage_pools(self):
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.scheduler_stats_client.list_pools()
-
-
-class SchedulerStatsV3RbacTest(SchedulerStatsRbacTest):
- _api_version = 3
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 fc39f4a..96243d8 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
@@ -22,17 +22,17 @@
CONF = config.CONF
-class SnapshotsActionsRbacTest(rbac_base.BaseVolumeRbacTest):
+class SnapshotsActionsV3RbacTest(rbac_base.BaseVolumeRbacTest):
@classmethod
def skip_checks(cls):
- super(SnapshotsActionsRbacTest, cls).skip_checks()
+ super(SnapshotsActionsV3RbacTest, cls).skip_checks()
if not CONF.volume_feature_enabled.snapshot:
raise cls.skipException("Cinder snapshot feature disabled")
@classmethod
def resource_setup(cls):
- super(SnapshotsActionsRbacTest, cls).resource_setup()
+ super(SnapshotsActionsV3RbacTest, cls).resource_setup()
cls.volume = cls.create_volume()
cls.snapshot = cls.create_snapshot(volume_id=cls.volume['id'])
cls.snapshot_id = cls.snapshot['id']
@@ -57,7 +57,3 @@
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.snapshots_client.force_delete_snapshot(temp_snapshot['id'])
self.snapshots_client.wait_for_resource_deletion(temp_snapshot['id'])
-
-
-class SnapshotsActionsV3RbacTest(SnapshotsActionsRbacTest):
- _api_version = 3
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 81cd854..1f82671 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
@@ -22,17 +22,17 @@
CONF = config.CONF
-class SnapshotMetadataRbacTest(rbac_base.BaseVolumeRbacTest):
+class SnapshotMetadataV3RbacTest(rbac_base.BaseVolumeRbacTest):
@classmethod
def skip_checks(cls):
- super(SnapshotMetadataRbacTest, cls).skip_checks()
+ super(SnapshotMetadataV3RbacTest, cls).skip_checks()
if not CONF.volume_feature_enabled.snapshot:
raise cls.skipException("Cinder snapshot feature disabled")
@classmethod
def resource_setup(cls):
- super(SnapshotMetadataRbacTest, cls).resource_setup()
+ super(SnapshotMetadataV3RbacTest, cls).resource_setup()
cls.volume = cls.create_volume()
# Create a snapshot
cls.snapshot = cls.create_snapshot(volume_id=cls.volume['id'])
@@ -80,6 +80,41 @@
self.snapshots_client.show_snapshot_metadata(
self.snapshot_id)['metadata']
+ @decorators.idempotent_id('7ea597f6-c544-4b10-aab0-ff68f595fb06')
+ @rbac_rule_validation.action(service="cinder",
+ rule="volume:update_snapshot_metadata")
+ def test_update_snapshot_metadata(self):
+ self._create_test_snapshot_metadata()
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ update = {"key3": "value3_update",
+ "key4": "value4"}
+ self.snapshots_client.update_snapshot_metadata(
+ self.snapshot['id'], metadata=update)
-class SnapshotMetadataV3RbacTest(SnapshotMetadataRbacTest):
- _api_version = 3
+ @decorators.idempotent_id('93068d02-0131-4dd3-af16-fc40d7128d93')
+ @rbac_rule_validation.action(service="cinder",
+ rule="volume:get_snapshot_metadata")
+ def test_show_snapshot_metadata_item(self):
+ self._create_test_snapshot_metadata()
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.snapshots_client.show_snapshot_metadata_item(
+ self.snapshot['id'], "key3")['meta']
+
+ @decorators.idempotent_id('1f8f43e7-da31-4128-bb3c-73fc548650e3')
+ @rbac_rule_validation.action(service="cinder",
+ rule="volume:update_snapshot_metadata")
+ def test_update_snapshot_metadata_item(self):
+ update_item = {"key3": "value3_update"}
+ self._create_test_snapshot_metadata()
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.snapshots_client.update_snapshot_metadata_item(
+ self.snapshot['id'], "key3", meta=update_item)['meta']
+
+ @decorators.idempotent_id('3ec32516-f7cd-4f88-b78a-ddee67492071')
+ @rbac_rule_validation.action(service="cinder",
+ rule="volume:delete_snapshot_metadata")
+ def test_delete_snapshot_metadata_item(self):
+ self._create_test_snapshot_metadata()
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.snapshots_client.delete_snapshot_metadata_item(
+ self.snapshot['id'], "key1")
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 fddaee4..bac9189 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
@@ -25,7 +25,6 @@
class MessagesV3RbacTest(rbac_base.BaseVolumeRbacTest):
- _api_version = 3
min_microversion = '3.3'
max_microversion = 'latest'
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 466fb0c..e9ebb99 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
@@ -27,19 +27,18 @@
CONF = config.CONF
-class VolumesActionsRbacTest(rbac_base.BaseVolumeRbacTest):
-
+class VolumesActionsV3RbacTest(rbac_base.BaseVolumeRbacTest):
credentials = ['primary', 'admin']
@classmethod
def setup_clients(cls):
- super(VolumesActionsRbacTest, cls).setup_clients()
+ super(VolumesActionsV3RbacTest, cls).setup_clients()
cls.admin_image_client = cls.os_admin.image_client_v2
cls.admin_volumes_client = cls.os_admin.volumes_client_latest
@classmethod
def resource_setup(cls):
- super(VolumesActionsRbacTest, cls).resource_setup()
+ super(VolumesActionsV3RbacTest, cls).resource_setup()
cls.volume = cls.create_volume()
def _create_server(self):
@@ -69,7 +68,9 @@
self.admin_volumes_client, volume_id, 'available')
@utils.services('compute')
- @rbac_rule_validation.action(service="cinder", rule="volume:attach")
+ @rbac_rule_validation.action(
+ service="cinder",
+ rule="volume_extension:volume_actions:attach")
@decorators.idempotent_id('f97b10e4-2eed-4f8b-8632-71c02cb9fe42')
def test_attach_volume_to_instance(self):
server = self._create_server()
@@ -78,7 +79,9 @@
@utils.services('compute')
@decorators.attr(type='slow')
- @rbac_rule_validation.action(service="cinder", rule="volume:detach")
+ @rbac_rule_validation.action(
+ service="cinder",
+ rule="volume_extension:volume_actions:detach")
@decorators.idempotent_id('5a042f6a-688b-42e6-a02e-fe5c47b89b07')
def test_detach_volume_from_instance(self):
server = self._create_server()
@@ -141,15 +144,17 @@
bootable=True)
@decorators.idempotent_id('41566922-75a1-4484-99c7-9c8782ee99ac')
- @rbac_rule_validation.action(service="cinder",
- rule="volume:reserve_volume")
+ @rbac_rule_validation.action(
+ service="cinder",
+ rule="volume_extension:volume_actions:reserve")
def test_volume_reserve(self):
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.volumes_client.reserve_volume(self.volume['id'])
@decorators.idempotent_id('e5fa9564-77d9-4e57-b0c0-3e0ae4d08535')
- @rbac_rule_validation.action(service="cinder",
- rule="volume:unreserve_volume")
+ @rbac_rule_validation.action(
+ service="cinder",
+ rule="volume_extension:volume_actions:unreserve")
def test_volume_unreserve(self):
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.volumes_client.unreserve_volume(self.volume['id'])
@@ -211,10 +216,6 @@
volume['id'], 'available')
-class VolumesActionsV3RbacTest(VolumesActionsRbacTest):
- _api_version = 3
-
-
class VolumesActionsV310RbacTest(rbac_base.BaseVolumeRbacTest):
_api_version = 3
min_microversion = '3.10'
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 3f5227e..244f333 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
@@ -20,11 +20,11 @@
from patrole_tempest_plugin.tests.api.volume import rbac_base
-class VolumesBasicCrudRbacTest(rbac_base.BaseVolumeRbacTest):
+class VolumesBasicCrudV3RbacTest(rbac_base.BaseVolumeRbacTest):
@classmethod
def resource_setup(cls):
- super(VolumesBasicCrudRbacTest, cls).resource_setup()
+ super(VolumesBasicCrudV3RbacTest, cls).resource_setup()
cls.volume = cls.create_volume()
@rbac_rule_validation.action(service="cinder",
@@ -70,7 +70,3 @@
def test_volume_list_image_metadata(self):
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.volumes_client.list_volumes(detail=True)
-
-
-class VolumesBasicCrudV3RbacTest(VolumesBasicCrudRbacTest):
- _api_version = 3
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 ee0a0be..726f84e 100644
--- a/patrole_tempest_plugin/tests/api/volume/test_volume_hosts_rbac.py
+++ b/patrole_tempest_plugin/tests/api/volume/test_volume_hosts_rbac.py
@@ -19,7 +19,7 @@
from patrole_tempest_plugin.tests.api.volume import rbac_base
-class VolumeHostsRbacTest(rbac_base.BaseVolumeRbacTest):
+class VolumeHostsV3RbacTest(rbac_base.BaseVolumeRbacTest):
@rbac_rule_validation.action(service="cinder",
rule="volume_extension:hosts")
@@ -28,6 +28,7 @@
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.volume_hosts_client.list_hosts()
+ @decorators.skip_because(bug="1732808")
@decorators.idempotent_id('9ddf321e-788f-4787-b8cc-dfa59e264143')
@rbac_rule_validation.action(service="cinder",
rule="volume_extension:hosts")
@@ -39,7 +40,3 @@
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.volume_hosts_client.show_host(host_names[0])
-
-
-class VolumeHostsV3RbacTest(VolumeHostsRbacTest):
- _api_version = 3
diff --git a/patrole_tempest_plugin/tests/api/volume/test_volume_metadata_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_volume_metadata_rbac.py
index f9114a8..5866934 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
@@ -14,6 +14,7 @@
# under the License.
from tempest import config
+from tempest.lib.common.utils import test_utils
from tempest.lib import decorators
from patrole_tempest_plugin import rbac_rule_validation
@@ -22,21 +23,21 @@
CONF = config.CONF
-class VolumeMetadataRbacTest(rbac_base.BaseVolumeRbacTest):
+class VolumeMetadataV3RbacTest(rbac_base.BaseVolumeRbacTest):
@classmethod
def resource_setup(cls):
- super(VolumeMetadataRbacTest, cls).resource_setup()
+ super(VolumeMetadataV3RbacTest, cls).resource_setup()
cls.volume = cls.create_volume()
cls.image_id = CONF.compute.image_ref
def setUp(self):
- super(VolumeMetadataRbacTest, self).setUp()
+ super(VolumeMetadataV3RbacTest, self).setUp()
self._add_metadata(self.volume)
def tearDown(self):
self.volumes_client.update_volume_metadata(self.volume['id'], {})
- super(VolumeMetadataRbacTest, self).tearDown()
+ super(VolumeMetadataV3RbacTest, self).tearDown()
def _add_metadata(self, volume):
# Create metadata for the volume
@@ -66,17 +67,6 @@
self.volumes_client.delete_volume_metadata_item(self.volume['id'],
"key1")
- @decorators.idempotent_id('a41c8eed-2051-4a25-b401-df036faacbdc')
- @rbac_rule_validation.action(
- service="cinder",
- rule="volume:delete_volume_metadata")
- def test_delete_volume_image_metadata(self):
- self.volumes_client.update_volume_image_metadata(
- self.volume['id'], image_id=self.image_id)
- self.rbac_utils.switch_role(self, toggle_rbac_role=True)
- self.volumes_client.delete_volume_image_metadata(self.volume['id'],
- 'image_id')
-
@rbac_rule_validation.action(service="cinder",
rule="volume:update_volume_metadata")
@decorators.idempotent_id('8ce2ff80-99ba-49ae-9bb1-7e96729ee5af')
@@ -98,12 +88,25 @@
@decorators.idempotent_id('a9d9e825-5ea3-42e6-96f3-7ac4e97b2ed0')
@rbac_rule_validation.action(
service="cinder",
- rule="volume:update_volume_metadata")
+ rule="volume_extension:volume_image_metadata")
def test_update_volume_image_metadata(self):
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.volumes_client.update_volume_image_metadata(
self.volume['id'], image_id=self.image_id)
+ self.addCleanup(self.volumes_client.delete_volume_image_metadata,
+ self.volume['id'], 'image_id')
+ @decorators.idempotent_id('a41c8eed-2051-4a25-b401-df036faacbdc')
+ @rbac_rule_validation.action(
+ service="cinder",
+ rule="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)
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.volumes_client.delete_volume_image_metadata,
+ self.volume['id'], 'image_id')
-class VolumeMetadataV3RbacTest(VolumeMetadataRbacTest):
- _api_version = 3
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.volumes_client.delete_volume_image_metadata(self.volume['id'],
+ '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 851d468..01f8203 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
@@ -19,16 +19,16 @@
from patrole_tempest_plugin.tests.api.volume import rbac_base
-class VolumeQuotasRbacTest(rbac_base.BaseVolumeRbacTest):
+class VolumeQuotasV3RbacTest(rbac_base.BaseVolumeRbacTest):
@classmethod
def setup_credentials(cls):
- super(VolumeQuotasRbacTest, cls).setup_credentials()
+ super(VolumeQuotasV3RbacTest, cls).setup_credentials()
cls.demo_tenant_id = cls.os_primary.credentials.tenant_id
@classmethod
def setup_clients(cls):
- super(VolumeQuotasRbacTest, cls).setup_clients()
+ super(VolumeQuotasV3RbacTest, cls).setup_clients()
cls.quotas_client = cls.os_primary.volume_quotas_v2_client
@rbac_rule_validation.action(service="cinder",
@@ -51,7 +51,3 @@
self.quotas_client.update_quota_set(
self.demo_tenant_id,
**new_quota_set)['quota_set']
-
-
-class VolumeQuotasV3RbacTest(VolumeQuotasRbacTest):
- _api_version = 3
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 63978aa..d36fb5a 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
@@ -20,7 +20,7 @@
from patrole_tempest_plugin.tests.api.volume import rbac_base
-class VolumeServicesRbacTest(rbac_base.BaseVolumeRbacTest):
+class VolumeServicesV3RbacTest(rbac_base.BaseVolumeRbacTest):
# TODO(felipemonteiro): Implement a test to cover the policy action,
# "volume_extension:services:update", once the Tempest client endpoint
@@ -28,14 +28,14 @@
@classmethod
def skip_checks(cls):
- super(VolumeServicesRbacTest, cls).skip_checks()
+ super(VolumeServicesV3RbacTest, cls).skip_checks()
if not utils.is_extension_enabled('os-services', 'volume'):
msg = "%s skipped as os-services not enabled." % cls.__name__
raise cls.skipException(msg)
@classmethod
def setup_clients(cls):
- super(VolumeServicesRbacTest, cls).setup_clients()
+ super(VolumeServicesV3RbacTest, cls).setup_clients()
cls.services_client = cls.os_primary.volume_services_v2_client
@decorators.idempotent_id('b9134f01-97c0-4abd-9455-fe2f03e3f966')
@@ -45,7 +45,3 @@
def test_list_services(self):
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.services_client.list_services()['services']
-
-
-class VolumeServicesV3RbacTest(VolumeServicesRbacTest):
- _api_version = 3
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 656a2e6..9640dc6 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
@@ -21,19 +21,18 @@
from patrole_tempest_plugin.tests.api.volume import rbac_base
-class VolumesTransfersRbacTest(rbac_base.BaseVolumeRbacTest):
-
+class VolumesTransfersV3RbacTest(rbac_base.BaseVolumeRbacTest):
credentials = ['primary', 'admin']
@classmethod
def setup_clients(cls):
- super(VolumesTransfersRbacTest, cls).setup_clients()
+ super(VolumesTransfersV3RbacTest, cls).setup_clients()
cls.transfers_client = cls.os_primary.volume_transfers_v2_client
cls.admin_volumes_client = cls.os_admin.volumes_client_latest
@classmethod
def resource_setup(cls):
- super(VolumesTransfersRbacTest, cls).resource_setup()
+ super(VolumesTransfersV3RbacTest, cls).resource_setup()
cls.volume = cls.create_volume()
def _delete_transfer(self, transfer):
@@ -89,7 +88,3 @@
transfer = self._create_transfer()
self.rbac_utils.switch_role(self, toggle_rbac_role=True)
self.transfers_client.delete_volume_transfer(transfer['id'])
-
-
-class VolumesTransfersV3RbacTest(VolumesTransfersRbacTest):
- _api_version = 3
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 773df2b..f4aeee8 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
@@ -22,7 +22,6 @@
class VolumeTypesAccessRbacTest(rbac_base.BaseVolumeRbacTest):
- _api_version = 3
@classmethod
def skip_checks(cls):
diff --git a/patrole_tempest_plugin/tests/api/volume/test_volume_types_extra_specs_rbac.py b/patrole_tempest_plugin/tests/api/volume/test_volume_types_extra_specs_rbac.py
index aa02316..2abfd32 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
@@ -23,7 +23,6 @@
class VolumeTypesExtraSpecsRbacTest(rbac_base.BaseVolumeRbacTest):
- _api_version = 3
@classmethod
def skip_checks(cls):
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 7ca3d9f..51ee925 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
@@ -29,24 +29,23 @@
CONF = config.CONF
-class VolumesBackupsRbacTest(rbac_base.BaseVolumeRbacTest):
-
+class VolumesBackupsV3RbacTest(rbac_base.BaseVolumeRbacTest):
credentials = ['primary', 'admin']
@classmethod
def skip_checks(cls):
- super(VolumesBackupsRbacTest, cls).skip_checks()
+ super(VolumesBackupsV3RbacTest, cls).skip_checks()
if not CONF.volume_feature_enabled.backup:
raise cls.skipException("Cinder backup feature disabled")
@classmethod
def setup_clients(cls):
- super(VolumesBackupsRbacTest, cls).setup_clients()
+ super(VolumesBackupsV3RbacTest, cls).setup_clients()
cls.admin_backups_client = cls.os_admin.backups_v2_client
@classmethod
def resource_setup(cls):
- super(VolumesBackupsRbacTest, cls).resource_setup()
+ super(VolumesBackupsV3RbacTest, cls).resource_setup()
cls.volume = cls.create_volume()
def _decode_url(self, backup_url):
@@ -141,7 +140,7 @@
@decorators.attr(type='slow')
@rbac_rule_validation.action(service="cinder",
- rule="backup:backup-export")
+ rule="backup:export-import")
@decorators.idempotent_id('e984ec8d-e8eb-485c-98bc-f1856020303c')
def test_export_backup(self):
backup = self.create_backup(volume_id=self.volume['id'])
@@ -168,10 +167,6 @@
self.addCleanup(self.backups_client.delete_backup, import_backup['id'])
-class VolumesBackupsV3RbacTest(VolumesBackupsRbacTest):
- _api_version = 3
-
-
class VolumesBackupsV318RbacTest(rbac_base.BaseVolumeRbacTest):
_api_version = 3
# The minimum microversion for showing 'os-backup-project-attr:project_id'
@@ -201,3 +196,31 @@
if expected_attr not in body:
raise rbac_exceptions.RbacMalformedResponse(
attribute=expected_attr)
+
+
+class VolumesBackupsV39RbacTest(rbac_base.BaseVolumeRbacTest):
+ _api_version = 3
+ min_microversion = '3.9'
+ max_microversion = 'latest'
+
+ @classmethod
+ def skip_checks(cls):
+ super(VolumesBackupsV39RbacTest, cls).skip_checks()
+ if not CONF.volume_feature_enabled.backup:
+ raise cls.skipException("Cinder backup feature disabled")
+
+ @decorators.attr(type='slow')
+ @decorators.idempotent_id('b45b0e98-6eb8-4c62-aa53-0f8c7c09faa6')
+ @rbac_rule_validation.action(
+ service="cinder",
+ rule="backup:update")
+ def test_backup_update(self):
+ volume = self.create_volume()
+ backup = self.create_backup(volume_id=volume['id'])
+ update_kwargs = {
+ 'name': data_utils.rand_name(self.__class__.__name__ + '-Backup'),
+ 'description': data_utils.rand_name("volume-backup-description")
+ }
+ self.rbac_utils.switch_role(self, toggle_rbac_role=True)
+ self.backups_client.update_backup(backup['id'],
+ **update_kwargs)
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 205be9e..8a34923 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
@@ -23,18 +23,17 @@
CONF = config.CONF
-class VolumesExtendRbacTest(rbac_base.BaseVolumeRbacTest):
-
+class VolumesExtendV3RbacTest(rbac_base.BaseVolumeRbacTest):
credentials = ['primary', 'admin']
@classmethod
def setup_clients(cls):
- super(VolumesExtendRbacTest, cls).setup_clients()
+ super(VolumesExtendV3RbacTest, cls).setup_clients()
cls.admin_volumes_client = cls.os_admin.volumes_client_latest
@classmethod
def resource_setup(cls):
- super(VolumesExtendRbacTest, cls).resource_setup()
+ super(VolumesExtendV3RbacTest, cls).resource_setup()
# Create a test shared volume for tests
cls.volume = cls.create_volume()
@@ -48,7 +47,3 @@
new_size=extend_size)
waiters.wait_for_volume_resource_status(
self.admin_volumes_client, self.volume['id'], 'available')
-
-
-class VolumesExtendV3RbacTest(VolumesExtendRbacTest):
- _api_version = 3
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 dab796d..1365b79 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
@@ -25,13 +25,12 @@
CONF = config.CONF
-class VolumesManageRbacTest(rbac_base.BaseVolumeRbacTest):
-
+class VolumesManageV3RbacTest(rbac_base.BaseVolumeRbacTest):
credentials = ['primary', 'admin']
@classmethod
def skip_checks(cls):
- super(VolumesManageRbacTest, cls).skip_checks()
+ super(VolumesManageV3RbacTest, cls).skip_checks()
if not CONF.volume_feature_enabled.manage_volume:
raise cls.skipException("Manage volume tests are disabled")
@@ -42,7 +41,7 @@
@classmethod
def setup_clients(cls):
- super(VolumesManageRbacTest, cls).setup_clients()
+ super(VolumesManageV3RbacTest, cls).setup_clients()
cls.volume_manage_client = cls.os_primary.volume_manage_v2_client
cls.admin_volumes_client = cls.os_admin.volumes_client_latest
@@ -110,7 +109,3 @@
# volume after the test. The _manage_volume method will set up the
# proper resource cleanup
self.addCleanup(self._manage_volume, volume)
-
-
-class VolumesManageV3RbacTest(VolumesManageRbacTest):
- _api_version = 3
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 249b88b..7491820 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
@@ -23,24 +23,23 @@
CONF = config.CONF
-class VolumesSnapshotRbacTest(rbac_base.BaseVolumeRbacTest):
-
+class VolumesSnapshotV3RbacTest(rbac_base.BaseVolumeRbacTest):
credentials = ['primary', 'admin']
@classmethod
def skip_checks(cls):
- super(VolumesSnapshotRbacTest, cls).skip_checks()
+ super(VolumesSnapshotV3RbacTest, cls).skip_checks()
if not CONF.volume_feature_enabled.snapshot:
raise cls.skipException("Cinder volume snapshots are disabled")
@classmethod
def setup_clients(cls):
- super(VolumesSnapshotRbacTest, cls).setup_clients()
+ super(VolumesSnapshotV3RbacTest, cls).setup_clients()
cls.admin_snapshots_client = cls.os_admin.snapshots_v2_client
@classmethod
def resource_setup(cls):
- super(VolumesSnapshotRbacTest, cls).resource_setup()
+ super(VolumesSnapshotV3RbacTest, cls).resource_setup()
# Create a test shared volume for tests
cls.volume = cls.create_volume()
# Create a test shared snapshot for tests
@@ -107,7 +106,3 @@
self.snapshots_client.delete_snapshot(temp_snapshot['id'])
self.admin_snapshots_client.wait_for_resource_deletion(
temp_snapshot['id'])
-
-
-class VolumesSnapshotV3RbacTest(VolumesSnapshotRbacTest):
- _api_version = 3
diff --git a/playbooks/legacy/tempest-dsvm-patrole-admin/post.yaml b/playbooks/legacy/tempest-dsvm-patrole-admin/post.yaml
new file mode 100644
index 0000000..dac8753
--- /dev/null
+++ b/playbooks/legacy/tempest-dsvm-patrole-admin/post.yaml
@@ -0,0 +1,80 @@
+- 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/legacy/tempest-dsvm-patrole-admin/run.yaml b/playbooks/legacy/tempest-dsvm-patrole-admin/run.yaml
new file mode 100644
index 0000000..57f208d
--- /dev/null
+++ b/playbooks/legacy/tempest-dsvm-patrole-admin/run.yaml
@@ -0,0 +1,60 @@
+- 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/legacy/tempest-dsvm-patrole-member/post.yaml b/playbooks/legacy/tempest-dsvm-patrole-member/post.yaml
new file mode 100644
index 0000000..dac8753
--- /dev/null
+++ b/playbooks/legacy/tempest-dsvm-patrole-member/post.yaml
@@ -0,0 +1,80 @@
+- 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/legacy/tempest-dsvm-patrole-member/run.yaml b/playbooks/legacy/tempest-dsvm-patrole-member/run.yaml
new file mode 100644
index 0000000..b95467f
--- /dev/null
+++ b/playbooks/legacy/tempest-dsvm-patrole-member/run.yaml
@@ -0,0 +1,61 @@
+- 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/legacy/tempest-dsvm-patrole-multinode-admin/post.yaml b/playbooks/legacy/tempest-dsvm-patrole-multinode-admin/post.yaml
new file mode 100644
index 0000000..dac8753
--- /dev/null
+++ b/playbooks/legacy/tempest-dsvm-patrole-multinode-admin/post.yaml
@@ -0,0 +1,80 @@
+- 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/legacy/tempest-dsvm-patrole-multinode-admin/run.yaml b/playbooks/legacy/tempest-dsvm-patrole-multinode-admin/run.yaml
new file mode 100644
index 0000000..bece4e2
--- /dev/null
+++ b/playbooks/legacy/tempest-dsvm-patrole-multinode-admin/run.yaml
@@ -0,0 +1,63 @@
+- hosts: primary
+ name: Autoconverted job legacy-tempest-dsvm-patrole-multinode-admin from old job
+ gate-tempest-dsvm-patrole-multinode-admin-ubuntu-xenial-nv
+ 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
+ # 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_TOPOLOGY="multinode"
+ export DEVSTACK_GATE_TEMPEST_REGEX='(?=.*\[.*\bslow\b.*\])(^patrole_tempest_plugin\.tests\.api)'
+ export DEVSTACK_GATE_TEMPEST_ALL_PLUGINS=1
+ 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/legacy/tempest-dsvm-patrole-multinode-member/post.yaml b/playbooks/legacy/tempest-dsvm-patrole-multinode-member/post.yaml
new file mode 100644
index 0000000..dac8753
--- /dev/null
+++ b/playbooks/legacy/tempest-dsvm-patrole-multinode-member/post.yaml
@@ -0,0 +1,80 @@
+- 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/legacy/tempest-dsvm-patrole-multinode-member/run.yaml b/playbooks/legacy/tempest-dsvm-patrole-multinode-member/run.yaml
new file mode 100644
index 0000000..4c7b70f
--- /dev/null
+++ b/playbooks/legacy/tempest-dsvm-patrole-multinode-member/run.yaml
@@ -0,0 +1,63 @@
+- hosts: primary
+ name: Autoconverted job legacy-tempest-dsvm-patrole-multinode-member from old job
+ gate-tempest-dsvm-patrole-multinode-member-ubuntu-xenial-nv
+ 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
+ # 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_TOPOLOGY="multinode"
+ export DEVSTACK_GATE_TEMPEST_REGEX='(?=.*\[.*\bslow\b.*\])(^patrole_tempest_plugin\.tests\.api)'
+ export DEVSTACK_GATE_TEMPEST_ALL_PLUGINS=1
+ 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/legacy/tempest-dsvm-patrole-py35-member/post.yaml b/playbooks/legacy/tempest-dsvm-patrole-py35-member/post.yaml
new file mode 100644
index 0000000..dac8753
--- /dev/null
+++ b/playbooks/legacy/tempest-dsvm-patrole-py35-member/post.yaml
@@ -0,0 +1,80 @@
+- 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/legacy/tempest-dsvm-patrole-py35-member/run.yaml b/playbooks/legacy/tempest-dsvm-patrole-py35-member/run.yaml
new file mode 100644
index 0000000..e895702
--- /dev/null
+++ b/playbooks/legacy/tempest-dsvm-patrole-py35-member/run.yaml
@@ -0,0 +1,70 @@
+- 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/deprecate-strict-policy-enforce-option-e15d2be4e753608e.yaml b/releasenotes/notes/deprecate-strict-policy-enforce-option-e15d2be4e753608e.yaml
new file mode 100644
index 0000000..4f56dd8
--- /dev/null
+++ b/releasenotes/notes/deprecate-strict-policy-enforce-option-e15d2be4e753608e.yaml
@@ -0,0 +1,10 @@
+---
+deprecations:
+ - |
+ The configuration option ``[patrole] strict_policy_check`` is deprecated
+ and will be removed in the Rocky release cycle.
+other:
+ - |
+ The default value for ``[patrole] strict_policy_check`` has been changed
+ to ``True`` because a Patrole test should always fail if the policy action
+ is invalid, to avoid false positives.
diff --git a/releasenotes/source/conf.py b/releasenotes/source/conf.py
index 7444c35..1aeff4b 100644
--- a/releasenotes/source/conf.py
+++ b/releasenotes/source/conf.py
@@ -58,15 +58,13 @@
project = u'Patrole Release Notes'
copyright = u'2017, Patrole Developers'
-# The version info for the project you're documenting, acts as replacement for
-# |version| and |release|, also used in various other places throughout the
-# built documents.
-#
-from patrole_tempest_plugin.version import version_info as patrole_version
+# Release do not need a version number in the title, they
+# cover multiple versions.
+
# The full version, including alpha/beta/rc tags.
-release = patrole_version.version_string_with_vcs()
+release = ''
# The short X.Y version.
-version = patrole_version.canonical_version_string()
+version = ''
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
diff --git a/requirements.txt b/requirements.txt
index 0e46596..94f3073 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -4,7 +4,7 @@
hacking>=1.0.0 # Apache-2.0
pbr!=2.1.0,>=2.0.0 # Apache-2.0
oslo.log>=3.30.0 # Apache-2.0
-oslo.config>=4.6.0 # Apache-2.0
+oslo.config>=5.1.0 # Apache-2.0
oslo.policy>=1.23.0 # Apache-2.0
-tempest>=16.1.0 # Apache-2.0
+tempest>=17.1.0 # Apache-2.0
stevedore>=1.20.0 # Apache-2.0
diff --git a/test-requirements.txt b/test-requirements.txt
index 1953685..a8a3044 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -14,4 +14,4 @@
oslotest>=1.10.0 # Apache-2.0
oslo.policy>=1.23.0 # Apache-2.0
oslo.log>=3.30.0 # Apache-2.0
-tempest>=16.1.0 # Apache-2.0
+tempest>=17.1.0 # Apache-2.0