Implemented neofs-adm lib
Signed-off-by: Vladimir Avdeev <v.avdeev@yadro.com>
This commit is contained in:
parent
b6a451dc8d
commit
f40111dc4a
24 changed files with 662 additions and 28 deletions
|
@ -6,15 +6,15 @@ from datetime import datetime
|
|||
|
||||
import allure
|
||||
import pytest
|
||||
from robot.api import deco
|
||||
|
||||
import wallet
|
||||
from cli_helpers import _cmd_run
|
||||
from cli_utils import NeofsAdm, NeofsCli
|
||||
from common import (ASSETS_DIR, FREE_STORAGE, INFRASTRUCTURE_TYPE, MAINNET_WALLET_PATH,
|
||||
NEOFS_NETMAP_DICT)
|
||||
from env_properties import save_env_properties
|
||||
from payment_neogo import neofs_deposit, transfer_mainnet_gas
|
||||
from python_keywords.node_management import node_healthcheck
|
||||
from robot.api import deco
|
||||
from service_helper import get_storage_service_helper
|
||||
|
||||
|
||||
|
@ -38,9 +38,15 @@ def cloud_infrastructure_check():
|
|||
@allure.title('Check binary versions')
|
||||
def check_binary_versions(request):
|
||||
# Collect versions of local binaries
|
||||
binaries = ['neo-go', 'neofs-cli', 'neofs-authmate']
|
||||
binaries = ['neo-go', 'neofs-authmate']
|
||||
local_binaries = _get_binaries_version_local(binaries)
|
||||
|
||||
try:
|
||||
local_binaries['neofs-adm'] = NeofsAdm().version.get()
|
||||
except RuntimeError:
|
||||
logger.info(f'neofs-adm not installed')
|
||||
local_binaries['neofs-cli'] = NeofsCli().version.get()
|
||||
|
||||
# Collect versions of remote binaries
|
||||
helper = get_storage_service_helper()
|
||||
remote_binaries = helper.get_binaries_version()
|
||||
|
|
|
@ -10,8 +10,8 @@ from typing import Any, Dict, List, Optional, Union
|
|||
|
||||
import allure
|
||||
import base58
|
||||
from cli import NeofsCli
|
||||
from cli_helpers import _cmd_run
|
||||
from cli_utils import NeofsCli
|
||||
from common import ASSETS_DIR, NEOFS_CLI_EXEC, NEOFS_ENDPOINT, WALLET_CONFIG
|
||||
from data_formatters import get_wallet_public_key
|
||||
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
from .adm import CompletionType, NeofsAdm
|
||||
from .cli import NeofsCli
|
|
@ -0,0 +1,2 @@
|
|||
from .adm import NeofsAdm
|
||||
from .completion_type import CompletionType
|
36
robot/resources/lib/python_keywords/cli_utils/adm/adm.py
Normal file
36
robot/resources/lib/python_keywords/cli_utils/adm/adm.py
Normal file
|
@ -0,0 +1,36 @@
|
|||
from typing import Optional
|
||||
|
||||
from common import NEOFS_ADM_EXEC
|
||||
|
||||
from .completion import NeofsAdmCompletion
|
||||
from .config import NeofsAdmConfig
|
||||
from .gendoc import NeofsAdmGenDoc
|
||||
from .morph import NeofsAdmMorph
|
||||
from .subnet import NeofsAdmMorphSubnet
|
||||
from .storage_config import NeofsAdmStorageConfig
|
||||
from .version import NeofsAdmVersion
|
||||
|
||||
|
||||
class NeofsAdm:
|
||||
neofs_adm_exec_path: Optional[str] = None
|
||||
config_file: Optional[str] = None
|
||||
|
||||
completion: Optional[NeofsAdmCompletion] = None
|
||||
config: Optional[NeofsAdmConfig] = None
|
||||
gendoc: Optional[NeofsAdmGenDoc] = None
|
||||
morph: Optional[NeofsAdmMorph] = None
|
||||
subnet: Optional[NeofsAdmMorphSubnet] = None
|
||||
storage_config: Optional[NeofsAdmStorageConfig] = None
|
||||
version: Optional[NeofsAdmVersion] = None
|
||||
|
||||
def __init__(self, neofs_adm_exec_path: Optional[str] = None, config_file: Optional[str] = None, timeout: int = 30):
|
||||
self.config_file = config_file
|
||||
self.neofs_adm_exec_path = neofs_adm_exec_path or NEOFS_ADM_EXEC
|
||||
|
||||
self.completion = NeofsAdmCompletion(self.neofs_adm_exec_path, timeout=timeout, config=config_file)
|
||||
self.config = NeofsAdmConfig(self.neofs_adm_exec_path, timeout=timeout, config=config_file)
|
||||
self.gendoc = NeofsAdmGenDoc(self.neofs_adm_exec_path, timeout=timeout, config=config_file)
|
||||
self.morph = NeofsAdmMorph(self.neofs_adm_exec_path, timeout=timeout, config=config_file)
|
||||
self.subnet = NeofsAdmMorphSubnet(self.neofs_adm_exec_path, timeout=timeout, config=config_file)
|
||||
self.storage_config = NeofsAdmStorageConfig(self.neofs_adm_exec_path, timeout=timeout, config=config_file)
|
||||
self.version = NeofsAdmVersion(self.neofs_adm_exec_path, timeout=timeout, config=config_file)
|
|
@ -0,0 +1,30 @@
|
|||
from cli_utils.cli_command import NeofsCliCommand
|
||||
|
||||
from .completion_type import CompletionType
|
||||
|
||||
|
||||
class NeofsAdmCompletion(NeofsCliCommand):
|
||||
def get(self, completion_type: CompletionType = CompletionType.FISH) -> str:
|
||||
"""To load completions:
|
||||
Bash:
|
||||
$ source <(neofs-adm completion bash)
|
||||
|
||||
Zsh:
|
||||
If shell completion is not already enabled in your environment you will need
|
||||
to enable it. You can execute the following once:
|
||||
$ echo "autoload -U compinit; compinit" >> ~/.zshrc
|
||||
|
||||
You will need to start a new shell for this setup to take effect.
|
||||
|
||||
Fish:
|
||||
$ neofs-adm completion fish | source
|
||||
|
||||
Args:
|
||||
completion_type (CompletionType): Select completion type (default: Fish)
|
||||
|
||||
|
||||
Returns:
|
||||
str: Command string
|
||||
|
||||
"""
|
||||
return self._execute('completion ' + completion_type.value)
|
|
@ -0,0 +1,8 @@
|
|||
from enum import Enum
|
||||
|
||||
|
||||
class CompletionType(Enum):
|
||||
BASH = 'bash'
|
||||
ZHS = 'zsh'
|
||||
FISH = 'fish'
|
||||
POWERSHELL = 'powershell'
|
19
robot/resources/lib/python_keywords/cli_utils/adm/config.py
Normal file
19
robot/resources/lib/python_keywords/cli_utils/adm/config.py
Normal file
|
@ -0,0 +1,19 @@
|
|||
from cli_utils.cli_command import NeofsCliCommand
|
||||
|
||||
|
||||
class NeofsAdmConfig(NeofsCliCommand):
|
||||
def init(self, path: str = '~/.neofs/adm/config.yml') -> str:
|
||||
"""Initialize basic neofs-adm configuration file.
|
||||
|
||||
Args:
|
||||
path (str): path to config (default ~/.neofs/adm/config.yml)
|
||||
|
||||
|
||||
Returns:
|
||||
str: Command string
|
||||
|
||||
"""
|
||||
return self._execute(
|
||||
'config init',
|
||||
**{param: param_value for param, param_value in locals().items() if param not in ['self']}
|
||||
)
|
34
robot/resources/lib/python_keywords/cli_utils/adm/gendoc.py
Normal file
34
robot/resources/lib/python_keywords/cli_utils/adm/gendoc.py
Normal file
|
@ -0,0 +1,34 @@
|
|||
from typing import Optional
|
||||
|
||||
from cli_utils.cli_command import NeofsCliCommand
|
||||
|
||||
|
||||
class NeofsAdmGenDoc(NeofsCliCommand):
|
||||
def get(self, doc_file: str, depth: int = 1, doc_type: str = 'md', extension: Optional[str] = None) -> str:
|
||||
"""Generate documentation for this command. If the template is not provided,
|
||||
builtin cobra generator is used and each subcommand is placed in
|
||||
a separate file in the same directory.
|
||||
|
||||
The last optional argument specifies the template to use with text/template.
|
||||
In this case there is a number of helper functions which can be used:
|
||||
replace STR FROM TO -- same as strings.ReplaceAll
|
||||
join ARRAY SEPARATOR -- same as strings.Join
|
||||
split STR SEPARATOR -- same as strings.Split
|
||||
fullUse CMD -- slice of all command names starting from the parent
|
||||
listFlags CMD -- list of command flags
|
||||
|
||||
Args:
|
||||
depth (int): if template is specified, unify all commands starting from depth in a single file.
|
||||
Default = 1.
|
||||
doc_file (str): file where to save generated documentation
|
||||
extension (str): if the template is specified, string to append to the output file names
|
||||
doc_type (str): type for the documentation ('md' or 'man') (default "md")
|
||||
|
||||
Returns:
|
||||
str: Command string
|
||||
|
||||
"""
|
||||
return self._execute(
|
||||
f'gendoc {doc_file}',
|
||||
**{param: param_value for param, param_value in locals().items() if param not in ['self', 'doc_file']}
|
||||
)
|
272
robot/resources/lib/python_keywords/cli_utils/adm/morph.py
Normal file
272
robot/resources/lib/python_keywords/cli_utils/adm/morph.py
Normal file
|
@ -0,0 +1,272 @@
|
|||
from typing import Optional
|
||||
|
||||
from cli_utils.cli_command import NeofsCliCommand
|
||||
|
||||
|
||||
class NeofsAdmMorph(NeofsCliCommand):
|
||||
def deposit_notary(self, rpc_endpoint: str, account: str, gas: str, storage_wallet: Optional[str] = None,
|
||||
till: Optional[str] = None) -> str:
|
||||
"""Deposit GAS for notary service.
|
||||
|
||||
Args:
|
||||
account (str): wallet account address
|
||||
gas (str): amount of GAS to deposit
|
||||
rpc_endpoint (str): N3 RPC node endpoint
|
||||
storage_wallet (str): path to storage node wallet
|
||||
till (str): notary deposit duration in blocks
|
||||
|
||||
|
||||
Returns:
|
||||
str: Command string
|
||||
|
||||
"""
|
||||
return self._execute(
|
||||
'morph deposit-notary',
|
||||
**{param: param_value for param, param_value in locals().items() if param not in ['self']}
|
||||
)
|
||||
|
||||
def dump_balances(self, rpc_endpoint: str, alphabet: Optional[str] = None, proxy: Optional[str] = None,
|
||||
script_hash: Optional[str] = None, storage: Optional[str] = None) -> str:
|
||||
"""Dump GAS balances
|
||||
|
||||
Args:
|
||||
alphabet (str): dump balances of alphabet contracts
|
||||
proxy (str): dump balances of the proxy contract
|
||||
rpc_endpoint (str): N3 RPC node endpoint
|
||||
script_hash (str): use script-hash format for addresses
|
||||
storage (str): dump balances of storage nodes from the current netmap
|
||||
|
||||
|
||||
Returns:
|
||||
str: Command string
|
||||
|
||||
"""
|
||||
return self._execute(
|
||||
'morph dump-balances',
|
||||
**{param: param_value for param, param_value in locals().items() if param not in ['self']}
|
||||
)
|
||||
|
||||
def dump_config(self, rpc_endpoint: str) -> str:
|
||||
"""Section for morph network configuration commands.
|
||||
|
||||
Args:
|
||||
rpc_endpoint (str): N3 RPC node endpoint
|
||||
|
||||
|
||||
Returns:
|
||||
str: Command string
|
||||
|
||||
"""
|
||||
return self._execute(
|
||||
'morph dump-config',
|
||||
**{param: param_value for param, param_value in locals().items() if param not in ['self']}
|
||||
)
|
||||
|
||||
def dump_containers(self, rpc_endpoint: str, cid: Optional[str] = None, container_contract: Optional[str] = None,
|
||||
dump: Optional[str] = None) -> str:
|
||||
"""Dump NeoFS containers to file.
|
||||
|
||||
Args:
|
||||
cid (str): containers to dump
|
||||
container_contract (str): container contract hash (for networks without NNS)
|
||||
dump (str): file where to save dumped containers
|
||||
rpc_endpoint (str): N3 RPC node endpoint
|
||||
|
||||
|
||||
Returns:
|
||||
str: Command string
|
||||
|
||||
"""
|
||||
return self._execute(
|
||||
'morph dump-containers',
|
||||
**{param: param_value for param, param_value in locals().items() if param not in ['self']}
|
||||
)
|
||||
|
||||
def dump_hashes(self, rpc_endpoint: str) -> str:
|
||||
"""Dump deployed contract hashes.
|
||||
|
||||
Args:
|
||||
rpc_endpoint (str): N3 RPC node endpoint
|
||||
|
||||
|
||||
Returns:
|
||||
str: Command string
|
||||
|
||||
"""
|
||||
return self._execute(
|
||||
'morph dump-hashes',
|
||||
**{param: param_value for param, param_value in locals().items() if param not in ['self']}
|
||||
)
|
||||
|
||||
def force_new_epoch(self, rpc_endpoint: Optional[str] = None, alphabet: Optional[str] = None) -> str:
|
||||
"""Create new NeoFS epoch event in the side chain
|
||||
|
||||
Args:
|
||||
alphabet (str): path to alphabet wallets dir
|
||||
rpc_endpoint (str): N3 RPC node endpoint
|
||||
|
||||
|
||||
Returns:
|
||||
str: Command string
|
||||
|
||||
"""
|
||||
return self._execute(
|
||||
'morph force-new-epoch',
|
||||
**{param: param_value for param, param_value in locals().items() if param not in ['self']}
|
||||
)
|
||||
|
||||
def generate_alphabet(self, rpc_endpoint: str, alphabet_wallets: str, size: int = 7) -> str:
|
||||
"""Generate alphabet wallets for consensus nodes of the morph network
|
||||
|
||||
Args:
|
||||
alphabet_wallets (str): path to alphabet wallets dir
|
||||
size (int): amount of alphabet wallets to generate (default 7)
|
||||
rpc_endpoint (str): N3 RPC node endpoint
|
||||
|
||||
|
||||
Returns:
|
||||
str: Command string
|
||||
|
||||
"""
|
||||
return self._execute(
|
||||
'morph generate-alphabet',
|
||||
**{param: param_value for param, param_value in locals().items() if param not in ['self']}
|
||||
)
|
||||
|
||||
def generate_storage_wallet(self, rpc_endpoint: str, alphabet_wallets: str, storage_wallet: str,
|
||||
initial_gas: Optional[str] = None) -> str:
|
||||
"""Generate storage node wallet for the morph network
|
||||
|
||||
Args:
|
||||
alphabet_wallets (str): path to alphabet wallets dir
|
||||
initial_gas (str): initial amount of GAS to transfer
|
||||
rpc_endpoint (str): N3 RPC node endpoint
|
||||
storage_wallet (str): path to new storage node wallet
|
||||
|
||||
|
||||
Returns:
|
||||
str: Command string
|
||||
|
||||
"""
|
||||
return self._execute(
|
||||
'morph generate-storage-wallet',
|
||||
**{param: param_value for param, param_value in locals().items() if param not in ['self']}
|
||||
)
|
||||
|
||||
def init(self, rpc_endpoint: str, alphabet_wallets: str, contracts: str, protocol: str,
|
||||
container_alias_fee: int = 500, container_fee: int = 1000, epoch_duration: int = 240,
|
||||
homomorphic_disabled: bool = False, local_dump: Optional[str] = None, max_object_size: int = 67108864
|
||||
) -> str:
|
||||
"""Section for morph network configuration commands.
|
||||
|
||||
Args:
|
||||
alphabet_wallets (str): path to alphabet wallets dir
|
||||
container_alias_fee (int): container alias fee (default 500)
|
||||
container_fee (int): container registration fee (default 1000)
|
||||
contracts (str): path to archive with compiled NeoFS contracts
|
||||
(default fetched from latest github release)
|
||||
epoch_duration (int): amount of side chain blocks in one NeoFS epoch (default 240)
|
||||
homomorphic_disabled: (bool): disable object homomorphic hashing
|
||||
local_dump (str): path to the blocks dump file
|
||||
max_object_size (int): max single object size in bytes (default 67108864)
|
||||
protocol (str): path to the consensus node configuration
|
||||
rpc_endpoint (str): N3 RPC node endpoint
|
||||
|
||||
|
||||
Returns:
|
||||
str: Command string
|
||||
|
||||
"""
|
||||
return self._execute(
|
||||
'morph init',
|
||||
**{param: param_value for param, param_value in locals().items() if param not in ['self']}
|
||||
)
|
||||
|
||||
def refill_gas(self, rpc_endpoint: str, alphabet_wallets: str, storage_wallet: str, gas: Optional[str] = None
|
||||
) -> str:
|
||||
"""Refill GAS of storage node's wallet in the morph network
|
||||
|
||||
Args:
|
||||
alphabet_wallets (str): path to alphabet wallets dir
|
||||
gas (str): additional amount of GAS to transfer
|
||||
rpc_endpoint (str): N3 RPC node endpoint
|
||||
storage_wallet (str): path to new storage node wallet
|
||||
|
||||
|
||||
Returns:
|
||||
str: Command string
|
||||
|
||||
"""
|
||||
return self._execute(
|
||||
'morph refill-gas',
|
||||
**{param: param_value for param, param_value in locals().items() if param not in ['self']}
|
||||
)
|
||||
|
||||
def restore_containers(self, rpc_endpoint: str, alphabet_wallets: str, cid: str, dump: str) -> str:
|
||||
"""Restore NeoFS containers from file.
|
||||
|
||||
Args:
|
||||
alphabet_wallets (str): path to alphabet wallets dir
|
||||
cid (str): containers to restore
|
||||
dump (str): file to restore containers from
|
||||
rpc_endpoint (str): N3 RPC node endpoint
|
||||
|
||||
|
||||
Returns:
|
||||
str: Command string
|
||||
|
||||
"""
|
||||
return self._execute(
|
||||
'morph restore-containers',
|
||||
**{param: param_value for param, param_value in locals().items() if param not in ['self']}
|
||||
)
|
||||
|
||||
def set_policy(self, rpc_endpoint: str, alphabet_wallets: str, exec_fee_factor: Optional[int] = None,
|
||||
storage_price: Optional[int] = None, fee_per_byte: Optional[int] = None) -> str:
|
||||
"""Set global policy values
|
||||
|
||||
Args:
|
||||
alphabet_wallets (str): path to alphabet wallets dir
|
||||
exec_fee_factor (int): ExecFeeFactor=<n1>
|
||||
storage_price (int): StoragePrice=<n2>
|
||||
fee_per_byte (int): FeePerByte=<n3>
|
||||
rpc_endpoint (str): N3 RPC node endpoint
|
||||
|
||||
|
||||
Returns:
|
||||
str: Command string
|
||||
|
||||
"""
|
||||
non_param_attribute = ''
|
||||
if exec_fee_factor:
|
||||
non_param_attribute += f'ExecFeeFactor={exec_fee_factor} '
|
||||
if storage_price:
|
||||
non_param_attribute += f'StoragePrice={storage_price} '
|
||||
if fee_per_byte:
|
||||
non_param_attribute += f'FeePerByte={fee_per_byte} '
|
||||
return self._execute(
|
||||
f'morph restore-containers {non_param_attribute}',
|
||||
**{param: param_value for param, param_value in locals().items() if param not in [
|
||||
'self', 'exec_fee_factor', 'storage_price', 'fee_per_byte'
|
||||
]}
|
||||
)
|
||||
|
||||
def update_contracts(self, rpc_endpoint: str, alphabet_wallets: str, contracts: Optional[str] = None
|
||||
) -> str:
|
||||
"""Update NeoFS contracts.
|
||||
|
||||
Args:
|
||||
alphabet_wallets (str): path to alphabet wallets dir
|
||||
contracts (str): path to archive with compiled NeoFS contracts
|
||||
(default fetched from latest github release)
|
||||
rpc_endpoint (str): N3 RPC node endpoint
|
||||
|
||||
|
||||
Returns:
|
||||
str: Command string
|
||||
|
||||
"""
|
||||
return self._execute(
|
||||
'morph update-contracts',
|
||||
**{param: param_value for param, param_value in locals().items() if param not in ['self']}
|
||||
)
|
|
@ -0,0 +1,20 @@
|
|||
from cli_utils.cli_command import NeofsCliCommand
|
||||
|
||||
|
||||
class NeofsAdmStorageConfig(NeofsCliCommand):
|
||||
def set(self, account: str, wallet: str) -> str:
|
||||
"""Initialize basic neofs-adm configuration file.
|
||||
|
||||
Args:
|
||||
account (str): wallet account
|
||||
wallet (str): path to wallet
|
||||
|
||||
|
||||
Returns:
|
||||
str: Command string
|
||||
|
||||
"""
|
||||
return self._execute(
|
||||
'storage-config',
|
||||
**{param: param_value for param, param_value in locals().items() if param not in ['self']}
|
||||
)
|
187
robot/resources/lib/python_keywords/cli_utils/adm/subnet.py
Normal file
187
robot/resources/lib/python_keywords/cli_utils/adm/subnet.py
Normal file
|
@ -0,0 +1,187 @@
|
|||
from typing import Optional
|
||||
|
||||
from cli_utils.cli_command import NeofsCliCommand
|
||||
|
||||
|
||||
class NeofsAdmMorphSubnet(NeofsCliCommand):
|
||||
def create(self, rpc_endpoint: str, address: str, wallet: str, notary: bool = False) -> str:
|
||||
"""Create NeoFS subnet.
|
||||
|
||||
Args:
|
||||
address (str): Address in the wallet, optional
|
||||
notary (bool): Flag to create subnet in notary environment
|
||||
rpc_endpoint (str): N3 RPC node endpoint
|
||||
wallet (str): Path to file with wallet
|
||||
|
||||
|
||||
Returns:
|
||||
str: Command string
|
||||
|
||||
"""
|
||||
return self._execute(
|
||||
'morph subnet create',
|
||||
**{param: param_value for param, param_value in locals().items() if param not in ['self']}
|
||||
)
|
||||
|
||||
def get(self, rpc_endpoint: str, subnet: str) -> str:
|
||||
"""Read information about the NeoFS subnet.
|
||||
|
||||
Args:
|
||||
rpc_endpoint (str): N3 RPC node endpoint
|
||||
subnet (str): ID of the subnet to read
|
||||
|
||||
|
||||
Returns:
|
||||
str: Command string
|
||||
|
||||
"""
|
||||
return self._execute(
|
||||
'morph subnet get',
|
||||
**{param: param_value for param, param_value in locals().items() if param not in ['self']}
|
||||
)
|
||||
|
||||
def remove(self, rpc_endpoint: str, wallet: str, subnet: str, address: Optional[str] = None) -> str:
|
||||
"""Remove NeoFS subnet.
|
||||
|
||||
Args:
|
||||
address (str): Address in the wallet, optional
|
||||
rpc_endpoint (str): N3 RPC node endpoint
|
||||
subnet (str): ID of the subnet to read
|
||||
wallet (str): Path to file with wallet
|
||||
|
||||
|
||||
Returns:
|
||||
str: Command string
|
||||
|
||||
"""
|
||||
return self._execute(
|
||||
'morph subnet remove',
|
||||
**{param: param_value for param, param_value in locals().items() if param not in ['self']}
|
||||
)
|
||||
|
||||
def admin_add(self, rpc_endpoint: str, wallet: str, admin: str, subnet: str, client: Optional[str] = None,
|
||||
group: Optional[str] = None, address: Optional[str] = None) -> str:
|
||||
"""Add admin to the NeoFS subnet.
|
||||
|
||||
Args:
|
||||
address (str): Address in the wallet, optional
|
||||
admin (str): Hex-encoded public key of the admin
|
||||
client (str): Add client admin instead of node one
|
||||
group (str): Client group ID in text format (needed with --client only)
|
||||
rpc_endpoint (str): N3 RPC node endpoint
|
||||
subnet (str): ID of the subnet to read
|
||||
wallet (str): Path to file with wallet
|
||||
|
||||
|
||||
Returns:
|
||||
str: Command string
|
||||
|
||||
"""
|
||||
return self._execute(
|
||||
'morph subnet admin add',
|
||||
**{param: param_value for param, param_value in locals().items() if param not in ['self']}
|
||||
)
|
||||
|
||||
def admin_remove(self, rpc_endpoint: str, wallet: str, admin: str, subnet: str, client: Optional[str] = None,
|
||||
address: Optional[str] = None) -> str:
|
||||
"""Remove admin of the NeoFS subnet.
|
||||
|
||||
Args:
|
||||
address (str): Address in the wallet, optional
|
||||
admin (str): Hex-encoded public key of the admin
|
||||
client (str): Remove client admin instead of node one
|
||||
rpc_endpoint (str): N3 RPC node endpoint
|
||||
subnet (str): ID of the subnet to read
|
||||
wallet (str): Path to file with wallet
|
||||
|
||||
|
||||
Returns:
|
||||
str: Command string
|
||||
|
||||
"""
|
||||
return self._execute(
|
||||
'morph subnet admin remove',
|
||||
**{param: param_value for param, param_value in locals().items() if param not in ['self']}
|
||||
)
|
||||
|
||||
def client_add(self, rpc_endpoint: str, wallet: str, subnet: str, client: Optional[str] = None,
|
||||
group: Optional[str] = None, address: Optional[str] = None) -> str:
|
||||
"""Add client to the NeoFS subnet.
|
||||
|
||||
Args:
|
||||
address (str): Address in the wallet, optional
|
||||
client (str): Add client admin instead of node one
|
||||
group (str): Client group ID in text format (needed with --client only)
|
||||
rpc_endpoint (str): N3 RPC node endpoint
|
||||
subnet (str): ID of the subnet to read
|
||||
wallet (str): Path to file with wallet
|
||||
|
||||
|
||||
Returns:
|
||||
str: Command string
|
||||
|
||||
"""
|
||||
return self._execute(
|
||||
'morph subnet client add',
|
||||
**{param: param_value for param, param_value in locals().items() if param not in ['self']}
|
||||
)
|
||||
|
||||
def client_remove(self, rpc_endpoint: str, wallet: str, client: str, group: str, subnet: str,
|
||||
address: Optional[str] = None) -> str:
|
||||
"""Remove client of the NeoFS subnet.
|
||||
|
||||
Args:
|
||||
address (str): Address in the wallet, optional
|
||||
client (str): Remove client admin instead of node one
|
||||
group (str): ID of the client group to work with
|
||||
rpc_endpoint (str): N3 RPC node endpoint
|
||||
subnet (str): ID of the subnet to read
|
||||
wallet (str): Path to file with wallet
|
||||
|
||||
|
||||
Returns:
|
||||
str: Command string
|
||||
|
||||
"""
|
||||
return self._execute(
|
||||
'morph subnet client remove',
|
||||
**{param: param_value for param, param_value in locals().items() if param not in ['self']}
|
||||
)
|
||||
|
||||
def node_add(self, rpc_endpoint: str, wallet: str, node: str, subnet: str) -> str:
|
||||
"""Add node to the NeoFS subnet.
|
||||
|
||||
Args:
|
||||
node (str): Hex-encoded public key of the node
|
||||
rpc_endpoint (str): N3 RPC node endpoint
|
||||
subnet (str): ID of the subnet to read
|
||||
wallet (str): Path to file with wallet
|
||||
|
||||
|
||||
Returns:
|
||||
str: Command string
|
||||
|
||||
"""
|
||||
return self._execute(
|
||||
'morph subnet node add',
|
||||
**{param: param_value for param, param_value in locals().items() if param not in ['self']}
|
||||
)
|
||||
|
||||
def node_remove(self, rpc_endpoint: str, wallet: str, node: str, subnet: str) -> str:
|
||||
"""Remove node from the NeoFS subnet.
|
||||
|
||||
Args:
|
||||
node (str): Hex-encoded public key of the node
|
||||
rpc_endpoint (str): N3 RPC node endpoint
|
||||
subnet (str): ID of the subnet to read
|
||||
wallet (str): Path to file with wallet
|
||||
|
||||
|
||||
Returns:
|
||||
str: Command string
|
||||
|
||||
"""
|
||||
return self._execute(
|
||||
'morph subnet node remove',
|
||||
**{param: param_value for param, param_value in locals().items() if param not in ['self']}
|
||||
)
|
12
robot/resources/lib/python_keywords/cli_utils/adm/version.py
Normal file
12
robot/resources/lib/python_keywords/cli_utils/adm/version.py
Normal file
|
@ -0,0 +1,12 @@
|
|||
from cli_utils.cli_command import NeofsCliCommand
|
||||
|
||||
|
||||
class NeofsAdmVersion(NeofsCliCommand):
|
||||
def get(self) -> str:
|
||||
"""Application version
|
||||
|
||||
Returns:
|
||||
str: Command string
|
||||
|
||||
"""
|
||||
return self._execute('', version=True)
|
|
@ -1,9 +1,9 @@
|
|||
from typing import Optional
|
||||
|
||||
from .cli_command import NeofsCliCommandBase
|
||||
from cli_utils.cli_command import NeofsCliCommand
|
||||
|
||||
|
||||
class NeofsCliAccounting(NeofsCliCommandBase):
|
||||
class NeofsCliAccounting(NeofsCliCommand):
|
||||
def balance(self, wallet: str, rpc_endpoint: str, address: Optional[str] = None,
|
||||
owner: Optional[str] = None) -> str:
|
||||
"""Get internal balance of NeoFS account
|
|
@ -1,9 +1,9 @@
|
|||
from typing import Optional
|
||||
|
||||
from .cli_command import NeofsCliCommandBase
|
||||
from cli_utils.cli_command import NeofsCliCommand
|
||||
|
||||
|
||||
class NeofsCliACL(NeofsCliCommandBase):
|
||||
class NeofsCliACL(NeofsCliCommand):
|
||||
def extended_create(self, cid: str, out: str, file: Optional[str] = None, rule: Optional[list] = None) -> str:
|
||||
|
||||
"""Create extended ACL from the text representation.
|
|
@ -4,9 +4,9 @@ from common import NEOFS_CLI_EXEC
|
|||
|
||||
from .accounting import NeofsCliAccounting
|
||||
from .acl import NeofsCliACL
|
||||
from .cli_command import NeofsCliCommandBase
|
||||
from .container import NeofsCliContainer
|
||||
from .object import NeofsCliObject
|
||||
from .version import NeofsCliVersion
|
||||
|
||||
|
||||
class NeofsCli:
|
||||
|
@ -16,6 +16,7 @@ class NeofsCli:
|
|||
acl: Optional[NeofsCliACL] = None
|
||||
container: Optional[NeofsCliContainer] = None
|
||||
object: Optional[NeofsCliObject] = None
|
||||
version: Optional[NeofsCliVersion] = None
|
||||
|
||||
def __init__(self, neofs_cli_exec_path: Optional[str] = None, config: Optional[str] = None, timeout: int = 30):
|
||||
self.config = config # config(str): config file (default is $HOME/.config/neofs-cli/config.yaml)
|
||||
|
@ -24,12 +25,4 @@ class NeofsCli:
|
|||
self.acl = NeofsCliACL(self.neofs_cli_exec_path, timeout=timeout, config=config)
|
||||
self.container = NeofsCliContainer(self.neofs_cli_exec_path, timeout=timeout, config=config)
|
||||
self.object = NeofsCliObject(self.neofs_cli_exec_path, timeout=timeout, config=config)
|
||||
|
||||
def version(self) -> str:
|
||||
"""Application version and NeoFS API compatibility
|
||||
|
||||
Returns:
|
||||
str: Command string
|
||||
|
||||
"""
|
||||
return NeofsCliCommandBase(self.neofs_cli_exec_path, config=self.config)._execute(command=None, version=True)
|
||||
self.version = NeofsCliVersion(self.neofs_cli_exec_path, timeout=timeout, config=config)
|
|
@ -1,9 +1,9 @@
|
|||
from typing import Optional
|
||||
|
||||
from .cli_command import NeofsCliCommandBase
|
||||
from cli_utils.cli_command import NeofsCliCommand
|
||||
|
||||
|
||||
class NeofsCliContainer(NeofsCliCommandBase):
|
||||
class NeofsCliContainer(NeofsCliCommand):
|
||||
def create(self, rpc_endpoint: str, wallet: str, address: Optional[str] = None, attributes: Optional[dict] = None,
|
||||
basic_acl: Optional[str] = None, await_mode: bool = False, disable_timestamp: bool = False,
|
||||
name: Optional[str] = None, nonce: Optional[str] = None, policy: Optional[str] = None,
|
|
@ -1,9 +1,9 @@
|
|||
from typing import Optional
|
||||
|
||||
from .cli_command import NeofsCliCommandBase
|
||||
from cli_utils.cli_command import NeofsCliCommand
|
||||
|
||||
|
||||
class NeofsCliObject(NeofsCliCommandBase):
|
||||
class NeofsCliObject(NeofsCliCommand):
|
||||
def delete(self, rpc_endpoint: str, wallet: str, cid: str, oid: str, address: Optional[str] = None,
|
||||
bearer: Optional[str] = None, session: Optional[str] = None, ttl: Optional[int] = None,
|
||||
xhdr: Optional[dict] = None) -> str:
|
12
robot/resources/lib/python_keywords/cli_utils/cli/version.py
Normal file
12
robot/resources/lib/python_keywords/cli_utils/cli/version.py
Normal file
|
@ -0,0 +1,12 @@
|
|||
from cli_utils.cli_command import NeofsCliCommand
|
||||
|
||||
|
||||
class NeofsCliVersion(NeofsCliCommand):
|
||||
def get(self) -> str:
|
||||
"""Application version and NeoFS API compatibility
|
||||
|
||||
Returns:
|
||||
str: Command string
|
||||
|
||||
"""
|
||||
return self._execute('', version=True)
|
|
@ -3,13 +3,13 @@ from typing import Optional
|
|||
from cli_helpers import _cmd_run
|
||||
|
||||
|
||||
class NeofsCliCommandBase:
|
||||
class NeofsCliCommand:
|
||||
neofs_cli_exec: Optional[str] = None
|
||||
timeout: Optional[int] = None
|
||||
__base_params: Optional[str] = None
|
||||
map_params = {'json_mode': 'json', 'await_mode': 'await', 'hash_type': 'hash'}
|
||||
map_params = {'json_mode': 'json', 'await_mode': 'await', 'hash_type': 'hash', 'doc_type': 'type'}
|
||||
|
||||
def __init__(self, neofs_cli_exec: str, timeout: int = 30, **base_params):
|
||||
def __init__(self, neofs_cli_exec: str, timeout: int, **base_params):
|
||||
self.neofs_cli_exec = neofs_cli_exec
|
||||
self.timeout = timeout
|
||||
self.__base_params = ' '.join([f'--{param} {value}' for param, value in base_params.items() if value])
|
|
@ -9,7 +9,7 @@ from time import sleep
|
|||
from typing import Optional, Union
|
||||
|
||||
import json_transformers
|
||||
from cli import NeofsCli
|
||||
from cli_utils import NeofsCli
|
||||
from common import NEOFS_ENDPOINT, WALLET_CONFIG
|
||||
from robot.api import logger
|
||||
from robot.api.deco import keyword
|
||||
|
|
|
@ -11,7 +11,7 @@ import uuid
|
|||
from typing import Optional
|
||||
|
||||
import json_transformers
|
||||
from cli import NeofsCli
|
||||
from cli_utils import NeofsCli
|
||||
from common import ASSETS_DIR, NEOFS_ENDPOINT, NEOFS_NETMAP, WALLET_CONFIG
|
||||
from robot.api import logger
|
||||
from robot.api.deco import keyword
|
||||
|
|
|
@ -107,7 +107,8 @@ STORAGE_NODE_SSH_PRIVATE_KEY_PATH = os.getenv("STORAGE_NODE_SSH_PRIVATE_KEY_PATH
|
|||
STORAGE_NODE_BIN_PATH = os.getenv("STORAGE_NODE_BIN_PATH", f"{DEVENV_PATH}/vendor")
|
||||
|
||||
# Path and config for neofs-adm utility. Optional if tests are running against devenv
|
||||
NEOFS_ADM_EXEC = os.getenv("NEOFS_ADM_EXEC")
|
||||
NEOFS_ADM_EXEC = os.getenv('NEOFS_ADM_EXEC', 'neofs-adm')
|
||||
|
||||
NEOFS_ADM_CONFIG_PATH = os.getenv("NEOFS_ADM_CONFIG_PATH")
|
||||
|
||||
INFRASTRUCTURE_TYPE = os.getenv("INFRASTRUCTURE_TYPE", "LOCAL_DEVENV")
|
||||
|
|
Loading…
Reference in a new issue