Implemented edit lifecycle API (#1533)
Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>
This commit is contained in:
@@ -34,11 +34,35 @@ import (
|
||||
// swagger:model updateBucketLifecycle
|
||||
type UpdateBucketLifecycle struct {
|
||||
|
||||
// disable
|
||||
// Non required, toggle to disable or enable rule
|
||||
Disable bool `json:"disable,omitempty"`
|
||||
|
||||
// tags
|
||||
// Non required, toggle to disable or enable rule
|
||||
ExpiredObjectDeleteMarker bool `json:"expired_object_delete_marker,omitempty"`
|
||||
|
||||
// Required in case of expiry_date or transition fields are not set. it defines an expiry days for ILM
|
||||
ExpiryDays int32 `json:"expiry_days,omitempty"`
|
||||
|
||||
// Non required, can be set in case of expiration is enabled
|
||||
NoncurrentversionExpirationDays int32 `json:"noncurrentversion_expiration_days,omitempty"`
|
||||
|
||||
// Non required, can be set in case of transition is enabled
|
||||
NoncurrentversionTransitionDays int32 `json:"noncurrentversion_transition_days,omitempty"`
|
||||
|
||||
// Non required, can be set in case of transition is enabled
|
||||
NoncurrentversionTransitionStorageClass string `json:"noncurrentversion_transition_storage_class,omitempty"`
|
||||
|
||||
// Non required field, it matches a prefix to perform ILM operations on it
|
||||
Prefix string `json:"prefix,omitempty"`
|
||||
|
||||
// Required only in case of transition is set. it refers to a tier
|
||||
StorageClass string `json:"storage_class,omitempty"`
|
||||
|
||||
// Non required field, tags to match ILM files
|
||||
Tags string `json:"tags,omitempty"`
|
||||
|
||||
// Required in case of transition_date or expiry fields are not set. it defines a transition days for ILM
|
||||
TransitionDays int32 `json:"transition_days,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this update bucket lifecycle
|
||||
|
||||
@@ -5956,10 +5956,52 @@ func init() {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"disable": {
|
||||
"description": "Non required, toggle to disable or enable rule",
|
||||
"type": "boolean"
|
||||
},
|
||||
"tags": {
|
||||
"expired_object_delete_marker": {
|
||||
"description": "Non required, toggle to disable or enable rule",
|
||||
"type": "boolean"
|
||||
},
|
||||
"expiry_days": {
|
||||
"description": "Required in case of expiry_date or transition fields are not set. it defines an expiry days for ILM",
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"default": 0
|
||||
},
|
||||
"noncurrentversion_expiration_days": {
|
||||
"description": "Non required, can be set in case of expiration is enabled",
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"default": 0
|
||||
},
|
||||
"noncurrentversion_transition_days": {
|
||||
"description": "Non required, can be set in case of transition is enabled",
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"default": 0
|
||||
},
|
||||
"noncurrentversion_transition_storage_class": {
|
||||
"description": "Non required, can be set in case of transition is enabled",
|
||||
"type": "string"
|
||||
},
|
||||
"prefix": {
|
||||
"description": "Non required field, it matches a prefix to perform ILM operations on it",
|
||||
"type": "string"
|
||||
},
|
||||
"storage_class": {
|
||||
"description": "Required only in case of transition is set. it refers to a tier",
|
||||
"type": "string"
|
||||
},
|
||||
"tags": {
|
||||
"description": "Non required field, tags to match ILM files",
|
||||
"type": "string"
|
||||
},
|
||||
"transition_days": {
|
||||
"description": "Required in case of transition_date or expiry fields are not set. it defines a transition days for ILM",
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"default": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -12183,10 +12225,52 @@ func init() {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"disable": {
|
||||
"description": "Non required, toggle to disable or enable rule",
|
||||
"type": "boolean"
|
||||
},
|
||||
"tags": {
|
||||
"expired_object_delete_marker": {
|
||||
"description": "Non required, toggle to disable or enable rule",
|
||||
"type": "boolean"
|
||||
},
|
||||
"expiry_days": {
|
||||
"description": "Required in case of expiry_date or transition fields are not set. it defines an expiry days for ILM",
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"default": 0
|
||||
},
|
||||
"noncurrentversion_expiration_days": {
|
||||
"description": "Non required, can be set in case of expiration is enabled",
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"default": 0
|
||||
},
|
||||
"noncurrentversion_transition_days": {
|
||||
"description": "Non required, can be set in case of transition is enabled",
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"default": 0
|
||||
},
|
||||
"noncurrentversion_transition_storage_class": {
|
||||
"description": "Non required, can be set in case of transition is enabled",
|
||||
"type": "string"
|
||||
},
|
||||
"prefix": {
|
||||
"description": "Non required field, it matches a prefix to perform ILM operations on it",
|
||||
"type": "string"
|
||||
},
|
||||
"storage_class": {
|
||||
"description": "Required only in case of transition is set. it refers to a tier",
|
||||
"type": "string"
|
||||
},
|
||||
"tags": {
|
||||
"description": "Non required field, tags to match ILM files",
|
||||
"type": "string"
|
||||
},
|
||||
"transition_days": {
|
||||
"description": "Required in case of transition_date or expiry fields are not set. it defines a transition days for ILM",
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"default": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -53,6 +53,14 @@ func registerBucketsLifecycleHandlers(api *operations.ConsoleAPI) {
|
||||
}
|
||||
return user_api.NewAddBucketLifecycleCreated()
|
||||
})
|
||||
api.UserAPIUpdateBucketLifecycleHandler = user_api.UpdateBucketLifecycleHandlerFunc(func(params user_api.UpdateBucketLifecycleParams, session *models.Principal) middleware.Responder {
|
||||
err := getEditBucketLifecycleRule(session, params)
|
||||
if err != nil {
|
||||
user_api.NewUpdateBucketLifecycleDefault(int(err.Code)).WithPayload(err)
|
||||
}
|
||||
|
||||
return user_api.NewUpdateBucketLifecycleOK()
|
||||
})
|
||||
}
|
||||
|
||||
// getBucketLifecycle() gets lifecycle lists for a bucket from MinIO API and returns their implementations
|
||||
@@ -224,7 +232,7 @@ func addBucketLifecycle(ctx context.Context, client MinioClient, params user_api
|
||||
return client.setBucketLifecycle(ctx, params.BucketName, lfcCfg)
|
||||
}
|
||||
|
||||
// getAddBucketLifecycleResponse returns the respose of adding a bucket lifecycle response
|
||||
// getAddBucketLifecycleResponse returns the response of adding a bucket lifecycle response
|
||||
func getAddBucketLifecycleResponse(session *models.Principal, params user_api.AddBucketLifecycleParams) *models.Error {
|
||||
ctx := context.Background()
|
||||
mClient, err := newMinioClient(session)
|
||||
@@ -242,3 +250,91 @@ func getAddBucketLifecycleResponse(session *models.Principal, params user_api.Ad
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// addBucketLifecycle gets lifecycle lists for a bucket from MinIO API and returns their implementations
|
||||
func editBucketLifecycle(ctx context.Context, client MinioClient, params user_api.UpdateBucketLifecycleParams) error {
|
||||
// Configuration that is already set.
|
||||
lfcCfg, err := client.getLifecycleRules(ctx, params.BucketName)
|
||||
if err != nil {
|
||||
if e := err; minio.ToErrorResponse(e).Code == "NoSuchLifecycleConfiguration" {
|
||||
lfcCfg = lifecycle.NewConfiguration()
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
id := params.LifecycleID
|
||||
|
||||
opts := ilm.LifecycleOptions{}
|
||||
|
||||
// Verify if transition items are set
|
||||
if params.Body.ExpiryDays == 0 && params.Body.TransitionDays != 0 {
|
||||
|
||||
if params.Body.NoncurrentversionExpirationDays != 0 {
|
||||
return errors.New("non current version expiration days cannot be set when transition is being configured")
|
||||
}
|
||||
|
||||
opts = ilm.LifecycleOptions{
|
||||
ID: id,
|
||||
Prefix: params.Body.Prefix,
|
||||
Status: !params.Body.Disable,
|
||||
IsTagsSet: params.Body.Tags != "",
|
||||
Tags: params.Body.Tags,
|
||||
TransitionDays: strconv.Itoa(int(params.Body.TransitionDays)),
|
||||
StorageClass: strings.ToUpper(params.Body.StorageClass),
|
||||
ExpiredObjectDeleteMarker: params.Body.ExpiredObjectDeleteMarker,
|
||||
NoncurrentVersionTransitionDays: int(params.Body.NoncurrentversionTransitionDays),
|
||||
NoncurrentVersionTransitionStorageClass: strings.ToUpper(params.Body.NoncurrentversionTransitionStorageClass),
|
||||
}
|
||||
} else if params.Body.TransitionDays == 0 && params.Body.ExpiryDays != 0 { // Verify if expiry configuration is set
|
||||
if params.Body.NoncurrentversionTransitionDays != 0 {
|
||||
return errors.New("non current version Transition Days cannot be set when expiry is being configured")
|
||||
}
|
||||
|
||||
if params.Body.NoncurrentversionTransitionStorageClass != "" {
|
||||
return errors.New("non current version Transition Storage Class cannot be set when expiry is being configured")
|
||||
}
|
||||
|
||||
opts = ilm.LifecycleOptions{
|
||||
ID: id,
|
||||
Prefix: params.Body.Prefix,
|
||||
Status: !params.Body.Disable,
|
||||
IsTagsSet: params.Body.Tags != "",
|
||||
Tags: params.Body.Tags,
|
||||
ExpiryDays: strconv.Itoa(int(params.Body.ExpiryDays)),
|
||||
ExpiredObjectDeleteMarker: params.Body.ExpiredObjectDeleteMarker,
|
||||
NoncurrentVersionExpirationDays: int(params.Body.NoncurrentversionExpirationDays),
|
||||
}
|
||||
|
||||
} else {
|
||||
// Non set, we return error
|
||||
return errors.New("transition and expiry cannot be set for the same rule")
|
||||
}
|
||||
|
||||
var err2 *probe.Error
|
||||
lfcCfg, err2 = opts.ToConfig(lfcCfg)
|
||||
if err2.ToGoError() != nil {
|
||||
return err2.ToGoError()
|
||||
}
|
||||
|
||||
return client.setBucketLifecycle(ctx, params.BucketName, lfcCfg)
|
||||
}
|
||||
|
||||
// getEditBucketLifecycleRule returns the response of bucket lyfecycle tier edit
|
||||
func getEditBucketLifecycleRule(session *models.Principal, params user_api.UpdateBucketLifecycleParams) *models.Error {
|
||||
ctx := context.Background()
|
||||
mClient, err := newMinioClient(session)
|
||||
if err != nil {
|
||||
return prepareError(err)
|
||||
}
|
||||
// create a minioClient interface implementation
|
||||
// defining the client to be used
|
||||
minioClient := minioClient{client: mClient}
|
||||
|
||||
err = editBucketLifecycle(ctx, minioClient, params)
|
||||
if err != nil {
|
||||
return prepareError(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -198,3 +198,65 @@ func TestSetLifecycleRule(t *testing.T) {
|
||||
|
||||
assert.Equal(errors.New("error setting lifecycle"), err2, fmt.Sprintf("Failed on %s: Error returned", function))
|
||||
}
|
||||
|
||||
func TestUpdateLifecycleRule(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
// mock minIO client
|
||||
minClient := minioClientMock{}
|
||||
|
||||
function := "editBucketLifecycle()"
|
||||
ctx := context.Background()
|
||||
|
||||
// Test-1 : editBucketLifecycle() get list of events for a particular bucket only one config (get lifecycle mock)
|
||||
// mock create request
|
||||
mockLifecycle := lifecycle.Configuration{
|
||||
Rules: []lifecycle.Rule{
|
||||
{
|
||||
ID: "TESTRULE",
|
||||
Expiration: lifecycle.Expiration{Days: 15},
|
||||
Status: "Enabled",
|
||||
RuleFilter: lifecycle.Filter{Tag: lifecycle.Tag{Key: "tag1", Value: "val1"}, And: lifecycle.And{Prefix: "prefix1"}},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
minioGetLifecycleRulesMock = func(ctx context.Context, bucketName string) (lifecycle *lifecycle.Configuration, err error) {
|
||||
return &mockLifecycle, nil
|
||||
}
|
||||
|
||||
// Test-2 : editBucketLifecycle() Update lifecycle rule
|
||||
|
||||
editMock := user_api.UpdateBucketLifecycleParams{
|
||||
BucketName: "testBucket",
|
||||
Body: &models.UpdateBucketLifecycle{
|
||||
Disable: false,
|
||||
ExpiredObjectDeleteMarker: false,
|
||||
ExpiryDays: int32(16),
|
||||
NoncurrentversionExpirationDays: 0,
|
||||
NoncurrentversionTransitionDays: 0,
|
||||
NoncurrentversionTransitionStorageClass: "",
|
||||
Prefix: "pref1",
|
||||
StorageClass: "",
|
||||
Tags: "",
|
||||
TransitionDays: 0,
|
||||
},
|
||||
}
|
||||
|
||||
minioSetBucketLifecycleMock = func(ctx context.Context, bucketName string, config *lifecycle.Configuration) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
err := editBucketLifecycle(ctx, minClient, editMock)
|
||||
|
||||
assert.Equal(nil, err, fmt.Sprintf("Failed on %s: Error returned", function))
|
||||
|
||||
// Test-3 : editBucketLifecycle() returns error
|
||||
|
||||
minioSetBucketLifecycleMock = func(ctx context.Context, bucketName string, config *lifecycle.Configuration) error {
|
||||
return errors.New("error setting lifecycle")
|
||||
}
|
||||
|
||||
err2 := editBucketLifecycle(ctx, minClient, editMock)
|
||||
|
||||
assert.Equal(errors.New("error setting lifecycle"), err2, fmt.Sprintf("Failed on %s: Error returned", function))
|
||||
}
|
||||
|
||||
@@ -3906,10 +3906,44 @@ definitions:
|
||||
updateBucketLifecycle:
|
||||
type: object
|
||||
properties:
|
||||
prefix:
|
||||
description: Non required field, it matches a prefix to perform ILM operations on it
|
||||
type: string
|
||||
tags:
|
||||
description: Non required field, tags to match ILM files
|
||||
type: string
|
||||
expiry_days:
|
||||
description: Required in case of expiry_date or transition fields are not set. it defines an expiry days for ILM
|
||||
type: integer
|
||||
format: int32
|
||||
default: 0
|
||||
transition_days:
|
||||
description: Required in case of transition_date or expiry fields are not set. it defines a transition days for ILM
|
||||
type: integer
|
||||
format: int32
|
||||
default: 0
|
||||
storage_class:
|
||||
description: Required only in case of transition is set. it refers to a tier
|
||||
type: string
|
||||
disable:
|
||||
description: Non required, toggle to disable or enable rule
|
||||
type: boolean
|
||||
expired_object_delete_marker:
|
||||
description: Non required, toggle to disable or enable rule
|
||||
type: boolean
|
||||
noncurrentversion_expiration_days:
|
||||
description: Non required, can be set in case of expiration is enabled
|
||||
type: integer
|
||||
format: int32
|
||||
default: 0
|
||||
noncurrentversion_transition_days:
|
||||
description: Non required, can be set in case of transition is enabled
|
||||
type: integer
|
||||
format: int32
|
||||
default: 0
|
||||
noncurrentversion_transition_storage_class:
|
||||
description: Non required, can be set in case of transition is enabled
|
||||
type: string
|
||||
|
||||
prefixAccessPair:
|
||||
type: object
|
||||
|
||||
Reference in New Issue
Block a user