[#327] Remove basic-acl from APE tests
Some checks failed
DCO check / Commits Check (pull_request) Has been cancelled
Some checks failed
DCO check / Commits Check (pull_request) Has been cancelled
Signed-off-by: a.berezin <a.berezin@yadro.com>
This commit is contained in:
parent
d8a3f51787
commit
abd810cef6
15 changed files with 934 additions and 1031 deletions
11
pytest.ini
11
pytest.ini
|
@ -37,11 +37,12 @@ markers =
|
||||||
session_token: tests for operations with session token
|
session_token: tests for operations with session token
|
||||||
static_session: tests for operations with static session token
|
static_session: tests for operations with static session token
|
||||||
bearer: tests for bearer tokens
|
bearer: tests for bearer tokens
|
||||||
acl: All tests for ACL
|
ape: tests for APE
|
||||||
acl_basic: tests for basic ACL
|
ape_allow: tests for APE allow rules
|
||||||
acl_bearer: tests for ACL with bearer
|
ape_deny: tests for APE deny rules
|
||||||
acl_extended: tests for extended ACL
|
ape_container: tests for APE on container operations
|
||||||
acl_filters: tests for extended ACL with filters and headers
|
ape_object: tests for APE on object operations
|
||||||
|
ape_namespace: tests for APE on namespace scope
|
||||||
storage_group: tests for storage groups
|
storage_group: tests for storage groups
|
||||||
failover: tests for system recovery after a failure
|
failover: tests for system recovery after a failure
|
||||||
failover_panic: tests for system recovery after panic reboot of a node
|
failover_panic: tests for system recovery after panic reboot of a node
|
||||||
|
|
|
@ -9,23 +9,29 @@ from frostfs_testlib.steps.cli.container import create_container, search_nodes_w
|
||||||
from frostfs_testlib.storage.cluster import Cluster
|
from frostfs_testlib.storage.cluster import Cluster
|
||||||
from frostfs_testlib.storage.dataclasses import ape
|
from frostfs_testlib.storage.dataclasses import ape
|
||||||
from frostfs_testlib.storage.dataclasses.wallet import WalletInfo
|
from frostfs_testlib.storage.dataclasses.wallet import WalletInfo
|
||||||
|
from frostfs_testlib.testing.parallel import parallel
|
||||||
from frostfs_testlib.utils import datetime_utils
|
from frostfs_testlib.utils import datetime_utils
|
||||||
|
|
||||||
from .container_request import ContainerRequest
|
from .container_request import ContainerRequest, MultipleContainersRequest
|
||||||
|
|
||||||
|
|
||||||
def create_container_with_ape(
|
def create_container_with_ape(
|
||||||
frostfs_cli: FrostfsCli, wallet: WalletInfo, shell: Shell, cluster: Cluster, endpoint: str, container_request: ContainerRequest
|
container_request: ContainerRequest,
|
||||||
):
|
frostfs_cli: FrostfsCli,
|
||||||
|
wallet: WalletInfo,
|
||||||
|
shell: Shell,
|
||||||
|
cluster: Cluster,
|
||||||
|
endpoint: str,
|
||||||
|
) -> str:
|
||||||
with reporter.step("Create container"):
|
with reporter.step("Create container"):
|
||||||
cid = _create_container_by_spec(wallet, shell, cluster, endpoint, container_request)
|
cid = _create_container_by_spec(container_request, wallet, shell, cluster, endpoint)
|
||||||
|
|
||||||
with reporter.step("Apply APE rules for container"):
|
if container_request.ape_rules:
|
||||||
if container_request.ape_rules:
|
with reporter.step("Apply APE rules for container"):
|
||||||
_apply_ape_rules(frostfs_cli, endpoint, cid, container_request.ape_rules)
|
_apply_ape_rules(cid, frostfs_cli, endpoint, container_request.ape_rules)
|
||||||
|
|
||||||
with reporter.step("Wait for one block"):
|
with reporter.step("Wait for one block"):
|
||||||
time.sleep(datetime_utils.parse_time(MORPH_BLOCK_TIME))
|
time.sleep(datetime_utils.parse_time(MORPH_BLOCK_TIME))
|
||||||
|
|
||||||
with reporter.step("Search nodes holding the container"):
|
with reporter.step("Search nodes holding the container"):
|
||||||
container_holder_nodes = search_nodes_with_container(wallet, cid, shell, cluster.default_rpc_endpoint, cluster)
|
container_holder_nodes = search_nodes_with_container(wallet, cid, shell, cluster.default_rpc_endpoint, cluster)
|
||||||
|
@ -36,14 +42,31 @@ def create_container_with_ape(
|
||||||
return cid
|
return cid
|
||||||
|
|
||||||
|
|
||||||
|
@reporter.step("Create multiple containers with APE")
|
||||||
|
def create_containers_with_ape(
|
||||||
|
frostfs_cli: FrostfsCli,
|
||||||
|
wallet: WalletInfo,
|
||||||
|
shell: Shell,
|
||||||
|
cluster: Cluster,
|
||||||
|
endpoint: str,
|
||||||
|
multiple_containers_request: MultipleContainersRequest,
|
||||||
|
) -> list[str]:
|
||||||
|
cids_futures = parallel(create_container_with_ape, multiple_containers_request, frostfs_cli, wallet, shell, cluster, endpoint)
|
||||||
|
return [future.result() for future in cids_futures]
|
||||||
|
|
||||||
|
|
||||||
@reporter.step("Create container by spec {container_request}")
|
@reporter.step("Create container by spec {container_request}")
|
||||||
def _create_container_by_spec(
|
def _create_container_by_spec(
|
||||||
wallet: WalletInfo, shell: Shell, cluster: Cluster, endpoint: str, container_request: ContainerRequest
|
container_request: ContainerRequest,
|
||||||
|
wallet: WalletInfo,
|
||||||
|
shell: Shell,
|
||||||
|
cluster: Cluster,
|
||||||
|
endpoint: str,
|
||||||
) -> str:
|
) -> str:
|
||||||
return create_container(wallet, shell, endpoint, container_request.parsed_rule(cluster), wait_for_creation=False)
|
return create_container(wallet, shell, endpoint, container_request.parsed_rule(cluster), wait_for_creation=False)
|
||||||
|
|
||||||
|
|
||||||
def _apply_ape_rules(frostfs_cli: FrostfsCli, endpoint: str, cid: str, ape_rules: list[ape.Rule]):
|
def _apply_ape_rules(cid: str, frostfs_cli: FrostfsCli, endpoint: str, ape_rules: list[ape.Rule]):
|
||||||
for ape_rule in ape_rules:
|
for ape_rule in ape_rules:
|
||||||
rule_str = ape_rule.as_string()
|
rule_str = ape_rule.as_string()
|
||||||
with reporter.step(f"Apply APE rule '{rule_str}' for container {cid}"):
|
with reporter.step(f"Apply APE rule '{rule_str}' for container {cid}"):
|
||||||
|
|
|
@ -54,6 +54,18 @@ class ContainerRequest:
|
||||||
return f"({', '.join(spec_info)})"
|
return f"({', '.join(spec_info)})"
|
||||||
|
|
||||||
|
|
||||||
|
class MultipleContainersRequest(list[ContainerRequest]):
|
||||||
|
def __init__(self, iterable=None):
|
||||||
|
"""Override initializer which can accept iterable"""
|
||||||
|
super(MultipleContainersRequest, self).__init__()
|
||||||
|
if iterable:
|
||||||
|
self.extend(iterable)
|
||||||
|
self.__set_name()
|
||||||
|
|
||||||
|
def __set_name(self):
|
||||||
|
self.__name__ = ", ".join([s.__name__ for s in self])
|
||||||
|
|
||||||
|
|
||||||
PUBLIC_WITH_POLICY = partial(ContainerRequest, ape_rules=APE_EVERYONE_ALLOW_ALL, short_name="Custom_policy_with_allow_all_ape_rule")
|
PUBLIC_WITH_POLICY = partial(ContainerRequest, ape_rules=APE_EVERYONE_ALLOW_ALL, short_name="Custom_policy_with_allow_all_ape_rule")
|
||||||
EVERYONE_ALLOW_ALL = ContainerRequest(policy=DEFAULT_PLACEMENT_RULE, ape_rules=APE_EVERYONE_ALLOW_ALL, short_name="Everyone_Allow_All")
|
EVERYONE_ALLOW_ALL = ContainerRequest(policy=DEFAULT_PLACEMENT_RULE, ape_rules=APE_EVERYONE_ALLOW_ALL, short_name="Everyone_Allow_All")
|
||||||
OWNER_ALLOW_ALL = ContainerRequest(policy=DEFAULT_PLACEMENT_RULE, ape_rules=APE_OWNER_ALLOW_ALL, short_name="Owner_Allow_All")
|
OWNER_ALLOW_ALL = ContainerRequest(policy=DEFAULT_PLACEMENT_RULE, ape_rules=APE_OWNER_ALLOW_ALL, short_name="Owner_Allow_All")
|
||||||
|
|
0
pytest_tests/testsuites/ape/__init__.py
Normal file
0
pytest_tests/testsuites/ape/__init__.py
Normal file
52
pytest_tests/testsuites/ape/conftest.py
Normal file
52
pytest_tests/testsuites/ape/conftest.py
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
import pytest
|
||||||
|
from frostfs_testlib import reporter
|
||||||
|
from frostfs_testlib.cli import FrostfsCli
|
||||||
|
from frostfs_testlib.resources.cli import FROSTFS_CLI_EXEC
|
||||||
|
from frostfs_testlib.shell.interfaces import Shell
|
||||||
|
from frostfs_testlib.steps.cli.object import put_object
|
||||||
|
from frostfs_testlib.storage.cluster import Cluster
|
||||||
|
from frostfs_testlib.storage.dataclasses.object_size import ObjectSize
|
||||||
|
from frostfs_testlib.storage.dataclasses.wallet import WalletInfo
|
||||||
|
from frostfs_testlib.utils.file_utils import generate_file
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="session")
|
||||||
|
def frostfs_cli_on_first_node(cluster: Cluster) -> FrostfsCli:
|
||||||
|
node = cluster.cluster_nodes[0]
|
||||||
|
shell = node.host.get_shell()
|
||||||
|
|
||||||
|
return FrostfsCli(shell, FROSTFS_CLI_EXEC, node.storage_node.get_remote_wallet_config_path())
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def object_id(
|
||||||
|
default_wallet: WalletInfo,
|
||||||
|
frostfs_cli_on_first_node: FrostfsCli,
|
||||||
|
simple_object_size: ObjectSize,
|
||||||
|
cluster: Cluster,
|
||||||
|
client_shell: Shell,
|
||||||
|
container: str,
|
||||||
|
) -> str:
|
||||||
|
test_file = generate_file(simple_object_size.value)
|
||||||
|
|
||||||
|
with reporter.step("Allow PutObject on first node via local override"):
|
||||||
|
frostfs_cli_on_first_node.control.add_rule(
|
||||||
|
endpoint=cluster.storage_nodes[0].get_control_endpoint(),
|
||||||
|
target_type="container",
|
||||||
|
target_name=container,
|
||||||
|
chain_id="allowPutObject",
|
||||||
|
rule=f"allow Object.Put *",
|
||||||
|
)
|
||||||
|
|
||||||
|
with reporter.step("Put objects in container on the first node"):
|
||||||
|
object_id = put_object(default_wallet, test_file, container, client_shell, cluster.storage_nodes[0].get_rpc_endpoint())
|
||||||
|
|
||||||
|
with reporter.step("Remove PutObject local override from first node"):
|
||||||
|
frostfs_cli_on_first_node.control.remove_rule(
|
||||||
|
endpoint=cluster.storage_nodes[0].get_control_endpoint(),
|
||||||
|
target_type="container",
|
||||||
|
target_name=container,
|
||||||
|
chain_id="allowPutObject",
|
||||||
|
)
|
||||||
|
|
||||||
|
return object_id
|
File diff suppressed because it is too large
Load diff
212
pytest_tests/testsuites/ape/test_ape_local_container.py
Normal file
212
pytest_tests/testsuites/ape/test_ape_local_container.py
Normal file
|
@ -0,0 +1,212 @@
|
||||||
|
from time import sleep
|
||||||
|
|
||||||
|
import allure
|
||||||
|
import pytest
|
||||||
|
from frostfs_testlib import reporter
|
||||||
|
from frostfs_testlib.cli import FrostfsCli
|
||||||
|
from frostfs_testlib.resources.cli import FROSTFS_CLI_EXEC
|
||||||
|
from frostfs_testlib.resources.common import MORPH_BLOCK_TIME
|
||||||
|
from frostfs_testlib.resources.error_patterns import RULE_ACCESS_DENIED_CONTAINER
|
||||||
|
from frostfs_testlib.shell.interfaces import Shell
|
||||||
|
from frostfs_testlib.storage.cluster import Cluster, ClusterNode
|
||||||
|
from frostfs_testlib.storage.dataclasses.ape import Operations
|
||||||
|
from frostfs_testlib.testing.cluster_test_base import ClusterTestBase
|
||||||
|
from frostfs_testlib.testing.parallel import parallel
|
||||||
|
from frostfs_testlib.testing.test_control import expect_not_raises
|
||||||
|
from frostfs_testlib.utils import datetime_utils
|
||||||
|
|
||||||
|
from ...helpers.container_request import APE_EVERYONE_ALLOW_ALL, ContainerRequest, MultipleContainersRequest
|
||||||
|
|
||||||
|
REP2 = ContainerRequest("REP 2", ape_rules=APE_EVERYONE_ALLOW_ALL, short_name="REP2_allow_all_ape")
|
||||||
|
|
||||||
|
|
||||||
|
def remove_local_overrides_on_node(node: ClusterNode):
|
||||||
|
target = "Chain ID"
|
||||||
|
shell: Shell = node.host.get_shell()
|
||||||
|
remote_config: str = node.storage_node.get_remote_wallet_config_path()
|
||||||
|
cli = FrostfsCli(shell=shell, frostfs_cli_exec_path=FROSTFS_CLI_EXEC, config_file=remote_config)
|
||||||
|
with reporter.step(f"Check local overrides on {node.storage_node.id} node"):
|
||||||
|
rules = cli.control.list_rules(
|
||||||
|
endpoint=node.storage_node.get_control_endpoint(), target_name="root", target_type="namespace"
|
||||||
|
).stdout
|
||||||
|
if target in rules:
|
||||||
|
with reporter.step("Delete rules"):
|
||||||
|
chain_ids = [i.split(" ")[2].strip() for i in rules.split("\n") if "Chain ID" in i]
|
||||||
|
for chain_id in chain_ids:
|
||||||
|
cli.control.remove_rule(
|
||||||
|
endpoint=node.storage_node.get_control_endpoint(),
|
||||||
|
target_type="namespace",
|
||||||
|
target_name="root",
|
||||||
|
chain_id=chain_id,
|
||||||
|
)
|
||||||
|
with reporter.step("Wait for one block"):
|
||||||
|
sleep(datetime_utils.parse_time(MORPH_BLOCK_TIME))
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="session")
|
||||||
|
def remove_local_ape_overrides(cluster: Cluster) -> None:
|
||||||
|
yield
|
||||||
|
with reporter.step("Check local overrides on nodes."):
|
||||||
|
parallel(remove_local_overrides_on_node, cluster.cluster_nodes)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.ape
|
||||||
|
@pytest.mark.ape_local
|
||||||
|
@pytest.mark.ape_container
|
||||||
|
@pytest.mark.ape_namespace
|
||||||
|
class TestApeLocalOverrideContainer(ClusterTestBase):
|
||||||
|
@allure.title("LocalOverride: Deny to GetContainer in root tenant")
|
||||||
|
def test_local_override_deny_to_get_container_root(
|
||||||
|
self,
|
||||||
|
frostfs_cli_on_first_node: FrostfsCli,
|
||||||
|
frostfs_cli: FrostfsCli,
|
||||||
|
container: str,
|
||||||
|
remove_local_ape_overrides: None,
|
||||||
|
):
|
||||||
|
with reporter.step("Create a namespace rule for the first node"):
|
||||||
|
frostfs_cli_on_first_node.control.add_rule(
|
||||||
|
endpoint=self.cluster.storage_nodes[0].get_control_endpoint(),
|
||||||
|
target_type="namespace",
|
||||||
|
target_name="root",
|
||||||
|
chain_id="denyContainerGet",
|
||||||
|
rule="deny Container.Get *",
|
||||||
|
)
|
||||||
|
|
||||||
|
with reporter.step("Check get the container property on the first node, expected denied error"):
|
||||||
|
with pytest.raises(RuntimeError, match=RULE_ACCESS_DENIED_CONTAINER.format(operation=Operations.GET_CONTAINER)):
|
||||||
|
frostfs_cli.container.get(self.cluster.storage_nodes[0].get_rpc_endpoint(), container)
|
||||||
|
|
||||||
|
with reporter.step("Check get the container property on the second node, expected allow"):
|
||||||
|
with expect_not_raises():
|
||||||
|
frostfs_cli.container.get(self.cluster.storage_nodes[1].get_rpc_endpoint(), container)
|
||||||
|
|
||||||
|
with reporter.step("Delete a rule"):
|
||||||
|
frostfs_cli_on_first_node.control.remove_rule(
|
||||||
|
endpoint=self.cluster.storage_nodes[0].get_control_endpoint(),
|
||||||
|
target_type="namespace",
|
||||||
|
target_name="root",
|
||||||
|
chain_id="denyContainerGet",
|
||||||
|
)
|
||||||
|
|
||||||
|
with reporter.step("Check get the container property on the first node, expected allow"):
|
||||||
|
with expect_not_raises():
|
||||||
|
frostfs_cli.container.get(self.cluster.storage_nodes[0].get_rpc_endpoint(), container)
|
||||||
|
|
||||||
|
@allure.title("LocalOverride: Deny to PutContainer in root tenant")
|
||||||
|
def test_local_override_deny_to_put_container_root(
|
||||||
|
self,
|
||||||
|
frostfs_cli_on_first_node: FrostfsCli,
|
||||||
|
frostfs_cli: FrostfsCli,
|
||||||
|
remove_local_ape_overrides: None,
|
||||||
|
):
|
||||||
|
with reporter.step("Create a namespace rule for the first node"):
|
||||||
|
frostfs_cli_on_first_node.control.add_rule(
|
||||||
|
endpoint=self.cluster.storage_nodes[0].get_control_endpoint(),
|
||||||
|
target_type="namespace",
|
||||||
|
target_name="root",
|
||||||
|
chain_id="denyContainerPut",
|
||||||
|
rule="deny Container.Put *",
|
||||||
|
)
|
||||||
|
|
||||||
|
with reporter.step("Check create container on the first node, expected access denied error"):
|
||||||
|
with pytest.raises(RuntimeError, match=RULE_ACCESS_DENIED_CONTAINER.format(operation=Operations.PUT_CONTAINER)):
|
||||||
|
frostfs_cli.container.create(
|
||||||
|
rpc_endpoint=self.cluster.storage_nodes[0].get_rpc_endpoint(),
|
||||||
|
policy="REP 1",
|
||||||
|
)
|
||||||
|
|
||||||
|
with reporter.step("Check create a container on the second node, expected allow"):
|
||||||
|
with expect_not_raises():
|
||||||
|
frostfs_cli.container.create(
|
||||||
|
rpc_endpoint=self.cluster.storage_nodes[1].get_rpc_endpoint(),
|
||||||
|
policy="REP 1",
|
||||||
|
)
|
||||||
|
|
||||||
|
with reporter.step("Delete a rule"):
|
||||||
|
frostfs_cli_on_first_node.control.remove_rule(
|
||||||
|
endpoint=self.cluster.storage_nodes[0].get_control_endpoint(),
|
||||||
|
target_type="namespace",
|
||||||
|
target_name="root",
|
||||||
|
chain_id="denyContainerPut",
|
||||||
|
)
|
||||||
|
|
||||||
|
with reporter.step("Check create a container on the first node, expected allow"):
|
||||||
|
with expect_not_raises():
|
||||||
|
frostfs_cli.container.create(
|
||||||
|
rpc_endpoint=self.cluster.storage_nodes[0].get_rpc_endpoint(),
|
||||||
|
policy="REP 1",
|
||||||
|
)
|
||||||
|
|
||||||
|
@allure.title("LocalOverride: Deny to ListContainer in root tenant")
|
||||||
|
def test_local_override_deny_to_list_container_root(
|
||||||
|
self,
|
||||||
|
frostfs_cli_on_first_node: FrostfsCli,
|
||||||
|
frostfs_cli: FrostfsCli,
|
||||||
|
remove_local_ape_overrides: None,
|
||||||
|
):
|
||||||
|
with reporter.step("Create a namespace rule for the first node"):
|
||||||
|
frostfs_cli_on_first_node.control.add_rule(
|
||||||
|
endpoint=self.cluster.storage_nodes[0].get_control_endpoint(),
|
||||||
|
target_type="namespace",
|
||||||
|
target_name="root",
|
||||||
|
chain_id="denyContainerList",
|
||||||
|
rule="deny Container.List *",
|
||||||
|
)
|
||||||
|
|
||||||
|
with reporter.step("Check list the container properties on the first node, expected access denied error"):
|
||||||
|
with pytest.raises(RuntimeError, match=RULE_ACCESS_DENIED_CONTAINER.format(operation=Operations.LIST_CONTAINER)):
|
||||||
|
frostfs_cli.container.list(rpc_endpoint=self.cluster.storage_nodes[0].get_rpc_endpoint(), ttl=1)
|
||||||
|
|
||||||
|
with reporter.step("Check list the container properties on the second node, expected allow"):
|
||||||
|
with expect_not_raises():
|
||||||
|
frostfs_cli.container.list(rpc_endpoint=self.cluster.storage_nodes[1].get_rpc_endpoint(), ttl=1)
|
||||||
|
|
||||||
|
with reporter.step("Delete a rule"):
|
||||||
|
frostfs_cli_on_first_node.control.remove_rule(
|
||||||
|
endpoint=self.cluster.storage_nodes[0].get_control_endpoint(),
|
||||||
|
target_type="namespace",
|
||||||
|
target_name="root",
|
||||||
|
chain_id="denyContainerList",
|
||||||
|
)
|
||||||
|
|
||||||
|
with reporter.step("Check display a list of containers on the first node, expected allow"):
|
||||||
|
with expect_not_raises():
|
||||||
|
frostfs_cli.container.list(rpc_endpoint=self.cluster.storage_nodes[0].get_rpc_endpoint(), ttl=1)
|
||||||
|
|
||||||
|
@allure.title("LocalOverride: Deny to DeleteContainer in root tenant")
|
||||||
|
@pytest.mark.parametrize("multiple_containers_request", [MultipleContainersRequest([REP2, REP2])], indirect=True)
|
||||||
|
def test_local_override_deny_to_delete_container_root(
|
||||||
|
self,
|
||||||
|
frostfs_cli_on_first_node: FrostfsCli,
|
||||||
|
frostfs_cli: FrostfsCli,
|
||||||
|
remove_local_ape_overrides: None,
|
||||||
|
containers: list[str],
|
||||||
|
):
|
||||||
|
with reporter.step("Create a namespace rule for the first node"):
|
||||||
|
frostfs_cli_on_first_node.control.add_rule(
|
||||||
|
endpoint=self.cluster.storage_nodes[0].get_control_endpoint(),
|
||||||
|
target_type="namespace",
|
||||||
|
target_name="root",
|
||||||
|
chain_id="denyContainerDelete",
|
||||||
|
rule="deny Container.Delete *",
|
||||||
|
)
|
||||||
|
|
||||||
|
with reporter.step("Check delete first container from the first node, expected access denied error"):
|
||||||
|
with pytest.raises(RuntimeError, match=RULE_ACCESS_DENIED_CONTAINER.format(operation=Operations.DELETE_CONTAINER)):
|
||||||
|
frostfs_cli.container.delete(self.cluster.storage_nodes[0].get_rpc_endpoint(), containers[0], ttl=1)
|
||||||
|
|
||||||
|
with reporter.step("Check delete a second container from the second node, expected allow"):
|
||||||
|
with expect_not_raises():
|
||||||
|
frostfs_cli.container.delete(self.cluster.storage_nodes[1].get_rpc_endpoint(), containers[1], ttl=1)
|
||||||
|
|
||||||
|
with reporter.step("Delete a rule"):
|
||||||
|
frostfs_cli_on_first_node.control.remove_rule(
|
||||||
|
endpoint=self.cluster.storage_nodes[0].get_control_endpoint(),
|
||||||
|
target_type="namespace",
|
||||||
|
target_name="root",
|
||||||
|
chain_id="denyContainerDelete",
|
||||||
|
)
|
||||||
|
|
||||||
|
with reporter.step("Check delete first container from the first node, expected allow"):
|
||||||
|
with expect_not_raises():
|
||||||
|
frostfs_cli.container.delete(self.cluster.storage_nodes[0].get_rpc_endpoint(), containers[0], ttl=1)
|
254
pytest_tests/testsuites/ape/test_ape_local_object_allow.py
Normal file
254
pytest_tests/testsuites/ape/test_ape_local_object_allow.py
Normal file
|
@ -0,0 +1,254 @@
|
||||||
|
import allure
|
||||||
|
import pytest
|
||||||
|
from frostfs_testlib import reporter
|
||||||
|
from frostfs_testlib.cli import FrostfsCli
|
||||||
|
from frostfs_testlib.resources.error_patterns import NO_RULE_FOUND_OBJECT
|
||||||
|
from frostfs_testlib.steps.cli.object import delete_object, get_object, get_range, get_range_hash, head_object, put_object, search_object
|
||||||
|
from frostfs_testlib.storage.dataclasses.object_size import ObjectSize
|
||||||
|
from frostfs_testlib.storage.dataclasses.wallet import WalletInfo
|
||||||
|
from frostfs_testlib.testing.cluster_test_base import ClusterTestBase
|
||||||
|
from frostfs_testlib.testing.test_control import expect_not_raises
|
||||||
|
from frostfs_testlib.utils.file_utils import generate_file
|
||||||
|
|
||||||
|
from ...helpers.container_request import ContainerRequest
|
||||||
|
|
||||||
|
REP1_MSK = ContainerRequest("REP 1 IN MOW CBF 1 SELECT 1 FROM MSK AS MOW FILTER SubDivCode EQ MOW AS MSK", short_name="REP1_MSK_no_ape")
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.ape
|
||||||
|
@pytest.mark.ape_local
|
||||||
|
@pytest.mark.ape_object
|
||||||
|
@pytest.mark.ape_allow
|
||||||
|
@pytest.mark.parametrize("container_request", [REP1_MSK], indirect=True)
|
||||||
|
class TestApeLocalOverrideAllow(ClusterTestBase):
|
||||||
|
@allure.title("LocalOverride: Allow to GetObject in root tenant")
|
||||||
|
def test_local_override_allow_to_get_object_root(
|
||||||
|
self,
|
||||||
|
default_wallet: WalletInfo,
|
||||||
|
frostfs_cli_on_first_node: FrostfsCli,
|
||||||
|
container: str,
|
||||||
|
object_id: str,
|
||||||
|
):
|
||||||
|
with reporter.step("Create local override on first node"):
|
||||||
|
frostfs_cli_on_first_node.control.add_rule(
|
||||||
|
endpoint=self.cluster.storage_nodes[0].get_control_endpoint(),
|
||||||
|
target_type="container",
|
||||||
|
target_name=container,
|
||||||
|
chain_id="allowGetObject",
|
||||||
|
rule=f"allow Object.Get *",
|
||||||
|
)
|
||||||
|
|
||||||
|
with reporter.step("Check get object in container on the first node, expected allow"):
|
||||||
|
with expect_not_raises():
|
||||||
|
get_object(default_wallet, container, object_id, self.shell, self.cluster.storage_nodes[0].get_rpc_endpoint())
|
||||||
|
|
||||||
|
with reporter.step("Check get object in container on the second node, epxected access denied error"):
|
||||||
|
with pytest.raises(RuntimeError, match=NO_RULE_FOUND_OBJECT):
|
||||||
|
get_object(default_wallet, container, object_id, self.shell, self.cluster.storage_nodes[1].get_rpc_endpoint())
|
||||||
|
|
||||||
|
with reporter.step("Delete a rule"):
|
||||||
|
frostfs_cli_on_first_node.control.remove_rule(
|
||||||
|
endpoint=self.cluster.storage_nodes[0].get_control_endpoint(),
|
||||||
|
target_type="container",
|
||||||
|
target_name=container,
|
||||||
|
chain_id="allowGetObject",
|
||||||
|
)
|
||||||
|
|
||||||
|
@allure.title("LocalOverride: Allow to PutObject in root tenant")
|
||||||
|
def test_local_override_allow_to_put_object_root(
|
||||||
|
self,
|
||||||
|
default_wallet: WalletInfo,
|
||||||
|
frostfs_cli_on_first_node: FrostfsCli,
|
||||||
|
simple_object_size: ObjectSize,
|
||||||
|
container: str,
|
||||||
|
):
|
||||||
|
test_file = generate_file(simple_object_size.value)
|
||||||
|
|
||||||
|
with reporter.step("Create local override on first node"):
|
||||||
|
frostfs_cli_on_first_node.control.add_rule(
|
||||||
|
endpoint=self.cluster.storage_nodes[0].get_control_endpoint(),
|
||||||
|
target_type="container",
|
||||||
|
target_name=container,
|
||||||
|
chain_id="allowPutObject",
|
||||||
|
rule=f"allow Object.Put *",
|
||||||
|
)
|
||||||
|
|
||||||
|
with reporter.step("Check put object in container on the first node, expected allow"):
|
||||||
|
with expect_not_raises():
|
||||||
|
put_object(default_wallet, test_file, container, self.shell, self.cluster.storage_nodes[0].get_rpc_endpoint())
|
||||||
|
|
||||||
|
with reporter.step("Check get object in container on the second node, epxected access denied error"):
|
||||||
|
with pytest.raises(RuntimeError, match=NO_RULE_FOUND_OBJECT):
|
||||||
|
put_object(default_wallet, test_file, container, self.shell, self.cluster.storage_nodes[1].get_rpc_endpoint())
|
||||||
|
|
||||||
|
with reporter.step("Delete a rule"):
|
||||||
|
frostfs_cli_on_first_node.control.remove_rule(
|
||||||
|
endpoint=self.cluster.storage_nodes[0].get_control_endpoint(),
|
||||||
|
target_type="container",
|
||||||
|
target_name=container,
|
||||||
|
chain_id="allowPutObject",
|
||||||
|
)
|
||||||
|
|
||||||
|
@allure.title("LocalOverride: Allow to HeadObject in root tenant")
|
||||||
|
def test_local_override_allow_to_head_object_root(
|
||||||
|
self,
|
||||||
|
default_wallet: WalletInfo,
|
||||||
|
frostfs_cli_on_first_node: FrostfsCli,
|
||||||
|
container: str,
|
||||||
|
object_id: str,
|
||||||
|
):
|
||||||
|
with reporter.step("Create local override on first node"):
|
||||||
|
frostfs_cli_on_first_node.control.add_rule(
|
||||||
|
endpoint=self.cluster.storage_nodes[0].get_control_endpoint(),
|
||||||
|
target_type="container",
|
||||||
|
target_name=container,
|
||||||
|
chain_id="allowHeadObject",
|
||||||
|
rule=f"allow Object.Head *",
|
||||||
|
)
|
||||||
|
|
||||||
|
with reporter.step("Check head object in container on the first node, expected allow"):
|
||||||
|
with expect_not_raises():
|
||||||
|
head_object(default_wallet, container, object_id, self.shell, self.cluster.storage_nodes[0].get_rpc_endpoint())
|
||||||
|
|
||||||
|
with reporter.step("Check head object in container on the second node, expected access denied error"):
|
||||||
|
with pytest.raises(RuntimeError, match=NO_RULE_FOUND_OBJECT):
|
||||||
|
head_object(default_wallet, container, object_id, self.shell, self.cluster.storage_nodes[1].get_rpc_endpoint())
|
||||||
|
|
||||||
|
with reporter.step("Delete a rule"):
|
||||||
|
frostfs_cli_on_first_node.control.remove_rule(
|
||||||
|
endpoint=self.cluster.storage_nodes[0].get_control_endpoint(),
|
||||||
|
target_type="container",
|
||||||
|
target_name=container,
|
||||||
|
chain_id="allowHeadObject",
|
||||||
|
)
|
||||||
|
|
||||||
|
@allure.title("LocalOverride: Allow to SearchObject in root tenant")
|
||||||
|
def test_local_override_allow_to_search_object_root(
|
||||||
|
self,
|
||||||
|
default_wallet: WalletInfo,
|
||||||
|
frostfs_cli_on_first_node: FrostfsCli,
|
||||||
|
container: str,
|
||||||
|
):
|
||||||
|
with reporter.step("Create local override on first node"):
|
||||||
|
frostfs_cli_on_first_node.control.add_rule(
|
||||||
|
endpoint=self.cluster.storage_nodes[0].get_control_endpoint(),
|
||||||
|
target_type="container",
|
||||||
|
target_name=container,
|
||||||
|
chain_id="allowSearchObject",
|
||||||
|
rule=f"allow Object.Search *",
|
||||||
|
)
|
||||||
|
|
||||||
|
with reporter.step("Check search object in container on the first node, expected allow"):
|
||||||
|
with expect_not_raises():
|
||||||
|
search_object(default_wallet, container, self.shell, self.cluster.storage_nodes[0].get_rpc_endpoint())
|
||||||
|
|
||||||
|
with reporter.step("Check search object from container on the second node, expected access denied error"):
|
||||||
|
with pytest.raises(RuntimeError, match=NO_RULE_FOUND_OBJECT):
|
||||||
|
search_object(default_wallet, container, self.shell, self.cluster.storage_nodes[1].get_rpc_endpoint())
|
||||||
|
|
||||||
|
with reporter.step("Delete a rule"):
|
||||||
|
frostfs_cli_on_first_node.control.remove_rule(
|
||||||
|
endpoint=self.cluster.storage_nodes[0].get_control_endpoint(),
|
||||||
|
target_type="container",
|
||||||
|
target_name=container,
|
||||||
|
chain_id="allowSearchObject",
|
||||||
|
)
|
||||||
|
|
||||||
|
@allure.title("LocalOverride: Allow to RangeObject in root tenant")
|
||||||
|
def test_local_override_allow_to_range_object_root(
|
||||||
|
self,
|
||||||
|
default_wallet: WalletInfo,
|
||||||
|
frostfs_cli_on_first_node: FrostfsCli,
|
||||||
|
container: str,
|
||||||
|
object_id: str,
|
||||||
|
):
|
||||||
|
with reporter.step("Create local override on first node"):
|
||||||
|
frostfs_cli_on_first_node.control.add_rule(
|
||||||
|
endpoint=self.cluster.storage_nodes[0].get_control_endpoint(),
|
||||||
|
target_type="container",
|
||||||
|
target_name=container,
|
||||||
|
chain_id="allowRangeObject",
|
||||||
|
rule=f"allow Object.Range *",
|
||||||
|
)
|
||||||
|
|
||||||
|
with reporter.step("Check get range object in container on the first node, expected allow"):
|
||||||
|
with expect_not_raises():
|
||||||
|
get_range(default_wallet, container, object_id, "0:10", self.shell, self.cluster.storage_nodes[0].get_rpc_endpoint())
|
||||||
|
|
||||||
|
with reporter.step("Check range object in container on the second node. expected access denied error"):
|
||||||
|
with pytest.raises(RuntimeError, match=NO_RULE_FOUND_OBJECT):
|
||||||
|
get_range(default_wallet, container, object_id, "0:10", self.shell, self.cluster.storage_nodes[1].get_rpc_endpoint())
|
||||||
|
|
||||||
|
with reporter.step("Delete a rule"):
|
||||||
|
frostfs_cli_on_first_node.control.remove_rule(
|
||||||
|
endpoint=self.cluster.storage_nodes[0].get_control_endpoint(),
|
||||||
|
target_type="container",
|
||||||
|
target_name=container,
|
||||||
|
chain_id="allowRangeObject",
|
||||||
|
)
|
||||||
|
|
||||||
|
@allure.title("LocalOverride: Allow to HashObject in root tenant")
|
||||||
|
def test_local_override_allow_to_hash_object_root(
|
||||||
|
self,
|
||||||
|
default_wallet: WalletInfo,
|
||||||
|
frostfs_cli_on_first_node: FrostfsCli,
|
||||||
|
container: str,
|
||||||
|
object_id: str,
|
||||||
|
):
|
||||||
|
with reporter.step("Create local override on first node"):
|
||||||
|
frostfs_cli_on_first_node.control.add_rule(
|
||||||
|
endpoint=self.cluster.storage_nodes[0].get_control_endpoint(),
|
||||||
|
target_type="container",
|
||||||
|
target_name=container,
|
||||||
|
chain_id="allowHashObject",
|
||||||
|
rule=f"allow Object.Hash *",
|
||||||
|
)
|
||||||
|
|
||||||
|
with reporter.step("Check get range hash object in container on the first node, expected allow"):
|
||||||
|
with expect_not_raises():
|
||||||
|
get_range_hash(default_wallet, container, object_id, "0:10", self.shell, self.cluster.storage_nodes[0].get_rpc_endpoint())
|
||||||
|
|
||||||
|
with reporter.step("Check get range hash object in container on the second node, expected access denied error"):
|
||||||
|
with pytest.raises(RuntimeError, match=NO_RULE_FOUND_OBJECT):
|
||||||
|
get_range_hash(default_wallet, container, object_id, "0:10", self.shell, self.cluster.storage_nodes[1].get_rpc_endpoint())
|
||||||
|
|
||||||
|
with reporter.step("Delete a rule"):
|
||||||
|
frostfs_cli_on_first_node.control.remove_rule(
|
||||||
|
endpoint=self.cluster.storage_nodes[0].get_control_endpoint(),
|
||||||
|
target_type="container",
|
||||||
|
target_name=container,
|
||||||
|
chain_id="allowHashObject",
|
||||||
|
)
|
||||||
|
|
||||||
|
@allure.title("LocalOverride: Allow to DeleteObject in root tenant")
|
||||||
|
def test_local_override_allow_to_delete_object_root(
|
||||||
|
self,
|
||||||
|
default_wallet: WalletInfo,
|
||||||
|
frostfs_cli_on_first_node: FrostfsCli,
|
||||||
|
container: str,
|
||||||
|
object_id: str,
|
||||||
|
):
|
||||||
|
with reporter.step("Create local override on first node"):
|
||||||
|
frostfs_cli_on_first_node.control.add_rule(
|
||||||
|
endpoint=self.cluster.storage_nodes[0].get_control_endpoint(),
|
||||||
|
target_type="container",
|
||||||
|
target_name=container,
|
||||||
|
chain_id="allowDeleteObject",
|
||||||
|
rule=f"allow Object.Head Object.Delete *",
|
||||||
|
)
|
||||||
|
|
||||||
|
with reporter.step("Check delete object from container on the second node, expected access denied error"):
|
||||||
|
with pytest.raises(RuntimeError, match=NO_RULE_FOUND_OBJECT):
|
||||||
|
delete_object(default_wallet, container, object_id, self.shell, self.cluster.storage_nodes[1].get_rpc_endpoint())
|
||||||
|
|
||||||
|
with reporter.step("Check delete object in container on the first node, expected allow"):
|
||||||
|
with expect_not_raises():
|
||||||
|
delete_object(default_wallet, container, object_id, self.shell, self.cluster.storage_nodes[0].get_rpc_endpoint())
|
||||||
|
|
||||||
|
with reporter.step("Delete a rule"):
|
||||||
|
frostfs_cli_on_first_node.control.remove_rule(
|
||||||
|
endpoint=self.cluster.storage_nodes[0].get_control_endpoint(),
|
||||||
|
target_type="container",
|
||||||
|
target_name=container,
|
||||||
|
chain_id="allowDeleteObject",
|
||||||
|
)
|
333
pytest_tests/testsuites/ape/test_ape_local_object_deny.py
Normal file
333
pytest_tests/testsuites/ape/test_ape_local_object_deny.py
Normal file
|
@ -0,0 +1,333 @@
|
||||||
|
import allure
|
||||||
|
import pytest
|
||||||
|
from frostfs_testlib.cli import FrostfsCli
|
||||||
|
from frostfs_testlib.reporter import get_reporter
|
||||||
|
from frostfs_testlib.resources.error_patterns import OBJECT_ACCESS_DENIED, RULE_ACCESS_DENIED_OBJECT
|
||||||
|
from frostfs_testlib.steps.cli.object import delete_object, get_object, get_range, get_range_hash, head_object, put_object, search_object
|
||||||
|
from frostfs_testlib.storage.dataclasses.ape import Operations
|
||||||
|
from frostfs_testlib.storage.dataclasses.object_size import ObjectSize
|
||||||
|
from frostfs_testlib.storage.dataclasses.wallet import WalletInfo
|
||||||
|
from frostfs_testlib.testing.cluster_test_base import ClusterTestBase
|
||||||
|
from frostfs_testlib.testing.test_control import expect_not_raises
|
||||||
|
from frostfs_testlib.utils.file_utils import generate_file
|
||||||
|
|
||||||
|
from ...helpers.container_request import APE_EVERYONE_ALLOW_ALL, ContainerRequest
|
||||||
|
|
||||||
|
reporter = get_reporter()
|
||||||
|
|
||||||
|
REP2 = ContainerRequest("REP 2", ape_rules=APE_EVERYONE_ALLOW_ALL, short_name="REP2_allow_all_ape")
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.ape
|
||||||
|
@pytest.mark.ape_local
|
||||||
|
@pytest.mark.ape_object
|
||||||
|
@pytest.mark.ape_deny
|
||||||
|
class TestApeLocalOverrideDeny(ClusterTestBase):
|
||||||
|
@allure.title("LocalOverride: Deny to GetObject in root tenant")
|
||||||
|
@pytest.mark.parametrize("container_request", [REP2], indirect=True)
|
||||||
|
def test_local_override_deny_to_get_object_root(
|
||||||
|
self,
|
||||||
|
default_wallet: WalletInfo,
|
||||||
|
frostfs_cli_on_first_node: FrostfsCli,
|
||||||
|
simple_object_size: ObjectSize,
|
||||||
|
container: str,
|
||||||
|
):
|
||||||
|
test_file = generate_file(simple_object_size.value)
|
||||||
|
|
||||||
|
with reporter.step("Create local override on first node"):
|
||||||
|
frostfs_cli_on_first_node.control.add_rule(
|
||||||
|
endpoint=self.cluster.storage_nodes[0].get_control_endpoint(),
|
||||||
|
target_type="container",
|
||||||
|
target_name=container,
|
||||||
|
chain_id="denyGetObject",
|
||||||
|
rule=f"deny Object.Get /{container}/*",
|
||||||
|
)
|
||||||
|
|
||||||
|
with reporter.step("Put object in container on the first node"):
|
||||||
|
oid = put_object(default_wallet, test_file, container, self.shell, self.cluster.storage_nodes[0].get_rpc_endpoint())
|
||||||
|
|
||||||
|
with reporter.step("Check get object from container on the first node, expected access denied error"):
|
||||||
|
with pytest.raises(RuntimeError, match=RULE_ACCESS_DENIED_OBJECT):
|
||||||
|
get_object(default_wallet, container, oid, self.shell, self.cluster.storage_nodes[0].get_rpc_endpoint())
|
||||||
|
|
||||||
|
with reporter.step("Check get object from container on the second node, expected allow"):
|
||||||
|
with expect_not_raises():
|
||||||
|
get_object(default_wallet, container, oid, self.shell, self.cluster.storage_nodes[1].get_rpc_endpoint())
|
||||||
|
|
||||||
|
with reporter.step("Delete a rule"):
|
||||||
|
frostfs_cli_on_first_node.control.remove_rule(
|
||||||
|
endpoint=self.cluster.storage_nodes[0].get_control_endpoint(),
|
||||||
|
target_type="container",
|
||||||
|
target_name=container,
|
||||||
|
chain_id="denyGetObject",
|
||||||
|
)
|
||||||
|
|
||||||
|
with reporter.step("Check get object in container on the first node, expected allow"):
|
||||||
|
with expect_not_raises():
|
||||||
|
get_object(default_wallet, container, oid, self.shell, self.cluster.storage_nodes[0].get_rpc_endpoint())
|
||||||
|
|
||||||
|
@allure.title("LocalOverride: Deny to PutObject in root tenant")
|
||||||
|
@pytest.mark.parametrize("container_request", [REP2], indirect=True)
|
||||||
|
def test_local_override_deny_to_put_object_root(
|
||||||
|
self,
|
||||||
|
default_wallet: WalletInfo,
|
||||||
|
frostfs_cli_on_first_node: FrostfsCli,
|
||||||
|
simple_object_size: ObjectSize,
|
||||||
|
container: str,
|
||||||
|
):
|
||||||
|
test_file = generate_file(simple_object_size.value)
|
||||||
|
|
||||||
|
with reporter.step("Create local override on first node"):
|
||||||
|
frostfs_cli_on_first_node.control.add_rule(
|
||||||
|
endpoint=self.cluster.storage_nodes[0].get_control_endpoint(),
|
||||||
|
target_type="container",
|
||||||
|
target_name=container,
|
||||||
|
chain_id="denyPutObject",
|
||||||
|
rule=f"deny Object.Put /{container}/*",
|
||||||
|
)
|
||||||
|
|
||||||
|
with reporter.step("Check put object from container on the first node, expected access denied error"):
|
||||||
|
with pytest.raises(RuntimeError, match=OBJECT_ACCESS_DENIED):
|
||||||
|
put_object(default_wallet, test_file, container, self.shell, self.cluster.storage_nodes[0].get_rpc_endpoint())
|
||||||
|
|
||||||
|
with reporter.step("Check put object from container on the second node, expected allow"):
|
||||||
|
with expect_not_raises():
|
||||||
|
put_object(
|
||||||
|
default_wallet, test_file, container, self.shell, self.cluster.storage_nodes[1].get_rpc_endpoint(), copies_number=3
|
||||||
|
)
|
||||||
|
|
||||||
|
with reporter.step("Delete a rule"):
|
||||||
|
frostfs_cli_on_first_node.control.remove_rule(
|
||||||
|
endpoint=self.cluster.storage_nodes[0].get_control_endpoint(),
|
||||||
|
target_type="container",
|
||||||
|
target_name=container,
|
||||||
|
chain_id="denyPutObject",
|
||||||
|
)
|
||||||
|
|
||||||
|
with reporter.step("Check get object in container on the first node, expected allow"):
|
||||||
|
with expect_not_raises():
|
||||||
|
put_object(default_wallet, test_file, container, self.shell, self.cluster.storage_nodes[0].get_rpc_endpoint())
|
||||||
|
|
||||||
|
@allure.title("LocalOverride: Deny to HeadObject in root tenant")
|
||||||
|
@pytest.mark.parametrize("container_request", [REP2], indirect=True)
|
||||||
|
def test_local_override_deny_to_head_object_root(
|
||||||
|
self,
|
||||||
|
default_wallet: WalletInfo,
|
||||||
|
frostfs_cli_on_first_node: FrostfsCli,
|
||||||
|
simple_object_size: ObjectSize,
|
||||||
|
container: str,
|
||||||
|
):
|
||||||
|
test_file = generate_file(simple_object_size.value)
|
||||||
|
|
||||||
|
with reporter.step("Create local override on first node"):
|
||||||
|
frostfs_cli_on_first_node.control.add_rule(
|
||||||
|
endpoint=self.cluster.storage_nodes[0].get_control_endpoint(),
|
||||||
|
target_type="container",
|
||||||
|
target_name=container,
|
||||||
|
chain_id="denyHeadObject",
|
||||||
|
rule=f"deny Object.Head /{container}/*",
|
||||||
|
)
|
||||||
|
|
||||||
|
with reporter.step("Put object in container on the first node"):
|
||||||
|
oid = put_object(default_wallet, test_file, container, self.shell, self.cluster.storage_nodes[0].get_rpc_endpoint())
|
||||||
|
|
||||||
|
with reporter.step("Check head object from container on the first node, expected access denied error"):
|
||||||
|
with pytest.raises(RuntimeError, match=RULE_ACCESS_DENIED_OBJECT):
|
||||||
|
head_object(default_wallet, container, oid, self.shell, self.cluster.storage_nodes[0].get_rpc_endpoint())
|
||||||
|
|
||||||
|
with reporter.step("Check head object from container on the second node, expected allow"):
|
||||||
|
with expect_not_raises():
|
||||||
|
head_object(default_wallet, container, oid, self.shell, self.cluster.storage_nodes[1].get_rpc_endpoint())
|
||||||
|
|
||||||
|
with reporter.step("Delete a rule"):
|
||||||
|
frostfs_cli_on_first_node.control.remove_rule(
|
||||||
|
endpoint=self.cluster.storage_nodes[0].get_control_endpoint(),
|
||||||
|
target_type="container",
|
||||||
|
target_name=container,
|
||||||
|
chain_id="denyHeadObject",
|
||||||
|
)
|
||||||
|
|
||||||
|
with reporter.step("Check head object in container on the first node, expected allow"):
|
||||||
|
with expect_not_raises():
|
||||||
|
head_object(default_wallet, container, oid, self.shell, self.cluster.storage_nodes[0].get_rpc_endpoint())
|
||||||
|
|
||||||
|
@allure.title("LocalOverride: Deny to SearchObject in root tenant")
|
||||||
|
@pytest.mark.parametrize("container_request", [REP2], indirect=True)
|
||||||
|
def test_local_override_deny_to_search_object_root(
|
||||||
|
self,
|
||||||
|
default_wallet: WalletInfo,
|
||||||
|
frostfs_cli_on_first_node: FrostfsCli,
|
||||||
|
container: str,
|
||||||
|
):
|
||||||
|
with reporter.step("Create local override on first node"):
|
||||||
|
frostfs_cli_on_first_node.control.add_rule(
|
||||||
|
endpoint=self.cluster.storage_nodes[0].get_control_endpoint(),
|
||||||
|
target_type="container",
|
||||||
|
target_name=container,
|
||||||
|
chain_id="denySearchObject",
|
||||||
|
rule=f"deny Object.Search /{container}/*",
|
||||||
|
)
|
||||||
|
|
||||||
|
with reporter.step("Check search object from container on the first node, expected access denied error"):
|
||||||
|
with pytest.raises(RuntimeError, match=RULE_ACCESS_DENIED_OBJECT.format(operation=Operations.SEARCH_OBJECT)):
|
||||||
|
search_object(default_wallet, container, self.shell, self.cluster.storage_nodes[0].get_rpc_endpoint())
|
||||||
|
|
||||||
|
with reporter.step("Check search object from container on the second node, expected allow"):
|
||||||
|
with expect_not_raises():
|
||||||
|
search_object(default_wallet, container, self.shell, self.cluster.storage_nodes[1].get_rpc_endpoint())
|
||||||
|
|
||||||
|
with reporter.step("Delete a rule"):
|
||||||
|
frostfs_cli_on_first_node.control.remove_rule(
|
||||||
|
endpoint=self.cluster.storage_nodes[0].get_control_endpoint(),
|
||||||
|
target_type="container",
|
||||||
|
target_name=container,
|
||||||
|
chain_id="denySearchObject",
|
||||||
|
)
|
||||||
|
|
||||||
|
with reporter.step("Check search object in container on the first node, expected allow"):
|
||||||
|
with expect_not_raises():
|
||||||
|
search_object(default_wallet, container, self.shell, self.cluster.storage_nodes[0].get_rpc_endpoint())
|
||||||
|
|
||||||
|
@allure.title("LocalOverride: Deny to RangeObject in root tenant")
|
||||||
|
@pytest.mark.parametrize("container_request", [REP2], indirect=True)
|
||||||
|
def test_local_override_deny_to_range_object_root(
|
||||||
|
self,
|
||||||
|
default_wallet: WalletInfo,
|
||||||
|
frostfs_cli_on_first_node: FrostfsCli,
|
||||||
|
simple_object_size: ObjectSize,
|
||||||
|
container: str,
|
||||||
|
):
|
||||||
|
test_file = generate_file(simple_object_size.value)
|
||||||
|
|
||||||
|
with reporter.step("Create local override on first node"):
|
||||||
|
frostfs_cli_on_first_node.control.add_rule(
|
||||||
|
endpoint=self.cluster.storage_nodes[0].get_control_endpoint(),
|
||||||
|
target_type="container",
|
||||||
|
target_name=container,
|
||||||
|
chain_id="denyRangeObject",
|
||||||
|
rule=f"deny Object.Range /{container}/*",
|
||||||
|
)
|
||||||
|
|
||||||
|
with reporter.step("Put object in container on the first node"):
|
||||||
|
oid = put_object(default_wallet, test_file, container, self.shell, self.cluster.storage_nodes[0].get_rpc_endpoint())
|
||||||
|
|
||||||
|
with reporter.step("Check range object from container on the first node, expected access denied error"):
|
||||||
|
with pytest.raises(RuntimeError, match=RULE_ACCESS_DENIED_OBJECT.format(operation=Operations.RANGE_OBJECT)):
|
||||||
|
get_range(default_wallet, container, oid, "0:10", self.shell, self.cluster.storage_nodes[0].get_rpc_endpoint())
|
||||||
|
|
||||||
|
with reporter.step("Check get range object from container on the second node, expected allow"):
|
||||||
|
with expect_not_raises():
|
||||||
|
get_range(default_wallet, container, oid, "0:10", self.shell, self.cluster.storage_nodes[1].get_rpc_endpoint())
|
||||||
|
|
||||||
|
with reporter.step("Delete a rule"):
|
||||||
|
frostfs_cli_on_first_node.control.remove_rule(
|
||||||
|
endpoint=self.cluster.storage_nodes[0].get_control_endpoint(),
|
||||||
|
target_type="container",
|
||||||
|
target_name=container,
|
||||||
|
chain_id="denyRangeObject",
|
||||||
|
)
|
||||||
|
|
||||||
|
with reporter.step("Check get range object in container on the first node, expected allow"):
|
||||||
|
with expect_not_raises():
|
||||||
|
get_range(default_wallet, container, oid, "0:10", self.shell, self.cluster.storage_nodes[0].get_rpc_endpoint())
|
||||||
|
|
||||||
|
@allure.title("LocalOverride: Deny to HashObject in root tenant")
|
||||||
|
@pytest.mark.parametrize("container_request", [REP2], indirect=True)
|
||||||
|
def test_local_override_deny_to_hash_object_root(
|
||||||
|
self,
|
||||||
|
default_wallet: WalletInfo,
|
||||||
|
frostfs_cli_on_first_node: FrostfsCli,
|
||||||
|
simple_object_size: ObjectSize,
|
||||||
|
container: str,
|
||||||
|
):
|
||||||
|
test_file = generate_file(simple_object_size.value)
|
||||||
|
|
||||||
|
with reporter.step("Create local override on first node"):
|
||||||
|
frostfs_cli_on_first_node.control.add_rule(
|
||||||
|
endpoint=self.cluster.storage_nodes[0].get_control_endpoint(),
|
||||||
|
target_type="container",
|
||||||
|
target_name=container,
|
||||||
|
chain_id="denyHashObject",
|
||||||
|
rule=f"deny Object.Hash /{container}/*",
|
||||||
|
)
|
||||||
|
|
||||||
|
with reporter.step("Put object in container on the first node"):
|
||||||
|
oid = put_object(default_wallet, test_file, container, self.shell, self.cluster.storage_nodes[0].get_rpc_endpoint())
|
||||||
|
|
||||||
|
with reporter.step("Check get range hash object from container on the first node, expected access denied error"):
|
||||||
|
with pytest.raises(RuntimeError, match=RULE_ACCESS_DENIED_OBJECT.format(operation=Operations.HASH_OBJECT)):
|
||||||
|
get_range_hash(default_wallet, container, oid, "0:10", self.shell, self.cluster.storage_nodes[0].get_rpc_endpoint())
|
||||||
|
|
||||||
|
with reporter.step("Check get range hash object from container on the second node, expected allow"):
|
||||||
|
with expect_not_raises():
|
||||||
|
get_range_hash(default_wallet, container, oid, "0:10", self.shell, self.cluster.storage_nodes[1].get_rpc_endpoint())
|
||||||
|
|
||||||
|
with reporter.step("Delete a rule"):
|
||||||
|
frostfs_cli_on_first_node.control.remove_rule(
|
||||||
|
endpoint=self.cluster.storage_nodes[0].get_control_endpoint(),
|
||||||
|
target_type="container",
|
||||||
|
target_name=container,
|
||||||
|
chain_id="denyHashObject",
|
||||||
|
)
|
||||||
|
|
||||||
|
with reporter.step("Check get range hash object in container on the first node, expected allow"):
|
||||||
|
with expect_not_raises():
|
||||||
|
get_range_hash(default_wallet, container, oid, "0:10", self.shell, self.cluster.storage_nodes[0].get_rpc_endpoint())
|
||||||
|
|
||||||
|
@allure.title("LocalOverride: Deny to DeleteObject in root tenant")
|
||||||
|
@pytest.mark.parametrize("container_request", [REP2], indirect=True)
|
||||||
|
def test_local_override_deny_to_delete_object_root(
|
||||||
|
self,
|
||||||
|
default_wallet: WalletInfo,
|
||||||
|
frostfs_cli_on_first_node: FrostfsCli,
|
||||||
|
simple_object_size: ObjectSize,
|
||||||
|
container: str,
|
||||||
|
):
|
||||||
|
test_file = generate_file(simple_object_size.value)
|
||||||
|
|
||||||
|
with reporter.step("Create local override on first node"):
|
||||||
|
frostfs_cli_on_first_node.control.add_rule(
|
||||||
|
endpoint=self.cluster.storage_nodes[0].get_control_endpoint(),
|
||||||
|
target_type="container",
|
||||||
|
target_name=container,
|
||||||
|
chain_id="denyDeleteObject",
|
||||||
|
rule=f"deny Object.Delete /{container}/*",
|
||||||
|
)
|
||||||
|
|
||||||
|
with reporter.step("Put objects in container on the first node"):
|
||||||
|
oid_1 = put_object(default_wallet, test_file, container, self.shell, self.cluster.storage_nodes[0].get_rpc_endpoint())
|
||||||
|
oid_2 = put_object(default_wallet, test_file, container, self.shell, self.cluster.storage_nodes[0].get_rpc_endpoint())
|
||||||
|
|
||||||
|
with reporter.step("Search object in container on the first node"):
|
||||||
|
search_object_in_container_1 = search_object(
|
||||||
|
default_wallet, container, self.shell, self.cluster.storage_nodes[0].get_rpc_endpoint()
|
||||||
|
)
|
||||||
|
assert oid_1 in search_object_in_container_1, f"Object {oid_1} was not found"
|
||||||
|
assert oid_2 in search_object_in_container_1, f"Object {oid_2} was not found"
|
||||||
|
|
||||||
|
with reporter.step("Search object from container on the second node"):
|
||||||
|
search_object_in_container_2 = search_object(
|
||||||
|
default_wallet, container, self.shell, self.cluster.storage_nodes[1].get_rpc_endpoint()
|
||||||
|
)
|
||||||
|
assert oid_1 in search_object_in_container_2, f"Object {oid_1} was not found"
|
||||||
|
assert oid_2 in search_object_in_container_2, f"Object {oid_2} was not found"
|
||||||
|
|
||||||
|
with reporter.step("Check delete object from container on the first node, expected access denied error"):
|
||||||
|
with pytest.raises(RuntimeError, match=RULE_ACCESS_DENIED_OBJECT):
|
||||||
|
delete_object(default_wallet, container, oid_1, self.shell, self.cluster.storage_nodes[0].get_rpc_endpoint())
|
||||||
|
|
||||||
|
with reporter.step("Check delete object from container on the second node, expected allow"):
|
||||||
|
with expect_not_raises():
|
||||||
|
delete_object(default_wallet, container, oid_2, self.shell, self.cluster.storage_nodes[1].get_rpc_endpoint())
|
||||||
|
|
||||||
|
with reporter.step("Delete a rule"):
|
||||||
|
frostfs_cli_on_first_node.control.remove_rule(
|
||||||
|
endpoint=self.cluster.storage_nodes[0].get_control_endpoint(),
|
||||||
|
target_type="container",
|
||||||
|
target_name=container,
|
||||||
|
chain_id="denyDeleteObject",
|
||||||
|
)
|
||||||
|
|
||||||
|
with reporter.step("Check delete object in container on the first node, expected allow"):
|
||||||
|
with expect_not_raises():
|
||||||
|
delete_object(default_wallet, container, oid_1, self.shell, self.cluster.storage_nodes[0].get_rpc_endpoint())
|
|
@ -34,8 +34,8 @@ from frostfs_testlib.testing.test_control import cached_fixture, run_optionally,
|
||||||
from frostfs_testlib.utils import env_utils, string_utils, version_utils
|
from frostfs_testlib.utils import env_utils, string_utils, version_utils
|
||||||
from frostfs_testlib.utils.file_utils import TestFile, generate_file
|
from frostfs_testlib.utils.file_utils import TestFile, generate_file
|
||||||
|
|
||||||
from ..helpers.container_creation import create_container_with_ape
|
from ..helpers.container_creation import create_container_with_ape, create_containers_with_ape
|
||||||
from ..helpers.container_request import EVERYONE_ALLOW_ALL, ContainerRequest
|
from ..helpers.container_request import EVERYONE_ALLOW_ALL, ContainerRequest, MultipleContainersRequest
|
||||||
from ..resources.common import TEST_CYCLES_COUNT
|
from ..resources.common import TEST_CYCLES_COUNT
|
||||||
|
|
||||||
logger = logging.getLogger("NeoLogger")
|
logger = logging.getLogger("NeoLogger")
|
||||||
|
@ -511,6 +511,17 @@ def container_request(request: pytest.FixtureRequest) -> ContainerRequest:
|
||||||
return container_request
|
return container_request
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="session")
|
||||||
|
def multiple_containers_request(request: pytest.FixtureRequest) -> ContainerRequest:
|
||||||
|
if "param" in request.__dict__:
|
||||||
|
return request.param
|
||||||
|
|
||||||
|
raise RuntimeError(
|
||||||
|
f"""Container specification is empty.
|
||||||
|
Add @pytest.mark.parametrize("container_requests", [[ContainerRequest(...), ..., ContainerRequest(...)]], indirect=True) decorator."""
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def container(
|
def container(
|
||||||
default_wallet: WalletInfo,
|
default_wallet: WalletInfo,
|
||||||
|
@ -520,7 +531,19 @@ def container(
|
||||||
rpc_endpoint: str,
|
rpc_endpoint: str,
|
||||||
container_request: ContainerRequest,
|
container_request: ContainerRequest,
|
||||||
) -> str:
|
) -> str:
|
||||||
return create_container_with_ape(frostfs_cli, default_wallet, client_shell, cluster, rpc_endpoint, container_request)
|
return create_container_with_ape(container_request, frostfs_cli, default_wallet, client_shell, cluster, rpc_endpoint)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def containers(
|
||||||
|
default_wallet: WalletInfo,
|
||||||
|
frostfs_cli: FrostfsCli,
|
||||||
|
client_shell: Shell,
|
||||||
|
cluster: Cluster,
|
||||||
|
rpc_endpoint: str,
|
||||||
|
multiple_containers_request: MultipleContainersRequest,
|
||||||
|
) -> list[str]:
|
||||||
|
return create_containers_with_ape(frostfs_cli, default_wallet, client_shell, cluster, rpc_endpoint, multiple_containers_request)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
@pytest.fixture()
|
||||||
|
|
|
@ -37,7 +37,6 @@ class TestContainer(ClusterTestBase):
|
||||||
container_info = container_info.casefold() # To ignore case when comparing with expected values
|
container_info = container_info.casefold() # To ignore case when comparing with expected values
|
||||||
|
|
||||||
info_to_check = {
|
info_to_check = {
|
||||||
f"basic ACL: {PRIVATE_ACL_F} (private)",
|
|
||||||
f"owner ID: {wallet.get_address_from_json(0)}",
|
f"owner ID: {wallet.get_address_from_json(0)}",
|
||||||
f"CID: {cid}",
|
f"CID: {cid}",
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,7 +72,7 @@ class TestPolicyWithPrice(ClusterTestBase):
|
||||||
# In these set of tests containers should be created after the fill_field_price fixture
|
# In these set of tests containers should be created after the fill_field_price fixture
|
||||||
fill_field_price,
|
fill_field_price,
|
||||||
) -> str:
|
) -> str:
|
||||||
return create_container_with_ape(frostfs_cli, default_wallet, client_shell, cluster, rpc_endpoint, container_request)
|
return create_container_with_ape(container_request, frostfs_cli, default_wallet, client_shell, cluster, rpc_endpoint)
|
||||||
|
|
||||||
@allure.title("Policy with SELECT and FILTER results with 25% of available nodes")
|
@allure.title("Policy with SELECT and FILTER results with 25% of available nodes")
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
|
|
|
@ -103,7 +103,7 @@ def common_container(
|
||||||
rpc_endpoint: str,
|
rpc_endpoint: str,
|
||||||
) -> str:
|
) -> str:
|
||||||
container_request = ContainerRequest(COMMON_CONTAINER_RULE, APE_EVERYONE_ALLOW_ALL)
|
container_request = ContainerRequest(COMMON_CONTAINER_RULE, APE_EVERYONE_ALLOW_ALL)
|
||||||
return create_container_with_ape(frostfs_cli, default_wallet, client_shell, cluster, rpc_endpoint, container_request)
|
return create_container_with_ape(container_request, frostfs_cli, default_wallet, client_shell, cluster, rpc_endpoint)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="module")
|
@pytest.fixture(scope="module")
|
||||||
|
@ -131,7 +131,7 @@ def storage_objects(
|
||||||
rpc_endpoint: str,
|
rpc_endpoint: str,
|
||||||
) -> list[StorageObjectInfo]:
|
) -> list[StorageObjectInfo]:
|
||||||
cid = create_container_with_ape(
|
cid = create_container_with_ape(
|
||||||
frostfs_cli, default_wallet, client_shell, cluster, rpc_endpoint, ContainerRequest(placement_policy.value, APE_EVERYONE_ALLOW_ALL)
|
ContainerRequest(placement_policy.value, APE_EVERYONE_ALLOW_ALL), frostfs_cli, default_wallet, client_shell, cluster, rpc_endpoint
|
||||||
)
|
)
|
||||||
|
|
||||||
with reporter.step("Generate file"):
|
with reporter.step("Generate file"):
|
||||||
|
|
|
@ -32,7 +32,7 @@ def user_container(
|
||||||
) -> StorageContainer:
|
) -> StorageContainer:
|
||||||
policy = request.param if "param" in request.__dict__ else SINGLE_PLACEMENT_RULE
|
policy = request.param if "param" in request.__dict__ else SINGLE_PLACEMENT_RULE
|
||||||
container_request = ContainerRequest(policy)
|
container_request = ContainerRequest(policy)
|
||||||
container_id = create_container_with_ape(frostfs_cli, default_wallet, client_shell, cluster, rpc_endpoint, container_request)
|
container_id = create_container_with_ape(container_request, frostfs_cli, default_wallet, client_shell, cluster, rpc_endpoint)
|
||||||
|
|
||||||
# Deliberately using s3gate wallet here to test bearer token
|
# Deliberately using s3gate wallet here to test bearer token
|
||||||
s3_gate_wallet = WalletInfo.from_node(cluster.s3_gates[0])
|
s3_gate_wallet = WalletInfo.from_node(cluster.s3_gates[0])
|
||||||
|
|
|
@ -43,7 +43,7 @@ FIXTURE_OBJECT_LIFETIME = 10
|
||||||
def user_container(
|
def user_container(
|
||||||
frostfs_cli: FrostfsCli, default_wallet: WalletInfo, client_shell: Shell, cluster: Cluster, rpc_endpoint: str
|
frostfs_cli: FrostfsCli, default_wallet: WalletInfo, client_shell: Shell, cluster: Cluster, rpc_endpoint: str
|
||||||
) -> StorageContainer:
|
) -> StorageContainer:
|
||||||
cid = create_container_with_ape(frostfs_cli, default_wallet, client_shell, cluster, rpc_endpoint, EVERYONE_ALLOW_ALL)
|
cid = create_container_with_ape(EVERYONE_ALLOW_ALL, frostfs_cli, default_wallet, client_shell, cluster, rpc_endpoint)
|
||||||
return StorageContainer(StorageContainerInfo(cid, default_wallet), client_shell, cluster)
|
return StorageContainer(StorageContainerInfo(cid, default_wallet), client_shell, cluster)
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue