Browse Source

Update tests for scoped tokens and default roles

This patch refactors the RBAC enforcement checks in the API tests.
It also updates those test for keystone scoped tokens and default roles.

Change-Id: I6fad03f5a89c213562918ca258884aac34ba7ce7
changes/17/776817/5
Michael Johnson 8 months ago
parent
commit
6006de75a7
  1. 1
      octavia_tempest_plugin/common/constants.py
  2. 34
      octavia_tempest_plugin/config.py
  3. 2
      octavia_tempest_plugin/plugin.py
  4. 472
      octavia_tempest_plugin/tests/RBAC_tests.py
  5. 66
      octavia_tempest_plugin/tests/api/v2/test_amphora.py
  6. 95
      octavia_tempest_plugin/tests/api/v2/test_availability_zone.py
  7. 17
      octavia_tempest_plugin/tests/api/v2/test_availability_zone_capabilities.py
  8. 84
      octavia_tempest_plugin/tests/api/v2/test_availability_zone_profile.py
  9. 85
      octavia_tempest_plugin/tests/api/v2/test_flavor.py
  10. 16
      octavia_tempest_plugin/tests/api/v2/test_flavor_capabilities.py
  11. 74
      octavia_tempest_plugin/tests/api/v2/test_flavor_profile.py
  12. 197
      octavia_tempest_plugin/tests/api/v2/test_healthmonitor.py
  13. 202
      octavia_tempest_plugin/tests/api/v2/test_l7policy.py
  14. 189
      octavia_tempest_plugin/tests/api/v2/test_l7rule.py
  15. 138
      octavia_tempest_plugin/tests/api/v2/test_listener.py
  16. 310
      octavia_tempest_plugin/tests/api/v2/test_load_balancer.py
  17. 207
      octavia_tempest_plugin/tests/api/v2/test_member.py
  18. 202
      octavia_tempest_plugin/tests/api/v2/test_pool.py
  19. 22
      octavia_tempest_plugin/tests/api/v2/test_provider.py
  20. 68
      octavia_tempest_plugin/tests/test_base.py
  21. 17
      releasenotes/notes/Add-RBAC-scoped-tokens-tests-920aa35faf4a8c9d.yaml
  22. 17
      zuul.d/jobs.yaml
  23. 2
      zuul.d/projects.yaml

1
octavia_tempest_plugin/common/constants.py

@ -183,6 +183,7 @@ PATH = 'PATH'
# RBAC options
ADVANCED = 'advanced'
KEYSTONE_DEFAULT_ROLES = 'keystone_default_roles'
OWNERADMIN = 'owner_or_admin'
NONE = 'none'

34
octavia_tempest_plugin/config.py

