Skip to content

Commit

Permalink
Disable S3 Express support for s3 sync command
Browse files Browse the repository at this point in the history
  • Loading branch information
kdaily committed Jan 23, 2024
1 parent 6376270 commit eff29d4
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changes/next-release/bugfix-s3sync-98772.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"type": "bugfix",
"category": "``s3 sync``",
"description": "Disable S3 Express support for s3 sync command"
}
16 changes: 16 additions & 0 deletions awscli/customizations/s3/subcommands.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import sys

from botocore.client import Config
from botocore.utils import is_s3express_bucket
from dateutil.parser import parse
from dateutil.tz import tzlocal

Expand Down Expand Up @@ -1199,6 +1200,21 @@ def add_paths(self, paths):
self._validate_streaming_paths()
self._validate_path_args()
self._validate_sse_c_args()
self._validate_not_s3_express_bucket_for_sync()

def _validate_not_s3_express_bucket_for_sync(self):
if self.cmd == 'sync' and \
(self._is_s3express_path(self.parameters['src']) or
self._is_s3express_path(self.parameters['dest'])):
raise ValueError(
"Cannot use sync command with a directory bucket."
)

def _is_s3express_path(self, path):
if path.startswith("s3://"):
bucket = split_s3_bucket_key(path)[0]
return is_s3express_bucket(bucket)
return False

def _validate_streaming_paths(self):
self.parameters['is_stream'] = False
Expand Down
36 changes: 35 additions & 1 deletion tests/functional/s3/test_sync_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

from awscli.compat import six
from awscli.customizations.s3.utils import relative_path
from awscli.testutils import mock
from awscli.testutils import mock, cd
from tests.functional.s3 import (
BaseS3TransferCommandTest, BaseS3CLIRunnerTest, BaseCRTTransferClientTest
)
Expand Down Expand Up @@ -467,3 +467,37 @@ def test_does_not_use_crt_client_for_copy_syncs(self):
self.run_command(cmdline)
self.assertEqual(self.get_crt_make_request_calls(), [])
self.assert_no_remaining_botocore_responses()

class TestSyncCommandWithS3Express(BaseS3TransferCommandTest):
prefix = 's3 sync '

def test_incompatible_with_sync_upload(self):
cmdline = '%s localdirectory/ s3://testdirectorybucket--usw2-az1--x-s3/' % self.prefix
stderr = self.run_cmd(cmdline, expected_rc=255)[1]
self.assertIn('Cannot use sync command with a directory bucket.', stderr)

def test_incompatible_with_sync_download(self):
cmdline = '%s s3://testdirectorybucket--usw2-az1--x-s3/ localdirectory/' % self.prefix
stderr = self.run_cmd(cmdline, expected_rc=255)[1]
self.assertIn('Cannot use sync command with a directory bucket.', stderr)

def test_incompatible_with_sync_copy(self):
cmdline = '%s s3://bucket/ s3://testdirectorybucket--usw2-az1--x-s3/' % self.prefix
stderr = self.run_cmd(cmdline, expected_rc=255)[1]
self.assertIn('Cannot use sync command with a directory bucket.', stderr)

def test_incompatible_with_sync_with_delete(self):
cmdline = '%s s3://bucket/ s3://testdirectorybucket--usw2-az1--x-s3/ --delete' % self.prefix
stderr = self.run_cmd(cmdline, expected_rc=255)[1]
self.assertIn('Cannot use sync command with a directory bucket.', stderr)

def test_compatible_with_sync_with_local_directory_like_directory_bucket(self):
self.parsed_responses = [
{'Contents': []}
]
cmdline = '%s s3://bucket/ testdirectorybucket--usw2-az1--x-s3/' % self.prefix
with cd(self.files.rootdir):
_, stderr, _ = self.run_cmd(cmdline)
# Just asserting that command validated and made an API call
self.assertEqual(len(self.operations_called), 1)
self.assertEqual(self.operations_called[0][0].name, 'ListObjectsV2')

0 comments on commit eff29d4

Please sign in to comment.