2022-07-12 09:59:19 +00:00
|
|
|
#!/usr/bin/python3.9
|
2022-04-25 09:53:20 +00:00
|
|
|
|
|
|
|
"""
|
2022-07-12 09:59:19 +00:00
|
|
|
This module contains keywords that utilize `neofs-cli container` commands.
|
2022-04-25 09:53:20 +00:00
|
|
|
"""
|
|
|
|
|
|
|
|
import json
|
|
|
|
import time
|
2022-07-12 09:59:19 +00:00
|
|
|
from typing import Optional
|
2022-04-25 09:53:20 +00:00
|
|
|
|
2022-06-13 20:33:09 +00:00
|
|
|
import json_transformers
|
2022-07-12 09:59:19 +00:00
|
|
|
from data_formatters import dict_to_attrs
|
|
|
|
from cli_helpers import _cmd_run
|
|
|
|
from common import NEOFS_ENDPOINT, NEOFS_CLI_EXEC, WALLET_CONFIG
|
2022-06-13 20:33:09 +00:00
|
|
|
|
2022-04-25 09:53:20 +00:00
|
|
|
from robot.api import logger
|
2022-06-09 13:08:11 +00:00
|
|
|
from robot.api.deco import keyword
|
2022-04-25 09:53:20 +00:00
|
|
|
|
|
|
|
ROBOT_AUTO_KEYWORDS = False
|
2022-07-12 09:59:19 +00:00
|
|
|
DEFAULT_PLACEMENT_RULE = "REP 2 IN X CBF 1 SELECT 4 FROM * AS X"
|
2022-04-25 09:53:20 +00:00
|
|
|
|
|
|
|
@keyword('Create Container')
|
2022-07-12 09:59:19 +00:00
|
|
|
def create_container(wallet: str, rule: str = DEFAULT_PLACEMENT_RULE, basic_acl: str = '',
|
|
|
|
attributes: Optional[dict] = None, session_token: str = '',
|
|
|
|
session_wallet: str = '', options: str = '') -> str:
|
2022-04-25 09:53:20 +00:00
|
|
|
"""
|
|
|
|
A wrapper for `neofs-cli container create` call.
|
|
|
|
|
|
|
|
Args:
|
|
|
|
wallet (str): a wallet on whose behalf a container is created
|
|
|
|
rule (optional, str): placement rule for container
|
|
|
|
basic_acl (optional, str): an ACL for container, will be
|
|
|
|
appended to `--basic-acl` key
|
|
|
|
attributes (optional, dict): container attributes , will be
|
|
|
|
appended to `--attributes` key
|
|
|
|
session_token (optional, str): a path to session token file
|
|
|
|
session_wallet(optional, str): a path to the wallet which signed
|
|
|
|
the session token; this parameter makes sense
|
|
|
|
when paired with `session_token`
|
|
|
|
options (optional, str): any other options to pass to the call
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
(str): CID of the created container
|
|
|
|
"""
|
|
|
|
|
|
|
|
cmd = (
|
|
|
|
f'{NEOFS_CLI_EXEC} --rpc-endpoint {NEOFS_ENDPOINT} container create '
|
|
|
|
f'--wallet {session_wallet if session_wallet else wallet} '
|
2022-06-13 20:33:09 +00:00
|
|
|
f'--config {WALLET_CONFIG} --policy "{rule}" '
|
2022-04-25 09:53:20 +00:00
|
|
|
f'{"--basic-acl " + basic_acl if basic_acl else ""} '
|
|
|
|
f'{"--attributes " + dict_to_attrs(attributes) if attributes else ""} '
|
|
|
|
f'{"--session " + session_token if session_token else ""} '
|
|
|
|
f'{options} --await'
|
|
|
|
)
|
|
|
|
output = _cmd_run(cmd, timeout=60)
|
|
|
|
cid = _parse_cid(output)
|
|
|
|
|
|
|
|
logger.info("Container created; waiting until it is persisted in sidechain")
|
|
|
|
|
2022-06-09 13:08:11 +00:00
|
|
|
deadline_to_persist = 15 # seconds
|
2022-04-25 09:53:20 +00:00
|
|
|
for i in range(0, deadline_to_persist):
|
|
|
|
time.sleep(1)
|
|
|
|
containers = list_containers(wallet)
|
|
|
|
if cid in containers:
|
|
|
|
break
|
|
|
|
logger.info(f"There is no {cid} in {containers} yet; continue")
|
2022-06-09 13:08:11 +00:00
|
|
|
if i + 1 == deadline_to_persist:
|
2022-04-25 09:53:20 +00:00
|
|
|
raise RuntimeError(
|
2022-06-09 13:08:11 +00:00
|
|
|
f"After {deadline_to_persist} seconds the container "
|
|
|
|
f"{cid} hasn't been persisted; exiting"
|
|
|
|
)
|
2022-04-25 09:53:20 +00:00
|
|
|
return cid
|
|
|
|
|
|
|
|
|
|
|
|
@keyword('List Containers')
|
2022-07-12 09:59:19 +00:00
|
|
|
def list_containers(wallet: str) -> list[str]:
|
2022-04-25 09:53:20 +00:00
|
|
|
"""
|
|
|
|
A wrapper for `neofs-cli container list` call. It returns all the
|
|
|
|
available containers for the given wallet.
|
|
|
|
Args:
|
|
|
|
wallet (str): a wallet on whose behalf we list the containers
|
|
|
|
Returns:
|
|
|
|
(list): list of containers
|
|
|
|
"""
|
|
|
|
cmd = (
|
|
|
|
f'{NEOFS_CLI_EXEC} --rpc-endpoint {NEOFS_ENDPOINT} --wallet {wallet} '
|
2022-06-13 20:33:09 +00:00
|
|
|
f'--config {WALLET_CONFIG} container list'
|
2022-04-25 09:53:20 +00:00
|
|
|
)
|
|
|
|
output = _cmd_run(cmd)
|
|
|
|
return output.split()
|
|
|
|
|
|
|
|
|
2022-05-27 14:42:42 +00:00
|
|
|
@keyword('Get Container')
|
2022-07-08 17:24:55 +00:00
|
|
|
def get_container(wallet: str, cid: str, flag: str = '--json') -> dict:
|
2022-04-25 09:53:20 +00:00
|
|
|
"""
|
2022-07-12 09:59:19 +00:00
|
|
|
A wrapper for `neofs-cli container get` call. It extracts container's
|
|
|
|
attributes and rearranges them into a more compact view.
|
2022-04-25 09:53:20 +00:00
|
|
|
Args:
|
2022-07-12 09:59:19 +00:00
|
|
|
wallet (str): path to a wallet on whose behalf we get the container
|
2022-04-25 09:53:20 +00:00
|
|
|
cid (str): ID of the container to get
|
2022-07-08 17:24:55 +00:00
|
|
|
flag (str): output as json or plain text
|
2022-04-25 09:53:20 +00:00
|
|
|
Returns:
|
2022-07-08 17:24:55 +00:00
|
|
|
(dict, str): dict of container attributes
|
2022-04-25 09:53:20 +00:00
|
|
|
"""
|
|
|
|
cmd = (
|
|
|
|
f'{NEOFS_CLI_EXEC} --rpc-endpoint {NEOFS_ENDPOINT} --wallet {wallet} '
|
2022-06-13 20:33:09 +00:00
|
|
|
f'--config {WALLET_CONFIG} --cid {cid} container get --json'
|
2022-04-25 09:53:20 +00:00
|
|
|
)
|
|
|
|
output = _cmd_run(cmd)
|
2022-07-08 17:24:55 +00:00
|
|
|
if flag != '--json':
|
|
|
|
return output
|
2022-04-25 09:53:20 +00:00
|
|
|
container_info = json.loads(output)
|
|
|
|
attributes = dict()
|
|
|
|
for attr in container_info['attributes']:
|
|
|
|
attributes[attr['key']] = attr['value']
|
2022-05-27 14:42:42 +00:00
|
|
|
container_info['attributes'] = attributes
|
2022-07-12 09:59:19 +00:00
|
|
|
container_info['ownerID'] = json_transformers.json_reencode(container_info['ownerID']['value'])
|
2022-05-27 14:42:42 +00:00
|
|
|
return container_info
|
2022-04-25 09:53:20 +00:00
|
|
|
|
|
|
|
|
|
|
|
@keyword('Delete Container')
|
|
|
|
# TODO: make the error message about a non-found container more user-friendly
|
|
|
|
# https://github.com/nspcc-dev/neofs-contract/issues/121
|
2022-07-12 09:59:19 +00:00
|
|
|
def delete_container(wallet: str, cid: str) -> None:
|
2022-04-25 09:53:20 +00:00
|
|
|
"""
|
|
|
|
A wrapper for `neofs-cli container delete` call.
|
|
|
|
Args:
|
2022-07-12 09:59:19 +00:00
|
|
|
wallet (str): path to a wallet on whose behalf we delete the container
|
2022-04-25 09:53:20 +00:00
|
|
|
cid (str): ID of the container to delete
|
|
|
|
This function doesn't return anything.
|
|
|
|
"""
|
|
|
|
|
|
|
|
cmd = (
|
|
|
|
f'{NEOFS_CLI_EXEC} --rpc-endpoint {NEOFS_ENDPOINT} --wallet {wallet} '
|
2022-06-13 20:33:09 +00:00
|
|
|
f'--config {WALLET_CONFIG} container delete --cid {cid}'
|
2022-04-25 09:53:20 +00:00
|
|
|
)
|
|
|
|
_cmd_run(cmd)
|
|
|
|
|
|
|
|
|
2022-07-12 09:59:19 +00:00
|
|
|
def _parse_cid(output: str) -> str:
|
2022-04-25 09:53:20 +00:00
|
|
|
"""
|
2022-07-12 09:59:19 +00:00
|
|
|
Parses container ID from a given CLI output. The input string we expect:
|
2022-04-25 09:53:20 +00:00
|
|
|
container ID: 2tz86kVTDpJxWHrhw3h6PbKMwkLtBEwoqhHQCKTre1FN
|
|
|
|
awaiting...
|
|
|
|
container has been persisted on sidechain
|
|
|
|
We want to take 'container ID' value from the string.
|
|
|
|
|
|
|
|
Args:
|
2022-07-12 09:59:19 +00:00
|
|
|
output (str): CLI output to parse
|
2022-04-25 09:53:20 +00:00
|
|
|
|
|
|
|
Returns:
|
|
|
|
(str): extracted CID
|
|
|
|
"""
|
|
|
|
try:
|
2022-07-12 09:59:19 +00:00
|
|
|
# taking first line from command's output
|
|
|
|
first_line = output.split('\n')[0]
|
2022-04-25 09:53:20 +00:00
|
|
|
except Exception:
|
2022-07-12 09:59:19 +00:00
|
|
|
logger.error(f"Got empty output: {output}")
|
|
|
|
splitted = first_line.split(": ")
|
2022-04-25 09:53:20 +00:00
|
|
|
if len(splitted) != 2:
|
2022-07-12 09:59:19 +00:00
|
|
|
raise ValueError(f"no CID was parsed from command output: \t{first_line}")
|
2022-04-25 09:53:20 +00:00
|
|
|
return splitted[1]
|