S3 - Correct error when creating a bucket that already exists (#4257)
This commit is contained in:
parent
0659ac6192
commit
c53183db70
@ -63,6 +63,8 @@ class BucketAlreadyExists(BucketError):
|
||||
code = 409
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
kwargs.setdefault("template", "bucket_error")
|
||||
self.templates["bucket_error"] = ERROR_WITH_BUCKET_NAME
|
||||
super(BucketAlreadyExists, self).__init__(
|
||||
"BucketAlreadyExists",
|
||||
(
|
||||
|
@ -811,11 +811,16 @@ class ResponseObject(_TemplateEnvironmentMixin, ActionAuthenticatorMixin):
|
||||
try:
|
||||
new_bucket = self.backend.create_bucket(bucket_name, region_name)
|
||||
except BucketAlreadyExists:
|
||||
if region_name == DEFAULT_REGION_NAME:
|
||||
# us-east-1 has different behavior
|
||||
new_bucket = self.backend.get_bucket(bucket_name)
|
||||
new_bucket = self.backend.get_bucket(bucket_name)
|
||||
if (
|
||||
new_bucket.region_name == DEFAULT_REGION_NAME
|
||||
and region_name == DEFAULT_REGION_NAME
|
||||
):
|
||||
# us-east-1 has different behavior - creating a bucket there is an idempotent operation
|
||||
pass
|
||||
else:
|
||||
raise
|
||||
template = self.response_template(S3_DUPLICATE_BUCKET_ERROR)
|
||||
return 409, {}, template.render(bucket_name=bucket_name)
|
||||
|
||||
if "x-amz-acl" in request.headers:
|
||||
# TODO: Support the XML-based ACL format
|
||||
@ -2662,3 +2667,13 @@ S3_BUCKET_LOCK_CONFIGURATION = """
|
||||
#</Rule>
|
||||
</ObjectLockConfiguration>
|
||||
"""
|
||||
|
||||
S3_DUPLICATE_BUCKET_ERROR = """<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Error>
|
||||
<Code>BucketAlreadyOwnedByYou</Code>
|
||||
<Message>Your previous request to create the named bucket succeeded and you already own it.</Message>
|
||||
<BucketName>{{ bucket_name }}</BucketName>
|
||||
<RequestId>44425877V1D0A2F9</RequestId>
|
||||
<HostId>9Gjjt1m+cjU4OPvX9O9/8RuvnG41MRb/18Oux2o5H5MY7ISNTlXN+Dz9IG62/ILVxhAGI0qyPfg=</HostId>
|
||||
</Error>
|
||||
"""
|
||||
|
@ -2106,19 +2106,6 @@ def test_boto3_bucket_create():
|
||||
)
|
||||
|
||||
|
||||
@mock_s3
|
||||
def test_bucket_create_duplicate():
|
||||
s3 = boto3.resource("s3", region_name="us-west-2")
|
||||
s3.create_bucket(
|
||||
Bucket="blah", CreateBucketConfiguration={"LocationConstraint": "us-west-2"}
|
||||
)
|
||||
with pytest.raises(ClientError) as exc:
|
||||
s3.create_bucket(
|
||||
Bucket="blah", CreateBucketConfiguration={"LocationConstraint": "us-west-2"}
|
||||
)
|
||||
exc.value.response["Error"]["Code"].should.equal("BucketAlreadyExists")
|
||||
|
||||
|
||||
@mock_s3
|
||||
def test_bucket_create_force_us_east_1():
|
||||
s3 = boto3.resource("s3", region_name=DEFAULT_REGION_NAME)
|
||||
@ -5353,3 +5340,74 @@ def test_get_object_versions_with_prefix():
|
||||
versions = s3_client.list_object_versions(Bucket=bucket_name, Prefix="file")
|
||||
versions["Versions"].should.have.length_of(3)
|
||||
versions["Prefix"].should.equal("file")
|
||||
|
||||
|
||||
@mock_s3
|
||||
def test_create_bucket_duplicate():
|
||||
bucket_name = "same-bucket-test-1371"
|
||||
alternate_region = "eu-north-1"
|
||||
# Create it in the default region
|
||||
default_client = boto3.client("s3", region_name=DEFAULT_REGION_NAME)
|
||||
default_client.create_bucket(Bucket=bucket_name)
|
||||
|
||||
# Create it again in the same region - should just return that same bucket
|
||||
default_client.create_bucket(Bucket=bucket_name)
|
||||
|
||||
# Create the bucket in a different region - should return an error
|
||||
diff_client = boto3.client("s3", region_name=alternate_region)
|
||||
with pytest.raises(ClientError) as ex:
|
||||
diff_client.create_bucket(
|
||||
Bucket=bucket_name,
|
||||
CreateBucketConfiguration={"LocationConstraint": alternate_region},
|
||||
)
|
||||
err = ex.value.response["Error"]
|
||||
err["Code"].should.equal("BucketAlreadyOwnedByYou")
|
||||
err["Message"].should.equal(
|
||||
"Your previous request to create the named bucket succeeded and you already own it."
|
||||
)
|
||||
err["BucketName"].should.equal(bucket_name)
|
||||
|
||||
# Try this again - but creating the bucket in a non-default region in the first place
|
||||
bucket_name = "same-bucket-nondefault-region-test-1371"
|
||||
diff_client.create_bucket(
|
||||
Bucket=bucket_name,
|
||||
CreateBucketConfiguration={"LocationConstraint": alternate_region},
|
||||
)
|
||||
|
||||
# Recreating the bucket in the same non-default region should fail
|
||||
with pytest.raises(ClientError) as ex:
|
||||
diff_client.create_bucket(
|
||||
Bucket=bucket_name,
|
||||
CreateBucketConfiguration={"LocationConstraint": alternate_region},
|
||||
)
|
||||
err = ex.value.response["Error"]
|
||||
err["Code"].should.equal("BucketAlreadyOwnedByYou")
|
||||
err["Message"].should.equal(
|
||||
"Your previous request to create the named bucket succeeded and you already own it."
|
||||
)
|
||||
err["BucketName"].should.equal(bucket_name)
|
||||
|
||||
# Recreating the bucket in the default region should fail
|
||||
diff_client = boto3.client("s3", region_name=DEFAULT_REGION_NAME)
|
||||
with pytest.raises(ClientError) as ex:
|
||||
diff_client.create_bucket(Bucket=bucket_name)
|
||||
err = ex.value.response["Error"]
|
||||
err["Code"].should.equal("BucketAlreadyOwnedByYou")
|
||||
err["Message"].should.equal(
|
||||
"Your previous request to create the named bucket succeeded and you already own it."
|
||||
)
|
||||
err["BucketName"].should.equal(bucket_name)
|
||||
|
||||
# Recreating the bucket in a third region should fail
|
||||
diff_client = boto3.client("s3", region_name="ap-northeast-1")
|
||||
with pytest.raises(ClientError) as ex:
|
||||
diff_client.create_bucket(
|
||||
Bucket=bucket_name,
|
||||
CreateBucketConfiguration={"LocationConstraint": "ap-northeast-1"},
|
||||
)
|
||||
err = ex.value.response["Error"]
|
||||
err["Code"].should.equal("BucketAlreadyOwnedByYou")
|
||||
err["Message"].should.equal(
|
||||
"Your previous request to create the named bucket succeeded and you already own it."
|
||||
)
|
||||
err["BucketName"].should.equal(bucket_name)
|
||||
|
Loading…
Reference in New Issue
Block a user