From dd52e5ebe99e9ec113ad01e8e220d5b3e7677a45 Mon Sep 17 00:00:00 2001 From: ebozduman Date: Fri, 8 Feb 2019 16:18:13 -0800 Subject: [PATCH] Implements dummy tagging handlers for Terraform (#7040) --- cmd/api-router.go | 25 +++++ cmd/dummy-handlers.go | 210 ++++++++++++++++++++++++++++++++++++++++ cmd/generic-handlers.go | 44 ++++++--- 3 files changed, 265 insertions(+), 14 deletions(-) create mode 100644 cmd/dummy-handlers.go diff --git a/cmd/api-router.go b/cmd/api-router.go index db5455d6f..1de35e97d 100644 --- a/cmd/api-router.go +++ b/cmd/api-router.go @@ -67,6 +67,8 @@ func registerAPIRouter(router *mux.Router, encryptionEnabled bool) { bucket.Methods("DELETE").Path("/{object:.+}").HandlerFunc(httpTraceAll(api.AbortMultipartUploadHandler)).Queries("uploadId", "{uploadId:.*}") // GetObjectACL - this is a dummy call. bucket.Methods("GET").Path("/{object:.+}").HandlerFunc(httpTraceHdrs(api.GetObjectACLHandler)).Queries("acl", "") + // GetObjectTagging - this is a dummy call. + bucket.Methods("GET").Path("/{object:.+}").HandlerFunc(httpTraceHdrs(api.GetObjectTaggingHandler)).Queries("tagging", "") // SelectObjectContent bucket.Methods("POST").Path("/{object:.+}").HandlerFunc(httpTraceHdrs(api.SelectObjectContentHandler)).Queries("select", "").Queries("select-type", "2") // GetObject @@ -84,8 +86,31 @@ func registerAPIRouter(router *mux.Router, encryptionEnabled bool) { // GetBucketPolicy bucket.Methods("GET").HandlerFunc(httpTraceAll(api.GetBucketPolicyHandler)).Queries("policy", "") + // Dummy Bucket Calls // GetBucketACL -- this is a dummy call. bucket.Methods("GET").HandlerFunc(httpTraceAll(api.GetBucketACLHandler)).Queries("acl", "") + // GetBucketCors - this is a dummy call. + bucket.Methods("GET").HandlerFunc(httpTraceAll(api.GetBucketCorsHandler)).Queries("cors", "") + // GetBucketWebsiteHandler - this is a dummy call. + bucket.Methods("GET").HandlerFunc(httpTraceAll(api.GetBucketWebsiteHandler)).Queries("website", "") + // GetBucketVersioningHandler - this is a dummy call. + bucket.Methods("GET").HandlerFunc(httpTraceAll(api.GetBucketVersioningHandler)).Queries("versioning", "") + // GetBucketAccelerateHandler - this is a dummy call. + bucket.Methods("GET").HandlerFunc(httpTraceAll(api.GetBucketAccelerateHandler)).Queries("accelerate", "") + // GetBucketRequestPaymentHandler - this is a dummy call. + bucket.Methods("GET").HandlerFunc(httpTraceAll(api.GetBucketRequestPaymentHandler)).Queries("requestPayment", "") + // GetBucketLoggingHandler - this is a dummy call. + bucket.Methods("GET").HandlerFunc(httpTraceAll(api.GetBucketLoggingHandler)).Queries("logging", "") + // GetBucketLifecycleHandler - this is a dummy call. + bucket.Methods("GET").HandlerFunc(httpTraceAll(api.GetBucketLifecycleHandler)).Queries("lifecycle", "") + // GetBucketReplicationHandler - this is a dummy call. + bucket.Methods("GET").HandlerFunc(httpTraceAll(api.GetBucketReplicationHandler)).Queries("replication", "") + // GetBucketTaggingHandler - this is a dummy call. + bucket.Methods("GET").HandlerFunc(httpTraceAll(api.GetBucketTaggingHandler)).Queries("tagging", "") + //DeleteBucketWebsiteHandler + bucket.Methods("DELETE").HandlerFunc(httpTraceAll(api.DeleteBucketWebsiteHandler)).Queries("website", "") + // DeleteBucketTaggingHandler + bucket.Methods("DELETE").HandlerFunc(httpTraceAll(api.DeleteBucketTaggingHandler)).Queries("tagging", "") // GetBucketNotification bucket.Methods("GET").HandlerFunc(httpTraceAll(api.GetBucketNotificationHandler)).Queries("notification", "") diff --git a/cmd/dummy-handlers.go b/cmd/dummy-handlers.go new file mode 100644 index 000000000..53451d6bc --- /dev/null +++ b/cmd/dummy-handlers.go @@ -0,0 +1,210 @@ +/* + * Minio Cloud Storage, (C) 2018 Minio, Inc. + * + * 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. + */ + +package cmd + +import ( + "encoding/xml" + "net/http" + + "github.com/gorilla/mux" +) + +// Data types used for returning dummy tagging XML. +// These variables shouldn't be used elsewhere. +// They are only defined to be used in this file alone. + +type tagging struct { + XMLName xml.Name `xml:"Tagging"` + TagSet tagSet `xml:"TagSet"` +} + +type tagSet struct { + Tag []tagElem `xml:"Tag"` +} + +type tagElem struct { + Key string `xml:"Key"` + Value string `xml:"Value"` +} + +// GetBucketWebsite - GET bucket website, a dummy api +func (api objectAPIHandlers) GetBucketWebsiteHandler(w http.ResponseWriter, r *http.Request) { + writeSuccessResponseHeadersOnly(w) + w.(http.Flusher).Flush() +} + +// GetBucketVersioning - GET bucket versioning, a dummy api +func (api objectAPIHandlers) GetBucketVersioningHandler(w http.ResponseWriter, r *http.Request) { + writeSuccessResponseHeadersOnly(w) + w.(http.Flusher).Flush() +} + +// GetBucketAccelerate - GET bucket accelerate, a dummy api +func (api objectAPIHandlers) GetBucketAccelerateHandler(w http.ResponseWriter, r *http.Request) { + writeSuccessResponseHeadersOnly(w) + w.(http.Flusher).Flush() +} + +// GetBucketRequestPaymentHandler - GET bucket requestPayment, a dummy api +func (api objectAPIHandlers) GetBucketRequestPaymentHandler(w http.ResponseWriter, r *http.Request) { + writeSuccessResponseHeadersOnly(w) + w.(http.Flusher).Flush() +} + +// GetBucketLoggingHandler - GET bucket logging, a dummy api +func (api objectAPIHandlers) GetBucketLoggingHandler(w http.ResponseWriter, r *http.Request) { + writeSuccessResponseHeadersOnly(w) + w.(http.Flusher).Flush() +} + +// GetBucketLifecycleHandler - GET bucket lifecycle, a dummy api +func (api objectAPIHandlers) GetBucketLifecycleHandler(w http.ResponseWriter, r *http.Request) { + writeSuccessResponseHeadersOnly(w) + w.(http.Flusher).Flush() +} + +// GetBucketReplicationHandler - GET bucket replication, a dummy api +func (api objectAPIHandlers) GetBucketReplicationHandler(w http.ResponseWriter, r *http.Request) { + writeSuccessResponseHeadersOnly(w) + w.(http.Flusher).Flush() +} + +// DeleteBucketTaggingHandler - DELETE bucket tagging, a dummy api +func (api objectAPIHandlers) DeleteBucketTaggingHandler(w http.ResponseWriter, r *http.Request) { + writeSuccessResponseHeadersOnly(w) + w.(http.Flusher).Flush() +} + +// DeleteBucketWebsiteHandler - DELETE bucket website, a dummy api +func (api objectAPIHandlers) DeleteBucketWebsiteHandler(w http.ResponseWriter, r *http.Request) { + writeSuccessResponseHeadersOnly(w) + w.(http.Flusher).Flush() +} + +// GetBucketCorsHandler - GET bucket cors, a dummy api +func (api objectAPIHandlers) GetBucketCorsHandler(w http.ResponseWriter, r *http.Request) { + ctx := newContext(r, w, "GetBucketCorsHandler") + + type allowedMethod int + const ( + GET allowedMethod = iota + PUT + HEAD + POST + DELETE + ) + type corsRule struct { + AllowedMethod allowedMethod `xml:"AllowedMethod"` + AllowedOrigin string `xml:"AllowedOrigin"` + ExposeHeader string `xml:"ExposeHeader"` + ID string `xml:"ID"` + MaxAgeSeconds int64 `xml:"MaxAgeSeconds"` + } + type corsConfiguration struct { + XMLName xml.Name `xml:"CORSConfiguration"` + CorsRule []corsRule `xml:"CORSRule"` + } + + vars := mux.Vars(r) + bucket := vars["bucket"] + + objAPI := api.ObjectAPI() + if objAPI == nil { + writeErrorResponse(w, ErrServerNotInitialized, r.URL, guessIsBrowserReq(r)) + return + } + + // Validate if bucket exists, before proceeding further... + _, err := objAPI.GetBucketInfo(ctx, bucket) + if err != nil { + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r)) + return + } + + tags := &tagging{} + tags.TagSet.Tag = append(tags.TagSet.Tag, tagElem{}) + + if err := xml.NewEncoder(w).Encode(tags); err != nil { + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r)) + return + } + + w.(http.Flusher).Flush() +} + +// GetBucketTaggingHandler - GET bucket tagging, a dummy api +func (api objectAPIHandlers) GetBucketTaggingHandler(w http.ResponseWriter, r *http.Request) { + ctx := newContext(r, w, "GetBucketTagging") + + vars := mux.Vars(r) + bucket := vars["bucket"] + + objAPI := api.ObjectAPI() + if objAPI == nil { + writeErrorResponse(w, ErrServerNotInitialized, r.URL, guessIsBrowserReq(r)) + return + } + + // Validate if bucket exists, before proceeding further... + _, err := objAPI.GetBucketInfo(ctx, bucket) + if err != nil { + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r)) + return + } + + tags := &tagging{} + tags.TagSet.Tag = append(tags.TagSet.Tag, tagElem{}) + + if err := xml.NewEncoder(w).Encode(tags); err != nil { + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r)) + return + } + + w.(http.Flusher).Flush() +} + +// GetObjectTaggingHandler - GET object tagging, a dummy api +func (api objectAPIHandlers) GetObjectTaggingHandler(w http.ResponseWriter, r *http.Request) { + ctx := newContext(r, w, "GetObjectTagging") + + vars := mux.Vars(r) + bucket := vars["bucket"] + object := vars["object"] + + objAPI := api.ObjectAPI() + if objAPI == nil { + writeErrorResponse(w, ErrServerNotInitialized, r.URL, guessIsBrowserReq(r)) + return + } + + // Validate if object exists, before proceeding further... + _, err := objAPI.GetObjectInfo(ctx, bucket, object, ObjectOptions{}) + if err != nil { + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r)) + return + } + + tags := &tagging{} + tags.TagSet.Tag = append(tags.TagSet.Tag, tagElem{}) + + if err := xml.NewEncoder(w).Encode(tags); err != nil { + writeErrorResponse(w, toAPIErrorCode(ctx, err), r.URL, guessIsBrowserReq(r)) + return + } + + w.(http.Flusher).Flush() +} diff --git a/cmd/generic-handlers.go b/cmd/generic-handlers.go index fcc2e4b72..16c5e2a9c 100644 --- a/cmd/generic-handlers.go +++ b/cmd/generic-handlers.go @@ -398,8 +398,24 @@ func setIgnoreResourcesHandler(h http.Handler) http.Handler { // Checks requests for not implemented Bucket resources func ignoreNotImplementedBucketResources(req *http.Request) bool { for name := range req.URL.Query() { - // Enable GetBucketACL dummy call specifically. - if name == "acl" && req.Method == http.MethodGet { + // Enable GetBucketACL, GetBucketCors, GetBucketWebsite, + // GetBucketAcccelerate, GetBucketRequestPayment, + // GetBucketLogging, GetBucketLifecycle, + // GetBucketReplication, GetBucketTagging, + // GetBucketVersioning, DeleteBucketTagging, + // and DeleteBucketWebsite dummy calls specifically. + if ((name == "acl" || + name == "cors" || + name == "website" || + name == "accelerate" || + name == "requestPayment" || + name == "logging" || + name == "lifecycle" || + name == "replication" || + name == "tagging" || + name == "versioning") && req.Method == http.MethodGet) || + ((name == "tagging" || + name == "website") && req.Method == http.MethodDelete) { return false } @@ -413,8 +429,8 @@ func ignoreNotImplementedBucketResources(req *http.Request) bool { // Checks requests for not implemented Object resources func ignoreNotImplementedObjectResources(req *http.Request) bool { for name := range req.URL.Query() { - // Enable GetObjectACL dummy call specifically. - if name == "acl" && req.Method == http.MethodGet { + // Enable GetObjectACL and GetObjectTagging dummy calls specifically. + if (name == "acl" || name == "tagging") && req.Method == http.MethodGet { return false } if notimplementedObjectResourceNames[name] { @@ -426,28 +442,28 @@ func ignoreNotImplementedObjectResources(req *http.Request) bool { // List of not implemented bucket queries var notimplementedBucketResourceNames = map[string]bool{ + "accelerate": true, "acl": true, "cors": true, + "inventory": true, "lifecycle": true, "logging": true, - "replication": true, - "tagging": true, - "versions": true, - "requestPayment": true, - "versioning": true, - "website": true, - "inventory": true, "metrics": true, - "accelerate": true, + "replication": true, + "requestPayment": true, + "tagging": true, + "versioning": true, + "versions": true, + "website": true, } // List of not implemented object queries var notimplementedObjectResourceNames = map[string]bool{ - "torrent": true, "acl": true, "policy": true, - "tagging": true, "restore": true, + "tagging": true, + "torrent": true, } // Resource handler ServeHTTP() wrapper