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

Limit DeleteObjects request object amount #849

Merged
merged 1 commit into from
Oct 16, 2023
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
9 changes: 5 additions & 4 deletions api/handler/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@ type (

// Config contains data which handler needs to keep.
Config struct {
Policy PlacementPolicy
DefaultMaxAge int
NotificatorEnabled bool
CopiesNumber uint32
Policy PlacementPolicy
DefaultMaxAge int
NotificatorEnabled bool
CopiesNumber uint32
MaxDeletePerRequest int
}

PlacementPolicy interface {
Expand Down
5 changes: 5 additions & 0 deletions api/handler/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,11 @@ func (h *handler) DeleteMultipleObjectsHandler(w http.ResponseWriter, r *http.Re
return
}

if len(requested.Objects) > h.cfg.MaxDeletePerRequest {
h.logAndSendError(w, "too many objects to delete", reqInfo, layer.ErrTooManyObjectForDeletion)
return
}

removed := make(map[string]*layer.VersionedObject)
toRemove := make([]*layer.VersionedObject, 0, len(requested.Objects))
for _, obj := range requested.Objects {
Expand Down
4 changes: 4 additions & 0 deletions api/handler/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ func transformToS3Error(err error) error {
return s3errors.GetAPIError(s3errors.ErrUnsupportedMetadata)
}

if errors.Is(err, layer.ErrTooManyObjectForDeletion) {
return s3errors.GetAPIError(s3errors.ErrBadRequest)
}

return s3errors.GetAPIError(s3errors.ErrInternalError)
}

Expand Down
3 changes: 3 additions & 0 deletions api/layer/neofs.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,9 @@ var ErrAccessDenied = errors.New("access denied")
// ErrMetaEmptyParameterValue describes situation when meta parameter was passed but with empty value.
var ErrMetaEmptyParameterValue = errors.New("meta empty parameter value")

// ErrTooManyObjectForDeletion is returned if user is trying to delete to many objects per request.
var ErrTooManyObjectForDeletion = errors.New("to many objects for deletion")

// NeoFS represents virtual connection to NeoFS network.
type NeoFS interface {
// CreateContainer creates and saves parameterized container in NeoFS.
Expand Down
5 changes: 5 additions & 0 deletions cmd/s3-gw/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -686,6 +686,11 @@ func (a *App) initHandler() {
cfg.CopiesNumber = val
}

cfg.MaxDeletePerRequest = a.cfg.GetInt(cfgMaxObjectToDeletePerRequest)
if cfg.MaxDeletePerRequest == 0 {
cfg.MaxDeletePerRequest = defaultMaxObjectDeletePerRequest
}

var err error
a.api, err = handler.New(a.log, a.obj, a.nc, cfg)
if err != nil {
Expand Down
5 changes: 5 additions & 0 deletions cmd/s3-gw/app_settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ const (

defaultMaxClientsCount = 100
defaultMaxClientsDeadline = time.Second * 30

defaultMaxObjectDeletePerRequest = 1000
)

const ( // Settings.
Expand Down Expand Up @@ -121,6 +123,9 @@ const ( // Settings.
// Number of the object copies to consider PUT to NeoFS successful.
cfgSetCopiesNumber = "neofs.set_copies_number"

// Maximum number of objects to be deleted per request limit by this value.
cfgMaxObjectToDeletePerRequest = "s3.max_object_to_delete_per_request"

// Timeout between retrieving actual epoch from NeoFS. Actual only if slicer.enabled = true.
cfgEpochUpdateInterval = "neofs.epoch_update_interval"

Expand Down
6 changes: 6 additions & 0 deletions config/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,9 @@ allowed_access_key_id_prefixes:

# Allows to use slicer for Object uploading.
internal_slicer: false

# S3

s3:
# Maximum number of objects to be deleted per request limit by this value.
max_object_to_delete_per_request: 1000
2 changes: 2 additions & 0 deletions docs/aws_s3_compat.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ Reference:
| 🔵 | WriteGetObjectResponse | Waiting for Lambda to be developed |
| 🟢 | GetObjectAttributes | |

* DeleteObjects limited by max amount of objects which can be deleted per request. See `max_object_to_delete_per_request` parameter.

## ACL

For now there are some limitations:
Expand Down
13 changes: 13 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -455,3 +455,16 @@ neofs:
| Parameter | Type | Default value | Description |
|---------------------|----------|---------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `set_copies_number` | `uint32` | `0` | Number of the object copies to consider PUT to NeoFS successful. <br/>Default value `0` means that object will be processed according to the container's placement policy |

# `s3` section

Contains parameters to configure requests runtime.

```yaml
s3:
max_object_to_delete_per_request: 1000
```

| Parameter | Type | Default value | Description |
|------------------------------------|-------|---------------|-------------------------------------------------------------------------------------------------------------------------------|
| `max_object_to_delete_per_request` | `int` | `1000` | Allows to set maximum object amount which can be deleted per request. If amount is higher, the `Bad request` will be returned |
Loading