Implement neofs-cli lib

Signed-off-by: Vladimir Avdeev <v.avdeev@yadro.com>
This commit is contained in:
Vladimir Avdeev 2022-10-06 10:38:48 +03:00 committed by Vladimir Avdeev
parent d3f51ee398
commit 655a86a5b0
9 changed files with 827 additions and 3 deletions

View file

@ -1,3 +1,4 @@
from neofs_testlib.cli.neofs_adm.adm import NeofsAdm from neofs_testlib.cli.neofs_adm import NeofsAdm
from neofs_testlib.cli.neofs_authmate.authmate import NeofsAuthmate from neofs_testlib.cli.neofs_authmate import NeofsAuthmate
from neofs_testlib.cli.neogo.go import NeoGo from neofs_testlib.cli.neofs_cli import NeofsCli
from neofs_testlib.cli.neogo import NeoGo, NetworkType

View file

@ -0,0 +1 @@
from neofs_testlib.cli.neofs_cli.cli import NeofsCli

View file

@ -0,0 +1,30 @@
from typing import Optional
from neofs_testlib.cli.cli_command import CliCommand
from neofs_testlib.shell import CommandResult
class NeofsCliAccounting(CliCommand):
def balance(
self,
wallet: Optional[str] = None,
rpc_endpoint: Optional[str] = None,
address: Optional[str] = None,
owner: Optional[str] = None,
) -> CommandResult:
"""Get internal balance of NeoFS account
Args:
address: Address of wallet account.
owner: Owner of balance account (omit to use owner from private key).
rpc_endpoint: Remote node address (as 'multiaddr' or '<host>:<port>').
wallet: WIF (NEP-2) string or path to the wallet or binary key.
Returns:
Command's result.
"""
return self._execute(
"accounting balance",
**{param: value for param, value in locals().items() if param not in ["self"]},
)

View file

@ -0,0 +1,52 @@
from typing import Optional
from neofs_testlib.cli.cli_command import CliCommand
from neofs_testlib.shell import CommandResult
class NeofsCliACL(CliCommand):
def extended_create(
self, cid: str, out: str, file: Optional[str] = None, rule: Optional[list] = None
) -> CommandResult:
"""Create extended ACL from the text representation.
Rule consist of these blocks: <action> <operation> [<filter1> ...] [<target1> ...]
Action is 'allow' or 'deny'.
Operation is an object service verb: 'get', 'head', 'put', 'search', 'delete', 'getrange',
or 'getrangehash'.
Filter consists of <typ>:<key><match><value>
Typ is 'obj' for object applied filter or 'req' for request applied filter.
Key is a valid unicode string corresponding to object or request header key.
Well-known system object headers start with '$Object:' prefix.
User defined headers start without prefix.
Read more about filter keys at:
http://github.com/nspcc-dev/neofs-api/blob/master/proto-docs/acl.md#message-eaclrecordfilter
Match is '=' for matching and '!=' for non-matching filter.
Value is a valid unicode string corresponding to object or request header value.
Target is
'user' for container owner,
'system' for Storage nodes in container and Inner Ring nodes,
'others' for all other request senders,
'pubkey:<key1>,<key2>,...' for exact request sender, where <key> is a hex-encoded 33-byte
public key.
When both '--rule' and '--file' arguments are used, '--rule' records will be placed higher
in resulting extended ACL table.
Args:
cid: Container ID.
file: Read list of extended ACL table records from from text file.
out: Save JSON formatted extended ACL table in file.
rule: Extended ACL table record to apply.
Returns:
Command's result.
"""
return self._execute(
"acl extended create",
**{param: value for param, value in locals().items() if param not in ["self"]},
)

View file

