s3api: Add basic support for ?tagging requests
https://docs.aws.amazon.com/cli/latest/userguide/cliv2-migration.html#cliv2-migration-s3-copy-metadata AWS CLI version 2 improves Amazon S3 handling of file properties and tags when performing multipart copies. We still don't supprt object tagging hence the aws s3 cp command fails for mulitpart copies with default options. This way get tagging request will receive an empty tagset in response and mulitpart copies will work fine Change-Id: I1f031b05025cafac00e86966c240aa5f7258d0bf
This commit is contained in:
parent
0b86f681f5
commit
6afefe1ad3
@ -31,6 +31,8 @@ from swift.common.middleware.s3api.controllers.logging import \
|
||||
LoggingStatusController
|
||||
from swift.common.middleware.s3api.controllers.versioning import \
|
||||
VersioningController
|
||||
from swift.common.middleware.s3api.controllers.tagging import \
|
||||
TaggingController
|
||||
|
||||
__all__ = [
|
||||
'Controller',
|
||||
@ -47,6 +49,7 @@ __all__ = [
|
||||
'LocationController',
|
||||
'LoggingStatusController',
|
||||
'VersioningController',
|
||||
'TaggingController',
|
||||
|
||||
'UnsupportedController',
|
||||
]
|
||||
|
57
swift/common/middleware/s3api/controllers/tagging.py
Normal file
57
swift/common/middleware/s3api/controllers/tagging.py
Normal file
@ -0,0 +1,57 @@
|
||||
# Copyright (c) 2014 OpenStack Foundation.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from swift.common.utils import public
|
||||
|
||||
from swift.common.middleware.s3api.controllers.base import Controller, \
|
||||
S3NotImplemented
|
||||
from swift.common.middleware.s3api.s3response import HTTPOk
|
||||
from swift.common.middleware.s3api.etree import Element, tostring, \
|
||||
SubElement
|
||||
|
||||
|
||||
class TaggingController(Controller):
|
||||
"""
|
||||
Handles the following APIs:
|
||||
|
||||
* GET Bucket and Object tagging
|
||||
* PUT Bucket and Object tagging
|
||||
* DELETE Bucket and Object tagging
|
||||
|
||||
"""
|
||||
@public
|
||||
def GET(self, req):
|
||||
"""
|
||||
Handles GET Bucket and Object tagging.
|
||||
"""
|
||||
elem = Element('Tagging')
|
||||
SubElement(elem, 'TagSet')
|
||||
body = tostring(elem)
|
||||
|
||||
return HTTPOk(body=body, content_type=None)
|
||||
|
||||
@public
|
||||
def PUT(self, req):
|
||||
"""
|
||||
Handles PUT Bucket and Object tagging.
|
||||
"""
|
||||
raise S3NotImplemented('The requested resource is not implemented')
|
||||
|
||||
@public
|
||||
def DELETE(self, req):
|
||||
"""
|
||||
Handles DELETE Bucket and Object tagging.
|
||||
"""
|
||||
raise S3NotImplemented('The requested resource is not implemented')
|
@ -45,7 +45,8 @@ from swift.common.middleware.s3api.controllers import ServiceController, \
|
||||
ObjectController, AclController, MultiObjectDeleteController, \
|
||||
LocationController, LoggingStatusController, PartController, \
|
||||
UploadController, UploadsController, VersioningController, \
|
||||
UnsupportedController, S3AclController, BucketController
|
||||
UnsupportedController, S3AclController, BucketController, \
|
||||
TaggingController
|
||||
from swift.common.middleware.s3api.s3response import AccessDenied, \
|
||||
InvalidArgument, InvalidDigest, BucketAlreadyOwnedByYou, \
|
||||
RequestTimeTooSkewed, S3Response, SignatureDoesNotMatch, \
|
||||
@ -1026,9 +1027,11 @@ class S3Request(swob.Request):
|
||||
return UploadsController
|
||||
if 'versioning' in self.params:
|
||||
return VersioningController
|
||||
if 'tagging' in self.params:
|
||||
return TaggingController
|
||||
|
||||
unsupported = ('notification', 'policy', 'requestPayment', 'torrent',
|
||||
'website', 'cors', 'tagging', 'restore')
|
||||
'website', 'cors', 'restore')
|
||||
if set(unsupported) & set(self.params):
|
||||
return UnsupportedController
|
||||
|
||||
|
@ -705,7 +705,24 @@ class TestS3ApiMiddleware(S3ApiTestCase):
|
||||
self._test_unsupported_resource('cors')
|
||||
|
||||
def test_tagging(self):
|
||||
self._test_unsupported_resource('tagging')
|
||||
req = Request.blank('/bucket?tagging',
|
||||
environ={'REQUEST_METHOD': 'GET'},
|
||||
headers={'Authorization': 'AWS test:tester:hmac',
|
||||
'Date': self.get_date_header()})
|
||||
status, headers, body = self.call_s3api(req)
|
||||
self.assertEqual(status.split()[0], '200')
|
||||
req = Request.blank('/bucket?tagging',
|
||||
environ={'REQUEST_METHOD': 'PUT'},
|
||||
headers={'Authorization': 'AWS test:tester:hmac',
|
||||
'Date': self.get_date_header()})
|
||||
status, headers, body = self.call_s3api(req)
|
||||
self.assertEqual(self._get_error_code(body), 'NotImplemented')
|
||||
req = Request.blank('/bucket?tagging',
|
||||
environ={'REQUEST_METHOD': 'DELETE'},
|
||||
headers={'Authorization': 'AWS test:tester:hmac',
|
||||
'Date': self.get_date_header()})
|
||||
status, headers, body = self.call_s3api(req)
|
||||
self.assertEqual(self._get_error_code(body), 'NotImplemented')
|
||||
|
||||
def test_restore(self):
|
||||
self._test_unsupported_resource('restore')
|
||||
|
Loading…
Reference in New Issue
Block a user