Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file.
55 changes: 55 additions & 0 deletions tests/install_upgrade_operators/role_aggregation/conftest.py
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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))