@ -0,0 +1,26 @@
from typing import Optional
from neofs_testlib.cli.neofs_cli.accounting import NeofsCliAccounting
from neofs_testlib.cli.neofs_cli.acl import NeofsCliACL
from neofs_testlib.cli.neofs_cli.container import NeofsCliContainer
from neofs_testlib.cli.neofs_cli.netmap import NeofsCliNetmap
from neofs_testlib.cli.neofs_cli.object import NeofsCliObject
from neofs_testlib.cli.neofs_cli.version import NeofsCliVersion
from neofs_testlib.shell import Shell
class NeofsCli:
accounting: Optional[NeofsCliAccounting] = None
acl: Optional[NeofsCliACL] = None
container: Optional[NeofsCliContainer] = None
netmap: Optional[NeofsCliNetmap] = None
object: Optional[NeofsCliObject] = None
version: Optional[NeofsCliVersion] = None
def __init__(self, shell: Shell, neofs_cli_exec_path: str, config_file: Optional[str] = None):
self.accounting = NeofsCliAccounting(shell, neofs_cli_exec_path, config=config_file)
self.acl = NeofsCliACL(shell, neofs_cli_exec_path, config=config_file)
self.container = NeofsCliContainer(shell, neofs_cli_exec_path, config=config_file)
self.netmap = NeofsCliNetmap(shell, neofs_cli_exec_path, config=config_file)
self.object = NeofsCliObject(shell, neofs_cli_exec_path, config=config_file)
self.version = NeofsCliVersion(shell, neofs_cli_exec_path, config=config_file)

View file

