[#358] Add minor improvements for convenient work with clients

Signed-off-by: Kirill Sosnovskikh <k.sosnovskikh@yadro.com>
This commit is contained in:
k.sosnovskikh 2025-02-21 16:27:13 +03:00
parent e9bc36b3d3
commit 97b9b5498a
6 changed files with 34 additions and 24 deletions

View file

@ -0,0 +1 @@
from frostfs_testlib.clients.http.http_client import HttpClient

View file

@ -1 +1,3 @@
from frostfs_testlib.clients.s3.interfaces import BucketContainerResolver, S3ClientWrapper, VersioningStatus from frostfs_testlib.clients.s3.aws_cli_client import AwsCliClient
from frostfs_testlib.clients.s3.boto3_client import Boto3ClientWrapper
from frostfs_testlib.clients.s3.interfaces import ACL, BucketContainerResolver, S3ClientWrapper, VersioningStatus

View file

@ -33,12 +33,14 @@ class AwsCliClient(S3ClientWrapper):
self, access_key_id: str, secret_access_key: str, s3gate_endpoint: str, profile: str = "default", region: str = "us-east-1" self, access_key_id: str, secret_access_key: str, s3gate_endpoint: str, profile: str = "default", region: str = "us-east-1"
) -> None: ) -> None:
self.s3gate_endpoint = s3gate_endpoint self.s3gate_endpoint = s3gate_endpoint
self.iam_endpoint = None
self.access_key_id: str = access_key_id self.access_key_id: str = access_key_id
self.secret_access_key: str = secret_access_key self.secret_access_key: str = secret_access_key
self.profile = profile self.profile = profile
self.local_shell = LocalShell()
self.region = region self.region = region
self.iam_endpoint = None
self.local_shell = LocalShell()
try: try:
_configure_aws_cli(f"aws configure --profile {profile}", access_key_id, secret_access_key, region) _configure_aws_cli(f"aws configure --profile {profile}", access_key_id, secret_access_key, region)
self.local_shell.exec(f"aws configure set max_attempts {MAX_REQUEST_ATTEMPTS} --profile {profile}") self.local_shell.exec(f"aws configure set max_attempts {MAX_REQUEST_ATTEMPTS} --profile {profile}")

View file

@ -35,26 +35,20 @@ class Boto3ClientWrapper(S3ClientWrapper):
def __init__( def __init__(
self, access_key_id: str, secret_access_key: str, s3gate_endpoint: str, profile: str = "default", region: str = "us-east-1" self, access_key_id: str, secret_access_key: str, s3gate_endpoint: str, profile: str = "default", region: str = "us-east-1"
) -> None: ) -> None:
self.boto3_client: S3Client = None
self.s3gate_endpoint: str = "" self.s3gate_endpoint: str = ""
self.boto3_client: S3Client = None
self.boto3_iam_client: S3Client = None
self.iam_endpoint: str = "" self.iam_endpoint: str = ""
self.boto3_iam_client: S3Client = None
self.boto3_sts_client: S3Client = None self.boto3_sts_client: S3Client = None
self.access_key_id: str = access_key_id self.access_key_id = access_key_id
self.secret_access_key: str = secret_access_key self.secret_access_key = secret_access_key
self.profile = profile self.profile = profile
self.region = region self.region = region
self.session = boto3.Session() self.session = boto3.Session()
self.config = Config( self.config = Config(retries={"max_attempts": MAX_REQUEST_ATTEMPTS, "mode": RETRY_MODE})
retries={
"max_attempts": MAX_REQUEST_ATTEMPTS,
"mode": RETRY_MODE,
}
)
self.set_endpoint(s3gate_endpoint) self.set_endpoint(s3gate_endpoint)
@ -90,7 +84,7 @@ class Boto3ClientWrapper(S3ClientWrapper):
endpoint_url=self.iam_endpoint, endpoint_url=self.iam_endpoint,
verify=False, verify=False,
) )
# since the STS does not have an enpoint, IAM is used # since the STS does not have an endpoint, IAM is used
self.boto3_sts_client = self.session.client( self.boto3_sts_client = self.session.client(
service_name="sts", service_name="sts",
aws_access_key_id=self.access_key_id, aws_access_key_id=self.access_key_id,
@ -145,6 +139,7 @@ class Boto3ClientWrapper(S3ClientWrapper):
params = {"Bucket": bucket} params = {"Bucket": bucket}
if object_lock_enabled_for_bucket is not None: if object_lock_enabled_for_bucket is not None:
params.update({"ObjectLockEnabledForBucket": object_lock_enabled_for_bucket}) params.update({"ObjectLockEnabledForBucket": object_lock_enabled_for_bucket})
if acl is not None: if acl is not None:
params.update({"ACL": acl}) params.update({"ACL": acl})
elif grant_write or grant_read or grant_full_control: elif grant_write or grant_read or grant_full_control:
@ -154,6 +149,7 @@ class Boto3ClientWrapper(S3ClientWrapper):
params.update({"GrantRead": grant_read}) params.update({"GrantRead": grant_read})
elif grant_full_control: elif grant_full_control:
params.update({"GrantFullControl": grant_full_control}) params.update({"GrantFullControl": grant_full_control})
if location_constraint: if location_constraint:
params.update({"CreateBucketConfiguration": {"LocationConstraint": location_constraint}}) params.update({"CreateBucketConfiguration": {"LocationConstraint": location_constraint}})

View file

@ -22,15 +22,15 @@ class VersioningStatus(HumanReadableEnum):
SUSPENDED = "Suspended" SUSPENDED = "Suspended"
ACL_COPY = [ class ACL:
"private", PRIVATE = "private"
"public-read", PUBLIC_READ = "public-read"
"public-read-write", PUBLIC_READ_WRITE = "public-read-write"
"authenticated-read", AUTHENTICATED_READ = "authenticated-read"
"aws-exec-read", AWS_EXEC_READ = "aws-exec-read"
"bucket-owner-read", BUCKET_OWNER_READ = "bucket-owner-read"
"bucket-owner-full-control", BUCKET_OWNER_FULL_CONTROL = "bucket-owner-full-control"
] LOG_DELIVERY_WRITE = "log-delivery-write"
class BucketContainerResolver(ABC): class BucketContainerResolver(ABC):
@ -50,6 +50,14 @@ class BucketContainerResolver(ABC):
class S3ClientWrapper(HumanReadableABC): class S3ClientWrapper(HumanReadableABC):
access_key_id: str
secret_access_key: str
profile: str
region: str
s3gate_endpoint: str
iam_endpoint: str
@abstractmethod @abstractmethod
def __init__(self, access_key_id: str, secret_access_key: str, s3gate_endpoint: str, profile: str, region: str) -> None: def __init__(self, access_key_id: str, secret_access_key: str, s3gate_endpoint: str, profile: str, region: str) -> None:
pass pass

View file

@ -1,5 +1,6 @@
# Regex patterns of status codes of Container service # Regex patterns of status codes of Container service
CONTAINER_NOT_FOUND = "code = 3072.*message = container not found" CONTAINER_NOT_FOUND = "code = 3072.*message = container not found"
SUBJECT_NOT_FOUND = "code = 1024.*message = frostfs error: chain/client.*subject not found.*"
# Regex patterns of status codes of Object service # Regex patterns of status codes of Object service
MALFORMED_REQUEST = "code = 1024.*message = malformed request" MALFORMED_REQUEST = "code = 1024.*message = malformed request"