1919
2020from awscli .customizations .commands import BasicCommand
2121from awscli .customizations .s3 .comparator import Comparator
22+ from awscli .customizations .s3 .fileinfobuilder import FileInfoBuilder
2223from awscli .customizations .s3 .fileformat import FileFormat
2324from awscli .customizations .s3 .filegenerator import FileGenerator
2425from awscli .customizations .s3 .fileinfo import TaskInfo
163164CONTENT_LANGUAGE = {'name' : 'content-language' , 'nargs' : 1 ,
164165 'help_text' : ("The language the content is in." )}
165166
167+ SOURCE_REGION = {'name' : 'source-region' , 'nargs' : 1 ,
168+ 'help_text' : (
169+ "When transferring objects from an s3 bucket to an s3 "
170+ "bucket, this specifies the region of the source bucket."
171+ " Note the region specified by ``--region`` or through "
172+ "configuration of the CLI refers to the region of the "
173+ "destination bucket. If ``--source-region`` is not "
174+ "specified the region of the source will be the same "
175+ "as the region of the destination bucket." )}
176+
166177EXPIRES = {'name' : 'expires' , 'nargs' : 1 , 'help_text' : ("The date and time at "
167178 "which the object is no longer cacheable." )}
168179
198209 FOLLOW_SYMLINKS , NO_FOLLOW_SYMLINKS , NO_GUESS_MIME_TYPE ,
199210 SSE , STORAGE_CLASS , GRANTS , WEBSITE_REDIRECT , CONTENT_TYPE ,
200211 CACHE_CONTROL , CONTENT_DISPOSITION , CONTENT_ENCODING ,
201- CONTENT_LANGUAGE , EXPIRES ]
212+ CONTENT_LANGUAGE , EXPIRES , SOURCE_REGION ]
202213
203214SYNC_ARGS = [DELETE , EXACT_TIMESTAMPS , SIZE_ONLY ] + TRANSFER_ARGS
204215
205216
217+ def get_endpoint (service , region , endpoint_url , verify ):
218+ return service .get_endpoint (region_name = region , endpoint_url = endpoint_url ,
219+ verify = verify )
220+
221+
206222class S3Command (BasicCommand ):
207223 def _run_main (self , parsed_args , parsed_globals ):
208224 self .service = self ._session .get_service ('s3' )
209- self .endpoint = self ._get_endpoint (self .service , parsed_globals )
210-
211- def _get_endpoint (self , service , parsed_globals ):
212- return service .get_endpoint (region_name = parsed_globals .region ,
213- endpoint_url = parsed_globals .endpoint_url ,
214- verify = parsed_globals .verify_ssl )
225+ self .endpoint = get_endpoint (self .service , parsed_globals .region ,
226+ parsed_globals .endpoint_url ,
227+ parsed_globals .verify_ssl )
215228
216229
217230class ListCommand (S3Command ):
@@ -363,6 +376,7 @@ def _run_main(self, parsed_args, parsed_globals):
363376 cmd_params .check_force (parsed_globals )
364377 cmd = CommandArchitecture (self ._session , self .NAME ,
365378 cmd_params .parameters )
379+ cmd .set_endpoints ()
366380 cmd .create_instructions ()
367381 return cmd .run ()
368382
@@ -463,10 +477,25 @@ def __init__(self, session, cmd, parameters):
463477 self .parameters = parameters
464478 self .instructions = []
465479 self ._service = self .session .get_service ('s3' )
466- self ._endpoint = self ._service .get_endpoint (
467- region_name = self .parameters ['region' ],
480+ self ._endpoint = None
481+ self ._source_endpoint = None
482+
483+ def set_endpoints (self ):
484+ self ._endpoint = get_endpoint (
485+ self ._service ,
486+ region = self .parameters ['region' ],
468487 endpoint_url = self .parameters ['endpoint_url' ],
469- verify = self .parameters ['verify_ssl' ])
488+ verify = self .parameters ['verify_ssl' ]
489+ )
490+ self ._source_endpoint = self ._endpoint
491+ if self .parameters ['source_region' ]:
492+ if self .parameters ['paths_type' ] == 's3s3' :
493+ self ._source_endpoint = get_endpoint (
494+ self ._service ,
495+ region = self .parameters ['source_region' ][0 ],
496+ endpoint_url = None ,
497+ verify = self .parameters ['verify_ssl' ]
498+ )
470499
471500 def create_instructions (self ):
472501 """
@@ -482,6 +511,8 @@ def create_instructions(self):
482511 self .instructions .append ('filters' )
483512 if self .cmd == 'sync' :
484513 self .instructions .append ('comparator' )
514+ if self .cmd not in ['mb' , 'rb' ]:
515+ self .instructions .append ('file_info_builder' )
485516 self .instructions .append ('s3_handler' )
486517
487518 def run (self ):
@@ -524,7 +555,8 @@ def run(self):
524555 'rb' : 'remove_bucket'
525556 }
526557 operation_name = cmd_translation [paths_type ][self .cmd ]
527- file_generator = FileGenerator (self ._service , self ._endpoint ,
558+ file_generator = FileGenerator (self ._service ,
559+ self ._source_endpoint ,
528560 operation_name ,
529561 self .parameters ['follow_symlinks' ])
530562 rev_generator = FileGenerator (self ._service , self ._endpoint , '' ,
@@ -534,6 +566,8 @@ def run(self):
534566 operation_name = operation_name ,
535567 service = self ._service ,
536568 endpoint = self ._endpoint )]
569+ file_info_builder = FileInfoBuilder (self ._service , self ._endpoint ,
570+ self ._source_endpoint , self .parameters )
537571 s3handler = S3Handler (self .session , self .parameters )
538572
539573 command_dict = {}
@@ -544,21 +578,25 @@ def run(self):
544578 'filters' : [create_filter (self .parameters ),
545579 create_filter (self .parameters )],
546580 'comparator' : [Comparator (self .parameters )],
581+ 'file_info_builder' : [file_info_builder ],
547582 's3_handler' : [s3handler ]}
548583 elif self .cmd == 'cp' :
549584 command_dict = {'setup' : [files ],
550585 'file_generator' : [file_generator ],
551586 'filters' : [create_filter (self .parameters )],
587+ 'file_info_builder' : [file_info_builder ],
552588 's3_handler' : [s3handler ]}
553589 elif self .cmd == 'rm' :
554590 command_dict = {'setup' : [files ],
555591 'file_generator' : [file_generator ],
556592 'filters' : [create_filter (self .parameters )],
593+ 'file_info_builder' : [file_info_builder ],
557594 's3_handler' : [s3handler ]}
558595 elif self .cmd == 'mv' :
559596 command_dict = {'setup' : [files ],
560597 'file_generator' : [file_generator ],
561598 'filters' : [create_filter (self .parameters )],
599+ 'file_info_builder' : [file_info_builder ],
562600 's3_handler' : [s3handler ]}
563601 elif self .cmd == 'mb' :
564602 command_dict = {'setup' : [taskinfo ],
@@ -610,6 +648,8 @@ def __init__(self, session, cmd, parameters, usage):
610648 self .parameters ['dir_op' ] = False
611649 if 'follow_symlinks' not in parameters :
612650 self .parameters ['follow_symlinks' ] = True
651+ if 'source_region' not in parameters :
652+ self .parameters ['source_region' ] = None
613653 if self .cmd in ['sync' , 'mb' , 'rb' ]:
614654 self .parameters ['dir_op' ] = True
615655
0 commit comments