From 3f6d624c7b089736482c00ff991445ec35a35865 Mon Sep 17 00:00:00 2001 From: P R <25353498+BigUstad@users.noreply.github.com> Date: Sat, 23 May 2020 11:09:35 -0700 Subject: [PATCH] add gateway object tagging support (#9124) --- cmd/fs-v1.go | 19 +++--- cmd/gateway-unsupported.go | 17 ++++-- cmd/gateway/nas/gateway-nas.go | 4 ++ cmd/gateway/s3/gateway-s3-utils.go | 4 +- cmd/gateway/s3/gateway-s3.go | 81 ++++++++++++++++++++++++- cmd/http/headers.go | 2 +- cmd/object-api-interface.go | 9 ++- cmd/object-handlers.go | 36 +++++++++-- cmd/xl-sets.go | 22 ++++--- cmd/xl-v1-bucket.go | 4 ++ cmd/xl-v1-object.go | 14 ++--- cmd/xl-zones.go | 28 +++++---- go.mod | 2 +- go.sum | 4 ++ mint/run/core/aws-sdk-go/quick-tests.go | 2 +- 15 files changed, 193 insertions(+), 55 deletions(-) diff --git a/cmd/fs-v1.go b/cmd/fs-v1.go index 9bedbb50b..61be1b13b 100644 --- a/cmd/fs-v1.go +++ b/cmd/fs-v1.go @@ -1218,8 +1218,8 @@ func (fs *FSObjects) ListObjects(ctx context.Context, bucket, prefix, marker, de fs.listDirFactory(), fs.getObjectInfo, fs.getObjectInfo) } -// GetObjectTag - get object tags from an existing object -func (fs *FSObjects) GetObjectTag(ctx context.Context, bucket, object string) (*tags.Tags, error) { +// GetObjectTags - get object tags from an existing object +func (fs *FSObjects) GetObjectTags(ctx context.Context, bucket, object string) (*tags.Tags, error) { oi, err := fs.GetObjectInfo(ctx, bucket, object, ObjectOptions{}) if err != nil { return nil, err @@ -1228,8 +1228,8 @@ func (fs *FSObjects) GetObjectTag(ctx context.Context, bucket, object string) (* return tags.ParseObjectTags(oi.UserTags) } -// PutObjectTag - replace or add tags to an existing object -func (fs *FSObjects) PutObjectTag(ctx context.Context, bucket, object string, tags string) error { +// PutObjectTags - replace or add tags to an existing object +func (fs *FSObjects) PutObjectTags(ctx context.Context, bucket, object string, tags string) error { fsMetaPath := pathJoin(fs.fsPath, minioMetaBucket, bucketMetaPrefix, bucket, object, fs.metaJSONFile) fsMeta := fsMetaV1{} wlk, err := fs.rwPool.Write(fsMetaPath) @@ -1260,9 +1260,9 @@ func (fs *FSObjects) PutObjectTag(ctx context.Context, bucket, object string, ta return nil } -// DeleteObjectTag - delete object tags from an existing object -func (fs *FSObjects) DeleteObjectTag(ctx context.Context, bucket, object string) error { - return fs.PutObjectTag(ctx, bucket, object, "") +// DeleteObjectTags - delete object tags from an existing object +func (fs *FSObjects) DeleteObjectTags(ctx context.Context, bucket, object string) error { + return fs.PutObjectTags(ctx, bucket, object, "") } // ReloadFormat - no-op for fs, Valid only for XL. @@ -1360,6 +1360,11 @@ func (fs *FSObjects) IsCompressionSupported() bool { return true } +// IsTaggingSupported returns true, object tagging is supported in fs object layer. +func (fs *FSObjects) IsTaggingSupported() bool { + return true +} + // IsReady - Check if the backend disk is ready to accept traffic. func (fs *FSObjects) IsReady(_ context.Context) bool { if _, err := os.Stat(fs.fsPath); err != nil { diff --git a/cmd/gateway-unsupported.go b/cmd/gateway-unsupported.go index be840ed42..74c03d349 100644 --- a/cmd/gateway-unsupported.go +++ b/cmd/gateway-unsupported.go @@ -228,20 +228,20 @@ func (a GatewayUnsupported) DeleteBucketTagging(ctx context.Context, bucket stri return NotImplemented{} } -// PutObjectTag - not implemented. -func (a GatewayUnsupported) PutObjectTag(ctx context.Context, bucket, object string, tags string) error { +// PutObjectTags - not implemented. +func (a GatewayUnsupported) PutObjectTags(ctx context.Context, bucket, object string, tags string) error { logger.LogIf(ctx, NotImplemented{}) return NotImplemented{} } -// GetObjectTag - not implemented. -func (a GatewayUnsupported) GetObjectTag(ctx context.Context, bucket, object string) (*tags.Tags, error) { +// GetObjectTags - not implemented. +func (a GatewayUnsupported) GetObjectTags(ctx context.Context, bucket, object string) (*tags.Tags, error) { logger.LogIf(ctx, NotImplemented{}) return nil, NotImplemented{} } -// DeleteObjectTag - not implemented. -func (a GatewayUnsupported) DeleteObjectTag(ctx context.Context, bucket, object string) error { +// DeleteObjectTags - not implemented. +func (a GatewayUnsupported) DeleteObjectTags(ctx context.Context, bucket, object string) error { logger.LogIf(ctx, NotImplemented{}) return NotImplemented{} } @@ -261,6 +261,11 @@ func (a GatewayUnsupported) IsEncryptionSupported() bool { return false } +// IsTaggingSupported returns whether object tagging is supported or not for this layer. +func (a GatewayUnsupported) IsTaggingSupported() bool { + return false +} + // IsCompressionSupported returns whether compression is applicable for this layer. func (a GatewayUnsupported) IsCompressionSupported() bool { return false diff --git a/cmd/gateway/nas/gateway-nas.go b/cmd/gateway/nas/gateway-nas.go index e257c234e..d2f9b6a1d 100644 --- a/cmd/gateway/nas/gateway-nas.go +++ b/cmd/gateway/nas/gateway-nas.go @@ -137,3 +137,7 @@ func (n *nasObjects) IsReady(ctx context.Context) bool { sinfo := n.ObjectLayer.StorageInfo(ctx, false) return sinfo.Backend.Type == minio.BackendFS } + +func (n *nasObjects) IsTaggingSupported() bool { + return true +} diff --git a/cmd/gateway/s3/gateway-s3-utils.go b/cmd/gateway/s3/gateway-s3-utils.go index af7ec53ae..784f244ad 100644 --- a/cmd/gateway/s3/gateway-s3-utils.go +++ b/cmd/gateway/s3/gateway-s3-utils.go @@ -16,7 +16,9 @@ package s3 -import minio "github.com/minio/minio/cmd" +import ( + minio "github.com/minio/minio/cmd" +) // List of header keys to be filtered, usually // from all S3 API http responses. diff --git a/cmd/gateway/s3/gateway-s3.go b/cmd/gateway/s3/gateway-s3.go index 3d388413a..4b847aa6c 100644 --- a/cmd/gateway/s3/gateway-s3.go +++ b/cmd/gateway/s3/gateway-s3.go @@ -29,10 +29,12 @@ import ( "github.com/minio/cli" miniogo "github.com/minio/minio-go/v6" "github.com/minio/minio-go/v6/pkg/credentials" + "github.com/minio/minio-go/v6/pkg/tags" minio "github.com/minio/minio/cmd" "github.com/minio/minio-go/v6/pkg/encrypt" "github.com/minio/minio-go/v6/pkg/s3utils" + xhttp "github.com/minio/minio/cmd/http" "github.com/minio/minio/cmd/logger" "github.com/minio/minio/pkg/auth" "github.com/minio/minio/pkg/bucket/policy" @@ -459,11 +461,25 @@ func (l *s3Objects) GetObjectInfo(ctx context.Context, bucket string, object str // PutObject creates a new object with the incoming data, func (l *s3Objects) PutObject(ctx context.Context, bucket string, object string, r *minio.PutObjReader, opts minio.ObjectOptions) (objInfo minio.ObjectInfo, err error) { data := r.Reader - - oi, err := l.Client.PutObject(bucket, object, data, data.Size(), data.MD5Base64String(), data.SHA256HexString(), minio.ToMinioClientMetadata(opts.UserDefined), opts.ServerSideEncryption) + var tagMap map[string]string + if tagstr, ok := opts.UserDefined[xhttp.AmzObjectTagging]; ok && tagstr != "" { + tagObj, err := tags.ParseObjectTags(tagstr) + if err != nil { + return objInfo, minio.ErrorRespToObjectError(err, bucket, object) + } + tagMap = tagObj.ToMap() + delete(opts.UserDefined, xhttp.AmzObjectTagging) + } + putOpts := miniogo.PutObjectOptions{ + UserMetadata: opts.UserDefined, + ServerSideEncryption: opts.ServerSideEncryption, + UserTags: tagMap, + } + oi, err := l.Client.PutObject(bucket, object, data, data.Size(), data.MD5Base64String(), data.SHA256HexString(), putOpts) if err != nil { return objInfo, minio.ErrorRespToObjectError(err, bucket, object) } + // On success, populate the key & metadata so they are present in the notification oi.Key = object oi.Metadata = minio.ToMinioClientObjectInfoMetadata(opts.UserDefined) @@ -490,6 +506,7 @@ func (l *s3Objects) CopyObject(ctx context.Context, srcBucket string, srcObject if dstOpts.ServerSideEncryption != nil { dstOpts.ServerSideEncryption.Marshal(header) } + for k, v := range header { srcInfo.UserDefined[k] = v[0] } @@ -530,8 +547,21 @@ func (l *s3Objects) ListMultipartUploads(ctx context.Context, bucket string, pre // NewMultipartUpload upload object in multiple parts func (l *s3Objects) NewMultipartUpload(ctx context.Context, bucket string, object string, o minio.ObjectOptions) (uploadID string, err error) { + var tagMap map[string]string + if tagStr, ok := o.UserDefined[xhttp.AmzObjectTagging]; ok { + tagObj, err := tags.Parse(tagStr, true) + if err != nil { + return uploadID, minio.ErrorRespToObjectError(err, bucket, object) + } + tagMap = tagObj.ToMap() + delete(o.UserDefined, xhttp.AmzObjectTagging) + } // Create PutObject options - opts := miniogo.PutObjectOptions{UserMetadata: o.UserDefined, ServerSideEncryption: o.ServerSideEncryption} + opts := miniogo.PutObjectOptions{ + UserMetadata: o.UserDefined, + ServerSideEncryption: o.ServerSideEncryption, + UserTags: tagMap, + } uploadID, err = l.Client.NewMultipartUpload(bucket, object, opts) if err != nil { return uploadID, minio.ErrorRespToObjectError(err, bucket, object) @@ -643,6 +673,47 @@ func (l *s3Objects) DeleteBucketPolicy(ctx context.Context, bucket string) error return nil } +// GetObjectTags gets the tags set on the object +func (l *s3Objects) GetObjectTags(ctx context.Context, bucket string, object string) (*tags.Tags, error) { + var err error + var tagObj *tags.Tags + var tagStr string + var opts minio.ObjectOptions + + if _, err = l.GetObjectInfo(ctx, bucket, object, opts); err != nil { + return nil, minio.ErrorRespToObjectError(err, bucket, object) + } + + if tagStr, err = l.Client.GetObjectTagging(bucket, object); err != nil { + return nil, minio.ErrorRespToObjectError(err, bucket, object) + } + + if tagObj, err = tags.ParseObjectXML(strings.NewReader(tagStr)); err != nil { + return nil, minio.ErrorRespToObjectError(err, bucket, object) + } + return tagObj, err +} + +// PutObjectTags attaches the tags to the object +func (l *s3Objects) PutObjectTags(ctx context.Context, bucket, object string, tagStr string) error { + tagObj, err := tags.Parse(tagStr, true) + if err != nil { + return minio.ErrorRespToObjectError(err, bucket, object) + } + if err = l.Client.PutObjectTagging(bucket, object, tagObj.ToMap()); err != nil { + return minio.ErrorRespToObjectError(err, bucket, object) + } + return nil +} + +// DeleteObjectTags removes the tags attached to the object +func (l *s3Objects) DeleteObjectTags(ctx context.Context, bucket, object string) error { + if err := l.Client.RemoveObjectTagging(bucket, object); err != nil { + return minio.ErrorRespToObjectError(err, bucket, object) + } + return nil +} + // IsCompressionSupported returns whether compression is applicable for this layer. func (l *s3Objects) IsCompressionSupported() bool { return false @@ -657,3 +728,7 @@ func (l *s3Objects) IsEncryptionSupported() bool { func (l *s3Objects) IsReady(ctx context.Context) bool { return minio.IsBackendOnline(ctx, l.HTTPClient, l.Client.EndpointURL().String()) } + +func (l *s3Objects) IsTaggingSupported() bool { + return true +} diff --git a/cmd/http/headers.go b/cmd/http/headers.go index 982a9ae4d..261ac5911 100644 --- a/cmd/http/headers.go +++ b/cmd/http/headers.go @@ -58,7 +58,7 @@ const ( // S3 object tagging AmzObjectTagging = "X-Amz-Tagging" - AmzTagCount = "X-Amz-Tag-Count" + AmzTagCount = "X-Amz-Tagging-Count" AmzTagDirective = "X-Amz-Tagging-Directive" // S3 extensions diff --git a/cmd/object-api-interface.go b/cmd/object-api-interface.go index 6134a72f7..5b82e941f 100644 --- a/cmd/object-api-interface.go +++ b/cmd/object-api-interface.go @@ -123,8 +123,11 @@ type ObjectLayer interface { // Check Readiness IsReady(ctx context.Context) bool + // Object Tagging Support check. + IsTaggingSupported() bool + // ObjectTagging operations - PutObjectTag(context.Context, string, string, string) error - GetObjectTag(context.Context, string, string) (*tags.Tags, error) - DeleteObjectTag(context.Context, string, string) error + PutObjectTags(context.Context, string, string, string) error + GetObjectTags(context.Context, string, string) (*tags.Tags, error) + DeleteObjectTags(context.Context, string, string) error } diff --git a/cmd/object-handlers.go b/cmd/object-handlers.go index 8644bd9ac..eb9659dc6 100644 --- a/cmd/object-handlers.go +++ b/cmd/object-handlers.go @@ -1072,6 +1072,7 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re // If x-amz-tagging-directive header is REPLACE, get passed tags. if isDirectiveReplace(r.Header.Get(xhttp.AmzTagDirective)) { objTags = r.Header.Get(xhttp.AmzObjectTagging) + srcInfo.UserDefined[xhttp.AmzTagDirective] = replaceDirective if _, err := tags.ParseObjectTags(objTags); err != nil { writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return @@ -1147,8 +1148,18 @@ func (api objectAPIHandlers) CopyObjectHandler(w http.ResponseWriter, r *http.Re writeErrorResponse(ctx, w, toAPIError(ctx, rerr), r.URL, guessIsBrowserReq(r)) return } + tag, err := tags.ParseObjectTags(objTags) + if err != nil { + writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) + return + } + opts := miniogo.PutObjectOptions{ + UserMetadata: srcInfo.UserDefined, + ServerSideEncryption: dstOpts.ServerSideEncryption, + UserTags: tag.ToMap(), + } remoteObjInfo, rerr := client.PutObject(dstBucket, dstObject, srcInfo.Reader, - srcInfo.Size, "", "", srcInfo.UserDefined, dstOpts.ServerSideEncryption) + srcInfo.Size, "", "", opts) if rerr != nil { writeErrorResponse(ctx, w, toAPIError(ctx, rerr), r.URL, guessIsBrowserReq(r)) return @@ -1284,6 +1295,11 @@ func (api objectAPIHandlers) PutObjectHandler(w http.ResponseWriter, r *http.Req } if objTags := r.Header.Get(xhttp.AmzObjectTagging); objTags != "" { + if !objectAPI.IsTaggingSupported() { + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r)) + return + } + if _, err := tags.ParseObjectTags(objTags); err != nil { writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return @@ -2946,6 +2962,10 @@ func (api objectAPIHandlers) GetObjectTaggingHandler(w http.ResponseWriter, r *h return } + if !objAPI.IsTaggingSupported() { + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r)) + return + } // Allow getObjectTagging if policy action is set. if s3Error := checkRequestAuthType(ctx, r, policy.GetObjectTaggingAction, bucket, object); s3Error != ErrNone { writeErrorResponse(ctx, w, errorCodes.ToAPIErr(s3Error), r.URL, guessIsBrowserReq(r)) @@ -2953,7 +2973,7 @@ func (api objectAPIHandlers) GetObjectTaggingHandler(w http.ResponseWriter, r *h } // Get object tags - tags, err := objAPI.GetObjectTag(ctx, bucket, object) + tags, err := objAPI.GetObjectTags(ctx, bucket, object) if err != nil { writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return @@ -2980,6 +3000,10 @@ func (api objectAPIHandlers) PutObjectTaggingHandler(w http.ResponseWriter, r *h writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) return } + if !objAPI.IsTaggingSupported() { + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r)) + return + } // Allow putObjectTagging if policy action is set if s3Error := checkRequestAuthType(ctx, r, policy.PutObjectTaggingAction, bucket, object); s3Error != ErrNone { @@ -2994,7 +3018,7 @@ func (api objectAPIHandlers) PutObjectTaggingHandler(w http.ResponseWriter, r *h } // Put object tags - err = objAPI.PutObjectTag(ctx, bucket, object, tags.String()) + err = objAPI.PutObjectTags(ctx, bucket, object, tags.String()) if err != nil { writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return @@ -3013,6 +3037,10 @@ func (api objectAPIHandlers) DeleteObjectTaggingHandler(w http.ResponseWriter, r writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL, guessIsBrowserReq(r)) return } + if !objAPI.IsTaggingSupported() { + writeErrorResponse(ctx, w, errorCodes.ToAPIErr(ErrNotImplemented), r.URL, guessIsBrowserReq(r)) + return + } vars := mux.Vars(r) bucket := vars["bucket"] @@ -3029,7 +3057,7 @@ func (api objectAPIHandlers) DeleteObjectTaggingHandler(w http.ResponseWriter, r } // Delete object tags - if err = objAPI.DeleteObjectTag(ctx, bucket, object); err != nil && err != errConfigNotFound { + if err = objAPI.DeleteObjectTags(ctx, bucket, object); err != nil && err != errConfigNotFound { writeErrorResponse(ctx, w, toAPIError(ctx, err), r.URL, guessIsBrowserReq(r)) return } diff --git a/cmd/xl-sets.go b/cmd/xl-sets.go index a42f89aa8..23b904f84 100644 --- a/cmd/xl-sets.go +++ b/cmd/xl-sets.go @@ -588,6 +588,10 @@ func (s *xlSets) IsCompressionSupported() bool { return s.getHashedSet("").IsCompressionSupported() } +func (s *xlSets) IsTaggingSupported() bool { + return true +} + // DeleteBucket - deletes a bucket on all sets simultaneously, // even if one of the sets fail to delete buckets, we proceed to // undo a successful operation. @@ -1684,19 +1688,19 @@ func (s *xlSets) HealObjects(ctx context.Context, bucket, prefix string, opts ma return nil } -// PutObjectTag - replace or add tags to an existing object -func (s *xlSets) PutObjectTag(ctx context.Context, bucket, object string, tags string) error { - return s.getHashedSet(object).PutObjectTag(ctx, bucket, object, tags) +// PutObjectTags - replace or add tags to an existing object +func (s *xlSets) PutObjectTags(ctx context.Context, bucket, object string, tags string) error { + return s.getHashedSet(object).PutObjectTags(ctx, bucket, object, tags) } -// DeleteObjectTag - delete object tags from an existing object -func (s *xlSets) DeleteObjectTag(ctx context.Context, bucket, object string) error { - return s.getHashedSet(object).DeleteObjectTag(ctx, bucket, object) +// DeleteObjectTags - delete object tags from an existing object +func (s *xlSets) DeleteObjectTags(ctx context.Context, bucket, object string) error { + return s.getHashedSet(object).DeleteObjectTags(ctx, bucket, object) } -// GetObjectTag - get object tags from an existing object -func (s *xlSets) GetObjectTag(ctx context.Context, bucket, object string) (*tags.Tags, error) { - return s.getHashedSet(object).GetObjectTag(ctx, bucket, object) +// GetObjectTags - get object tags from an existing object +func (s *xlSets) GetObjectTags(ctx context.Context, bucket, object string) (*tags.Tags, error) { + return s.getHashedSet(object).GetObjectTags(ctx, bucket, object) } // GetMetrics - no op diff --git a/cmd/xl-v1-bucket.go b/cmd/xl-v1-bucket.go index 9f42860fd..5c1cf6a38 100644 --- a/cmd/xl-v1-bucket.go +++ b/cmd/xl-v1-bucket.go @@ -269,3 +269,7 @@ func (xl xlObjects) IsEncryptionSupported() bool { func (xl xlObjects) IsCompressionSupported() bool { return true } + +func (xl xlObjects) IsTaggingSupported() bool { + return true +} diff --git a/cmd/xl-v1-object.go b/cmd/xl-v1-object.go index 61cadc0fe..4adb7754a 100644 --- a/cmd/xl-v1-object.go +++ b/cmd/xl-v1-object.go @@ -1009,8 +1009,8 @@ func (xl xlObjects) addPartialUpload(bucket, key string) { } } -// PutObjectTag - replace or add tags to an existing object -func (xl xlObjects) PutObjectTag(ctx context.Context, bucket, object string, tags string) error { +// PutObjectTags - replace or add tags to an existing object +func (xl xlObjects) PutObjectTags(ctx context.Context, bucket, object string, tags string) error { disks := xl.getDisks() // Read metadata associated with the object from all disks. @@ -1046,13 +1046,13 @@ func (xl xlObjects) PutObjectTag(ctx context.Context, bucket, object string, tag return nil } -// DeleteObjectTag - delete object tags from an existing object -func (xl xlObjects) DeleteObjectTag(ctx context.Context, bucket, object string) error { - return xl.PutObjectTag(ctx, bucket, object, "") +// DeleteObjectTags - delete object tags from an existing object +func (xl xlObjects) DeleteObjectTags(ctx context.Context, bucket, object string) error { + return xl.PutObjectTags(ctx, bucket, object, "") } -// GetObjectTag - get object tags from an existing object -func (xl xlObjects) GetObjectTag(ctx context.Context, bucket, object string) (*tags.Tags, error) { +// GetObjectTags - get object tags from an existing object +func (xl xlObjects) GetObjectTags(ctx context.Context, bucket, object string) (*tags.Tags, error) { // GetObjectInfo will return tag value as well oi, err := xl.GetObjectInfo(ctx, bucket, object, ObjectOptions{}) if err != nil { diff --git a/cmd/xl-zones.go b/cmd/xl-zones.go index c8a794544..4049cc81a 100644 --- a/cmd/xl-zones.go +++ b/cmd/xl-zones.go @@ -1223,6 +1223,10 @@ func (z *xlZones) IsCompressionSupported() bool { return true } +func (z *xlZones) IsTaggingSupported() bool { + return true +} + // DeleteBucket - deletes a bucket on all zones simultaneously, // even if one of the zones fail to delete buckets, we proceed to // undo a successful operation. @@ -1538,13 +1542,13 @@ func (z *xlZones) IsReady(ctx context.Context) bool { return z.zones[0].IsReady(ctx) } -// PutObjectTag - replace or add tags to an existing object -func (z *xlZones) PutObjectTag(ctx context.Context, bucket, object string, tags string) error { +// PutObjectTags - replace or add tags to an existing object +func (z *xlZones) PutObjectTags(ctx context.Context, bucket, object string, tags string) error { if z.SingleZone() { - return z.zones[0].PutObjectTag(ctx, bucket, object, tags) + return z.zones[0].PutObjectTags(ctx, bucket, object, tags) } for _, zone := range z.zones { - err := zone.PutObjectTag(ctx, bucket, object, tags) + err := zone.PutObjectTags(ctx, bucket, object, tags) if err != nil { if isErrBucketNotFound(err) { continue @@ -1558,13 +1562,13 @@ func (z *xlZones) PutObjectTag(ctx context.Context, bucket, object string, tags } } -// DeleteObjectTag - delete object tags from an existing object -func (z *xlZones) DeleteObjectTag(ctx context.Context, bucket, object string) error { +// DeleteObjectTags - delete object tags from an existing object +func (z *xlZones) DeleteObjectTags(ctx context.Context, bucket, object string) error { if z.SingleZone() { - return z.zones[0].DeleteObjectTag(ctx, bucket, object) + return z.zones[0].DeleteObjectTags(ctx, bucket, object) } for _, zone := range z.zones { - err := zone.DeleteObjectTag(ctx, bucket, object) + err := zone.DeleteObjectTags(ctx, bucket, object) if err != nil { if isErrBucketNotFound(err) { continue @@ -1578,13 +1582,13 @@ func (z *xlZones) DeleteObjectTag(ctx context.Context, bucket, object string) er } } -// GetObjectTag - get object tags from an existing object -func (z *xlZones) GetObjectTag(ctx context.Context, bucket, object string) (*tags.Tags, error) { +// GetObjectTags - get object tags from an existing object +func (z *xlZones) GetObjectTags(ctx context.Context, bucket, object string) (*tags.Tags, error) { if z.SingleZone() { - return z.zones[0].GetObjectTag(ctx, bucket, object) + return z.zones[0].GetObjectTags(ctx, bucket, object) } for _, zone := range z.zones { - tags, err := zone.GetObjectTag(ctx, bucket, object) + tags, err := zone.GetObjectTags(ctx, bucket, object) if err != nil { if isErrBucketNotFound(err) { continue diff --git a/go.mod b/go.mod index 672ccc2da..8a4a5db64 100644 --- a/go.mod +++ b/go.mod @@ -66,7 +66,7 @@ require ( github.com/minio/hdfs/v3 v3.0.1 github.com/minio/highwayhash v1.0.0 github.com/minio/lsync v1.0.1 - github.com/minio/minio-go/v6 v6.0.55-0.20200425081427-89eebdef2af0 + github.com/minio/minio-go/v6 v6.0.56-0.20200522164946-44a5f2e3b76b github.com/minio/parquet-go v0.0.0-20200414234858-838cfa8aae61 github.com/minio/sha256-simd v0.1.1 github.com/minio/simdjson-go v0.1.5-0.20200303142138-b17fe061ea37 diff --git a/go.sum b/go.sum index d38fda368..97fb592ad 100644 --- a/go.sum +++ b/go.sum @@ -267,6 +267,10 @@ github.com/minio/lsync v1.0.1/go.mod h1:tCFzfo0dlvdGl70IT4IAK/5Wtgb0/BrTmo/jE8pA github.com/minio/minio-go/v6 v6.0.53/go.mod h1:DIvC/IApeHX8q1BAMVCXSXwpmrmM+I+iBvhvztQorfI= github.com/minio/minio-go/v6 v6.0.55-0.20200425081427-89eebdef2af0 h1:PdHKpM9h2vqCDr1AjJdK8e/6tRdOSjUNzIqeNmxu7ak= github.com/minio/minio-go/v6 v6.0.55-0.20200425081427-89eebdef2af0/go.mod h1:KQMM+/44DSlSGSQWSfRrAZ12FVMmpWNuX37i2AX0jfI= +github.com/minio/minio-go/v6 v6.0.56-0.20200522005053-e9bc14bbccf9 h1:GpjSzFSjmNL9+SOzdJaQ6vxdvpFjhJR+xjtoK00Rle4= +github.com/minio/minio-go/v6 v6.0.56-0.20200522005053-e9bc14bbccf9/go.mod h1:KQMM+/44DSlSGSQWSfRrAZ12FVMmpWNuX37i2AX0jfI= +github.com/minio/minio-go/v6 v6.0.56-0.20200522164946-44a5f2e3b76b h1:hY8tAl7MwUuUB9ZqVDXEnrIqCuEy3dfU1RH0cZ7gu+o= +github.com/minio/minio-go/v6 v6.0.56-0.20200522164946-44a5f2e3b76b/go.mod h1:KQMM+/44DSlSGSQWSfRrAZ12FVMmpWNuX37i2AX0jfI= github.com/minio/parquet-go v0.0.0-20200414234858-838cfa8aae61 h1:pUSI/WKPdd77gcuoJkSzhJ4wdS8OMDOsOu99MtpXEQA= github.com/minio/parquet-go v0.0.0-20200414234858-838cfa8aae61/go.mod h1:4trzEJ7N1nBTd5Tt7OCZT5SEin+WiAXpdJ/WgPkESA8= github.com/minio/sha256-simd v0.1.1 h1:5QHSlgo3nt5yKOJrC7W8w7X+NFl8cMPZm96iu8kKUJU= diff --git a/mint/run/core/aws-sdk-go/quick-tests.go b/mint/run/core/aws-sdk-go/quick-tests.go index 4ac55d90c..e9f4a887d 100644 --- a/mint/run/core/aws-sdk-go/quick-tests.go +++ b/mint/run/core/aws-sdk-go/quick-tests.go @@ -626,7 +626,7 @@ func testObjectTagging(s3Client *s3.S3) { func testObjectTaggingErrors(s3Client *s3.S3) { startTime := time.Now() - function := "testObjectTagging" + function := "testObjectTaggingErrors" bucket := randString(60, rand.NewSource(time.Now().UnixNano()), "aws-sdk-go-test-") object := randString(60, rand.NewSource(time.Now().UnixNano()), "") args := map[string]interface{}{