Added Exclude Folders & Exclude Prefixes support (#2973)

Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>
This commit is contained in:
Alex
2023-08-02 13:35:00 -06:00
committed by GitHub
parent 0d628f589a
commit 49f856bdd5
17 changed files with 433 additions and 194 deletions

View File

@@ -232,7 +232,7 @@ type MCClient interface {
list(ctx context.Context, opts mc.ListOptions) <-chan *mc.ClientContent
get(ctx context.Context, opts mc.GetOptions) (io.ReadCloser, *probe.Error)
shareDownload(ctx context.Context, versionID string, expires time.Duration) (string, *probe.Error)
setVersioning(ctx context.Context, status string) *probe.Error
setVersioning(ctx context.Context, status string, excludePrefix []string, excludeFolders bool) *probe.Error
}
// Interface implementation
@@ -265,8 +265,8 @@ func (c mcClient) deleteAllReplicationRules(ctx context.Context) *probe.Error {
return c.client.RemoveReplication(ctx)
}
func (c mcClient) setVersioning(ctx context.Context, status string) *probe.Error {
return c.client.SetVersion(ctx, status, []string{}, false)
func (c mcClient) setVersioning(ctx context.Context, status string, excludePrefix []string, excludeFolders bool) *probe.Error {
return c.client.SetVersion(ctx, status, excludePrefix, excludeFolders)
}
func (c mcClient) remove(ctx context.Context, isIncomplete, isRemoveBucket, isBypass, forceDelete bool, contentCh <-chan *mc.ClientContent) <-chan mc.RemoveResult {

View File

@@ -7124,7 +7124,7 @@ func init() {
"$ref": "#/definitions/putBucketRetentionRequest"
},
"versioning": {
"type": "boolean"
"$ref": "#/definitions/setBucketVersioning"
}
}
},
@@ -8195,8 +8195,18 @@ func init() {
"setBucketVersioning": {
"type": "object",
"properties": {
"versioning": {
"enabled": {
"type": "boolean"
},
"excludeFolders": {
"type": "boolean"
},
"excludePrefixes": {
"type": "array",
"maxLength": 10,
"items": {
"type": "string"
}
}
}
},
@@ -16257,7 +16267,7 @@ func init() {
"$ref": "#/definitions/putBucketRetentionRequest"
},
"versioning": {
"type": "boolean"
"$ref": "#/definitions/setBucketVersioning"
}
}
},
@@ -17328,8 +17338,18 @@ func init() {
"setBucketVersioning": {
"type": "object",
"properties": {
"versioning": {
"enabled": {
"type": "boolean"
},
"excludeFolders": {
"type": "boolean"
},
"excludePrefixes": {
"type": "array",
"maxLength": 10,
"items": {
"type": "string"
}
}
}
},

View File

@@ -188,8 +188,8 @@ const (
)
// removeBucket deletes a bucket
func doSetVersioning(ctx context.Context, client MCClient, state VersionState) error {
err := client.setVersioning(ctx, string(state))
func doSetVersioning(ctx context.Context, client MCClient, state VersionState, excludePrefix []string, excludeFolders bool) error {
err := client.setVersioning(ctx, string(state), excludePrefix, excludeFolders)
if err != nil {
return err.Cause
}
@@ -212,11 +212,19 @@ func setBucketVersioningResponse(session *models.Principal, params bucketApi.Set
versioningState := VersionSuspend
if params.Body.Versioning {
if params.Body.Enabled {
versioningState = VersionEnable
}
if err := doSetVersioning(ctx, amcClient, versioningState); err != nil {
var excludePrefixes []string
if params.Body.ExcludePrefixes != nil {
excludePrefixes = params.Body.ExcludePrefixes
}
excludeFolders := params.Body.ExcludeFolders
if err := doSetVersioning(ctx, amcClient, versioningState, excludePrefixes, excludeFolders); err != nil {
return ErrorWithContext(ctx, fmt.Errorf("error setting versioning for bucket: %s", err))
}
return nil
@@ -486,8 +494,14 @@ func getMakeBucketResponse(session *models.Principal, params bucketApi.MakeBucke
}
}()
versioningEnabled := false
if br.Versioning != nil && br.Versioning.Enabled {
versioningEnabled = true
}
// enable versioning if indicated or retention enabled
if br.Versioning || br.Retention != nil {
if versioningEnabled || br.Retention != nil {
s3Client, err := newS3BucketClient(session, *br.Name, "", getClientIP(params.HTTPRequest))
if err != nil {
return nil, ErrorWithContext(ctx, err)
@@ -496,7 +510,18 @@ func getMakeBucketResponse(session *models.Principal, params bucketApi.MakeBucke
// defining the client to be used
amcClient := mcClient{client: s3Client}
if err = doSetVersioning(ctx, amcClient, VersionEnable); err != nil {
excludePrefixes := []string{}
excludeFolders := false
if br.Versioning.ExcludeFolders && !br.Locking {
excludeFolders = true
}
if br.Versioning.ExcludePrefixes != nil && !br.Locking {
excludePrefixes = br.Versioning.ExcludePrefixes
}
if err = doSetVersioning(ctx, amcClient, VersionEnable, excludePrefixes, excludeFolders); err != nil {
return nil, ErrorWithContext(ctx, fmt.Errorf("error setting versioning for bucket: %s", err))
}
}

View File

@@ -50,7 +50,7 @@ var (
minioSetObjectLockConfigMock func(ctx context.Context, bucketName string, mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit) error
minioGetBucketObjectLockConfigMock func(ctx context.Context, bucketName string) (mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error)
minioGetObjectLockConfigMock func(ctx context.Context, bucketName string) (lock string, mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error)
minioSetVersioningMock func(ctx context.Context, state string) *probe.Error
minioSetVersioningMock func(ctx context.Context, state string, excludePrefix []string, excludeFolders bool) *probe.Error
minioCopyObjectMock func(ctx context.Context, dst minio.CopyDestOptions, src minio.CopySrcOptions) (minio.UploadInfo, error)
minioSetBucketTaggingMock func(ctx context.Context, bucketName string, tags *tags.Tags) error
minioRemoveBucketTaggingMock func(ctx context.Context, bucketName string) error
@@ -112,8 +112,8 @@ func (mc minioClientMock) copyObject(ctx context.Context, dst minio.CopyDestOpti
return minioCopyObjectMock(ctx, dst, src)
}
func (c s3ClientMock) setVersioning(ctx context.Context, state string) *probe.Error {
return minioSetVersioningMock(ctx, state)
func (c s3ClientMock) setVersioning(ctx context.Context, state string, excludePrefix []string, excludeFolders bool) *probe.Error {
return minioSetVersioningMock(ctx, state, excludePrefix, excludeFolders)
}
func (mc minioClientMock) GetBucketTagging(ctx context.Context, bucketName string) (*tags.Tags, error) {
@@ -813,9 +813,11 @@ func Test_SetBucketVersioning(t *testing.T) {
type args struct {
ctx context.Context
state VersionState
excludePrefix []string
excludeFolders bool
bucketName string
client s3ClientMock
setVersioningFunc func(ctx context.Context, state string) *probe.Error
setVersioningFunc func(ctx context.Context, state string, excludePrefix []string, excludeFolders bool) *probe.Error
}
tests := []struct {
name string
@@ -829,7 +831,36 @@ func Test_SetBucketVersioning(t *testing.T) {
state: VersionEnable,
bucketName: "test",
client: minClient,
setVersioningFunc: func(ctx context.Context, state string) *probe.Error {
setVersioningFunc: func(ctx context.Context, state string, excludePrefix []string, excludeFolders bool) *probe.Error {
return nil
},
},
expectedError: nil,
},
{
name: "Set Bucket Version with Prefixes Success",
args: args{
ctx: ctx,
state: VersionEnable,
excludePrefix: []string{"prefix1", "prefix2"},
bucketName: "test",
client: minClient,
setVersioningFunc: func(ctx context.Context, state string, excludePrefix []string, excludeFolders bool) *probe.Error {
return nil
},
},
expectedError: nil,
},
{
name: "Set Bucket Version with Excluded Folders Success",
args: args{
ctx: ctx,
state: VersionEnable,
excludePrefix: []string{"prefix1", "prefix2"},
excludeFolders: true,
bucketName: "test",
client: minClient,
setVersioningFunc: func(ctx context.Context, state string, excludePrefix []string, excludeFolders bool) *probe.Error {
return nil
},
},
@@ -842,7 +873,7 @@ func Test_SetBucketVersioning(t *testing.T) {
state: VersionEnable,
bucketName: "test",
client: minClient,
setVersioningFunc: func(ctx context.Context, state string) *probe.Error {
setVersioningFunc: func(ctx context.Context, state string, excludePrefix []string, excludeFolders bool) *probe.Error {
return probe.NewError(errors.New(errorMsg))
},
},
@@ -854,7 +885,7 @@ func Test_SetBucketVersioning(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
minioSetVersioningMock = tt.args.setVersioningFunc
err := doSetVersioning(tt.args.ctx, tt.args.client, tt.args.state)
err := doSetVersioning(tt.args.ctx, tt.args.client, tt.args.state, tt.args.excludePrefix, tt.args.excludeFolders)
fmt.Println(t.Name())
fmt.Println("Expected:", tt.expectedError, "Error:", err)