diff --git a/tests/install_upgrade_operators/role_aggregation/__init__.py b/tests/install_upgrade_operators/role_aggregation/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/install_upgrade_operators/role_aggregation/conftest.py b/tests/install_upgrade_operators/role_aggregation/conftest.py new file mode 100644 index 0000000000..52f476eba5 --- /dev/null +++ b/tests/install_upgrade_operators/role_aggregation/conftest.py @@ -0,0 +1,55 @@ +"""Pytest conftest file for role aggregation opt-out tests.""" + +import pytest +from ocp_resources.cluster_role import ClusterRole +from ocp_resources.kubevirt import KubeVirt +from ocp_resources.role_binding import RoleBinding + +from utilities.constants import UNPRIVILEGED_USER +from utilities.hco import ResourceEditorValidateHCOReconcile +from utilities.infra import create_ns + + +@pytest.fixture(scope="class") +def role_aggregation_opt_out(hyperconverged_resource_scope_class): + with ResourceEditorValidateHCOReconcile( + patches={hyperconverged_resource_scope_class: {"spec": {"roleAggregationStrategy": "Manual"}}}, + list_resource_reconcile=[KubeVirt], + wait_for_reconcile_post_update=True, + ): + yield + + +@pytest.fixture(scope="class") +def admin_namespace(admin_client): + yield from create_ns(name="role-aggregation-test-ns", admin_client=admin_client) + + +@pytest.fixture() +def edit_role_binding(admin_client, admin_namespace): + with RoleBinding( + name="unprivileged-user-edit-binding", + namespace=admin_namespace.name, + client=admin_client, + subjects_kind="User", + subjects_name=UNPRIVILEGED_USER, + subjects_namespace=admin_namespace.name, + role_ref_kind=ClusterRole.kind, + role_ref_name="edit", + ) as role_binding: + yield role_binding + + +@pytest.fixture() +def view_role_binding(admin_client, admin_namespace): + with RoleBinding( + name="unprivileged-user-view-binding", + namespace=admin_namespace.name, + client=admin_client, + subjects_kind="User", + subjects_name=UNPRIVILEGED_USER, + subjects_namespace=admin_namespace.name, + role_ref_kind=ClusterRole.kind, + role_ref_name="view", + ) as role_binding: + yield role_binding diff --git a/tests/install_upgrade_operators/role_aggregation/test_role_aggregation_opt_out.py b/tests/install_upgrade_operators/role_aggregation/test_role_aggregation_opt_out.py new file mode 100644 index 0000000000..0d7a14e9c9 --- /dev/null +++ b/tests/install_upgrade_operators/role_aggregation/test_role_aggregation_opt_out.py @@ -0,0 +1,111 @@ +""" +Role Aggregation Opt-Out Tests + +STP: https://github.com/RedHatQE/openshift-virtualization-tests-design-docs/pull/73 +""" + +import pytest +from kubernetes.dynamic.exceptions import ForbiddenError +from ocp_resources.kubevirt import KubeVirt +from ocp_resources.virtual_machine import VirtualMachine + +from utilities.hco import ResourceEditorValidateHCOReconcile + + +@pytest.mark.usefixtures("role_aggregation_opt_out") +class TestRoleAggregationOptOut: + """ + Tests that virtualization actions are forbidden when role aggregation opt-out is enabled. + + Preconditions: + - Role aggregation opt-out enabled on HCO CR (roleAggregationStrategy: Manual) + """ + + @pytest.mark.polarion("CNV-69075") + def test_project_admin_forbidden_virtualization_actions(self, unprivileged_client, namespace): + """ + [NEGATIVE] Test that a project admin user cannot list virtualization resources + when role aggregation opt-out is enabled. + + Preconditions: + - Role aggregation opt-out enabled on HCO CR (roleAggregationStrategy: Manual) + - Namespace where unprivileged user is project admin (created via ProjectRequest) + + Steps: + 1. List VirtualMachine resources in the namespace using the project admin user's client + + Expected: + - Operation fails with ForbiddenError + """ + with pytest.raises(ForbiddenError): + list(VirtualMachine.get(client=unprivileged_client, namespace=namespace.name)) + + @pytest.mark.polarion("CNV-69075") + @pytest.mark.usefixtures("edit_role_binding") + def test_edit_role_forbidden_virtualization_actions(self, unprivileged_client, admin_namespace): + """ + [NEGATIVE] Test that a user with edit role cannot list virtualization resources + when role aggregation opt-out is enabled. + + Preconditions: + - Role aggregation opt-out enabled on HCO CR (roleAggregationStrategy: Manual) + - Admin-created namespace with explicit "edit" RoleBinding for unprivileged user + + Steps: + 1. List VirtualMachine resources in the namespace using the edit-role user's client + + Expected: + - Operation fails with ForbiddenError + """ + with pytest.raises(ForbiddenError): + list(VirtualMachine.get(client=unprivileged_client, namespace=admin_namespace.name)) + + @pytest.mark.polarion("CNV-69075") + @pytest.mark.usefixtures("view_role_binding") + def test_view_role_forbidden_virtualization_actions(self, unprivileged_client, admin_namespace): + """ + [NEGATIVE] Test that a user with view role cannot list virtualization resources + when role aggregation opt-out is enabled. + + Preconditions: + - Role aggregation opt-out enabled on HCO CR (roleAggregationStrategy: Manual) + - Admin-created namespace with explicit "view" RoleBinding for unprivileged user + + Steps: + 1. List VirtualMachine resources in the namespace using the view-role user's client + + Expected: + - Operation fails with ForbiddenError + """ + with pytest.raises(ForbiddenError): + list(VirtualMachine.get(client=unprivileged_client, namespace=admin_namespace.name)) + + +@pytest.mark.polarion("CNV-69075") +def test_opt_out_disabled_restores_access(hyperconverged_resource_scope_function, unprivileged_client, namespace): + """ + Test that disabling role aggregation opt-out restores virtualization access + for a project admin user. + + Preconditions: + - Namespace where unprivileged user is project admin (created via ProjectRequest) + - HCO CR with default roleAggregationStrategy (aggregation enabled) + + Steps: + 1. Enable role aggregation opt-out on HCO CR (set roleAggregationStrategy to Manual) + 2. Verify the project admin user cannot list VirtualMachine resources (ForbiddenError) + 3. Disable role aggregation opt-out (restore HCO CR to default) + 4. List VirtualMachine resources in the namespace using the project admin user's client + + Expected: + - Listing VirtualMachine resources succeeds without error + """ + with ResourceEditorValidateHCOReconcile( + patches={hyperconverged_resource_scope_function: {"spec": {"roleAggregationStrategy": "Manual"}}}, + list_resource_reconcile=[KubeVirt], + wait_for_reconcile_post_update=True, + ): + with pytest.raises(ForbiddenError): + list(VirtualMachine.get(client=unprivileged_client, namespace=namespace.name)) + + list(VirtualMachine.get(client=unprivileged_client, namespace=namespace.name))