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
|
code = 409
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
kwargs.setdefault("template", "bucket_error")
|
||||||
|
self.templates["bucket_error"] = ERROR_WITH_BUCKET_NAME
|
||||||
super(BucketAlreadyExists, self).__init__(
|
super(BucketAlreadyExists, self).__init__(
|
||||||
"BucketAlreadyExists",
|
"BucketAlreadyExists",
|
||||||
(
|
(
|
||||||
|
@ -811,11 +811,16 @@ class ResponseObject(_TemplateEnvironmentMixin, ActionAuthenticatorMixin):
|
|||||||
try:
|
try:
|
||||||
new_bucket = self.backend.create_bucket(bucket_name, region_name)
|
new_bucket = self.backend.create_bucket(bucket_name, region_name)
|
||||||
except BucketAlreadyExists:
|
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:
|
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:
|
if "x-amz-acl" in request.headers:
|
||||||
# TODO: Support the XML-based ACL format
|
# TODO: Support the XML-based ACL format
|
||||||
@ -2662,3 +2667,13 @@ S3_BUCKET_LOCK_CONFIGURATION = """
|
|||||||
#</Rule>
|
#</Rule>
|
||||||
</ObjectLockConfiguration>
|
</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
|
@mock_s3
|
||||||
def test_bucket_create_force_us_east_1():
|
def test_bucket_create_force_us_east_1():
|
||||||
s3 = boto3.resource("s3", region_name=DEFAULT_REGION_NAME)
|
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 = s3_client.list_object_versions(Bucket=bucket_name, Prefix="file")
|
||||||
versions["Versions"].should.have.length_of(3)
|
versions["Versions"].should.have.length_of(3)
|
||||||
versions["Prefix"].should.equal("file")
|
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