From 412abce3ca501bb2423de0e79569c34a9ef77c2e Mon Sep 17 00:00:00 2001 From: Guillaume Boutry Date: Tue, 29 Apr 2025 21:30:54 +0200 Subject: [PATCH] Add tempest target with new RBAC With Epoxy, new rbacs becomes the default under oslo.policy. Add a new test target TempestTestWithKeystoneMinimalNewRBAC to ensure proper configuration for tempest under new RBAC environments. Signed-off-by: Guillaume Boutry --- .../tempest/templates/tempest_v3.j2 | 11 +++++++ zaza/openstack/charm_tests/tempest/tests.py | 21 +++++++++++++ zaza/openstack/charm_tests/tempest/utils.py | 30 +++++++++++++++---- 3 files changed, 57 insertions(+), 5 deletions(-) diff --git a/zaza/openstack/charm_tests/tempest/templates/tempest_v3.j2 b/zaza/openstack/charm_tests/tempest/templates/tempest_v3.j2 index ba5bdd1..3fe8660 100644 --- a/zaza/openstack/charm_tests/tempest/templates/tempest_v3.j2 +++ b/zaza/openstack/charm_tests/tempest/templates/tempest_v3.j2 @@ -47,7 +47,11 @@ auth_version = v3 admin_role = Admin region = RegionOne default_domain_id = {{ default_domain_id }} +{% if admin_domain_scope is defined -%} +admin_domain_scope = {{ admin_domain_scope }} +{% else -%} admin_domain_scope = true +{% endif -%} disable_ssl_certificate_validation = true [identity-feature-enabled] @@ -164,3 +168,10 @@ nameservers = {{ test_name_server }} [service-clients] # Default is 60s which is not enough for resource constrained environments. http_timeout = 120 + +{% if enforce_scopes is defined and enforce_scopes -%} +[enforce_scope] +{% for svc in enforce_scopes -%} +{{ svc }} = True +{% endfor -%} +{% endif -%} diff --git a/zaza/openstack/charm_tests/tempest/tests.py b/zaza/openstack/charm_tests/tempest/tests.py index 26057f5..16a69df 100644 --- a/zaza/openstack/charm_tests/tempest/tests.py +++ b/zaza/openstack/charm_tests/tempest/tests.py @@ -156,6 +156,27 @@ class TempestTestWithKeystoneMinimal(TempestTestBase): return super().run() +class TempestTestWithKeystoneMinimalNewRBAC(TempestTestBase): + """Tempest test class to validate an OpenStack setup with Keystone V3. + + Validate the new RBAC model. + """ + + def run(self): + """Run tempest tests as specified in tests/tests.yaml. + + Allow test to run even if some components are missing (like + external network setup). + See TempestTestBase.run() for the available test options. + + :returns: Status of tempest run + :rtype: bool + """ + tempest_utils.render_tempest_config_keystone_v3(minimal=True, + new_rbac=True) + return super().run() + + class TempestTestScaleK8SBase(TempestTestBase): """Tempest test class to validate an OpenStack setup after scaling.""" diff --git a/zaza/openstack/charm_tests/tempest/utils.py b/zaza/openstack/charm_tests/tempest/utils.py index 31db6aa..e8bff76 100644 --- a/zaza/openstack/charm_tests/tempest/utils.py +++ b/zaza/openstack/charm_tests/tempest/utils.py @@ -46,6 +46,9 @@ TEMPEST_ALT_FLAVOR_NAME = 'm2.tempest' TEMPEST_SVC_LIST = ['ceilometer', 'cinder', 'glance', 'heat', 'horizon', 'ironic', 'manila', 'neutron', 'nova', 'octavia', 'sahara', 'swift', 'trove', 'watcher', 'zaqar'] +SUPPORTS_ENFORCE_SCOPE = ['barbican', 'cinder', 'designate', 'glance', + 'ironic', 'keystone', 'nova', 'magnum', + 'manila', 'neutron', 'octavia', 'placement'] def render_tempest_config_keystone_v2(): @@ -57,18 +60,21 @@ def render_tempest_config_keystone_v2(): _setup_tempest('tempest_v2.j2', 'accounts.j2') -def render_tempest_config_keystone_v3(minimal=False): +def render_tempest_config_keystone_v3(minimal=False, new_rbac=False): """Render tempest config for Keystone V3 API. :param minimal: Run in minimal mode eg ignore missing setup :type minimal: bool + :param new_rbac: Use new RBAC rules + :type new_rbac: bool :returns: None :rtype: None """ _setup_tempest( 'tempest_v3.j2', 'accounts.j2', - minimal=minimal) + minimal=minimal, + new_rbac=new_rbac) def get_workspace(): @@ -116,7 +122,8 @@ def _init_workspace(workspace_path): pass -def _setup_tempest(tempest_template, accounts_template, minimal=False): +def _setup_tempest(tempest_template, accounts_template, + minimal=False, new_rbac=False): """Initialize tempest and render tempest config. :param tempest_template: tempest.conf template @@ -125,13 +132,17 @@ def _setup_tempest(tempest_template, accounts_template, minimal=False): :type accounts_template: module :param minimal: Run in minimal mode eg ignore missing setup :type minimal: bool + :param new_rbac: Use new RBAC rules + :type new_rbac: bool :returns: None :rtype: None """ workspace_name, workspace_path = get_workspace() destroy_workspace(workspace_name, workspace_path) _init_workspace(workspace_path) - context = _get_tempest_context(workspace_path, missing_fatal=not minimal) + context = _get_tempest_context(workspace_path, + missing_fatal=not minimal, + new_rbac=new_rbac) _render_tempest_config( os.path.join(workspace_path, 'etc/tempest.conf'), context, @@ -142,13 +153,15 @@ def _setup_tempest(tempest_template, accounts_template, minimal=False): accounts_template) -def _get_tempest_context(workspace_path, missing_fatal=True): +def _get_tempest_context(workspace_path, missing_fatal=True, new_rbac=False): """Generate the tempest config context. :param workspace_path: path to workspace directory :type workspace_path: str :param missing_fatal: Raise an exception if a resource is missing :type missing_fatal: bool + :param new_rbac: Use new RBAC rules + :type new_rbac: bool :returns: Context dictionary :rtype: dict """ @@ -170,6 +183,10 @@ def _get_tempest_context(workspace_path, missing_fatal=True): ctxt['disabled_services'] = list( set(TEMPEST_SVC_LIST) - set(ctxt['enabled_services'])) _add_application_ips(ctxt) + ctxt['enforce_scopes'] = [] + for svc_name in ctxt['enabled_services']: + if svc_name in SUPPORTS_ENFORCE_SCOPE and new_rbac: + ctxt['enforce_scopes'].append(svc_name) for svc_name, ctxt_func in ctxt_funcs.items(): if svc_name in ctxt['enabled_services']: ctxt_func( @@ -375,6 +392,9 @@ def _add_keystone_config(ctxt, keystone_session, missing_fatal=True): keystone_session) domain = keystone_client.domains.find(name="admin_domain") ctxt['default_domain_id'] = domain.id + # note(gboutry): Enable admin_domain_scope if new RBAC is not used + ctxt['admin_domain_scope'] = 'keystone' not in ctxt.get('enforce_scopes', + []) def _add_octavia_config(ctxt, missing_fatal=True):