Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add MRAP support for CRT s3transfer integration #9076

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 52 additions & 2 deletions awscli/s3transfer/crt.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
# ANY KIND, either express or implied. See the License for the specific
# language governing permissions and limitations under the License.
import logging
import re
import threading
from io import BytesIO

Expand Down Expand Up @@ -41,7 +42,7 @@
from botocore.compat import urlsplit
from botocore.config import Config
from botocore.exceptions import NoCredentialsError
from botocore.utils import is_s3express_bucket
from botocore.utils import ArnParser, InvalidArnException, is_s3express_bucket

from s3transfer.constants import MB
from s3transfer.exceptions import TransferNotDoneError
Expand Down Expand Up @@ -840,7 +841,19 @@ def _default_get_make_request_args(
x.title() for x in request_type.split('_')
)

if is_s3express_bucket(call_args.bucket):
arn_handler = _S3ArnParamHandler()
if (
(accesspoint_arn_details := arn_handler.handle_arn(call_args.bucket))
and accesspoint_arn_details['region'] == ""
):
# Configure our region to `*` to propogate in `x-amz-region-set`
# for multi-region support in MRAP accesspoints.
make_request_args['signing_config'] = AwsSigningConfig(
algorithm=AwsSigningAlgorithm.V4_ASYMMETRIC,
region="*",
nateprewitt marked this conversation as resolved.
Show resolved Hide resolved
)
call_args.bucket = accesspoint_arn_details['resource_name']
elif is_s3express_bucket(call_args.bucket):
make_request_args['signing_config'] = AwsSigningConfig(
algorithm=AwsSigningAlgorithm.V4_S3EXPRESS
)
Expand Down Expand Up @@ -883,3 +896,40 @@ def __init__(self, fileobj):

def __call__(self, chunk, **kwargs):
self._fileobj.write(chunk)


class _S3ArnParamHandler:
"""Partial port of S3ArnParamHandler from botocore.

This is used to make a determination on MRAP accesspoints for signing
purposes. This should be safe to remove once we properly integrate auth
resolution from Botocore into the CRT transfer integration.
"""
_RESOURCE_REGEX = re.compile(
r'^(?P<resource_type>accesspoint|outpost)[/:](?P<resource_name>.+)$'
)

def __init__(self):
self._arn_parser = ArnParser()

def handle_arn(self, bucket):
arn_details = self._get_arn_details_from_bucket(bucket)
if arn_details is None:
return
if arn_details['resource_type'] == 'accesspoint':
return arn_details

def _get_arn_details_from_bucket(self, bucket):
try:
arn_details = self._arn_parser.parse_arn(bucket)
self._add_resource_type_and_name(arn_details)
return arn_details
except InvalidArnException:
pass
return None

def _add_resource_type_and_name(self, arn_details):
match = self._RESOURCE_REGEX.match(arn_details['resource'])
if match:
arn_details['resource_type'] = match.group('resource_type')
arn_details['resource_name'] = match.group('resource_name')
Loading