diff --git a/.zuul.yaml b/.zuul.yaml index 0ad6e1f..7eca582 100644 --- a/.zuul.yaml +++ b/.zuul.yaml @@ -15,6 +15,9 @@ - cinder-tempest-plugin-basic-victoria - cinder-tempest-plugin-basic-ussuri - cinder-tempest-plugin-basic-train + # Set this job to voting once we have some actual tests to run + - cinder-tempest-plugin-protection-functional: + voting: false gate: jobs: - cinder-tempest-plugin-lvm-lio-barbican @@ -27,6 +30,26 @@ - cinder-tempest-plugin-cbak-ceph-ussuri - cinder-tempest-plugin-cbak-ceph-train +- job: + name: cinder-tempest-plugin-protection-functional + parent: devstack-tempest + required-projects: + - opendev.org/openstack/cinder-tempest-plugin + - opendev.org/openstack/cinder + vars: + tox_envlist: all + tempest_test_regex: 'cinder_tempest_plugin.rbac' + devstack_local_conf: + test-config: + $CINDER_CONF: + oslo_policy: + enforce_new_defaults: True + $TEMPEST_CONFIG: + enforce_scope: + cinder: True + tempest_plugins: + - cinder-tempest-plugin + - job: name: cinder-tempest-plugin-lvm-barbican-base-abstract description: | diff --git a/cinder_tempest_plugin/rbac/__init__.py b/cinder_tempest_plugin/rbac/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/cinder_tempest_plugin/rbac/v3/__init__.py b/cinder_tempest_plugin/rbac/v3/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/cinder_tempest_plugin/rbac/v3/base.py b/cinder_tempest_plugin/rbac/v3/base.py new file mode 100644 index 0000000..d1a11e5 --- /dev/null +++ b/cinder_tempest_plugin/rbac/v3/base.py @@ -0,0 +1,42 @@ +# 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 + +CONF = config.CONF + + +class VolumeV3RbacBaseTests(object): + + identity_version = 'v3' + + @classmethod + def skip_checks(cls): + super(VolumeV3RbacBaseTests, cls).skip_checks() + if not CONF.enforce_scope.cinder: + raise cls.skipException( + "Tempest is not configured to enforce_scope for cinder, " + "skipping RBAC tests. To enable these tests set " + "`tempest.conf [enforce_scope] cinder=True`." + ) + + def do_request(self, method, expected_status=200, client=None, **payload): + if not client: + client = self.client + if isinstance(expected_status, type(Exception)): + self.assertRaises(expected_status, + getattr(client, method), + **payload) + else: + response = getattr(client, method)(**payload) + self.assertEqual(response.response.status, expected_status) + return response diff --git a/cinder_tempest_plugin/rbac/v3/test_capabilities.py b/cinder_tempest_plugin/rbac/v3/test_capabilities.py new file mode 100644 index 0000000..1fa542d --- /dev/null +++ b/cinder_tempest_plugin/rbac/v3/test_capabilities.py @@ -0,0 +1,80 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import abc + +from tempest.lib import exceptions + +from cinder_tempest_plugin.api.volume import base +from cinder_tempest_plugin.rbac.v3 import base as rbac_base + + +class VolumeV3RbacCapabilityTests(rbac_base.VolumeV3RbacBaseTests, + metaclass=abc.ABCMeta): + + @classmethod + def setup_clients(cls): + super().setup_clients() + cls.persona = getattr(cls, 'os_%s' % cls.credentials[0]) + cls.client = cls.persona.volume_capabilities_client_latest + # NOTE(lbragstad): This admin_client will be more useful later when + # cinder supports system-scope and we need it for administrative + # operations. For now, keep os_project_admin as the admin client until + # we have system-scope. + admin_client = cls.os_project_admin + cls.admin_capabilities_client = ( + admin_client.volume_capabilities_client_latest) + cls.admin_stats_client = ( + admin_client.volume_scheduler_stats_client_latest) + + @classmethod + def setup_credentials(cls): + super().setup_credentials() + cls.os_primary = getattr(cls, 'os_%s' % cls.credentials[0]) + + @abc.abstractmethod + def test_get_capabilities(self): + """Test volume_extension:capabilities policy. + + This test must check: + * whether the persona can fetch capabilities for a host. + + """ + pass + + +class ProjectAdminTests(VolumeV3RbacCapabilityTests, base.BaseVolumeTest): + + credentials = ['project_admin', 'system_admin'] + + def test_get_capabilities(self): + pools = self.admin_stats_client.list_pools()['pools'] + host_name = pools[0]['name'] + self.do_request('show_backend_capabilities', expected_status=200, + host=host_name) + + +class ProjectMemberTests(ProjectAdminTests, base.BaseVolumeTest): + + credentials = ['project_member', 'project_admin', 'system_admin'] + + def test_get_capabilities(self): + pools = self.admin_stats_client.list_pools()['pools'] + host_name = pools[0]['name'] + self.do_request('show_backend_capabilities', + expected_status=exceptions.Forbidden, + host=host_name) + + +class ProjectReaderTests(ProjectMemberTests, base.BaseVolumeTest): + + credentials = ['project_reader', 'project_admin', 'system_admin']