[#376] Added ape manager group command to grpc client
All checks were successful
DCO action / DCO (pull_request) Successful in 31s

Signed-off-by: Dmitriy Zayakin
Signed-off-by: Dmitriy Zayakin <d.zayakin@yadro.com>
This commit is contained in:
Dmitriy Zayakin 2025-04-29 10:43:02 +03:00
parent 9ad620121e
commit 3dcf494e97
9 changed files with 150 additions and 0 deletions

View file

@ -29,6 +29,7 @@ class FrostfsCli:
util: FrostfsCliUtil util: FrostfsCliUtil
version: FrostfsCliVersion version: FrostfsCliVersion
control: FrostfsCliControl control: FrostfsCliControl
ape_manager: FrostfsCliApeManager
def __init__(self, shell: Shell, frostfs_cli_exec_path: str, config_file: Optional[str] = None): def __init__(self, shell: Shell, frostfs_cli_exec_path: str, config_file: Optional[str] = None):
self.accounting = FrostfsCliAccounting(shell, frostfs_cli_exec_path, config=config_file) self.accounting = FrostfsCliAccounting(shell, frostfs_cli_exec_path, config=config_file)

View file

@ -8,6 +8,7 @@ class CliClientWrapper(interfaces_wrapper.GrpcClientWrapper):
self.object: interfaces.ObjectInterface = implementations.ObjectOperations(self.cli) self.object: interfaces.ObjectInterface = implementations.ObjectOperations(self.cli)
self.container: interfaces.ContainerInterface = implementations.ContainerOperations(self.cli) self.container: interfaces.ContainerInterface = implementations.ContainerOperations(self.cli)
self.netmap: interfaces.NetmapInterface = implementations.NetmapOperations(self.cli) self.netmap: interfaces.NetmapInterface = implementations.NetmapOperations(self.cli)
self.ape_manager: interfaces.ApeManagerInterface = implementations.ApeManagerOperations(self.cli)
class RpcClientWrapper(interfaces_wrapper.GrpcClientWrapper): class RpcClientWrapper(interfaces_wrapper.GrpcClientWrapper):

View file

@ -1,3 +1,4 @@
from .ape_manager import ApeManagerOperations
from .chunks import ChunksOperations from .chunks import ChunksOperations
from .container import ContainerOperations from .container import ContainerOperations
from .netmap import NetmapOperations from .netmap import NetmapOperations

View file

@ -0,0 +1,79 @@
from typing import Optional
from frostfs_testlib import reporter
from frostfs_testlib.cli.frostfs_cli.cli import FrostfsCli
from frostfs_testlib.resources.cli import CLI_DEFAULT_TIMEOUT
class ApeManagerOperations:
def __init__(self, cli: FrostfsCli):
self.cli = cli
@reporter.step("Add ape rule")
def add(
self,
rpc_endpoint: str,
chain_id: Optional[str] = None,
chain_id_hex: Optional[str] = None,
path: Optional[str] = None,
rule: Optional[str] | Optional[list[str]] = None,
target_name: Optional[str] = None,
target_type: Optional[str] = None,
wallet: Optional[str] = None,
address: Optional[str] = None,
timeout: Optional[str] = CLI_DEFAULT_TIMEOUT,
):
return self.cli.ape_manager.add(
rpc_endpoint=rpc_endpoint,
chain_id=chain_id,
chain_id_hex=chain_id_hex,
path=path,
rule=rule,
target_name=target_name,
target_type=target_type,
wallet=wallet,
address=address,
timeout=timeout,
)
@reporter.step("Get list APE rules")
def list(
self,
rpc_endpoint: str,
target_name: Optional[str] = None,
target_type: Optional[str] = None,
wallet: Optional[str] = None,
address: Optional[str] = None,
timeout: Optional[str] = CLI_DEFAULT_TIMEOUT,
):
return self.cli.ape_manager.list(
rpc_endpoint=rpc_endpoint,
target_name=target_name,
target_type=target_type,
wallet=wallet,
address=address,
timeout=timeout,
)
@reporter.step("Remove APE rule")
def remove(
self,
rpc_endpoint: str,
chain_id: Optional[str] = None,
chain_id_hex: Optional[str] = None,
target_name: Optional[str] = None,
target_type: Optional[str] = None,
wallet: Optional[str] = None,
address: Optional[str] = None,
timeout: Optional[str] = CLI_DEFAULT_TIMEOUT,
):
return self.cli.ape_manager.remove(
rpc_endpoint=rpc_endpoint,
chain_id=chain_id,
chain_id_hex=chain_id_hex,
target_name=target_name,
target_type=target_type,
wallet=wallet,
address=address,
timeout=timeout,
)

View file

@ -1,6 +1,7 @@
import json import json
import logging import logging
import re import re
from time import sleep
from typing import List, Optional, Union from typing import List, Optional, Union
from frostfs_testlib import reporter from frostfs_testlib import reporter
@ -301,6 +302,16 @@ class ContainerOperations(interfaces.ContainerInterface):
resolver: BucketContainerResolver = resolver_cls() resolver: BucketContainerResolver = resolver_cls()
return resolver.resolve(node, name) return resolver.resolve(node, name)
@reporter.step("Wait create container, with list")
def wait_creation(self, cid: str, endpoint: str, attempts: int = 15, sleep_interval: int = 1):
for _ in range(attempts):
containers = self.list(endpoint)
if cid in containers:
return
logger.info(f"There is no {cid} in {containers} yet; sleep {sleep_interval} and continue")
sleep(sleep_interval)
raise RuntimeError(f"After {attempts * sleep_interval} seconds container {cid} hasn't been persisted; exiting")
def _parse_cid(self, output: str) -> str: def _parse_cid(self, output: str) -> str:
""" """
Parses container ID from a given CLI output. The input string we expect: Parses container ID from a given CLI output. The input string we expect:

View file

@ -1,3 +1,4 @@
from .ape_manager import ApeManagerInterface
from .chunks import ChunksInterface from .chunks import ChunksInterface
from .container import ContainerInterface from .container import ContainerInterface
from .netmap import NetmapInterface from .netmap import NetmapInterface

View file

@ -0,0 +1,48 @@
from abc import ABC, abstractmethod
from typing import Optional
from frostfs_testlib.shell.interfaces import CommandResult
class ApeManagerInterface(ABC):
@abstractmethod
def add(
self,
rpc_endpoint: str,
chain_id: Optional[str] = None,
chain_id_hex: Optional[str] = None,
path: Optional[str] = None,
rule: Optional[str] | Optional[list[str]] = None,
target_name: Optional[str] = None,
target_type: Optional[str] = None,
wallet: Optional[str] = None,
address: Optional[str] = None,
timeout: Optional[str] = None,
) -> CommandResult:
pass
@abstractmethod
def list(
self,
rpc_endpoint: str,
target_name: Optional[str] = None,
target_type: Optional[str] = None,
wallet: Optional[str] = None,
address: Optional[str] = None,
timeout: Optional[str] = None,
) -> CommandResult:
pass
@abstractmethod
def remove(
self,
rpc_endpoint: str,
chain_id: Optional[str] = None,
chain_id_hex: Optional[str] = None,
target_name: Optional[str] = None,
target_type: Optional[str] = None,
wallet: Optional[str] = None,
address: Optional[str] = None,
timeout: Optional[str] = None,
) -> CommandResult:
pass

View file

@ -123,3 +123,7 @@ class ContainerInterface(ABC):
) -> List[ClusterNode]: ) -> List[ClusterNode]:
"""Show the nodes participating in the container in the current epoch.""" """Show the nodes participating in the container in the current epoch."""
raise NotImplementedError("No implemethed method nodes") raise NotImplementedError("No implemethed method nodes")
@abstractmethod
def wait_creation(self, cid: str, endpoint: str, attempts: Optional[str], sleep_interval: Optional[int]) -> None:
raise NotImplementedError("No implemented method wait_creation")

View file

@ -1,10 +1,14 @@
from abc import ABC from abc import ABC
from frostfs_testlib.cli.frostfs_cli.cli import FrostfsCli
from . import interfaces from . import interfaces
class GrpcClientWrapper(ABC): class GrpcClientWrapper(ABC):
def __init__(self) -> None: def __init__(self) -> None:
self.cli: FrostfsCli
self.object: interfaces.ObjectInterface self.object: interfaces.ObjectInterface
self.container: interfaces.ContainerInterface self.container: interfaces.ContainerInterface
self.netmap: interfaces.NetmapInterface self.netmap: interfaces.NetmapInterface
self.ape_manager: interfaces.ApeManagerInterface