Skip to content

Commit

Permalink
Fallback to trying to create bucket without LocationConstraint
Browse files Browse the repository at this point in the history
  • Loading branch information
hloeung committed Dec 5, 2024
1 parent 769dda2 commit 8b48898
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 8 deletions.
27 changes: 21 additions & 6 deletions src/backups.py
Original file line number Diff line number Diff line change
Expand Up @@ -284,13 +284,28 @@ def _create_bucket_if_not_exists(self) -> None:
except ClientError:
logger.warning("Bucket %s doesn't exist or you don't have access to it.", bucket_name)
exists = False
if not exists:
try:
bucket.create(CreateBucketConfiguration={"LocationConstraint": region})
if exists:
return

bucket.wait_until_exists()
logger.info("Created bucket '%s' in region=%s", bucket_name, region)
except ClientError as error:
try:
bucket.create(CreateBucketConfiguration={"LocationConstraint": region})

bucket.wait_until_exists()
logger.info("Created bucket '%s' in region=%s", bucket_name, region)
except ClientError as error:
if error.response["Error"]["Code"] == "InvalidLocationConstraint":
logger.info("Specified location-constraint is not valid, trying create without it")
try:
bucket.create()

bucket.wait_until_exists()
logger.info("Created bucket '%s', ignored region=%s", bucket_name, region)
except ClientError as error:
logger.exception(
"Couldn't create bucket named '%s' in region=%s.", bucket_name, region
)
raise error
else:
logger.exception(
"Couldn't create bucket named '%s' in region=%s.", bucket_name, region
)
Expand Down
27 changes: 25 additions & 2 deletions tests/unit/test_backups.py
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ def test_create_bucket_if_not_exists(harness, tls_ca_chain_filename):
# Test when the bucket doesn't exist.
head_bucket.reset_mock()
head_bucket.side_effect = ClientError(
error_response={"Error": {"Code": 1, "message": "fake error"}},
error_response={"Error": {"Code": "SomeFakeException", "message": "fake error"}},
operation_name="fake operation name",
)
harness.charm.backup._create_bucket_if_not_exists()
Expand All @@ -381,7 +381,7 @@ def test_create_bucket_if_not_exists(harness, tls_ca_chain_filename):
create.reset_mock()
wait_until_exists.reset_mock()
create.side_effect = ClientError(
error_response={"Error": {"Code": 1, "message": "fake error"}},
error_response={"Error": {"Code": "SomeFakeException", "message": "fake error"}},
operation_name="fake operation name",
)
with pytest.raises(ClientError):
Expand All @@ -391,9 +391,32 @@ def test_create_bucket_if_not_exists(harness, tls_ca_chain_filename):
create.assert_called_once()
wait_until_exists.assert_not_called()

# Test when the bucket creation fails with InvalidLocationConstraint.
head_bucket.reset_mock()
create.reset_mock()
wait_until_exists.reset_mock()
create.side_effect = ClientError(
error_response={
"Error": {"Code": "InvalidLocationConstraint", "message": "fake error"}
},
operation_name="fake operation name",
)
with pytest.raises(ClientError):
harness.charm.backup._create_bucket_if_not_exists()
assert False
head_bucket.assert_called_once()
want = [
call(CreateBucketConfiguration={"LocationConstraint": "test-region"}),
call(),
]
create.assert_has_calls(want)
wait_until_exists.assert_not_called()
wait_until_exists.assert_has_calls([call(), call()])

# Test when the bucket creation fails due to a timeout error.
head_bucket.reset_mock()
create.reset_mock()
wait_until_exists.reset_mock()
head_bucket.side_effect = botocore.exceptions.ConnectTimeoutError(
endpoint_url="fake endpoint URL"
)
Expand Down

0 comments on commit 8b48898

Please sign in to comment.