Send a bucket notification event on DeleteObject() for non-existing object (#19037)

Send a bucket notification event on DeleteObject for non-existing objects
This commit is contained in:
Praveen raj Mani 2024-02-13 21:04:17 +05:30 committed by GitHub
parent cfd8645843
commit ac8e9ce04f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 30 additions and 2 deletions

View File

@ -225,7 +225,11 @@ func (args eventArgs) ToEvent(escape bool) event.Event {
}, },
} }
if args.EventName != event.ObjectRemovedDelete && args.EventName != event.ObjectRemovedDeleteMarkerCreated { isRemovedEvent := args.EventName == event.ObjectRemovedDelete ||
args.EventName == event.ObjectRemovedDeleteMarkerCreated ||
args.EventName == event.ObjectRemovedNoOP
if !isRemovedEvent {
newEvent.S3.Object.ETag = args.Object.ETag newEvent.S3.Object.ETag = args.Object.ETag
newEvent.S3.Object.Size = args.Object.Size newEvent.S3.Object.Size = args.Object.Size
newEvent.S3.Object.ContentType = args.Object.ContentType newEvent.S3.Object.ContentType = args.Object.ContentType

View File

@ -2891,6 +2891,18 @@ func (api objectAPIHandlers) DeleteObjectHandler(w http.ResponseWriter, r *http.
return return
} }
if isErrObjectNotFound(err) || isErrVersionNotFound(err) { if isErrObjectNotFound(err) || isErrVersionNotFound(err) {
// Send an event when the object is not found
objInfo.Name = object
objInfo.VersionID = opts.VersionID
sendEvent(eventArgs{
EventName: event.ObjectRemovedNoOP,
BucketName: bucket,
Object: objInfo,
ReqParams: extractReqParams(r),
RespElements: extractRespElements(w),
UserAgent: r.UserAgent(),
Host: handlers.GetSourceIP(r),
})
writeSuccessNoContent(w) writeSuccessNoContent(w)
return return
} }

View File

@ -47,6 +47,7 @@ const (
ObjectCreatedDeleteTagging ObjectCreatedDeleteTagging
ObjectRemovedDelete ObjectRemovedDelete
ObjectRemovedDeleteMarkerCreated ObjectRemovedDeleteMarkerCreated
ObjectRemovedNoOP
BucketCreated BucketCreated
BucketRemoved BucketRemoved
ObjectReplicationFailed ObjectReplicationFailed
@ -98,6 +99,7 @@ func (name Name) Expand() []Name {
return []Name{ return []Name{
ObjectRemovedDelete, ObjectRemovedDelete,
ObjectRemovedDeleteMarkerCreated, ObjectRemovedDeleteMarkerCreated,
ObjectRemovedNoOP,
} }
case ObjectReplicationAll: case ObjectReplicationAll:
return []Name{ return []Name{
@ -189,6 +191,8 @@ func (name Name) String() string {
return "s3:ObjectRemoved:Delete" return "s3:ObjectRemoved:Delete"
case ObjectRemovedDeleteMarkerCreated: case ObjectRemovedDeleteMarkerCreated:
return "s3:ObjectRemoved:DeleteMarkerCreated" return "s3:ObjectRemoved:DeleteMarkerCreated"
case ObjectRemovedNoOP:
return "s3:ObjectRemoved:NoOP"
case ObjectReplicationAll: case ObjectReplicationAll:
return "s3:Replication:*" return "s3:Replication:*"
case ObjectReplicationFailed: case ObjectReplicationFailed:
@ -307,6 +311,8 @@ func ParseName(s string) (Name, error) {
return ObjectRemovedDelete, nil return ObjectRemovedDelete, nil
case "s3:ObjectRemoved:DeleteMarkerCreated": case "s3:ObjectRemoved:DeleteMarkerCreated":
return ObjectRemovedDeleteMarkerCreated, nil return ObjectRemovedDeleteMarkerCreated, nil
case "s3:ObjectRemoved:NoOP":
return ObjectRemovedNoOP, nil
case "s3:Replication:*": case "s3:Replication:*":
return ObjectReplicationAll, nil return ObjectReplicationAll, nil
case "s3:Replication:OperationFailedReplication": case "s3:Replication:OperationFailedReplication":

View File

@ -36,7 +36,7 @@ func TestNameExpand(t *testing.T) {
ObjectCreatedCompleteMultipartUpload, ObjectCreatedCopy, ObjectCreatedPost, ObjectCreatedPut, ObjectCreatedCompleteMultipartUpload, ObjectCreatedCopy, ObjectCreatedPost, ObjectCreatedPut,
ObjectCreatedPutRetention, ObjectCreatedPutLegalHold, ObjectCreatedPutTagging, ObjectCreatedDeleteTagging, ObjectCreatedPutRetention, ObjectCreatedPutLegalHold, ObjectCreatedPutTagging, ObjectCreatedDeleteTagging,
}}, }},
{ObjectRemovedAll, []Name{ObjectRemovedDelete, ObjectRemovedDeleteMarkerCreated}}, {ObjectRemovedAll, []Name{ObjectRemovedDelete, ObjectRemovedDeleteMarkerCreated, ObjectRemovedNoOP}},
{ObjectAccessedHead, []Name{ObjectAccessedHead}}, {ObjectAccessedHead, []Name{ObjectAccessedHead}},
} }
@ -68,6 +68,7 @@ func TestNameString(t *testing.T) {
{ObjectCreatedPut, "s3:ObjectCreated:Put"}, {ObjectCreatedPut, "s3:ObjectCreated:Put"},
{ObjectRemovedAll, "s3:ObjectRemoved:*"}, {ObjectRemovedAll, "s3:ObjectRemoved:*"},
{ObjectRemovedDelete, "s3:ObjectRemoved:Delete"}, {ObjectRemovedDelete, "s3:ObjectRemoved:Delete"},
{ObjectRemovedNoOP, "s3:ObjectRemoved:NoOP"},
{ObjectCreatedPutRetention, "s3:ObjectCreated:PutRetention"}, {ObjectCreatedPutRetention, "s3:ObjectCreated:PutRetention"},
{ObjectCreatedPutLegalHold, "s3:ObjectCreated:PutLegalHold"}, {ObjectCreatedPutLegalHold, "s3:ObjectCreated:PutLegalHold"},
{ObjectAccessedGetRetention, "s3:ObjectAccessed:GetRetention"}, {ObjectAccessedGetRetention, "s3:ObjectAccessed:GetRetention"},
@ -95,6 +96,7 @@ func TestNameMarshalXML(t *testing.T) {
}{ }{
{ObjectAccessedAll, []byte("<Name>s3:ObjectAccessed:*</Name>"), false}, {ObjectAccessedAll, []byte("<Name>s3:ObjectAccessed:*</Name>"), false},
{ObjectRemovedDelete, []byte("<Name>s3:ObjectRemoved:Delete</Name>"), false}, {ObjectRemovedDelete, []byte("<Name>s3:ObjectRemoved:Delete</Name>"), false},
{ObjectRemovedNoOP, []byte("<Name>s3:ObjectRemoved:NoOP</Name>"), false},
{blankName, []byte("<Name></Name>"), false}, {blankName, []byte("<Name></Name>"), false},
} }
@ -124,6 +126,7 @@ func TestNameUnmarshalXML(t *testing.T) {
}{ }{
{[]byte("<Name>s3:ObjectAccessed:*</Name>"), ObjectAccessedAll, false}, {[]byte("<Name>s3:ObjectAccessed:*</Name>"), ObjectAccessedAll, false},
{[]byte("<Name>s3:ObjectRemoved:Delete</Name>"), ObjectRemovedDelete, false}, {[]byte("<Name>s3:ObjectRemoved:Delete</Name>"), ObjectRemovedDelete, false},
{[]byte("<Name>s3:ObjectRemoved:NoOP</Name>"), ObjectRemovedNoOP, false},
{[]byte("<Name></Name>"), blankName, true}, {[]byte("<Name></Name>"), blankName, true},
} }
@ -154,6 +157,7 @@ func TestNameMarshalJSON(t *testing.T) {
}{ }{
{ObjectAccessedAll, []byte(`"s3:ObjectAccessed:*"`), false}, {ObjectAccessedAll, []byte(`"s3:ObjectAccessed:*"`), false},
{ObjectRemovedDelete, []byte(`"s3:ObjectRemoved:Delete"`), false}, {ObjectRemovedDelete, []byte(`"s3:ObjectRemoved:Delete"`), false},
{ObjectRemovedNoOP, []byte(`"s3:ObjectRemoved:NoOP"`), false},
{blankName, []byte(`""`), false}, {blankName, []byte(`""`), false},
} }
@ -183,6 +187,7 @@ func TestNameUnmarshalJSON(t *testing.T) {
}{ }{
{[]byte(`"s3:ObjectAccessed:*"`), ObjectAccessedAll, false}, {[]byte(`"s3:ObjectAccessed:*"`), ObjectAccessedAll, false},
{[]byte(`"s3:ObjectRemoved:Delete"`), ObjectRemovedDelete, false}, {[]byte(`"s3:ObjectRemoved:Delete"`), ObjectRemovedDelete, false},
{[]byte(`"s3:ObjectRemoved:NoOP"`), ObjectRemovedNoOP, false},
{[]byte(`""`), blankName, true}, {[]byte(`""`), blankName, true},
} }
@ -213,6 +218,7 @@ func TestParseName(t *testing.T) {
}{ }{
{"s3:ObjectAccessed:*", ObjectAccessedAll, false}, {"s3:ObjectAccessed:*", ObjectAccessedAll, false},
{"s3:ObjectRemoved:Delete", ObjectRemovedDelete, false}, {"s3:ObjectRemoved:Delete", ObjectRemovedDelete, false},
{"s3:ObjectRemoved:NoOP", ObjectRemovedNoOP, false},
{"", blankName, true}, {"", blankName, true},
} }