@ -86,6 +86,12 @@ OctaviaGroup = [
cfg.StrOpt('admin_role',
default='load-balancer_admin',
help='The load balancing admin RBAC role.'),
cfg.StrOpt('observer_role',
default='load-balancer_observer',
help='The load balancing observer RBAC role.'),
cfg.StrOpt('global_observer_role',
default='load-balancer_global_observer',
help='The load balancing global observer RBAC role.'),
cfg.IntOpt('scp_connection_timeout',
default=5,
help='Timeout in seconds to wait for a '
@ -97,10 +103,13 @@ OctaviaGroup = [
default='octavia',
help='The provider driver to use for the tests.'),
cfg.StrOpt('RBAC_test_type', default=const.ADVANCED,
choices=[const.ADVANCED, const.OWNERADMIN, const.NONE],
choices=[const.ADVANCED, const.KEYSTONE_DEFAULT_ROLES,
const.OWNERADMIN, const.NONE],
help='Type of RBAC tests to run. "advanced" runs the octavia '
'default RBAC tests. "owner_or_admin" runs the legacy '
'owner or admin tests. "none" disables the RBAC tests.'),
'owner or admin tests. "keystone_default_roles" runs the '
'tests using only the keystone default roles. "none" '
'disables the RBAC tests.'),
cfg.DictOpt('enabled_provider_drivers',
help=('A comma separated list of dictionaries of the '
'enabled provider driver names and descriptions. '
@ -217,6 +226,15 @@ OctaviaGroup = [
default='/opt/octavia-tempest-plugin/test_server.bin',
help='Filesystem path to the test web server that will be '
'installed in the web server VMs.'),
# RBAC related options
# Note: Also see the enforce_scope section (from tempest) for Octavia API
# scope checking setting.
cfg.BoolOpt('enforce_new_defaults',
default=False,
help='Does the load-balancer service API policies enforce '
'the new keystone default roles? This configuration '
'value should be same as octavia.conf: '
'[oslo_policy].enforce_new_defaults option.'),
]
lb_feature_enabled_group = cfg.OptGroup(name='loadbalancer-feature-enabled',
@ -261,3 +279,15 @@ LBFeatureEnabledGroup = [
"the tempest instance have access to the log files "
"specified in the tempest configuration."),
]
# Extending this enforce_scope group defined in tempest
enforce_scope_group = cfg.OptGroup(name="enforce_scope",
title="OpenStack Services with "
"enforce scope")
EnforceScopeGroup = [
cfg.BoolOpt('octavia',
default=False,
help='Does the load-balancer service API policies enforce '
'scope? This configuration value should be same as '
'octavia.conf: [oslo_policy].enforce_scope option.'),
]

2
octavia_tempest_plugin/plugin.py

@ -38,6 +38,8 @@ class OctaviaTempestPlugin(plugins.TempestPlugin):
config.register_opt_group(conf,
project_config.lb_feature_enabled_group,
project_config.LBFeatureEnabledGroup)
config.register_opt_group(conf, project_config.enforce_scope_group,
project_config.EnforceScopeGroup)
def get_opt_lists(self):
return [

472
octavia_tempest_plugin/tests/RBAC_tests.py

@ -0,0 +1,472 @@
# Copyright 2021 Red Hat, Inc. 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.
import copy
from oslo_log import log as logging
from tempest import config
from tempest.lib import exceptions
from tempest import test
from octavia_tempest_plugin.common import constants
from octavia_tempest_plugin.tests import waiters
CONF = config.CONF
LOG = logging.getLogger(__name__)
class RBACTestsMixin(test.BaseTestCase):
def _check_allowed(self, client_str, method_str, allowed_list,
*args, **kwargs):
"""Test an API call allowed RBAC enforcement.
:param client_str: The service client to use for the test, without the
credential. Example: 'amphora_client'
:param method_str: The method on the client to call for the test.
Example: 'list_amphorae'
:param allowed_list: The list of credentials expected to be
allowed. Example: ['os_roles_lb_member'].
:param args: Any positional parameters needed by the method.
:param kwargs: Any named parameters needed by the method.
:raises AssertionError: Raised if the RBAC tests fail.
:raises Forbidden: Raised if a credential that should have access does
not and is denied.
:raises InvalidScope: Raised if a credential that should have the
correct scope for access is denied.
:returns: None on success
"""
for cred in allowed_list:
try:
cred_obj = getattr(self, cred)
except AttributeError:
# TODO(johnsom) Remove once scoped tokens is the default.
if ((cred == 'os_system_admin' or cred == 'os_system_reader')
and not CONF.enforce_scope.octavia):
LOG.info('Skipping %s allowed RBAC test because '
'enforce_scope.octavia is not True', cred)
continue
else:
self.fail('Credential {} "expected_allowed" for RBAC '
'testing was not created by tempest '
'credentials setup. This is likely a bug in the '
'test.'.format(cred))
client = getattr(cred_obj, client_str)
method = getattr(client, method_str)
try:
method(*args, **kwargs)
except exceptions.Forbidden as e:
self.fail('Method {}.{} failed to allow access via RBAC using '
'credential {}. Error: {}'.format(
client_str, method_str, cred, str(e)))
def _check_disallowed(self, client_str, method_str, allowed_list,
status_method=None, obj_id=None, *args, **kwargs):
"""Test an API call disallowed RBAC enforcement.
:param client_str: The service client to use for the test, without the
credential. Example: 'amphora_client'
:param method_str: The method on the client to call for the test.
Example: 'list_amphorae'
:param allowed_list: The list of credentials expected to be
allowed. Example: ['os_roles_lb_member'].
:param status_method: The service client method that will provide
the object status for a status change waiter.
:param obj_id: The ID of the object to check for the expected status
update.
:param args: Any positional parameters needed by the method.
:param kwargs: Any named parameters needed by the method.
:raises AssertionError: Raised if the RBAC tests fail.
:raises Forbidden: Raised if a credential that should have access does
not and is denied.
:raises InvalidScope: Raised if a credential that should have the
correct scope for access is denied.
:returns: None on success
"""
expected_disallowed = (set(self.allocated_credentials) -
set(allowed_list))
for cred in expected_disallowed:
cred_obj = getattr(self, cred)
client = getattr(cred_obj, client_str)
method = getattr(client, method_str)
# Unfortunately tempest uses testtools assertRaises[1] which means
# we cannot use the unittest assertRaises context[2] with msg= to
# give a useful error.
# Also, testtools doesn't work with subTest[3], so we can't use
# that to expose the failing credential.
# This all means the exception raised testtools assertRaises
# is less than useful.
# TODO(johnsom) Remove this try block once testtools is useful.
# [1] https://testtools.readthedocs.io/en/latest/
# api.html#testtools.TestCase.assertRaises
# [2] https://docs.python.org/3/library/
# unittest.html#unittest.TestCase.assertRaises
# [3] https://github.com/testing-cabal/testtools/issues/235
try:
method(*args, **kwargs)
except exceptions.Forbidden:
if status_method:
waiters.wait_for_status(
status_method, obj_id,
constants.PROVISIONING_STATUS, constants.ACTIVE,
CONF.load_balancer.check_interval,
CONF.load_balancer.check_timeout)
continue
self.fail('Method {}.{} failed to deny access via RBAC using '
'credential {}.'.format(client_str, method_str, cred))
def _list_get_RBAC_enforcement(self, client_str, method_str,
expected_allowed, *args, **kwargs):
"""Test an API call RBAC enforcement.
:param client_str: The service client to use for the test, without the
credential. Example: 'amphora_client'
:param method_str: The method on the client to call for the test.
Example: 'list_amphorae'
:param expected_allowed: The list of credentials expected to be
allowed. Example: ['os_roles_lb_member'].
:param args: Any positional parameters needed by the method.
:param kwargs: Any named parameters needed by the method.
:raises AssertionError: Raised if the RBAC tests fail.
:raises Forbidden: Raised if a credential that should have access does
not and is denied.
:raises InvalidScope: Raised if a credential that should have the
correct scope for access is denied.
:returns: None on success
"""
allowed_list = copy.deepcopy(expected_allowed)
# os_admin is a special case as it is valid with the old defaults,
# but will not be with the new defaults and/or token scoping.
# The old keystone role "admin" becomes project scoped "admin"
# instead of being a global admin.
# To keep the tests simple, handle that edge case here.
# TODO(johnsom) Once token scope is default, remove this.
if ('os_system_admin' in expected_allowed and
not CONF.load_balancer.enforce_new_defaults and
not CONF.enforce_scope.octavia):
allowed_list.append('os_admin')
# #### Test that disallowed credentials cannot access the API.
self._check_disallowed(client_str, method_str, allowed_list,
None, None, *args, **kwargs)
# #### Test that allowed credentials can access the API.
self._check_allowed(client_str, method_str, allowed_list,
*args, **kwargs)
def check_show_RBAC_enforcement(self, client_str, method_str,
expected_allowed, *args, **kwargs):
"""Test an API show call RBAC enforcement.
:param client_str: The service client to use for the test, without the
credential. Example: 'amphora_client'
:param method_str: The method on the client to call for the test.
Example: 'list_amphorae'
:param expected_allowed: The list of credentials expected to be
allowed. Example: ['os_roles_lb_member'].
:param args: Any positional parameters needed by the method.
:param kwargs: Any named parameters needed by the method.
:raises AssertionError: Raised if the RBAC tests fail.
:raises Forbidden: Raised if a credential that should have access does
not and is denied.
:raises InvalidScope: Raised if a credential that should have the
correct scope for access is denied.
:returns: None on success
"""
self._list_get_RBAC_enforcement(client_str, method_str,
expected_allowed, *args, **kwargs)
def check_list_RBAC_enforcement(self, client_str, method_str,
expected_allowed, *args, **kwargs):
"""Test an API list call RBAC enforcement.
:param client_str: The service client to use for the test, without the
credential. Example: 'amphora_client'
:param method_str: The method on the client to call for the test.
Example: 'list_amphorae'
:param expected_allowed: The list of credentials expected to be
allowed. Example: ['os_roles_lb_member'].
:param args: Any positional parameters needed by the method.
:param kwargs: Any named parameters needed by the method.
:raises AssertionError: Raised if the RBAC tests fail.
:raises Forbidden: Raised if a credential that should have access does
not and is denied.
:raises InvalidScope: Raised if a credential that should have the
correct scope for access is denied.
:returns: None on success
"""
self._list_get_RBAC_enforcement(client_str, method_str,
expected_allowed, *args, **kwargs)
def _CUD_RBAC_enforcement(self, client_str, method_str, expected_allowed,
status_method=None, obj_id=None,
*args, **kwargs):
"""Test an API create/update/delete call RBAC enforcement.
:param client_str: The service client to use for the test, without the
credential. Example: 'amphora_client'
:param method_str: The method on the client to call for the test.
Example: 'list_amphorae'
:param expected_allowed: The list of credentials expected to be
allowed. Example: ['os_roles_lb_member'].
:param status_method: The service client method that will provide
the object status for a status change waiter.
:param obj_id: The ID of the object to check for the expected status
update.
:param args: Any positional parameters needed by the method.
:param kwargs: Any named parameters needed by the method.
:raises AssertionError: Raised if the RBAC tests fail.
:raises Forbidden: Raised if a credential that should have access does
not and is denied.
:raises InvalidScope: Raised if a credential that should have the
correct scope for access is denied.
:returns: None on success
"""
allowed_list = copy.deepcopy(expected_allowed)
# os_admin is a special case as it is valid with the old defaults,
# but will not be with the new defaults and/or token scoping.
# The old keystone role "admin" becomes project scoped "admin"
# instead of being a global admin.
# To keep the tests simple, handle that edge case here.
# TODO(johnsom) Once token scope is default, remove this.
if ('os_system_admin' in expected_allowed and
not CONF.load_balancer.enforce_new_defaults and
not CONF.enforce_scope.octavia):
allowed_list.append('os_admin')
# #### Test that disallowed credentials cannot access the API.
self._check_disallowed(client_str, method_str, allowed_list,
status_method, obj_id, *args, **kwargs)
def check_create_RBAC_enforcement(
self, client_str, method_str, expected_allowed,
status_method=None, obj_id=None, *args, **kwargs):
"""Test an API create call RBAC enforcement.
:param client_str: The service client to use for the test, without the
credential. Example: 'amphora_client'
:param method_str: The method on the client to call for the test.
Example: 'list_amphorae'
:param expected_allowed: The list of credentials expected to be
allowed. Example: ['os_roles_lb_member'].
:param status_method: The service client method that will provide
the object status for a status change waiter.
:param obj_id: The ID of the object to check for the expected status
update.
:param args: Any positional parameters needed by the method.
:param kwargs: Any named parameters needed by the method.
:raises AssertionError: Raised if the RBAC tests fail.
:raises Forbidden: Raised if a credential that should have access does
not and is denied.
:raises InvalidScope: Raised if a credential that should have the
correct scope for access is denied.
:returns: None on success
"""
self._CUD_RBAC_enforcement(client_str, method_str, expected_allowed,
status_method, obj_id, *args, **kwargs)
def check_delete_RBAC_enforcement(
self, client_str, method_str, expected_allowed,
status_method=None, obj_id=None, *args, **kwargs):
"""Test an API delete call RBAC enforcement.
:param client_str: The service client to use for the test, without the
credential. Example: 'amphora_client'
:param method_str: The method on the client to call for the test.
Example: 'list_amphorae'
:param expected_allowed: The list of credentials expected to be
allowed. Example: ['os_roles_lb_member'].
:param status_method: The service client method that will provide
the object status for a status change waiter.
:param obj_id: The ID of the object to check for the expected status
update.
:param args: Any positional parameters needed by the method.
:param kwargs: Any named parameters needed by the method.
:raises AssertionError: Raised if the RBAC tests fail.
:raises Forbidden: Raised if a credential that should have access does
not and is denied.
:raises InvalidScope: Raised if a credential that should have the
correct scope for access is denied.
:returns: None on success
"""
self._CUD_RBAC_enforcement(client_str, method_str, expected_allowed,
status_method, obj_id, *args, **kwargs)
def check_update_RBAC_enforcement(
self, client_str, method_str, expected_allowed,
status_method=None, obj_id=None, *args, **kwargs):
"""Test an API update call RBAC enforcement.
:param client_str: The service client to use for the test, without the
credential. Example: 'amphora_client'
:param method_str: The method on the client to call for the test.
Example: 'list_amphorae'
:param expected_allowed: The list of credentials expected to be
allowed. Example: ['os_roles_lb_member'].
:param status_method: The service client method that will provide
the object status for a status change waiter.
:param obj_id: The ID of the object to check for the expected status
update.
:param args: Any positional parameters needed by the method.
:param kwargs: Any named parameters needed by the method.
:raises AssertionError: Raised if the RBAC tests fail.
:raises Forbidden: Raised if a credential that should have access does
not and is denied.
:raises InvalidScope: Raised if a credential that should have the
correct scope for access is denied.
:returns: None on success
"""
self._CUD_RBAC_enforcement(client_str, method_str, expected_allowed,
status_method, obj_id, *args, **kwargs)
def check_list_RBAC_enforcement_count(
self, client_str, method_str, expected_allowed, expected_count,
*args, **kwargs):
"""Test an API list call RBAC enforcement result count.
List APIs will return the object list for the project associated
with the token used to access the API. This means most credentials
will have access, but will get differing results.
This test will query the list API using a list of credentials and
will validate that only the expected count of results are returned.
:param client_str: The service client to use for the test, without the
credential. Example: 'amphora_client'
:param method_str: The method on the client to call for the test.
Example: 'list_amphorae'
:param expected_allowed: The list of credentials expected to be
allowed. Example: ['os_roles_lb_member'].
:param expected_count: The number of results expected in the list
returned from the API.
:param args: Any positional parameters needed by the method.
:param kwargs: Any named parameters needed by the method.
:raises AssertionError: Raised if the RBAC tests fail.
:raises Forbidden: Raised if a credential that should have access does
not and is denied.
:raises InvalidScope: Raised if a credential that should have the
correct scope for access is denied.
:returns: None on success
"""
allowed_list = copy.deepcopy(expected_allowed)
# os_admin is a special case as it is valid with the old defaults,
# but will not be with the new defaults and/or token scoping.
# The old keystone role "admin" becomes project scoped "admin"
# instead of being a global admin.
# To keep the tests simple, handle that edge case here.
# TODO(johnsom) Once token scope is default, remove this.
if ('os_system_admin' in expected_allowed and
not CONF.load_balancer.enforce_new_defaults and
not CONF.enforce_scope.octavia):
allowed_list.append('os_admin')
for cred in allowed_list:
try:
cred_obj = getattr(self, cred)
except AttributeError:
# TODO(johnsom) Remove once scoped tokens is the default.
if ((cred == 'os_system_admin' or cred == 'os_system_reader')
and not CONF.enforce_scope.octavia):
LOG.info('Skipping %s allowed RBAC test because '
'enforce_scope.octavia is not True', cred)
continue
else:
self.fail('Credential {} "expected_allowed" for RBAC '
'testing was not created by tempest '
'credentials setup. This is likely a bug in the '
'test.'.format(cred))
client = getattr(cred_obj, client_str)
method = getattr(client, method_str)
try:
result = method(*args, **kwargs)
except exceptions.Forbidden as e:
self.fail('Method {}.{} failed to allow access via RBAC using '
'credential {}. Error: {}'.format(
client_str, method_str, cred, str(e)))
self.assertEqual(expected_count, len(result), message='Credential '
'{} saw {} objects when {} was expected.'.format(
cred, len(result), expected_count))
def check_list_IDs_RBAC_enforcement(
self, client_str, method_str, expected_allowed, expected_ids,
*args, **kwargs):
"""Test an API list call RBAC enforcement result contains IDs.
List APIs will return the object list for the project associated
with the token used to access the API. This means most credentials
will have access, but will get differing results.
This test will query the list API using a list of credentials and
will validate that the expected object Ids in included in the results.
:param client_str: The service client to use for the test, without the
credential. Example: 'amphora_client'
:param method_str: The method on the client to call for the test.
Example: 'list_amphorae'
:param expected_allowed: The list of credentials expected to be
allowed. Example: ['os_roles_lb_member'].
:param expected_ids: The list of object IDs to validate are included
in the returned list from the API.
:param args: Any positional parameters needed by the method.
:param kwargs: Any named parameters needed by the method.
:raises AssertionError: Raised if the RBAC tests fail.
:raises Forbidden: Raised if a credential that should have access does
not and is denied.
:raises InvalidScope: Raised if a credential that should have the
correct scope for access is denied.
:returns: None on success
"""
allowed_list = copy.deepcopy(expected_allowed)
# os_admin is a special case as it is valid with the old defaults,
# but will not be with the new defaults and/or token scoping.
# The old keystone role "admin" becomes project scoped "admin"
# instead of being a global admin.
# To keep the tests simple, handle that edge case here.
# TODO(johnsom) Once token scope is default, remove this.
if ('os_system_admin' in expected_allowed and
not CONF.load_balancer.enforce_new_defaults and
not CONF.enforce_scope.octavia):
allowed_list.append('os_admin')
for cred in allowed_list:
try:
cred_obj = getattr(self, cred)
except AttributeError:
# TODO(johnsom) Remove once scoped tokens is the default.
if ((cred == 'os_system_admin' or cred == 'os_system_reader')
and not CONF.enforce_scope.octavia):
LOG.info('Skipping %s allowed RBAC test because '
'enforce_scope.octavia is not True', cred)
continue
else:
self.fail('Credential {} "expected_allowed" for RBAC '
'testing was not created by tempest '
'credentials setup. This is likely a bug in the '
'test.'.format(cred))
client = getattr(cred_obj, client_str)
method = getattr(client, method_str)
try:
result = method(*args, **kwargs)
except exceptions.Forbidden as e:
self.fail('Method {}.{} failed to allow access via RBAC using '
'credential {}. Error: {}'.format(
client_str, method_str, cred, str(e)))
result_ids = [lb[constants.ID] for lb in result]
self.assertTrue(set(expected_ids).issubset(set(result_ids)))

66
octavia_tempest_plugin/tests/api/v2/test_amphora.py

@ -20,7 +20,6 @@ from dateutil import parser
from tempest import config
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
from tempest.lib import exceptions
from octavia_tempest_plugin.common import constants as const
from octavia_tempest_plugin.tests import test_base
@ -90,12 +89,17 @@ class AmphoraAPITest(test_base.LoadBalancerBaseTest):
CONF.load_balancer.lb_build_interval,
CONF.load_balancer.lb_build_timeout)
# Test that a user, without the load balancer member role, cannot
# list amphorae
# Test RBAC for list amphorae
expected_allowed = []
if CONF.load_balancer.RBAC_test_type == const.OWNERADMIN:
expected_allowed = ['os_admin', 'os_roles_lb_admin']
if CONF.load_balancer.RBAC_test_type == const.KEYSTONE_DEFAULT_ROLES:
expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
if CONF.load_balancer.RBAC_test_type == const.ADVANCED:
self.assertRaises(
exceptions.Forbidden,
self.os_primary.amphora_client.list_amphorae)
expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
if expected_allowed:
self.check_list_RBAC_enforcement(
'amphora_client', 'list_amphorae', expected_allowed)
# Get an actual list of the amphorae
amphorae = self.lb_admin_amphora_client.list_amphorae()
@ -112,13 +116,11 @@ class AmphoraAPITest(test_base.LoadBalancerBaseTest):
self.assertEqual(self._expected_amp_count(amphorae), len(amphorae))
self.assertEqual(self.lb_id, amphorae[0][const.LOADBALANCER_ID])
# Test that a different user, with load balancer member role, cannot
# see this amphora
if not CONF.load_balancer.RBAC_test_type == const.NONE:
member2_client = self.os_roles_lb_member2.amphora_client
self.assertRaises(exceptions.Forbidden,
member2_client.show_amphora,
amphora_id=amphorae[0][const.ID])
# Test RBAC for show amphora
if expected_allowed:
self.check_show_RBAC_enforcement(
'amphora_client', 'show_amphora', expected_allowed,
amphora_id=amphorae[0][const.ID])
show_amphora_response_fields = const.SHOW_AMPHORA_RESPONSE_FIELDS
if self.lb_admin_amphora_client.is_version_supported(
@ -175,13 +177,18 @@ class AmphoraAPITest(test_base.LoadBalancerBaseTest):
loadbalancer_id=const.LOADBALANCER_ID, lb_id=self.lb_id))
amphora_1 = amphorae[0]
# Test that a user without the load balancer admin role cannot
# create a flavor
# Test RBAC for update an amphora
expected_allowed = []
if CONF.load_balancer.RBAC_test_type == const.OWNERADMIN:
expected_allowed = ['os_admin', 'os_roles_lb_admin']
if CONF.load_balancer.RBAC_test_type == const.KEYSTONE_DEFAULT_ROLES:
expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
if CONF.load_balancer.RBAC_test_type == const.ADVANCED:
self.assertRaises(
exceptions.Forbidden,
self.os_primary.amphora_client.update_amphora_config,
amphora_1[const.ID])
expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
if expected_allowed:
self.check_update_RBAC_enforcement(
'amphora_client', 'update_amphora_config', expected_allowed,
None, None, amphora_1[const.ID])
self.lb_admin_amphora_client.update_amphora_config(amphora_1[const.ID])
@ -205,15 +212,18 @@ class AmphoraAPITest(test_base.LoadBalancerBaseTest):
loadbalancer_id=const.LOADBALANCER_ID, lb_id=self.lb_id))
amphora_1 = amphorae[0]
# Test RBAC not authorized for non-admin role
if not CONF.load_balancer.RBAC_test_type == const.NONE:
self.assertRaises(exceptions.Forbidden,
self.os_primary.amphora_client.amphora_failover,
amphora_1[const.ID])
self.assertRaises(
exceptions.Forbidden,
self.os_roles_lb_member.amphora_client.amphora_failover,
amphora_1[const.ID])
# Test RBAC for failover an amphora
expected_allowed = []
if CONF.load_balancer.RBAC_test_type == const.OWNERADMIN:
expected_allowed = ['os_admin', 'os_roles_lb_admin']
if CONF.load_balancer.RBAC_test_type == const.KEYSTONE_DEFAULT_ROLES:
expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
if CONF.load_balancer.RBAC_test_type == const.ADVANCED:
expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
if expected_allowed:
self.check_update_RBAC_enforcement(
'amphora_client', 'amphora_failover', expected_allowed,
None, None, amphora_1[const.ID])
self.lb_admin_amphora_client.amphora_failover(amphora_1[const.ID])

