Implement basic protection testing jobs

This commit lays down a basic structure for protection tests. These are
useful for testing various secure RBAC personas, but leveraging all the
dynamic credential work in tempest's authentication libraries to
provision clients for testing. We're also adding a non-voting protection
test job so that we can integrate protection testing into the cinder
gate as we work through policy changes.

This commit also adds some basic tests exercising the capabilities
admin-only API. These tests ensure that only operators (e.g.,
system-administrators) or formally known as project-administrators, can
access the capabilities API. Assertions and functionality in these tests
may expand in the future to accomodate system-scope when cinder can
properly consume system-scoped tokens from keystone.

For now, the tests assume project-administrators are deployment
operators, which is the legacy way of denoting "admin-ness" in OpenStack
deployments.

Depends-On: https://review.opendev.org/c/openstack/tempest/+/778753

Change-Id: I6d4ae6d516f4c2dda4dcb6b974857b34f2ef2254
This commit is contained in:
Lance Bragstad 2021-02-16 16:27:13 +00:00 committed by Luigi Toscano
parent 1a0b126246
commit d3fddec498
5 changed files with 145 additions and 0 deletions

View File

@ -14,6 +14,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
@ -25,6 +28,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: |

View File

View File

@ -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

View File

@ -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']