github.com/treeverse/lakefs@v1.24.1-0.20240520134607-95648127bfb0/pkg/gateway/operations/deleteobject.go (about)

     1  package operations
     2  
     3  import (
     4  	"errors"
     5  	"net/http"
     6  
     7  	"github.com/treeverse/lakefs/pkg/block"
     8  	gatewayerrors "github.com/treeverse/lakefs/pkg/gateway/errors"
     9  	"github.com/treeverse/lakefs/pkg/graveler"
    10  	"github.com/treeverse/lakefs/pkg/logging"
    11  	"github.com/treeverse/lakefs/pkg/permissions"
    12  )
    13  
    14  type DeleteObject struct{}
    15  
    16  func (controller *DeleteObject) RequiredPermissions(_ *http.Request, repoID, _, path string) (permissions.Node, error) {
    17  	return permissions.Node{
    18  		Permission: permissions.Permission{
    19  			Action:   permissions.DeleteObjectAction,
    20  			Resource: permissions.ObjectArn(repoID, path),
    21  		},
    22  	}, nil
    23  }
    24  
    25  func (controller *DeleteObject) HandleAbortMultipartUpload(w http.ResponseWriter, req *http.Request, o *PathOperation) {
    26  	o.Incr("abort_mpu", o.Principal, o.Repository.Name, o.Reference)
    27  	query := req.URL.Query()
    28  	uploadID := query.Get(QueryParamUploadID)
    29  
    30  	ctx := req.Context()
    31  	mpu, err := o.MultipartTracker.Get(ctx, uploadID)
    32  	if err != nil {
    33  		o.Log(req).WithError(err).Error("upload id not found in tracker")
    34  		_ = o.EncodeError(w, req, err, gatewayerrors.Codes.ToAPIErr(gatewayerrors.ErrNoSuchKey))
    35  		return
    36  	}
    37  	if mpu.Path != o.Path {
    38  		o.Log(req).Error("could not match multipart upload with multipart tracker record")
    39  		_ = o.EncodeError(w, req, err, gatewayerrors.Codes.ToAPIErr(gatewayerrors.ErrNoSuchKey))
    40  		return
    41  	}
    42  
    43  	req = req.WithContext(logging.AddFields(ctx, logging.Fields{logging.UploadIDFieldKey: uploadID}))
    44  	err = o.BlockStore.AbortMultiPartUpload(ctx, block.ObjectPointer{
    45  		StorageNamespace: o.Repository.StorageNamespace,
    46  		IdentifierType:   block.IdentifierTypeRelative,
    47  		Identifier:       mpu.PhysicalAddress,
    48  	}, uploadID)
    49  	if err != nil {
    50  		o.Log(req).WithError(err).Error("could not abort multipart upload")
    51  		_ = o.EncodeError(w, req, err, gatewayerrors.Codes.ToAPIErr(gatewayerrors.ErrInternalError))
    52  		return
    53  	}
    54  
    55  	if err := o.MultipartTracker.Delete(ctx, uploadID); err != nil {
    56  		o.Log(req).WithError(err).Warn("could not delete multipart record")
    57  	}
    58  
    59  	w.WriteHeader(http.StatusNoContent)
    60  }
    61  
    62  func (controller *DeleteObject) Handle(w http.ResponseWriter, req *http.Request, o *PathOperation) {
    63  	if o.HandleUnsupported(w, req, "tagging", "acl", "torrent") {
    64  		return
    65  	}
    66  	query := req.URL.Query()
    67  	if query.Has(QueryParamUploadID) {
    68  		controller.HandleAbortMultipartUpload(w, req, o)
    69  		return
    70  	}
    71  
    72  	o.Incr("delete_object", o.Principal, o.Repository.Name, o.Reference)
    73  	lg := o.Log(req).WithField("key", o.Path)
    74  	err := o.Catalog.DeleteEntry(req.Context(), o.Repository.Name, o.Reference, o.Path)
    75  	switch {
    76  	case errors.Is(err, graveler.ErrNotFound):
    77  		lg.WithError(err).Debug("could not delete object, it doesn't exist")
    78  	case errors.Is(err, graveler.ErrWriteToProtectedBranch):
    79  		_ = o.EncodeError(w, req, err, gatewayerrors.Codes.ToAPIErr(gatewayerrors.ErrWriteToProtectedBranch))
    80  		return
    81  	case errors.Is(err, graveler.ErrReadOnlyRepository):
    82  		_ = o.EncodeError(w, req, err, gatewayerrors.Codes.ToAPIErr(gatewayerrors.ErrReadOnlyRepository))
    83  		return
    84  	case err != nil:
    85  		lg.WithError(err).Error("could not delete object")
    86  		_ = o.EncodeError(w, req, err, gatewayerrors.Codes.ToAPIErr(gatewayerrors.ErrInternalError))
    87  		return
    88  	default:
    89  		lg.Debug("object set for deletion")
    90  	}
    91  	w.WriteHeader(http.StatusNoContent)
    92  }