95
octavia_tempest_plugin/tests/api/v2/test_availability_zone.py

@ -104,12 +104,18 @@ class AvailabilityZoneAPITest(test_base.LoadBalancerBaseTest):
self.availability_zone_profile_id}
# Test that a user without the load balancer admin role cannot
# create an availability zone
# create an availability zone.
expected_allowed = []
if CONF.load_balancer.RBAC_test_type == const.OWNERADMIN:
expected_allowed = ['os_admin', 'os_roles_lb_admin']
if CONF.load_balancer.RBAC_test_type == const.KEYSTONE_DEFAULT_ROLES:
expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
if CONF.load_balancer.RBAC_test_type == const.ADVANCED:
self.assertRaises(exceptions.Forbidden,
self.os_primary.availability_zone_client
.create_availability_zone,
**availability_zone_kwargs)
expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
if expected_allowed:
self.check_create_RBAC_enforcement(
'availability_zone_client', 'create_availability_zone',
expected_allowed, **availability_zone_kwargs)
# Happy path
availability_zone = (
@ -220,11 +226,26 @@ class AvailabilityZoneAPITest(test_base.LoadBalancerBaseTest):
# Test that a user without the load balancer role cannot
# list availability zones.
expected_allowed = []
if CONF.load_balancer.RBAC_test_type == const.OWNERADMIN:
expected_allowed = [
'os_admin', 'os_primary', 'os_roles_lb_admin',
'os_roles_lb_observer', 'os_roles_lb_global_observer',
'os_roles_lb_member', 'os_roles_lb_member2']
if CONF.load_balancer.RBAC_test_type == const.KEYSTONE_DEFAULT_ROLES:
expected_allowed = ['os_admin', 'os_primary', 'os_system_admin',
'os_system_reader', 'os_roles_lb_observer',
'os_roles_lb_global_observer',
'os_roles_lb_member', 'os_roles_lb_member2']
if CONF.load_balancer.RBAC_test_type == const.ADVANCED:
self.assertRaises(
exceptions.Forbidden,
self.os_primary.availability_zone_client
.list_availability_zones)
expected_allowed = [
'os_system_admin', 'os_system_reader', 'os_roles_lb_admin',
'os_roles_lb_observer', 'os_roles_lb_global_observer',
'os_roles_lb_member', 'os_roles_lb_member2']
if expected_allowed:
self.check_list_RBAC_enforcement(
'availability_zone_client', 'list_availability_zones',
expected_allowed)
# Check the default sort order (by ID)
availability_zones = (
@ -359,12 +380,26 @@ class AvailabilityZoneAPITest(test_base.LoadBalancerBaseTest):
# Test that a user without the load balancer role cannot
# show availability zone details.
expected_allowed = []
if CONF.load_balancer.RBAC_test_type == const.OWNERADMIN:
expected_allowed = [
'os_admin', 'os_primary', 'os_roles_lb_admin',
'os_roles_lb_observer', 'os_roles_lb_global_observer',
'os_roles_lb_member', 'os_roles_lb_member2']
if CONF.load_balancer.RBAC_test_type == const.KEYSTONE_DEFAULT_ROLES:
expected_allowed = ['os_admin', 'os_primary', 'os_system_admin',
'os_system_reader', 'os_roles_lb_observer',
'os_roles_lb_global_observer',
'os_roles_lb_member', 'os_roles_lb_member2']
if CONF.load_balancer.RBAC_test_type == const.ADVANCED:
self.assertRaises(
exceptions.Forbidden,
self.os_primary.availability_zone_client
.show_availability_zone,
availability_zone[const.NAME])
expected_allowed = [
'os_system_admin', 'os_system_reader', 'os_roles_lb_admin',
'os_roles_lb_observer', 'os_roles_lb_global_observer',
'os_roles_lb_member', 'os_roles_lb_member2']
if expected_allowed:
self.check_show_RBAC_enforcement(
'availability_zone_client', 'show_availability_zone',
expected_allowed, availability_zone[const.NAME])
result = self.mem_availability_zone_client.show_availability_zone(
availability_zone[const.NAME])
@ -420,13 +455,18 @@ class AvailabilityZoneAPITest(test_base.LoadBalancerBaseTest):
const.ENABLED: False}
# Test that a user without the load balancer role cannot
# show availability zone details.
# update availability zone details.
expected_allowed = []
if CONF.load_balancer.RBAC_test_type == const.OWNERADMIN:
expected_allowed = ['os_admin', 'os_roles_lb_admin']
if CONF.load_balancer.RBAC_test_type == const.KEYSTONE_DEFAULT_ROLES:
expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
if CONF.load_balancer.RBAC_test_type == const.ADVANCED:
self.assertRaises(
exceptions.Forbidden,
self.os_primary.availability_zone_client
.update_availability_zone,
availability_zone[const.NAME],
expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
if expected_allowed:
self.check_update_RBAC_enforcement(
'availability_zone_client', 'update_availability_zone',
expected_allowed, None, None, availability_zone[const.NAME],
**availability_zone_updated_kwargs)
updated_availability_zone = (
@ -493,12 +533,17 @@ class AvailabilityZoneAPITest(test_base.LoadBalancerBaseTest):
# Test that a user without the load balancer admin role cannot
# delete an availability zone.
expected_allowed = []
if CONF.load_balancer.RBAC_test_type == const.OWNERADMIN:
expected_allowed = ['os_admin', 'os_roles_lb_admin']
if CONF.load_balancer.RBAC_test_type == const.KEYSTONE_DEFAULT_ROLES:
expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
if CONF.load_balancer.RBAC_test_type == const.ADVANCED:
self.assertRaises(
exceptions.Forbidden,
self.os_primary.availability_zone_client
.delete_availability_zone,
availability_zone[const.NAME])
expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
if expected_allowed:
self.check_delete_RBAC_enforcement(
'availability_zone_client', 'delete_availability_zone',
expected_allowed, None, None, availability_zone[const.NAME])
# Happy path
self.lb_admin_availability_zone_client.delete_availability_zone(

17
octavia_tempest_plugin/tests/api/v2/test_availability_zone_capabilities.py

@ -15,7 +15,6 @@
from tempest import config
from tempest.lib import decorators
from tempest.lib import exceptions
from octavia_tempest_plugin.common import constants as const
from octavia_tempest_plugin.tests import test_base
@ -45,13 +44,17 @@ class AvailabilityZoneCapabilitiesAPITest(test_base.LoadBalancerBaseTest):
# Test that a user without the load balancer admin role cannot
# list provider availability zone capabilities.
expected_allowed = []
if CONF.load_balancer.RBAC_test_type == const.OWNERADMIN:
expected_allowed = ['os_admin', 'os_roles_lb_admin']
if CONF.load_balancer.RBAC_test_type == const.KEYSTONE_DEFAULT_ROLES:
expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
if CONF.load_balancer.RBAC_test_type == const.ADVANCED:
os_primary_capabilities_client = (
self.os_primary.availability_zone_capabilities_client)
self.assertRaises(
exceptions.Forbidden,
(os_primary_capabilities_client
.list_availability_zone_capabilities),
expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
if expected_allowed:
self.check_list_RBAC_enforcement(
'availability_zone_capabilities_client',
'list_availability_zone_capabilities', expected_allowed,
CONF.load_balancer.provider)
# Check for an expected availability zone capability for the

84
octavia_tempest_plugin/tests/api/v2/test_availability_zone_profile.py

@ -75,13 +75,19 @@ class AvailabilityZoneProfileAPITest(test_base.LoadBalancerBaseTest):
}
# Test that a user without the load balancer admin role cannot
# create an availability zone profile profile
# create an availability zone profile.
expected_allowed = []
if CONF.load_balancer.RBAC_test_type == const.OWNERADMIN:
expected_allowed = ['os_admin', 'os_roles_lb_admin']
if CONF.load_balancer.RBAC_test_type == const.KEYSTONE_DEFAULT_ROLES:
expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
if CONF.load_balancer.RBAC_test_type == const.ADVANCED:
self.assertRaises(
exceptions.Forbidden,
self.os_primary.availability_zone_profile_client
.create_availability_zone_profile,
**availability_zone_profile_kwargs)
expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
if expected_allowed:
self.check_create_RBAC_enforcement(
'availability_zone_profile_client',
'create_availability_zone_profile',
expected_allowed, **availability_zone_profile_kwargs)
# Happy path
availability_zone_profile = (
@ -225,11 +231,17 @@ class AvailabilityZoneProfileAPITest(test_base.LoadBalancerBaseTest):
# Test that a user without the load balancer admin role cannot
# list availability zone profiles.
expected_allowed = []
if CONF.load_balancer.RBAC_test_type == const.OWNERADMIN:
expected_allowed = ['os_admin', 'os_roles_lb_admin']
if CONF.load_balancer.RBAC_test_type == const.KEYSTONE_DEFAULT_ROLES:
expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
if CONF.load_balancer.RBAC_test_type == const.ADVANCED:
self.assertRaises(
exceptions.Forbidden,
self.os_primary.availability_zone_profile_client
.list_availability_zone_profiles)
expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
if expected_allowed:
self.check_list_RBAC_enforcement(
'availability_zone_profile_client',
'list_availability_zone_profiles', expected_allowed)
# Check the default sort order (by ID)
profiles = (self.lb_admin_availability_zone_profile_client
@ -379,12 +391,18 @@ class AvailabilityZoneProfileAPITest(test_base.LoadBalancerBaseTest):
availability_zone_profile[const.ID])
# Test that a user without the load balancer admin role cannot
# show an availability zone profile profile
# show an availability zone profile
expected_allowed = []
if CONF.load_balancer.RBAC_test_type == const.OWNERADMIN:
expected_allowed = ['os_admin', 'os_roles_lb_admin']
if CONF.load_balancer.RBAC_test_type == const.KEYSTONE_DEFAULT_ROLES:
expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
if CONF.load_balancer.RBAC_test_type == const.ADVANCED:
self.assertRaises(
exceptions.Forbidden,
self.os_primary.availability_zone_profile_client
.show_availability_zone_profile,
expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
if expected_allowed:
self.check_show_RBAC_enforcement(
'availability_zone_profile_client',
'show_availability_zone_profile', expected_allowed,
availability_zone_profile[const.ID])
result = (
@ -475,13 +493,19 @@ class AvailabilityZoneProfileAPITest(test_base.LoadBalancerBaseTest):
}
# Test that a user without the load balancer admin role cannot
# create an availability zone profile profile
# update an availability zone profile.
expected_allowed = []
if CONF.load_balancer.RBAC_test_type == const.OWNERADMIN:
expected_allowed = ['os_admin', 'os_roles_lb_admin']
if CONF.load_balancer.RBAC_test_type == const.KEYSTONE_DEFAULT_ROLES:
expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
if CONF.load_balancer.RBAC_test_type == const.ADVANCED:
self.assertRaises(
exceptions.Forbidden,
self.os_primary.availability_zone_profile_client
.update_availability_zone_profile,
availability_zone_profile[const.ID],
expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
if expected_allowed:
self.check_update_RBAC_enforcement(
'availability_zone_profile_client',
'update_availability_zone_profile', expected_allowed,
None, None, availability_zone_profile[const.ID],
**availability_zone_profile_updated_kwargs)
result = (
@ -551,13 +575,19 @@ class AvailabilityZoneProfileAPITest(test_base.LoadBalancerBaseTest):
availability_zone_profile[const.ID])
# Test that a user without the load balancer admin role cannot
# delete an availability zone profile profile
# delete an availability zone profile.
expected_allowed = []
if CONF.load_balancer.RBAC_test_type == const.OWNERADMIN:
expected_allowed = ['os_admin', 'os_roles_lb_admin']
if CONF.load_balancer.RBAC_test_type == const.KEYSTONE_DEFAULT_ROLES:
expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
if CONF.load_balancer.RBAC_test_type == const.ADVANCED:
self.assertRaises(
exceptions.Forbidden,
self.os_primary.availability_zone_profile_client
.delete_availability_zone_profile,
availability_zone_profile[const.ID])
expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
if expected_allowed:
self.check_delete_RBAC_enforcement(
'availability_zone_profile_client',
'delete_availability_zone_profile', expected_allowed,
None, None, availability_zone_profile[const.ID])
# Happy path
(self.lb_admin_availability_zone_profile_client

85
octavia_tempest_plugin/tests/api/v2/test_flavor.py

@ -87,11 +87,18 @@ class FlavorAPITest(test_base.LoadBalancerBaseTest):
const.FLAVOR_PROFILE_ID: self.flavor_profile_id}
# Test that a user without the load balancer admin role cannot
# create a flavor
# create a flavor.
expected_allowed = []
if CONF.load_balancer.RBAC_test_type == const.OWNERADMIN:
expected_allowed = ['os_admin', 'os_roles_lb_admin']
if CONF.load_balancer.RBAC_test_type == const.KEYSTONE_DEFAULT_ROLES:
expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
if CONF.load_balancer.RBAC_test_type == const.ADVANCED:
self.assertRaises(exceptions.Forbidden,
self.os_primary.flavor_client.create_flavor,
**flavor_kwargs)
expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
if expected_allowed:
self.check_create_RBAC_enforcement(
'flavor_client', 'create_flavor',
expected_allowed, None, None, **flavor_kwargs)
# Happy path
flavor = self.lb_admin_flavor_client.create_flavor(**flavor_kwargs)
@ -185,10 +192,25 @@ class FlavorAPITest(test_base.LoadBalancerBaseTest):
# Test that a user without the load balancer role cannot
# list flavors.
expected_allowed = []
if CONF.load_balancer.RBAC_test_type == const.OWNERADMIN:
expected_allowed = [
'os_admin', 'os_primary', 'os_roles_lb_admin',
'os_roles_lb_observer', 'os_roles_lb_global_observer',
'os_roles_lb_member', 'os_roles_lb_member2']
if CONF.load_balancer.RBAC_test_type == const.KEYSTONE_DEFAULT_ROLES:
expected_allowed = ['os_admin', 'os_primary', 'os_system_admin',
'os_system_reader', 'os_roles_lb_observer',
'os_roles_lb_global_observer',
'os_roles_lb_member', 'os_roles_lb_member2']
if CONF.load_balancer.RBAC_test_type == const.ADVANCED:
self.assertRaises(
exceptions.Forbidden,
self.os_primary.flavor_client.list_flavors)
expected_allowed = [
'os_system_admin', 'os_system_reader', 'os_roles_lb_admin',
'os_roles_lb_observer', 'os_roles_lb_global_observer',
'os_roles_lb_member', 'os_roles_lb_member2']
if expected_allowed:
self.check_list_RBAC_enforcement(
'flavor_client', 'list_flavors', expected_allowed)
# Check the default sort order (by ID)
flavors = self.mem_flavor_client.list_flavors()
@ -299,10 +321,25 @@ class FlavorAPITest(test_base.LoadBalancerBaseTest):
# Test that a user without the load balancer role cannot
# show flavor details.
expected_allowed = []
if CONF.load_balancer.RBAC_test_type == const.OWNERADMIN:
expected_allowed = [
'os_admin', 'os_primary', 'os_roles_lb_observer',
'os_roles_lb_global_observer', 'os_roles_lb_admin',
'os_roles_lb_member', 'os_roles_lb_member2']
if CONF.load_balancer.RBAC_test_type == const.KEYSTONE_DEFAULT_ROLES:
expected_allowed = ['os_admin', 'os_primary', 'os_system_admin',
'os_system_reader', 'os_roles_lb_observer',
'os_roles_lb_global_observer',
'os_roles_lb_member', 'os_roles_lb_member2']
if CONF.load_balancer.RBAC_test_type == const.ADVANCED:
self.assertRaises(
exceptions.Forbidden,
self.os_primary.flavor_client.show_flavor,
expected_allowed = [
'os_system_admin', 'os_system_reader', 'os_roles_lb_admin',
'os_roles_lb_observer', 'os_roles_lb_global_observer',
'os_roles_lb_member', 'os_roles_lb_member2']
if expected_allowed:
self.check_show_RBAC_enforcement(
'flavor_client', 'show_flavor', expected_allowed,
flavor[const.ID])
result = self.mem_flavor_client.show_flavor(flavor[const.ID])
@ -354,11 +391,17 @@ class FlavorAPITest(test_base.LoadBalancerBaseTest):
const.ENABLED: False}
# Test that a user without the load balancer role cannot
# show flavor details.
# update flavor details.
expected_allowed = []
if CONF.load_balancer.RBAC_test_type == const.OWNERADMIN:
expected_allowed = ['os_admin', 'os_roles_lb_admin']
if CONF.load_balancer.RBAC_test_type == const.KEYSTONE_DEFAULT_ROLES:
expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
if CONF.load_balancer.RBAC_test_type == const.ADVANCED:
self.assertRaises(
exceptions.Forbidden,
self.os_primary.flavor_client.update_flavor,
expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
if expected_allowed:
self.check_update_RBAC_enforcement(
'flavor_client', 'update_flavor', expected_allowed, None, None,
flavor[const.ID], **flavor_updated_kwargs)
updated_flavor = self.lb_admin_flavor_client.update_flavor(
@ -413,11 +456,17 @@ class FlavorAPITest(test_base.LoadBalancerBaseTest):
# Test that a user without the load balancer admin role cannot
# delete a flavor.
expected_allowed = []
if CONF.load_balancer.RBAC_test_type == const.OWNERADMIN:
expected_allowed = ['os_admin', 'os_roles_lb_admin']
if CONF.load_balancer.RBAC_test_type == const.KEYSTONE_DEFAULT_ROLES:
expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
if CONF.load_balancer.RBAC_test_type == const.ADVANCED:
self.assertRaises(
exceptions.Forbidden,
self.os_primary.flavor_client.delete_flavor,
flavor[const.ID])
expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
if expected_allowed:
self.check_delete_RBAC_enforcement(
'flavor_client', 'delete_flavor', expected_allowed,
None, None, flavor[const.ID])
# Happy path
self.lb_admin_flavor_client.delete_flavor(flavor[const.ID])

16
octavia_tempest_plugin/tests/api/v2/test_flavor_capabilities.py

@ -14,7 +14,6 @@
from tempest import config
from tempest.lib import decorators
from tempest.lib import exceptions
from octavia_tempest_plugin.common import constants as const
from octavia_tempest_plugin.tests import test_base
@ -43,12 +42,17 @@ class FlavorCapabilitiesAPITest(test_base.LoadBalancerBaseTest):
# Test that a user without the load balancer admin role cannot
# list provider flavor capabilities.
expected_allowed = []
if CONF.load_balancer.RBAC_test_type == const.OWNERADMIN:
expected_allowed = ['os_admin', 'os_roles_lb_admin']
if CONF.load_balancer.RBAC_test_type == const.KEYSTONE_DEFAULT_ROLES:
expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
if CONF.load_balancer.RBAC_test_type == const.ADVANCED:
os_primary_capabilities_client = (
self.os_primary.flavor_capabilities_client)
self.assertRaises(
exceptions.Forbidden,
os_primary_capabilities_client.list_flavor_capabilities,
expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
if expected_allowed:
self.check_list_RBAC_enforcement(
'flavor_capabilities_client',
'list_flavor_capabilities', expected_allowed,
CONF.load_balancer.provider)
# Check for an expected flavor capability for the configured provider

74
octavia_tempest_plugin/tests/api/v2/test_flavor_profile.py

@ -60,11 +60,17 @@ class FlavorProfileAPITest(test_base.LoadBalancerBaseTest):
# Test that a user without the load balancer admin role cannot
# create a flavor profile
expected_allowed = []
if CONF.load_balancer.RBAC_test_type == const.OWNERADMIN:
expected_allowed = ['os_admin', 'os_roles_lb_admin']
if CONF.load_balancer.RBAC_test_type == const.KEYSTONE_DEFAULT_ROLES:
expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
if CONF.load_balancer.RBAC_test_type == const.ADVANCED:
self.assertRaises(
exceptions.Forbidden,
self.os_primary.flavor_profile_client.create_flavor_profile,
**flavor_profile_kwargs)
expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
if expected_allowed:
self.check_create_RBAC_enforcement(
'flavor_profile_client', 'create_flavor_profile',
expected_allowed, None, None, **flavor_profile_kwargs)
# Happy path
flavor_profile = (
@ -174,10 +180,17 @@ class FlavorProfileAPITest(test_base.LoadBalancerBaseTest):
# Test that a user without the load balancer admin role cannot
# list flavor profiles.
expected_allowed = []
if CONF.load_balancer.RBAC_test_type == const.OWNERADMIN:
expected_allowed = ['os_admin', 'os_roles_lb_admin']
if CONF.load_balancer.RBAC_test_type == const.KEYSTONE_DEFAULT_ROLES:
expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
if CONF.load_balancer.RBAC_test_type == const.ADVANCED:
self.assertRaises(
exceptions.Forbidden,
self.os_primary.flavor_profile_client.list_flavor_profiles)
expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
if expected_allowed:
self.check_list_RBAC_enforcement(
'flavor_profile_client', 'list_flavor_profiles',
expected_allowed)
# Check the default sort order (by ID)
profiles = self.lb_admin_flavor_profile_client.list_flavor_profiles()
@ -295,12 +308,18 @@ class FlavorProfileAPITest(test_base.LoadBalancerBaseTest):
flavor_profile[const.ID])
# Test that a user without the load balancer admin role cannot
# show a flavor profile
# show a flavor profile.
expected_allowed = []
if CONF.load_balancer.RBAC_test_type == const.OWNERADMIN:
expected_allowed = ['os_admin', 'os_roles_lb_admin']
if CONF.load_balancer.RBAC_test_type == const.KEYSTONE_DEFAULT_ROLES:
expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
if CONF.load_balancer.RBAC_test_type == const.ADVANCED:
self.assertRaises(
exceptions.Forbidden,
self.os_primary.flavor_profile_client.show_flavor_profile,
flavor_profile[const.ID])
expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
if expected_allowed:
self.check_show_RBAC_enforcement(
'flavor_profile_client', 'show_flavor_profile',
expected_allowed, flavor_profile[const.ID])
result = (
self.lb_admin_flavor_profile_client.show_flavor_profile(
@ -367,12 +386,19 @@ class FlavorProfileAPITest(test_base.LoadBalancerBaseTest):
}
# Test that a user without the load balancer admin role cannot
# create a flavor profile
# update a flavor profile.
expected_allowed = []
if CONF.load_balancer.RBAC_test_type == const.OWNERADMIN:
expected_allowed = ['os_admin', 'os_roles_lb_admin']
if CONF.load_balancer.RBAC_test_type == const.KEYSTONE_DEFAULT_ROLES:
expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
if CONF.load_balancer.RBAC_test_type == const.ADVANCED:
self.assertRaises(
exceptions.Forbidden,
self.os_primary.flavor_profile_client.update_flavor_profile,
flavor_profile[const.ID], **flavor_profile_updated_kwargs)
expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
if expected_allowed:
self.check_update_RBAC_enforcement(
'flavor_profile_client', 'update_flavor_profile',
expected_allowed, None, None, flavor_profile[const.ID],
**flavor_profile_updated_kwargs)
result = self.lb_admin_flavor_profile_client.update_flavor_profile(
flavor_profile[const.ID], **flavor_profile_updated_kwargs)
@ -428,11 +454,17 @@ class FlavorProfileAPITest(test_base.LoadBalancerBaseTest):
# Test that a user without the load balancer admin role cannot
# delete a flavor profile
expected_allowed = []
if CONF.load_balancer.RBAC_test_type == const.OWNERADMIN:
expected_allowed = ['os_admin', 'os_roles_lb_admin']
if CONF.load_balancer.RBAC_test_type == const.KEYSTONE_DEFAULT_ROLES:
expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
if CONF.load_balancer.RBAC_test_type == const.ADVANCED:
self.assertRaises(
exceptions.Forbidden,
self.os_primary.flavor_profile_client.delete_flavor_profile,
flavor_profile[const.ID])
expected_allowed = ['os_system_admin', 'os_roles_lb_admin']
if expected_allowed:
self.check_delete_RBAC_enforcement(
'flavor_profile_client', 'delete_flavor_profile',
expected_allowed, None, None, flavor_profile[const.ID])
# Happy path
self.lb_admin_flavor_profile_client.delete_flavor_profile(

197
octavia_tempest_plugin/tests/api/v2/test_healthmonitor.py

@ -277,11 +277,21 @@ class HealthMonitorAPITest(test_base.LoadBalancerBaseTest):
# Test that a user without the loadbalancer role cannot
# create a healthmonitor
expected_allowed = []
if CONF.load_balancer.RBAC_test_type == const.OWNERADMIN:
expected_allowed = ['os_admin', 'os_roles_lb_admin',
'os_roles_lb_member']
if CONF.load_balancer.RBAC_test_type == const.KEYSTONE_DEFAULT_ROLES:
expected_allowed = ['os_system_admin', 'os_roles_lb_member']
if CONF.load_balancer.RBAC_test_type == const.ADVANCED:
self.assertRaises(
exceptions.Forbidden,
self.os_primary.healthmonitor_client.create_healthmonitor,
**hm_kwargs)
expected_allowed = ['os_system_admin', 'os_roles_lb_admin',
'os_roles_lb_member']
if expected_allowed:
self.check_create_RBAC_enforcement(
'healthmonitor_client', 'create_healthmonitor',
expected_allowed,
status_method=self.mem_lb_client.show_loadbalancer,
obj_id=self.lb_id, **hm_kwargs)
hm = self.mem_healthmonitor_client.create_healthmonitor(**hm_kwargs)
self.addCleanup(
@ -488,6 +498,9 @@ class HealthMonitorAPITest(test_base.LoadBalancerBaseTest):
* List the healthmonitors filtering to one of the three.
* List the healthmonitors filtered, one field, and sorted.
"""
# IDs of health monitors created in the test
test_ids = []
if (pool_algorithm == const.LB_ALGORITHM_SOURCE_IP_PORT and not
self.mem_listener_client.is_version_supported(
self.api_version, '2.13')):
@ -614,6 +627,7 @@ class HealthMonitorAPITest(test_base.LoadBalancerBaseTest):
const.ACTIVE,
CONF.load_balancer.build_interval,
CONF.load_balancer.build_timeout)
test_ids.append(hm1[const.ID])
# Time resolution for created_at is only to the second, and we need to
# ensure that each object has a distinct creation time. Delaying one
# second is both a simple and a reliable way to accomplish this.
@ -658,6 +672,7 @@ class HealthMonitorAPITest(test_base.LoadBalancerBaseTest):
const.ACTIVE,
CONF.load_balancer.build_interval,
CONF.load_balancer.build_timeout)
test_ids.append(hm2[const.ID])
# Time resolution for created_at is only to the second, and we need to
# ensure that each object has a distinct creation time. Delaying one
# second is both a simple and a reliable way to accomplish this.
@ -702,19 +717,68 @@ class HealthMonitorAPITest(test_base.LoadBalancerBaseTest):
const.ACTIVE,
CONF.load_balancer.build_interval,
CONF.load_balancer.build_timeout)
# Test that a different user cannot list healthmonitors
if not CONF.load_balancer.RBAC_test_type == const.NONE:
member2_client = self.os_roles_lb_member2.healthmonitor_client
primary = member2_client.list_healthmonitors(
query_params='pool_id={pool_id}'.format(pool_id=pool1_id))
self.assertEqual(0, len(primary))
test_ids.append(hm3[const.ID])
# Test that a different users cannot see the lb_member healthmonitors
expected_allowed = []
if CONF.load_balancer.RBAC_test_type == const.OWNERADMIN:
expected_allowed = ['os_primary', 'os_roles_lb_member2',
'os_roles_lb_observer']
if CONF.load_balancer.RBAC_test_type == const.KEYSTONE_DEFAULT_ROLES:
expected_allowed = ['os_admin', 'os_primary',
'os_roles_lb_member2', 'os_roles_lb_observer',
'os_roles_lb_global_observer']
if CONF.load_balancer.RBAC_test_type == const.ADVANCED:
expected_allowed = ['os_roles_lb_observer', 'os_roles_lb_member2']
if expected_allowed:
self.check_list_RBAC_enforcement_count(
'healthmonitor_client', 'list_healthmonitors',
expected_allowed, 0)
# Test credentials that should see these healthmonitors can see them.
expected_allowed = []
if CONF.load_balancer.RBAC_test_type == const.OWNERADMIN:
expected_allowed = ['os_admin', 'os_roles_lb_member']
if CONF.load_balancer.RBAC_test_type == const.KEYSTONE_DEFAULT_ROLES:
expected_allowed = ['os_system_admin', 'os_system_reader',
'os_roles_lb_member']
if CONF.load_balancer.RBAC_test_type == const.ADVANCED:
expected_allowed = ['os_system_admin', 'os_system_reader',
'os_roles_lb_admin', 'os_roles_lb_member',
'os_roles_lb_global_observer']
if expected_allowed:
self.check_list_IDs_RBAC_enforcement(
'healthmonitor_client', 'list_healthmonitors',
expected_allowed, test_ids)
# Test that users without the lb member role cannot list healthmonitors
# Note: non-owners can still call this API, they will just get the list
# of health monitors for their project (zero). The above tests
# are intended to cover the cross project use case.
expected_allowed = []
if CONF.load_balancer.RBAC_test_type == const.OWNERADMIN:
expected_allowed = ['os_admin', 'os_primary', 'os_roles_lb_admin',
'os_roles_lb_member', 'os_roles_lb_member2',
'os_roles_lb_observer',
'os_roles_lb_global_observer']
# Note: os_admin is here because it evaluaties to "project_admin"
# in oslo_policy and since keystone considers "project_admin"
# a superscope of "project_reader". This means it can read
# objects in the "admin" credential's project.
if CONF.load_balancer.RBAC_test_type == const.KEYSTONE_DEFAULT_ROLES:
expected_allowed = ['os_admin', 'os_primary', 'os_system_admin',
'os_system_reader', 'os_roles_lb_observer',
'os_roles_lb_global_observer',
'os_roles_lb_member', 'os_roles_lb_member2']
if CONF.load_balancer.RBAC_test_type == const.ADVANCED:
self.assertRaises(
exceptions.Forbidden,
self.os_primary.healthmonitor_client.list_healthmonitors)
expected_allowed = ['os_system_admin'</