@ -0,0 +1,250 @@
from typing import Optional
from neofs_testlib.cli.cli_command import CliCommand
from neofs_testlib.shell import CommandResult
class NeofsCliContainer(CliCommand):
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,
session: Optional[str] = None,
subnet: Optional[str] = None,
ttl: Optional[int] = None,
xhdr: Optional[dict] = None,
) -> CommandResult:
"""
Create a new container and register it in the NeoFS.
It will be stored in the sidechain when the Inner Ring accepts it.
Args:
address: Address of wallet account.
attributes: Comma separated pairs of container attributes in form of
Key1=Value1,Key2=Value2.
await_mode: Block execution until container is persisted.
basic_acl: Hex encoded basic ACL value or keywords like 'public-read-write',
'private', 'eacl-public-read' (default "private").
disable_timestamp: Disable timestamp container attribute.
name: Container name attribute.
nonce: UUIDv4 nonce value for container.
policy: QL-encoded or JSON-encoded placement policy or path to file with it.
rpc_endpoint: Remote node address (as 'multiaddr' or '<host>:<port>').
session: Path to a JSON-encoded container session token.
subnet: String representation of container subnetwork.
ttl: TTL value in request meta header (default 2).
wallet: WIF (NEP-2) string or path to the wallet or binary key.
xhdr: Request X-Headers in form of Key=Value.
Returns:
Command's result.
"""
return self._execute(
"container create",
**{param: value for param, value in locals().items() if param not in ["self"]},
)
def delete(
self,
rpc_endpoint: str,
wallet: str,
cid: str,
address: Optional[str] = None,
await_mode: bool = False,
session: Optional[str] = None,
ttl: Optional[int] = None,
xhdr: Optional[dict] = None,
force: bool = False,
) -> CommandResult:
"""
Delete an existing container.
Only the owner of the container has permission to remove the container.
Args:
address: Address of wallet account.
await_mode: Block execution until container is removed.
cid: Container ID.
force: Do not check whether container contains locks and remove immediately.
rpc_endpoint: Remote node address (as 'multiaddr' or '<host>:<port>').
session: Path to a JSON-encoded container session token.
ttl: TTL value in request meta header (default 2).
wallet: WIF (NEP-2) string or path to the wallet or binary key.
xhdr: Request X-Headers in form of Key=Value.
Returns:
Command's result.
"""
return self._execute(
"container delete",
**{param: value for param, value in locals().items() if param not in ["self"]},
)
def get(
self,
rpc_endpoint: str,
wallet: str,
cid: str,
address: Optional[str] = None,
await_mode: bool = False,
to: Optional[str] = None,
json_mode: bool = False,
ttl: Optional[int] = None,
xhdr: Optional[dict] = None,
) -> CommandResult:
"""
Get container field info.
Args:
address: Address of wallet account.
await_mode: Block execution until container is removed.
cid: Container ID.
json_mode: Print or dump container in JSON format.
rpc_endpoint: Remote node address (as 'multiaddr' or '<host>:<port>').
to: Path to dump encoded container.
ttl: TTL value in request meta header (default 2).
wallet: WIF (NEP-2) string or path to the wallet or binary key.
xhdr: Request X-Headers in form of Key=Value.
Returns:
Command's result.
"""
return self._execute(
"container get",
**{param: value for param, value in locals().items() if param not in ["self"]},
)
def get_eacl(
self,
rpc_endpoint: str,
wallet: str,
cid: str,
address: Optional[str] = None,
await_mode: bool = False,
to: Optional[str] = None,
session: Optional[str] = None,
ttl: Optional[int] = None,
xhdr: Optional[dict] = None,
) -> CommandResult:
"""
Get extended ACL table of container.
Args:
address: Address of wallet account.
await_mode: Block execution until container is removed.
cid: Container ID.
rpc_endpoint: Remote node address (as 'multiaddr' or '<host>:<port>').
to: Path to dump encoded container.
session: Path to a JSON-encoded container session token.
ttl: TTL value in request meta header (default 2).
wallet: WIF (NEP-2) string or path to the wallet or binary key.
xhdr: Request X-Headers in form of Key=Value.
Returns:
Command's result.
"""
return self._execute(
"container get-eacl",
**{param: value for param, value in locals().items() if param not in ["self"]},
)
def list(
self,
rpc_endpoint: str,
wallet: str,
address: Optional[str] = None,
owner: Optional[str] = None,
ttl: Optional[int] = None,
xhdr: Optional[dict] = None,
**params,
) -> CommandResult:
"""
List all created containers.
Args:
address: Address of wallet account.
owner: Owner of containers (omit to use owner from private key).
rpc_endpoint: Remote node address (as 'multiaddr' or '<host>:<port>').
ttl: TTL value in request meta header (default 2).
wallet: WIF (NEP-2) string or path to the wallet or binary key.
xhdr: Request X-Headers in form of Key=Value.
Returns:
Command's result.
"""
return self._execute(
"container list",
**{param: value for param, value in locals().items() if param not in ["self"]},
)
def list_objects(
self,
rpc_endpoint: str,
wallet: str,
cid: str,
address: Optional[str] = None,
ttl: Optional[int] = None,
xhdr: Optional[dict] = None,
) -> CommandResult:
"""
List existing objects in container.
Args:
address: Address of wallet account.
cid: Container ID.
rpc_endpoint: Remote node address (as 'multiaddr' or '<host>:<port>').
ttl: TTL value in request meta header (default 2).
wallet: WIF (NEP-2) string or path to the wallet or binary key.
xhdr: Request X-Headers in form of Key=Value.
Returns:
Command's result.
"""
return self._execute(
"container list-objects",
**{param: value for param, value in locals().items() if param not in ["self"]},
)
def set_eacl(
self,
rpc_endpoint: str,
wallet: str,
cid: str,
address: Optional[str] = None,
await_mode: bool = False,
table: Optional[str] = None,
session: Optional[str] = None,
ttl: Optional[int] = None,
xhdr: Optional[dict] = None,
) -> CommandResult:
"""
Set a new extended ACL table for the container.
Container ID in the EACL table will be substituted with the ID from the CLI.
Args:
address: Address of wallet account.
await_mode: Block execution until container is removed.
cid: Container ID.
rpc_endpoint: Remote node address (as 'multiaddr' or '<host>:<port>').
session: Path to a JSON-encoded container session token.
table: Path to file with JSON or binary encoded EACL table.
ttl: TTL value in request meta header (default 2).
wallet: WIF (NEP-2) string or path to the wallet or binary key.
xhdr: Request X-Headers in form of Key=Value.
Returns:
Command's result.
"""
return self._execute(
"container set-eacl",
**{param: value for param, value in locals().items() if param not in ["self"]},
)

View file

@ -0,0 +1,120 @@
from typing import Optional
from neofs_testlib.cli.cli_command import CliCommand
from neofs_testlib.shell import CommandResult
class NeofsCliNetmap(CliCommand):
def epoch(
self,
rpc_endpoint: str,
wallet: str,
address: Optional[str] = None,
generate_key: bool = False,
ttl: Optional[int] = None,
xhdr: Optional[dict] = None,
) -> CommandResult:
"""
Get current epoch number.
Args:
address: Address of wallet account.
generate_key: Generate new private key.
rpc_endpoint: Remote node address (as 'multiaddr' or '<host>:<port>').
ttl: TTL value in request meta header (default 2).
wallet: Path to the wallet or binary key.
xhdr: Request X-Headers in form of Key=Value.
Returns:
Command's result.
"""
return self._execute(
"netmap epoch",
**{param: value for param, value in locals().items() if param not in ["self"]},
)
def netinfo(
self,
rpc_endpoint: str,
wallet: str,
address: Optional[str] = None,
generate_key: bool = False,
ttl: Optional[int] = None,
xhdr: Optional[dict] = None,
) -> CommandResult:
"""
Get information about NeoFS network.
Args:
address: Address of wallet account
generate_key: Generate new private key
rpc_endpoint: Remote node address (as 'multiaddr' or '<host>:<port>')
ttl: TTL value in request meta header (default 2)
wallet: Path to the wallet or binary key
xhdr: Request X-Headers in form of Key=Value
Returns:
Command's result.
"""
return self._execute(
"netmap netinfo",
**{param: value for param, value in locals().items() if param not in ["self"]},
)
def nodeinfo(
self,
rpc_endpoint: str,
wallet: str,
address: Optional[str] = None,
generate_key: bool = False,
json: bool = False,
ttl: Optional[int] = None,
xhdr: Optional[dict] = None,
) -> CommandResult:
"""
Get target node info.
Args:
address: Address of wallet account.
generate_key: Generate new private key.
json: Print node info in JSON format.
rpc_endpoint: Remote node address (as 'multiaddr' or '<host>:<port>').
ttl: TTL value in request meta header (default 2).
wallet: Path to the wallet or binary key.
xhdr: Request X-Headers in form of Key=Value.
Returns:
Command's result.
"""
return self._execute(
"netmap nodeinfo",
**{param: value for param, value in locals().items() if param not in ["self"]},
)
def snapshot(
self,
rpc_endpoint: str,
wallet: str,
address: Optional[str] = None,
generate_key: bool = False,
ttl: Optional[int] = None,
xhdr: Optional[dict] = None,
) -> CommandResult:
"""
Request current local snapshot of the network map.
Args:
address: Address of wallet account.
generate_key: Generate new private key.
rpc_endpoint: Remote node address (as 'multiaddr' or '<host>:<port>').
ttl: TTL value in request meta header (default 2).
wallet: Path to the wallet or binary key.
xhdr: Request X-Headers in form of Key=Value.
Returns:
Command's result.
"""
return self._execute(
"netmap snapshot",
**{param: value for param, value in locals().items() if param not in ["self"]},
)

View file

