Add ACL and eACL PyTest tests

Signed-off-by: Vladimir Avdeev <v.avdeev@yadro.com>
This commit is contained in:
Vladimir Avdeev 2022-08-25 13:57:55 +03:00 committed by Vladimir Avdeev
parent 590a5cfb0e
commit 6d040c6834
36 changed files with 979 additions and 1318 deletions

View file

@ -0,0 +1,47 @@
from typing import Optional
from .cli_command import NeofsCliCommandBase
class NeofsCliACL(NeofsCliCommandBase):
def extended_create(self, cid: str, out: str, file: Optional[str] = None, rule: Optional[list] = None) -> str:
"""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:
str: Command string
"""
return self._execute(
'acl extended create',
**{param: param_value for param, param_value in locals().items() if param not in ['self']}
)

View file

@ -3,6 +3,7 @@ from typing import Optional
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
@ -12,6 +13,7 @@ class NeofsCli:
neofs_cli_exec_path: Optional[str] = None
config: Optional[str] = None
accounting: Optional[NeofsCliAccounting] = None
acl: Optional[NeofsCliACL] = None
container: Optional[NeofsCliContainer] = None
object: Optional[NeofsCliObject] = None
@ -19,6 +21,7 @@ class NeofsCli:
self.config = config # config(str): config file (default is $HOME/.config/neofs-cli/config.yaml)
self.neofs_cli_exec_path = neofs_cli_exec_path or NEOFS_CLI_EXEC
self.accounting = NeofsCliAccounting(self.neofs_cli_exec_path, timeout=timeout, config=config)
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)

View file

@ -24,13 +24,21 @@ class NeofsCliCommandBase:
continue
if isinstance(value, bool):
param_str.append(f'--{param}')
elif isinstance(value, int):
param_str.append(f'--{param} {value}')
elif isinstance(value, list):
param_str.append(f'--{param} \'{",".join(value)}\'')
for value_item in value:
val_str = str(value_item).replace("'", "\\'")
param_str.append(f"--{param} '{val_str}'")
elif isinstance(value, dict):
param_str.append(f'--{param} \'{",".join(f"{key}={val}" for key, val in value.items())}\'')
else:
value_str = str(value).replace("'", "\\'")
param_str.append(f"--{param} '{value_str}'")
if "'" in str(value):
value_str = str(value).replace('"', '\\"')
param_str.append(f'--{param} "{value_str}"')
else:
param_str.append(f"--{param} '{value}'")
param_str = ' '.join(param_str)
return f'{self.neofs_cli_exec} {self.__base_params} {command or ""} {param_str}'

View file

@ -8,7 +8,7 @@ class NeofsCliContainer(NeofsCliCommandBase):
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[list] = None) -> str:
xhdr: Optional[dict] = None) -> str:
"""Create a new container and register it in the NeoFS.
It will be stored in the sidechain when the Inner Ring accepts it.
@ -39,7 +39,8 @@ class NeofsCliContainer(NeofsCliCommandBase):
)
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[list] = None) -> str:
session: Optional[str] = None, ttl: Optional[int] = None, xhdr: Optional[dict] = None,
force: bool = False) -> str:
"""Delete an existing container.
Only the owner of the container has permission to remove the container.
@ -47,6 +48,7 @@ class NeofsCliContainer(NeofsCliCommandBase):
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)

View file

@ -6,7 +6,7 @@ from .cli_command import NeofsCliCommandBase
class NeofsCliObject(NeofsCliCommandBase):
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[list] = None, **params) -> str:
xhdr: Optional[dict] = None) -> str:
"""Delete object from NeoFS
Args:
@ -26,13 +26,13 @@ class NeofsCliObject(NeofsCliCommandBase):
"""
return self._execute(
'object delete',
**{param: param_value for param, param_value in locals().items() if param not in ['self', 'params']}
**{param: param_value for param, 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[list] = None, **params) -> str:
session: Optional[str] = None, ttl: Optional[int] = None, xhdr: Optional[dict] = None) -> str:
"""Get object from NeoFS
Args:
@ -56,13 +56,12 @@ class NeofsCliObject(NeofsCliCommandBase):
"""
return self._execute(
'object get',
**{param: param_value for param, param_value in locals().items() if param not in ['self', 'params']}
**{param: param_value for param, 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[list] = None,
**params) -> str:
ttl: Optional[int] = None, hash_type: Optional[str] = None, xhdr: Optional[dict] = None) -> str:
"""Get object hash
Args:
@ -90,7 +89,7 @@ class NeofsCliObject(NeofsCliCommandBase):
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[list] = None, **params) -> str:
session: Optional[str] = None, ttl: Optional[int] = None, xhdr: Optional[dict] = None) -> str:
"""Get object header
Args:
@ -116,12 +115,12 @@ class NeofsCliObject(NeofsCliCommandBase):
"""
return self._execute(
'object head',
**{param: param_value for param, param_value in locals().items() if param not in ['self', 'params']}
**{param: param_value for param, 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[list] = None, **params) -> str:
bearer: Optional[str] = None, session: Optional[str] = None, ttl: Optional[int] = None,
xhdr: Optional[dict] = None) -> str:
"""Lock object in container
Args:
@ -143,14 +142,14 @@ class NeofsCliObject(NeofsCliCommandBase):
"""
return self._execute(
'object lock',
**{param: param_value for param, param_value in locals().items() if param not in ['self', 'params']}
**{param: param_value for param, 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[list] = None, **params) -> str:
xhdr: Optional[dict] = None) -> str:
"""Put object to NeoFS
Args:
@ -176,12 +175,12 @@ class NeofsCliObject(NeofsCliCommandBase):
"""
return self._execute(
'object put',
**{param: param_value for param, param_value in locals().items() if param not in ['self', 'params']}
**{param: param_value for param, 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[list] = None, **params) -> str:
session: Optional[str] = None, ttl: Optional[int] = None, xhdr: Optional[dict] = None) -> str:
"""Get payload range data of an object
Args:
@ -206,13 +205,13 @@ class NeofsCliObject(NeofsCliCommandBase):
"""
return self._execute(
'object range',
**{param: param_value for param, param_value in locals().items() if param not in ['self', 'params']}
**{param: param_value for param, 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[list] = None, **params) -> str:
xhdr: Optional[dict] = None) -> str:
"""Search object
Args:
@ -236,5 +235,5 @@ class NeofsCliObject(NeofsCliCommandBase):
"""
return self._execute(
'object search',
**{param: param_value for param, param_value in locals().items() if param not in ['self', 'params']}
**{param: param_value for param, param_value in locals().items() if param not in ['self']}
)