This repository has been archived by the owner on Mar 29, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 13
Add functionality to deploy custom neofs environments #81
Merged
roman-khimov
merged 2 commits into
nspcc-dev:master
from
evgeniiz321:ezayats/new-dev-env
Dec 15, 2023
Merged
Changes from 1 commit
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
def pytest_addoption(parser): | ||
parser.addoption( | ||
"--persist-env", action="store_true", default=False, help="persist deployed env" | ||
) | ||
parser.addoption("--load-env", action="store", help="load persisted env from file") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"rep-1": "REP 1" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
[pytest] | ||
log_cli = 1 | ||
log_cli_level = DEBUG | ||
log_cli_format = %(asctime)s [%(levelname)4s] %(message)s | ||
log_format = %(asctime)s [%(levelname)4s] %(message)s | ||
log_cli_date_format = %Y-%m-%d %H:%M:%S | ||
log_date_format = %H:%M:%S |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
{ | ||
"records": | ||
[ | ||
{ | ||
"operation":"PUT", | ||
"action":"ALLOW", | ||
"filters":[], | ||
"targets": | ||
[ | ||
{ | ||
"role":"OTHERS", | ||
"keys":[] | ||
} | ||
] | ||
}, | ||
{ | ||
"operation":"HEAD", | ||
"action":"ALLOW", | ||
"filters":[], | ||
"targets": | ||
[ | ||
{ | ||
"role":"OTHERS", | ||
"keys":[] | ||
} | ||
] | ||
}, | ||
{ | ||
"operation":"DELETE", | ||
"action":"ALLOW", | ||
"filters":[], | ||
"targets": | ||
[ | ||
{ | ||
"role":"OTHERS", | ||
"keys":[] | ||
} | ||
] | ||
}, | ||
{ | ||
"operation":"SEARCH", | ||
"action":"ALLOW", | ||
"filters":[], | ||
"targets": | ||
[ | ||
{ | ||
"role":"OTHERS", | ||
"keys":[] | ||
} | ||
] | ||
}, | ||
{ | ||
"operation":"GET", | ||
"action":"ALLOW", | ||
"filters":[], | ||
"targets": | ||
[ | ||
{ | ||
"role":"OTHERS", | ||
"keys":[] | ||
} | ||
] | ||
}, | ||
{ | ||
"operation":"GETRANGE", | ||
"action":"ALLOW", | ||
"filters":[], | ||
"targets": | ||
[ | ||
{ | ||
"role":"OTHERS", | ||
"keys":[] | ||
} | ||
] | ||
}, | ||
{ | ||
"operation":"GETRANGEHASH", | ||
"action":"ALLOW", | ||
"filters":[], | ||
"targets": | ||
[ | ||
{ | ||
"role":"OTHERS", | ||
"keys":[] | ||
} | ||
] | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
import json | ||
import os | ||
import re | ||
import uuid | ||
from time import sleep | ||
|
||
import boto3 | ||
import pexpect | ||
import pytest | ||
from botocore.config import Config | ||
|
||
from neofs_testlib.env.env import NeoFSEnv, NodeWallet | ||
from neofs_testlib.utils.wallet import get_last_public_key_from_wallet, init_wallet | ||
|
||
|
||
def _run_with_passwd(cmd: str, password: str) -> str: | ||
child = pexpect.spawn(cmd) | ||
child.delaybeforesend = 1 | ||
child.expect(".*") | ||
child.sendline(f"{password}\r") | ||
child.wait() | ||
cmd = child.read() | ||
return cmd.decode() | ||
|
||
|
||
@pytest.fixture | ||
def neofs_env(request): | ||
if request.config.getoption("--load-env"): | ||
neofs_env = NeoFSEnv.load(request.config.getoption("--load-env")) | ||
else: | ||
neofs_env = NeoFSEnv.simple() | ||
|
||
yield neofs_env | ||
|
||
if request.config.getoption("--persist-env"): | ||
neofs_env.persist() | ||
else: | ||
if not request.config.getoption("--load-env"): | ||
neofs_env.kill() | ||
|
||
|
||
@pytest.fixture | ||
def wallet() -> NodeWallet: | ||
wallet_name = f"{str(uuid.uuid4())}.json" | ||
wallet_path = os.path.join(os.getcwd(), wallet_name) | ||
wallet_password = "password" | ||
wallet_address = init_wallet(wallet_path, wallet_password) | ||
return NodeWallet(path=wallet_path, address=wallet_address, password=wallet_password) | ||
|
||
|
||
@pytest.fixture | ||
def s3_creds(neofs_env: NeoFSEnv, zero_fee, wallet: NodeWallet) -> tuple: | ||
bucket = str(uuid.uuid4()) | ||
s3_bearer_rules = "pytest_tests/s3_bearer_rules.json" | ||
|
||
gate_public_key = get_last_public_key_from_wallet( | ||
neofs_env.s3_gw.wallet.path, neofs_env.s3_gw.wallet.password | ||
) | ||
cmd = ( | ||
f"{neofs_env.neofs_s3_authmate_path} --debug --with-log --timeout 1m " | ||
f"issue-secret --wallet {wallet.path} --gate-public-key={gate_public_key} " | ||
f"--peer {neofs_env.storage_nodes[0].endpoint} --container-friendly-name {bucket} " | ||
f"--bearer-rules {s3_bearer_rules} --container-placement-policy 'REP 1' " | ||
f"--container-policy container_policy.json" | ||
) | ||
output = _run_with_passwd(cmd, wallet.password) | ||
|
||
# output contains some debug info and then several JSON structures, so we find each | ||
# JSON structure by curly brackets (naive approach, but works while JSON is not nested) | ||
# and then we take JSON containing secret_access_key | ||
json_blocks = re.findall(r"\{.*?\}", output, re.DOTALL) | ||
for json_block in json_blocks: | ||
parsed_json_block = json.loads(json_block) | ||
if "secret_access_key" in parsed_json_block: | ||
return ( | ||
parsed_json_block["container_id"], | ||
bucket, | ||
parsed_json_block["access_key_id"], | ||
parsed_json_block["secret_access_key"], | ||
parsed_json_block["owner_private_key"], | ||
) | ||
raise AssertionError("Can't get s3 creds") | ||
|
||
|
||
@pytest.fixture | ||
def zero_fee(neofs_env: NeoFSEnv): | ||
neofs_env.neofs_adm().morph.set_config( | ||
rpc_endpoint=f"http://{neofs_env.morph_rpc}", | ||
alphabet_wallets=neofs_env.alphabet_wallets_dir, | ||
post_data=f"ContainerFee=0 ContainerAliasFee=0", | ||
) | ||
|
||
|
||
def test_s3_gw_put_get(neofs_env: NeoFSEnv, s3_creds, wallet: NodeWallet): | ||
( | ||
cid, | ||
bucket, | ||
access_key_id, | ||
secret_access_key, | ||
_, | ||
) = s3_creds | ||
|
||
cli = neofs_env.neofs_cli(neofs_env.generate_cli_config(wallet)) | ||
result = cli.container.list(rpc_endpoint=neofs_env.sn_rpc, wallet=wallet.path) | ||
containers_list = result.stdout.split() | ||
assert cid in containers_list, f"Expected cid {cid} in {containers_list}" | ||
|
||
session = boto3.Session() | ||
config = Config( | ||
retries={ | ||
"max_attempts": 1, | ||
"mode": "standard", | ||
} | ||
) | ||
|
||
s3_client = session.client( | ||
service_name="s3", | ||
aws_access_key_id=access_key_id, | ||
aws_secret_access_key=secret_access_key, | ||
config=config, | ||
endpoint_url=f"https://{neofs_env.s3_gw.address}", | ||
verify=False, | ||
) | ||
|
||
bucket_name = str(uuid.uuid4()) | ||
params = {"Bucket": bucket_name, "CreateBucketConfiguration": {"LocationConstraint": "rep-1"}} | ||
s3_client.create_bucket(**params) | ||
sleep(5) | ||
|
||
filename = neofs_env._generate_temp_file() | ||
|
||
with open(filename, "w") as file: | ||
file.write("123456789") | ||
|
||
with open(filename, "rb") as file: | ||
file_content = file.read() | ||
|
||
filekey = os.path.basename(filename) | ||
s3_client.put_object(**{"Body": file_content, "Bucket": bucket_name, "Key": filekey}) | ||
s3_client.get_object(**{"Bucket": bucket_name, "Key": filekey}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
from typing import Optional | ||
|
||
from neofs_testlib.cli.cli_command import CliCommand | ||
from neofs_testlib.shell import CommandResult | ||
|
||
|
||
class NeofsCliControl(CliCommand): | ||
def healthcheck( | ||
self, | ||
endpoint: str, | ||
post_data="", | ||
) -> 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: Dict with request X-Headers. | ||
|
||
Returns: | ||
Command's result. | ||
""" | ||
return self._execute( | ||
"control healthcheck", | ||
**{param: value for param, value in locals().items() if param not in ["self"]}, | ||
) |
Empty file.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
S3 as a part of base env?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this particular case - yes. But actually any kind of env is configured via this kind of classmethods or fixtures:
So we can have whatever we want. But for the purpose of this PR - to have a working example - I use s3 gate here.