@ -0,0 +1,331 @@
from typing import Optional
from neofs_testlib.cli.cli_command import CliCommand
from neofs_testlib.shell import CommandResult
class NeofsCliObject(CliCommand):
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,
) -> CommandResult:
"""
Delete object from NeoFS.
Args:
address: Address of wallet account.
bearer: File with signed JSON or binary encoded bearer token.
cid: Container ID.
oid: Object ID.
rpc_endpoint: Remote node address (as 'multiaddr' or '<host>:<port>').
session: Path to a JSON-encoded container session token.
ttl: TTL value in request meta header (default 2).
wallet: WIF (NEP-2) string or path to the wallet or binary key.
xhdr: Request X-Headers in form of Key=Value.
Returns:
Command's result.
"""
return self._execute(
"object delete",
**{param: value for param, value in locals().items() if param not in ["self"]},
)
def get(
self,
rpc_endpoint: str,
wallet: str,
cid: str,
oid: str,
address: Optional[str] = None,
bearer: Optional[str] = None,
file: Optional[str] = None,
header: Optional[str] = None,
no_progress: bool = False,
raw: bool = False,
session: Optional[str] = None,
ttl: Optional[int] = None,
xhdr: Optional[dict] = None,
) -> CommandResult:
"""
Get object from NeoFS.
Args:
address: Address of wallet account.
bearer: File with signed JSON or binary encoded bearer token.
cid: Container ID.
file: File to write object payload to. Default: stdout.
header: File to write header to. Default: stdout.
no_progress: Do not show progress bar.
oid: Object ID.
raw: Set raw request option.
rpc_endpoint: Remote node address (as 'multiaddr' or '<host>:<port>').
session: Path to a JSON-encoded container session token.
ttl: TTL value in request meta header (default 2).
wallet: WIF (NEP-2) string or path to the wallet or binary key.
xhdr: Request X-Headers in form of Key=Value.
Returns:
Command's result.
"""
return self._execute(
"object get",
**{param: value for param, value in locals().items() if param not in ["self"]},
)
def hash(
self,
rpc_endpoint: str,
wallet: str,
cid: str,
oid: str,
address: Optional[str] = None,
bearer: Optional[str] = None,
range: Optional[str] = None,
salt: Optional[str] = None,
ttl: Optional[int] = None,
hash_type: Optional[str] = None,
xhdr: Optional[dict] = None,
) -> CommandResult:
"""
Get object hash.
Args:
address: Address of wallet account.
bearer: File with signed JSON or binary encoded bearer token.
cid: Container ID.
oid: Object ID.
range: Range to take hash from in the form offset1:length1,...
rpc_endpoint: Remote node address (as 'multiaddr' or '<host>:<port>').
salt: Salt in hex format.
ttl: TTL value in request meta header (default 2).
hash_type: Hash type. Either 'sha256' or 'tz' (default "sha256").
wallet: WIF (NEP-2) string or path to the wallet or binary key.
xhdr: Request X-Headers in form of Key=Value.
Returns:
Command's result.
"""
return self._execute(
"object hash",
**{
param: value for param, value in locals().items() if param not in ["self", "params"]
},
)
def head(
self,
rpc_endpoint: str,
wallet: str,
cid: str,
oid: str,
address: Optional[str] = None,
bearer: Optional[str] = None,
file: Optional[str] = None,
json_mode: bool = False,
main_only: bool = False,
proto: bool = False,
raw: bool = False,
session: Optional[str] = None,
ttl: Optional[int] = None,
xhdr: Optional[dict] = None,
) -> CommandResult:
"""
Get object header.
Args:
address: Address of wallet account.
bearer: File with signed JSON or binary encoded bearer token.
cid: Container ID.
file: File to write object payload to. Default: stdout.
json_mode: Marshal output in JSON.
main_only: Return only main fields.
oid: Object ID.
proto: Marshal output in Protobuf.
raw: Set raw request option.
rpc_endpoint: Remote node address (as 'multiaddr' or '<host>:<port>').
session: Path to a JSON-encoded container session token.
ttl: TTL value in request meta header (default 2).
wallet: WIF (NEP-2) string or path to the wallet or binary key.
xhdr: Request X-Headers in form of Key=Value.
Returns:
Command's result.
"""
return self._execute(
"object head",
**{param: value for param, value in locals().items() if param not in ["self"]},
)
def lock(
self,
rpc_endpoint: str,
wallet: str,
cid: str,
oid: str,
lifetime: int,
address: Optional[str] = None,
bearer: Optional[str] = None,
session: Optional[str] = None,
ttl: Optional[int] = None,
xhdr: Optional[dict] = None,
) -> CommandResult:
"""
Lock object in container.
Args:
address: Address of wallet account.
bearer: File with signed JSON or binary encoded bearer token.
cid: Container ID.
oid: Object ID.
lifetime: Object lifetime.
rpc_endpoint: Remote node address (as 'multiaddr' or '<host>:<port>').
session: Path to a JSON-encoded container session token.
ttl: TTL value in request meta header (default 2).
wallet: WIF (NEP-2) string or path to the wallet or binary key.
xhdr: Request X-Headers in form of Key=Value.
Returns:
Command's result.
"""
return self._execute(
"object lock",
**{param: value for param, value in locals().items() if param not in ["self"]},
)
def put(
self,
rpc_endpoint: str,
wallet: str,
cid: str,
file: str,
address: Optional[str] = None,
attributes: Optional[dict] = None,
bearer: Optional[str] = None,
disable_filename: bool = False,
disable_timestamp: bool = False,
expire_at: Optional[int] = None,
no_progress: bool = False,
notify: Optional[str] = None,
session: Optional[str] = None,
ttl: Optional[int] = None,
xhdr: Optional[dict] = None,
) -> CommandResult:
"""
Put object to NeoFS.
Args:
address: Address of wallet account.
attributes: User attributes in form of Key1=Value1,Key2=Value2.
bearer: File with signed JSON or binary encoded bearer token.
cid: Container ID.
disable_filename: Do not set well-known filename attribute.
disable_timestamp: Do not set well-known timestamp attribute.
expire_at: Last epoch in the life of the object.
file: File with object payload.
no_progress: Do not show progress bar.
notify: Object notification in the form of *epoch*:*topic*; '-'
topic means using default.
rpc_endpoint: Remote node address (as 'multiaddr' or '<host>:<port>').
session: Path to a JSON-encoded container session token.
ttl: TTL value in request meta header (default 2).
wallet: WIF (NEP-2) string or path to the wallet or binary key.
xhdr: Request X-Headers in form of Key=Value.
Returns:
Command's result.
"""
return self._execute(
"object put",
**{param: value for param, value in locals().items() if param not in ["self"]},
)
def range(
self,
rpc_endpoint: str,
wallet: str,
cid: str,
oid: str,
range: str,
address: Optional[str] = None,
bearer: Optional[str] = None,
file: Optional[str] = None,
json_mode: bool = False,
raw: bool = False,
session: Optional[str] = None,
ttl: Optional[int] = None,
xhdr: Optional[dict] = None,
) -> CommandResult:
"""
Get payload range data of an object.
Args:
address: Address of wallet account.
bearer: File with signed JSON or binary encoded bearer token.
cid: Container ID.
file: File to write object payload to. Default: stdout.
json_mode: Marshal output in JSON.
oid: Object ID.
range: Range to take data from in the form offset:length.
raw: Set raw request option.
rpc_endpoint: Remote node address (as 'multiaddr' or '<host>:<port>').
session: Path to a JSON-encoded container session token.
ttl: TTL value in request meta header (default 2).
wallet: WIF (NEP-2) string or path to the wallet or binary key.
xhdr: Request X-Headers in form of Key=Value.
Returns:
Command's result.
"""
return self._execute(
"object range",
**{param: value for param, value in locals().items() if param not in ["self"]},
)
def search(
self,
rpc_endpoint: str,
wallet: str,
cid: str,
address: Optional[str] = None,
bearer: Optional[str] = None,
filters: Optional[list] = None,
oid: Optional[str] = None,
phy: bool = False,
root: bool = False,
session: Optional[str] = None,
ttl: Optional[int] = None,
xhdr: Optional[dict] = None,
) -> CommandResult:
"""
Search object.
Args:
address: Address of wallet account.
bearer: File with signed JSON or binary encoded bearer token.
cid: Container ID.
filters: Repeated filter expressions or files with protobuf JSON.
oid: Object ID.
phy: Search physically stored objects.
root: Search for user objects.
rpc_endpoint: Remote node address (as 'multiaddr' or '<host>:<port>').
session: Path to a JSON-encoded container session token.
ttl: TTL value in request meta header (default 2).
wallet: WIF (NEP-2) string or path to the wallet or binary key.
xhdr: Request X-Headers in form of Key=Value.
Returns:
Command's result.
"""
return self._execute(
"object search",
**{param: value for param, value in locals().items() if param not in ["self"]},
)

View file

@ -0,0 +1,13 @@
from neofs_testlib.cli.cli_command import CliCommand
from neofs_testlib.shell import CommandResult
class NeofsCliVersion(CliCommand):
def get(self) -> CommandResult:
"""
Application version and NeoFS API compatibility.
Returns:
Command's result.
"""
return self._execute("", version=True)