Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[S3 gateway] Return HTTP 409 (Conflict) when creating existing repo #2451

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pkg/gateway/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ func NewHandler(
operations.OperationIDDeleteObject: PathOperationHandler(sc, &operations.DeleteObject{}),
operations.OperationIDDeleteObjects: RepoOperationHandler(sc, &operations.DeleteObjects{}),
operations.OperationIDGetObject: PathOperationHandler(sc, &operations.GetObject{}),
operations.OperationIDPutBucket: RepoOperationHandler(sc, &operations.PutBucket{}),
operations.OperationIDHeadBucket: RepoOperationHandler(sc, &operations.HeadBucket{}),
operations.OperationIDHeadObject: PathOperationHandler(sc, &operations.HeadObject{}),
operations.OperationIDListBuckets: OperationHandler(sc, &operations.ListBuckets{}),
Expand Down
4 changes: 3 additions & 1 deletion pkg/gateway/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,8 +280,10 @@ func pathBasedOperationID(method string) operations.OperationID {

func repositoryBasedOperationID(method string) operations.OperationID {
switch method {
case http.MethodDelete, http.MethodPut:
case http.MethodDelete:
return operations.OperationIDUnsupportedOperation
case http.MethodPut:
return operations.OperationIDPutBucket
case http.MethodHead:
return operations.OperationIDHeadBucket
case http.MethodPost:
Expand Down
1 change: 1 addition & 0 deletions pkg/gateway/operations/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const (
OperationIDListObjects OperationID = "list_objects"
OperationIDPostObject OperationID = "post_object"
OperationIDPutObject OperationID = "put_object"
OperationIDPutBucket OperationID = "put_bucket"

OperationIDUnsupportedOperation OperationID = "unsupported"
OperationIDOperationNotFound OperationID = "not_found"
Expand Down
35 changes: 35 additions & 0 deletions pkg/gateway/operations/putbucket.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package operations

import (
"net/http"

gatewayerrors "github.com/treeverse/lakefs/pkg/gateway/errors"
"github.com/treeverse/lakefs/pkg/permissions"
)

// PutBucket handles S3 Create Bucket operations. It does *not* actually
// create new repos (there is not enough information in the S3 request to
// create a new repo), but *does* detect whether the repo already exists.
type PutBucket struct{}

func (controller *PutBucket) RequiredPermissions(_ *http.Request, repoID string) ([]permissions.Permission, error) {
return []permissions.Permission{
{
// Mimic S3, which requires s3:CreateBucket to call
// create-bucket, even if we only want to receive
// 409.
Action: permissions.CreateRepositoryAction,
Resource: permissions.RepoArn(repoID),
},
}, nil
}

func (controller *PutBucket) Handle(w http.ResponseWriter, req *http.Request, o *RepoOperation) {
o.Incr("put_repo")
if o.Repository == nil {
// No repo, would have to create it, but not enough
// information -- so not supported.
o.EncodeError(w, req, gatewayerrors.ERRLakeFSNotSupported.ToAPIErr())
}
o.EncodeError(w, req, gatewayerrors.ErrBucketAlreadyExists.ToAPIErr())
}