Sending a DeleteObjects request from AWS Go SDK to localStack ( set to latest, so fetched moto-ext>=1.3.15.12) results is 500 error.
DeleteObject operation works successfully, it's the DeleteObjects that fails. Looking into the difference between the request payload (AWS Go SDK github.com/aws/aws-sdk-go v1.28.6):
DeleteObject:
op := &request.Operation{
Name: opDeleteObject,
HTTPMethod: "DELETE",
HTTPPath: "/{Bucket}/{Key+}",
}
Where const opDeleteObject = "DeleteObject"
DeleteObjects
op := &request.Operation{
Name: opDeleteObjects,
HTTPMethod: "POST",
HTTPPath: "/{Bucket}?delete",
}
Where const opDeleteObjects = "DeleteObjects"
In _bucket_response_delete_keys method of class ResponseObject *_line 843_ the check is:
objects = body_dict["Delete"].get("Object", [])*
In case of DeleteObjects the key is "Objects", so objects variable will be []
Note the difference between how each of these operations is called:
DeleteObject
_, err := s.Client.DeleteObject(&s3.DeleteObjectInput{Bucket: aws.String(bucket), Key: aws.String(key)})
DeleteObjects
_, err := s.Client.DeleteObjects(&s3.DeleteObjectsInput{Bucket: aws.String(bucket), Delete: &s3.Delete{
Objects: keys,
Quiet: aws.Bool(false),
}})
the Delete struct has a field Objects instead of Object
Objects []*ObjectIdentifierlocationName:"Object" type:"list" flattened:"true" required:"true"
How to replicate:
Place some files in 'examplebucket'
call the DeleteObjects (code from AWS Docs) which the keys:
`svc := s3.New(session.New())
input := &s3.DeleteObjectsInput{
Bucket: aws.String("examplebucket"),
Delete: &s3.Delete{
Objects: []*s3.ObjectIdentifier{
{
Key: aws.String("objectkey1"),
},
{
Key: aws.String("objectkey2"),
},
},
Quiet: aws.Bool(false),
},
}
result, err := svc.DeleteObjects(input)
if err != nil {
if aerr, ok := err.(awserr.Error); ok {
switch aerr.Code() {
default:
fmt.Println(aerr.Error())
}
} else {
// Print the error, cast err to awserr.Error to get the Code and
// Message from an error.
fmt.Println(err.Error())
}
return
}
fmt.Println(result)
}`
Hi @Nasrin-Shiraly, thanks for raising this.
We have a unit test where we use the correct request: client.delete_objects(
Bucket="blah", Delete={"Objects": [{"Key": "test1", "VersionId": id_to_delete}]}
), which works as it should.
So I'm a little confused 1) why our unit test works, and 2) why yours doesn't.
Will mark it as debugging for now - I'll try to have a look today
It's officially a bug, due to a slight difference in how the HTTP requests are formatted by the Python and GoLang lib. See the attached PR for more info