S3 - create_multipart_upload - support tags (#4548)
This commit is contained in:
parent
669e7048f1
commit
0bad68f9f0
@ -330,9 +330,11 @@ class FakeKey(BaseModel):
|
|||||||
|
|
||||||
|
|
||||||
class FakeMultipart(BaseModel):
|
class FakeMultipart(BaseModel):
|
||||||
def __init__(self, key_name, metadata):
|
def __init__(self, key_name, metadata, storage=None, tags=None):
|
||||||
self.key_name = key_name
|
self.key_name = key_name
|
||||||
self.metadata = metadata
|
self.metadata = metadata
|
||||||
|
self.storage = storage
|
||||||
|
self.tags = tags
|
||||||
self.parts = {}
|
self.parts = {}
|
||||||
self.partlist = [] # ordered list of part ID's
|
self.partlist = [] # ordered list of part ID's
|
||||||
rand_b64 = base64.b64encode(os.urandom(UPLOAD_ID_BYTES))
|
rand_b64 = base64.b64encode(os.urandom(UPLOAD_ID_BYTES))
|
||||||
@ -1834,9 +1836,10 @@ class S3Backend(BaseBackend):
|
|||||||
bucket = self.get_bucket(bucket_name)
|
bucket = self.get_bucket(bucket_name)
|
||||||
return len(bucket.multiparts[multipart_id].parts) >= next_part_number_marker
|
return len(bucket.multiparts[multipart_id].parts) >= next_part_number_marker
|
||||||
|
|
||||||
def create_multipart_upload(self, bucket_name, key_name, metadata, storage_type):
|
def create_multipart_upload(
|
||||||
multipart = FakeMultipart(key_name, metadata)
|
self, bucket_name, key_name, metadata, storage_type, tags
|
||||||
multipart.storage = storage_type
|
):
|
||||||
|
multipart = FakeMultipart(key_name, metadata, storage=storage_type, tags=tags)
|
||||||
|
|
||||||
bucket = self.get_bucket(bucket_name)
|
bucket = self.get_bucket(bucket_name)
|
||||||
bucket.multiparts[multipart.id] = multipart
|
bucket.multiparts[multipart.id] = multipart
|
||||||
|
@ -2009,9 +2009,10 @@ class ResponseObject(_TemplateEnvironmentMixin, ActionAuthenticatorMixin):
|
|||||||
|
|
||||||
if body == b"" and "uploads" in query:
|
if body == b"" and "uploads" in query:
|
||||||
metadata = metadata_from_headers(request.headers)
|
metadata = metadata_from_headers(request.headers)
|
||||||
|
tagging = self._tagging_from_headers(request.headers)
|
||||||
storage_type = request.headers.get("x-amz-storage-class", "STANDARD")
|
storage_type = request.headers.get("x-amz-storage-class", "STANDARD")
|
||||||
multipart_id = self.backend.create_multipart_upload(
|
multipart_id = self.backend.create_multipart_upload(
|
||||||
bucket_name, key_name, metadata, storage_type
|
bucket_name, key_name, metadata, storage_type, tagging
|
||||||
)
|
)
|
||||||
|
|
||||||
template = self.response_template(S3_MULTIPART_INITIATE_RESPONSE)
|
template = self.response_template(S3_MULTIPART_INITIATE_RESPONSE)
|
||||||
@ -2039,6 +2040,7 @@ class ResponseObject(_TemplateEnvironmentMixin, ActionAuthenticatorMixin):
|
|||||||
multipart=multipart,
|
multipart=multipart,
|
||||||
)
|
)
|
||||||
key.set_metadata(multipart.metadata)
|
key.set_metadata(multipart.metadata)
|
||||||
|
self.backend.set_key_tags(key, multipart.tags)
|
||||||
|
|
||||||
template = self.response_template(S3_MULTIPART_COMPLETE_RESPONSE)
|
template = self.response_template(S3_MULTIPART_COMPLETE_RESPONSE)
|
||||||
headers = {}
|
headers = {}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
from botocore.exceptions import ClientError
|
from botocore.exceptions import ClientError
|
||||||
from moto import mock_s3
|
from moto import mock_s3
|
||||||
import boto3
|
import boto3
|
||||||
|
import os
|
||||||
import pytest
|
import pytest
|
||||||
import sure # pylint: disable=unused-import
|
import sure # pylint: disable=unused-import
|
||||||
|
|
||||||
@ -52,3 +53,30 @@ def test_boto3_multipart_part_size():
|
|||||||
err["Message"].should.equal(
|
err["Message"].should.equal(
|
||||||
"The specified upload does not exist. The upload ID may be invalid, or the upload may have been aborted or completed."
|
"The specified upload does not exist. The upload ID may be invalid, or the upload may have been aborted or completed."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_s3
|
||||||
|
def test_multipart_upload_with_tags():
|
||||||
|
bucket = "mybucket"
|
||||||
|
key = "test/multipartuploadtag/file.txt"
|
||||||
|
tags = "a=b"
|
||||||
|
|
||||||
|
client = boto3.client("s3", region_name="us-east-1")
|
||||||
|
client.create_bucket(Bucket=bucket)
|
||||||
|
|
||||||
|
response = client.create_multipart_upload(Bucket=bucket, Key=key, Tagging=tags)
|
||||||
|
u = boto3.resource("s3").MultipartUpload(bucket, key, response["UploadId"])
|
||||||
|
parts = [
|
||||||
|
{
|
||||||
|
"ETag": u.Part(i).upload(Body=os.urandom(5 * (2 ** 20)))["ETag"],
|
||||||
|
"PartNumber": i,
|
||||||
|
}
|
||||||
|
for i in range(1, 3)
|
||||||
|
]
|
||||||
|
|
||||||
|
u.complete(MultipartUpload={"Parts": parts})
|
||||||
|
|
||||||
|
# check tags
|
||||||
|
response = client.get_object_tagging(Bucket=bucket, Key=key)
|
||||||
|
actual = {t["Key"]: t["Value"] for t in response.get("TagSet", [])}
|
||||||
|
actual.should.equal({"a": "b"})
|
||||||
|
Loading…
Reference in New Issue
Block a user