@@ -350,6 +350,32 @@ def _vvv(self, message):
350350 def _vvvv (self , message ):
351351 self ._display (display .vvvv , message )
352352
353+ def _get_bucket_endpoint (self ):
354+ # Fetch the correct S3 endpoint for use with our bucket.
355+ # If we don't explicitly set the endpoint then some commands will use the global
356+ # endpoint and fail
357+ # (new AWS regions and new buckets in a region other than the one we're running in)
358+
359+ region_name = self .get_option ('region' ) or 'us-east-1'
360+ profile_name = self .get_option ('profile' ) or ''
361+ self ._vvvv ("_get_bucket_endpoint: S3 (global)" )
362+ tmp_s3_client = self ._get_boto_client (
363+ 's3' , region_name = region_name , profile_name = profile_name ,
364+ )
365+ # Fetch the location of the bucket so we can open a client against the 'right' endpoint
366+ # This /should/ always work
367+ bucket_location = tmp_s3_client .get_bucket_location (
368+ Bucket = (self .get_option ('bucket_name' )),
369+ )
370+ bucket_region = bucket_location ['LocationConstraint' ]
371+ # Create another client for the region the bucket lives in, so we can nab the endpoint URL
372+ self ._vvvv (f"_get_bucket_endpoint: S3 (bucket region) - { bucket_region } " )
373+ s3_bucket_client = self ._get_boto_client (
374+ 's3' , region_name = bucket_region , profile_name = profile_name ,
375+ )
376+
377+ return s3_bucket_client .meta .endpoint_url , s3_bucket_client .meta .region_name
378+
353379 def _init_clients (self ):
354380 self ._vvvv ("INITIALIZE BOTO3 CLIENTS" )
355381 profile_name = self .get_option ('profile' ) or ''
@@ -358,20 +384,17 @@ def _init_clients(self):
358384 # The SSM Boto client, currently used to initiate and manage the session
359385 # Note: does not handle the actual SSM session traffic
360386 self ._vvvv ("SETUP BOTO3 CLIENTS: SSM" )
361- ssm_client = self ._get_boto_client ('ssm' , region_name = region_name , profile_name = profile_name )
387+ ssm_client = self ._get_boto_client (
388+ 'ssm' , region_name = region_name , profile_name = profile_name ,
389+ )
362390 self ._client = ssm_client
363391
364- region_name = self .get_option ('region' ) or 'us-east-1'
365- self ._vvvv ("SETUP BOTO3 CLIENTS: S3 (tmp)" )
366- tmp_s3_client = self ._get_boto_client ('s3' , region_name = region_name , profile_name = profile_name )
367- # Fetch the location of the bucket so we can open a client against the 'right' endpoint
368- bucket_location = tmp_s3_client .get_bucket_location (
369- Bucket = (self .get_option ('bucket_name' )),
392+ s3_endpoint_url , s3_region_name = self ._get_bucket_endpoint ()
393+ self ._vvvv (f"SETUP BOTO3 CLIENTS: S3 { s3_endpoint_url } " )
394+ s3_bucket_client = self ._get_boto_client (
395+ 's3' , region_name = s3_region_name , endpoint_url = s3_endpoint_url , profile_name = profile_name ,
370396 )
371- bucket_region = bucket_location ['LocationConstraint' ]
372- # This is the S3 client we'll really be using
373- self ._vvvv (f"SETUP BOTO3 CLIENTS: S3 - { bucket_region } " )
374- s3_bucket_client = self ._get_boto_client ('s3' , region_name = bucket_region , profile_name = profile_name )
397+
375398 self ._s3_client = s3_bucket_client
376399
377400 def __init__ (self , * args , ** kwargs ):
@@ -706,7 +729,7 @@ def _get_url(self, client_method, bucket_name, out_path, http_method, extra_args
706729 params .update (extra_args )
707730 return client .generate_presigned_url (client_method , Params = params , ExpiresIn = 3600 , HttpMethod = http_method )
708731
709- def _get_boto_client (self , service , region_name = None , profile_name = None ):
732+ def _get_boto_client (self , service , region_name = None , profile_name = None , endpoint_url = None ):
710733 ''' Gets a boto3 client based on the STS token '''
711734
712735 aws_access_key_id = self .get_option ('access_key_id' )
@@ -734,6 +757,7 @@ def _get_boto_client(self, service, region_name=None, profile_name=None):
734757
735758 client = session .client (
736759 service ,
760+ endpoint_url = endpoint_url ,
737761 config = Config (
738762 signature_version = "s3v4" ,
739763 s3 = {'addressing_style' : self .get_option ('s3_addressing_style' )}
0 commit comments