mirror of
https://github.com/OpenMaxIO/openmaxio-object-browser
synced 2026-07-01 07:41:18 -07:00
Added Exclude Folders & Exclude Prefixes support (#2973)
Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>
This commit is contained in:
@@ -31,7 +31,7 @@ import (
|
|||||||
func Test_AddAccessRuleAPI(t *testing.T) {
|
func Test_AddAccessRuleAPI(t *testing.T) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
|
|
||||||
AddBucket("testaccessruleadd", false, false, nil, nil)
|
AddBucket("testaccessruleadd", false, nil, nil, nil)
|
||||||
|
|
||||||
type args struct {
|
type args struct {
|
||||||
bucket string
|
bucket string
|
||||||
@@ -111,7 +111,7 @@ func Test_AddAccessRuleAPI(t *testing.T) {
|
|||||||
func Test_GetAccessRulesAPI(t *testing.T) {
|
func Test_GetAccessRulesAPI(t *testing.T) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
|
|
||||||
AddBucket("testaccessruleget", false, false, nil, nil)
|
AddBucket("testaccessruleget", false, nil, nil, nil)
|
||||||
|
|
||||||
type args struct {
|
type args struct {
|
||||||
bucket string
|
bucket string
|
||||||
@@ -161,7 +161,7 @@ func Test_GetAccessRulesAPI(t *testing.T) {
|
|||||||
func Test_DeleteAccessRuleAPI(t *testing.T) {
|
func Test_DeleteAccessRuleAPI(t *testing.T) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
|
|
||||||
AddBucket("testaccessruledelete", false, false, nil, nil)
|
AddBucket("testaccessruledelete", false, nil, nil, nil)
|
||||||
|
|
||||||
type args struct {
|
type args struct {
|
||||||
prefix string
|
prefix string
|
||||||
|
|||||||
@@ -42,14 +42,14 @@ import (
|
|||||||
type AddBucketOps struct {
|
type AddBucketOps struct {
|
||||||
Name string
|
Name string
|
||||||
Locking bool
|
Locking bool
|
||||||
Versioning bool
|
Versioning map[string]interface{}
|
||||||
Quota map[string]interface{}
|
Quota map[string]interface{}
|
||||||
Retention map[string]interface{}
|
Retention map[string]interface{}
|
||||||
Endpoint *string
|
Endpoint *string
|
||||||
UseToken *string
|
UseToken *string
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddBucket(name string, locking, versioning bool, quota, retention map[string]interface{}) (*http.Response, error) {
|
func AddBucket(name string, locking bool, versioning, quota, retention map[string]interface{}) (*http.Response, error) {
|
||||||
return AddBucketWithOpts(&AddBucketOps{
|
return AddBucketWithOpts(&AddBucketOps{
|
||||||
Name: name,
|
Name: name,
|
||||||
Locking: locking,
|
Locking: locking,
|
||||||
@@ -142,11 +142,11 @@ func getTokenForEndpoint(endpoint string) string {
|
|||||||
return loginToken
|
return loginToken
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupBucket(name string, locking, versioning bool, quota, retention map[string]interface{}, assert *assert.Assertions, expected int) bool {
|
func setupBucket(name string, locking bool, versioning, quota, retention map[string]interface{}, assert *assert.Assertions, expected int) bool {
|
||||||
return setupBucketForEndpoint(name, locking, versioning, quota, retention, assert, expected, nil, nil)
|
return setupBucketForEndpoint(name, locking, versioning, quota, retention, assert, expected, nil, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupBucketForEndpoint(name string, locking, versioning bool, quota, retention map[string]interface{}, assert *assert.Assertions, expected int, endpoint, endpointToken *string) bool {
|
func setupBucketForEndpoint(name string, locking bool, versioning, quota, retention map[string]interface{}, assert *assert.Assertions, expected int, endpoint, endpointToken *string) bool {
|
||||||
/*
|
/*
|
||||||
The intention of this function is to return either true or false to
|
The intention of this function is to return either true or false to
|
||||||
reduce the code by performing the verification in one place only.
|
reduce the code by performing the verification in one place only.
|
||||||
@@ -751,7 +751,7 @@ func TestPutObjectsLegalholdStatus(t *testing.T) {
|
|||||||
status := "enabled"
|
status := "enabled"
|
||||||
|
|
||||||
// 1. Create bucket
|
// 1. Create bucket
|
||||||
if !setupBucket(bucketName, true, true, nil, nil, assert, 200) {
|
if !setupBucket(bucketName, true, map[string]interface{}{"enabled": true}, nil, nil, assert, 200) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -838,7 +838,7 @@ func TestGetBucketQuota(t *testing.T) {
|
|||||||
validBucket := "testgetbucketquota"
|
validBucket := "testgetbucketquota"
|
||||||
|
|
||||||
// 1. Create bucket
|
// 1. Create bucket
|
||||||
if !setupBucket(validBucket, true, true, nil, nil, assert, 200) {
|
if !setupBucket(validBucket, true, map[string]interface{}{"enabled": true}, nil, nil, assert, 200) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -915,7 +915,7 @@ func TestPutBucketQuota(t *testing.T) {
|
|||||||
validBucket := "testputbucketquota"
|
validBucket := "testputbucketquota"
|
||||||
|
|
||||||
// 1. Create bucket
|
// 1. Create bucket
|
||||||
if !setupBucket(validBucket, true, true, nil, nil, assert, 200) {
|
if !setupBucket(validBucket, true, map[string]interface{}{"enabled": true}, nil, nil, assert, 200) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -974,7 +974,7 @@ func TestListBucketEvents(t *testing.T) {
|
|||||||
validBucket := "testlistbucketevents"
|
validBucket := "testlistbucketevents"
|
||||||
|
|
||||||
// 1. Create bucket
|
// 1. Create bucket
|
||||||
if !setupBucket(validBucket, true, true, nil, nil, assert, 200) {
|
if !setupBucket(validBucket, true, map[string]interface{}{"enabled": true}, nil, nil, assert, 200) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1032,7 +1032,7 @@ func TestDeleteObjectsRetentionStatus(t *testing.T) {
|
|||||||
validPrefix := encodeBase64(fileName)
|
validPrefix := encodeBase64(fileName)
|
||||||
|
|
||||||
// 1. Create bucket
|
// 1. Create bucket
|
||||||
if !setupBucket(bucketName, true, true, nil, nil, assert, 200) {
|
if !setupBucket(bucketName, true, map[string]interface{}{"enabled": true}, nil, nil, assert, 200) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1139,7 +1139,7 @@ func TestBucketSetPolicy(t *testing.T) {
|
|||||||
validBucketName := "testbucketsetpolicy"
|
validBucketName := "testbucketsetpolicy"
|
||||||
|
|
||||||
// 1. Create bucket
|
// 1. Create bucket
|
||||||
if !setupBucket(validBucketName, true, true, nil, nil, assert, 200) {
|
if !setupBucket(validBucketName, true, map[string]interface{}{"enabled": true}, nil, nil, assert, 200) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1200,7 +1200,7 @@ func TestRestoreObjectToASelectedVersion(t *testing.T) {
|
|||||||
validPrefix := encodeBase64(fileName)
|
validPrefix := encodeBase64(fileName)
|
||||||
|
|
||||||
// 1. Create bucket
|
// 1. Create bucket
|
||||||
if !setupBucket(bucketName, true, true, nil, nil, assert, 200) {
|
if !setupBucket(bucketName, true, map[string]interface{}{"enabled": true}, nil, nil, assert, 200) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1288,7 +1288,7 @@ func TestPutBucketsTags(t *testing.T) {
|
|||||||
// 1. Create the bucket
|
// 1. Create the bucket
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
validBucketName := "testputbuckettags1"
|
validBucketName := "testputbuckettags1"
|
||||||
if !setupBucket(validBucketName, false, false, nil, nil, assert, 200) {
|
if !setupBucket(validBucketName, false, nil, nil, nil, assert, 200) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1346,7 +1346,7 @@ func TestGetsTheMetadataOfAnObject(t *testing.T) {
|
|||||||
tags["tag"] = "testputobjecttagbucketonetagone"
|
tags["tag"] = "testputobjecttagbucketonetagone"
|
||||||
|
|
||||||
// 1. Create the bucket
|
// 1. Create the bucket
|
||||||
if !setupBucket(bucketName, false, false, nil, nil, assert, 200) {
|
if !setupBucket(bucketName, false, nil, nil, nil, assert, 200) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1417,7 +1417,7 @@ func TestPutObjectsRetentionStatus(t *testing.T) {
|
|||||||
prefix := encodeBase64(fileName)
|
prefix := encodeBase64(fileName)
|
||||||
|
|
||||||
// 1. Create bucket
|
// 1. Create bucket
|
||||||
if !setupBucket(bucketName, true, true, nil, nil, assert, 200) {
|
if !setupBucket(bucketName, true, map[string]interface{}{"enabled": true}, nil, nil, assert, 200) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1515,7 +1515,7 @@ func TestShareObjectOnURL(t *testing.T) {
|
|||||||
versionID := "null"
|
versionID := "null"
|
||||||
|
|
||||||
// 1. Create the bucket
|
// 1. Create the bucket
|
||||||
if !setupBucket(bucketName, false, false, nil, nil, assert, 200) {
|
if !setupBucket(bucketName, false, nil, nil, nil, assert, 200) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1589,7 +1589,7 @@ func TestListObjects(t *testing.T) {
|
|||||||
fileName := "testlistobjecttobucket1.txt"
|
fileName := "testlistobjecttobucket1.txt"
|
||||||
|
|
||||||
// 1. Create the bucket
|
// 1. Create the bucket
|
||||||
if !setupBucket(bucketName, false, false, nil, nil, assert, 200) {
|
if !setupBucket(bucketName, false, nil, nil, nil, assert, 200) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1637,7 +1637,7 @@ func TestDeleteObject(t *testing.T) {
|
|||||||
numberOfFiles := 2
|
numberOfFiles := 2
|
||||||
|
|
||||||
// 1. Create bucket
|
// 1. Create bucket
|
||||||
if !setupBucket(bucketName, true, true, nil, nil, assert, 200) {
|
if !setupBucket(bucketName, true, map[string]interface{}{"enabled": true}, nil, nil, assert, 200) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1703,7 +1703,7 @@ func TestUploadObjectToBucket(t *testing.T) {
|
|||||||
fileName := "sample.txt"
|
fileName := "sample.txt"
|
||||||
|
|
||||||
// 1. Create the bucket
|
// 1. Create the bucket
|
||||||
if !setupBucket(bucketName, false, false, nil, nil, assert, 200) {
|
if !setupBucket(bucketName, false, nil, nil, nil, assert, 200) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1738,7 +1738,7 @@ func TestDownloadObject(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 1. Create the bucket
|
// 1. Create the bucket
|
||||||
if !setupBucket(bucketName, true, true, nil, nil, assert, 200) {
|
if !setupBucket(bucketName, true, map[string]interface{}{"enabled": true}, nil, nil, assert, 200) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1800,7 +1800,7 @@ func TestDeleteMultipleObjects(t *testing.T) {
|
|||||||
fileName := "testdeletemultipleobjs"
|
fileName := "testdeletemultipleobjs"
|
||||||
|
|
||||||
// 1. Create a bucket for this particular test
|
// 1. Create a bucket for this particular test
|
||||||
if !setupBucket(bucketName, false, false, nil, nil, assert, 200) {
|
if !setupBucket(bucketName, false, nil, nil, nil, assert, 200) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1877,7 +1877,7 @@ func TestPutObjectTag(t *testing.T) {
|
|||||||
versionID := "null"
|
versionID := "null"
|
||||||
|
|
||||||
// 1. Create the bucket
|
// 1. Create the bucket
|
||||||
if !setupBucket(bucketName, false, false, nil, nil, assert, 200) {
|
if !setupBucket(bucketName, false, nil, nil, nil, assert, 200) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1951,7 +1951,7 @@ func TestBucketRetention(t *testing.T) {
|
|||||||
retention["mode"] = "compliance"
|
retention["mode"] = "compliance"
|
||||||
retention["unit"] = "years"
|
retention["unit"] = "years"
|
||||||
retention["validity"] = 2
|
retention["validity"] = 2
|
||||||
if !setupBucket("setbucketretention1", true, true, nil, retention, assert, 200) {
|
if !setupBucket("setbucketretention1", true, map[string]interface{}{"enabled": true}, nil, retention, assert, 200) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2002,7 +2002,7 @@ func TestBucketInformationGenericErrorResponse(t *testing.T) {
|
|||||||
|
|
||||||
// 1. Create the bucket
|
// 1. Create the bucket
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
if !setupBucket("bucketinformation2", false, false, nil, nil, assert, 200) {
|
if !setupBucket("bucketinformation2", false, nil, nil, nil, assert, 200) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2047,7 +2047,7 @@ func TestBucketInformationSuccessfulResponse(t *testing.T) {
|
|||||||
|
|
||||||
// 1. Create the bucket
|
// 1. Create the bucket
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
if !setupBucket("bucketinformation1", false, false, nil, nil, assert, 200) {
|
if !setupBucket("bucketinformation1", false, nil, nil, nil, assert, 200) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2160,7 +2160,7 @@ func TestListBuckets(t *testing.T) {
|
|||||||
// 1. Create buckets
|
// 1. Create buckets
|
||||||
numberOfBuckets := 3
|
numberOfBuckets := 3
|
||||||
for i := 1; i <= numberOfBuckets; i++ {
|
for i := 1; i <= numberOfBuckets; i++ {
|
||||||
if !setupBucket("testlistbuckets"+strconv.Itoa(i), false, false, nil, nil, assert, 200) {
|
if !setupBucket("testlistbuckets"+strconv.Itoa(i), false, nil, nil, nil, assert, 200) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2267,7 +2267,7 @@ func TestBucketVersioning(t *testing.T) {
|
|||||||
|
|
||||||
requestDataBody := bytes.NewReader(requestDataJSON)
|
requestDataBody := bytes.NewReader(requestDataJSON)
|
||||||
|
|
||||||
if !setupBucket("test2", true, false, nil, nil, assert, 200) {
|
if !setupBucket("test2", true, nil, nil, nil, assert, 200) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2335,7 +2335,7 @@ func TestSetBucketTags(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// put bucket
|
// put bucket
|
||||||
if !setupBucket("test4", false, false, nil, nil, assert, 200) {
|
if !setupBucket("test4", false, nil, nil, nil, assert, 200) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2402,7 +2402,7 @@ func TestGetBucket(t *testing.T) {
|
|||||||
Timeout: 2 * time.Second,
|
Timeout: 2 * time.Second,
|
||||||
}
|
}
|
||||||
|
|
||||||
if !setupBucket("test3", false, false, nil, nil, assert, 200) {
|
if !setupBucket("test3", false, nil, nil, nil, assert, 200) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2455,7 +2455,7 @@ func TestAddBucket(t *testing.T) {
|
|||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
if !setupBucket(tt.args.bucketName, false, false, nil, nil, assert, tt.expectedStatus) {
|
if !setupBucket(tt.args.bucketName, false, nil, nil, nil, assert, tt.expectedStatus) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -3000,7 +3000,7 @@ func TestReturnsTheStatusOfObjectLockingSupportOnTheBucket(t *testing.T) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetBucketVersioning(bucketName string, versioning bool, endpoint, useToken *string) (*http.Response, error) {
|
func SetBucketVersioning(bucketName string, versioning map[string]interface{}, endpoint, useToken *string) (*http.Response, error) {
|
||||||
/*
|
/*
|
||||||
Helper function to set Bucket Versioning
|
Helper function to set Bucket Versioning
|
||||||
*/
|
*/
|
||||||
@@ -3037,7 +3037,7 @@ func TestSetBucketVersioning(t *testing.T) {
|
|||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
bucket := "test-set-bucket-versioning"
|
bucket := "test-set-bucket-versioning"
|
||||||
locking := false
|
locking := false
|
||||||
versioning := true
|
versioning := map[string]interface{}{"enabled": true}
|
||||||
|
|
||||||
// 1. Create bucket with versioning as true and locking as false
|
// 1. Create bucket with versioning as true and locking as false
|
||||||
if !setupBucket(bucket, locking, versioning, nil, nil, assert, 200) {
|
if !setupBucket(bucket, locking, versioning, nil, nil, assert, 200) {
|
||||||
@@ -3045,7 +3045,7 @@ func TestSetBucketVersioning(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 2. Set versioning as False i.e Suspend versioning
|
// 2. Set versioning as False i.e Suspend versioning
|
||||||
response, err := SetBucketVersioning(bucket, false, nil, nil)
|
response, err := SetBucketVersioning(bucket, map[string]interface{}{"enabled": false}, nil, nil)
|
||||||
assert.Nil(err)
|
assert.Nil(err)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
@@ -3118,12 +3118,11 @@ func TestEnableBucketEncryption(t *testing.T) {
|
|||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
bucketName := "test-enable-bucket-encryption"
|
bucketName := "test-enable-bucket-encryption"
|
||||||
locking := false
|
locking := false
|
||||||
versioning := false
|
|
||||||
encType := "sse-s3"
|
encType := "sse-s3"
|
||||||
kmsKeyID := ""
|
kmsKeyID := ""
|
||||||
|
|
||||||
// 1. Add bucket
|
// 1. Add bucket
|
||||||
if !setupBucket(bucketName, locking, versioning, nil, nil, assert, 200) {
|
if !setupBucket(bucketName, locking, nil, nil, nil, assert, 200) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3381,7 +3380,6 @@ func TestBucketLifeCycle(t *testing.T) {
|
|||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
bucketName := "test-bucket-life-cycle"
|
bucketName := "test-bucket-life-cycle"
|
||||||
locking := false
|
locking := false
|
||||||
versioning := false
|
|
||||||
ltype := "expiry"
|
ltype := "expiry"
|
||||||
prefix := ""
|
prefix := ""
|
||||||
tags := ""
|
tags := ""
|
||||||
@@ -3392,7 +3390,7 @@ func TestBucketLifeCycle(t *testing.T) {
|
|||||||
var noncurrentversionExpirationDays int64
|
var noncurrentversionExpirationDays int64
|
||||||
|
|
||||||
// 1. Add bucket
|
// 1. Add bucket
|
||||||
if !setupBucket(bucketName, locking, versioning, nil, nil, assert, 200) {
|
if !setupBucket(bucketName, locking, nil, nil, nil, assert, 200) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3597,12 +3595,11 @@ func TestAccessRule(t *testing.T) {
|
|||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
bucketName := "test-access-rule-bucket"
|
bucketName := "test-access-rule-bucket"
|
||||||
locking := false
|
locking := false
|
||||||
versioning := false
|
|
||||||
prefix := "prefix"
|
prefix := "prefix"
|
||||||
access := "readonly"
|
access := "readonly"
|
||||||
|
|
||||||
// 1. Add bucket
|
// 1. Add bucket
|
||||||
if !setupBucket(bucketName, locking, versioning, nil, nil, assert, 200) {
|
if !setupBucket(bucketName, locking, nil, nil, nil, assert, 200) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3846,16 +3843,16 @@ func TestAddRemoteBucket(t *testing.T) {
|
|||||||
fmt.Println("targetBucket: ", targetBucket)
|
fmt.Println("targetBucket: ", targetBucket)
|
||||||
|
|
||||||
// 1. Create bucket
|
// 1. Create bucket
|
||||||
if !setupBucket("source", true, true, nil, nil, assert, 200) {
|
if !setupBucket("source", true, map[string]interface{}{"enabled": true}, nil, nil, assert, 200) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 1.1. Create target bucket
|
// 1.1. Create target bucket
|
||||||
targetEndpoint := "http://localhost:9092"
|
targetEndpoint := "http://localhost:9092"
|
||||||
targetToken := getTokenForEndpoint(targetEndpoint)
|
targetToken := getTokenForEndpoint(targetEndpoint)
|
||||||
if !setupBucketForEndpoint(targetBucket, true, true, nil, nil, assert, 200, &targetEndpoint, &targetToken) {
|
if !setupBucketForEndpoint(targetBucket, true, map[string]interface{}{"enabled": true}, nil, nil, assert, 200, &targetEndpoint, &targetToken) {
|
||||||
log.Println("bucket already exists")
|
log.Println("bucket already exists")
|
||||||
}
|
}
|
||||||
_, err := SetBucketVersioning(targetBucket, false, &targetURL, &targetToken)
|
_, err := SetBucketVersioning(targetBucket, map[string]interface{}{"enabled": false}, &targetURL, &targetToken)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("bucket already has versioning")
|
log.Println("bucket already has versioning")
|
||||||
}
|
}
|
||||||
@@ -3905,16 +3902,16 @@ func TestDeleteRemoteBucket(t *testing.T) {
|
|||||||
fmt.Println("targetBucket: ", targetBucket)
|
fmt.Println("targetBucket: ", targetBucket)
|
||||||
|
|
||||||
// 1. Create bucket
|
// 1. Create bucket
|
||||||
if !setupBucket("deletesource", true, true, nil, nil, assert, 200) {
|
if !setupBucket("deletesource", true, map[string]interface{}{"enabled": true}, nil, nil, assert, 200) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 1.1. Create target bucket
|
// 1.1. Create target bucket
|
||||||
targetEndpoint := "http://localhost:9092"
|
targetEndpoint := "http://localhost:9092"
|
||||||
targetToken := getTokenForEndpoint(targetEndpoint)
|
targetToken := getTokenForEndpoint(targetEndpoint)
|
||||||
if !setupBucketForEndpoint(targetBucket, true, true, nil, nil, assert, 200, &targetEndpoint, &targetToken) {
|
if !setupBucketForEndpoint(targetBucket, true, map[string]interface{}{"enabled": true}, nil, nil, assert, 200, &targetEndpoint, &targetToken) {
|
||||||
log.Println("bucket already exists")
|
log.Println("bucket already exists")
|
||||||
}
|
}
|
||||||
_, err := SetBucketVersioning(targetBucket, false, &targetURL, &targetToken)
|
_, err := SetBucketVersioning(targetBucket, map[string]interface{}{"enabled": false}, &targetURL, &targetToken)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("bucket already has versioning")
|
log.Println("bucket already has versioning")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ type MakeBucketRequest struct {
|
|||||||
Retention *PutBucketRetentionRequest `json:"retention,omitempty"`
|
Retention *PutBucketRetentionRequest `json:"retention,omitempty"`
|
||||||
|
|
||||||
// versioning
|
// versioning
|
||||||
Versioning bool `json:"versioning,omitempty"`
|
Versioning *SetBucketVersioning `json:"versioning,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate validates this make bucket request
|
// Validate validates this make bucket request
|
||||||
@@ -69,6 +69,10 @@ func (m *MakeBucketRequest) Validate(formats strfmt.Registry) error {
|
|||||||
res = append(res, err)
|
res = append(res, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := m.validateVersioning(formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
if len(res) > 0 {
|
if len(res) > 0 {
|
||||||
return errors.CompositeValidationError(res...)
|
return errors.CompositeValidationError(res...)
|
||||||
}
|
}
|
||||||
@@ -122,6 +126,25 @@ func (m *MakeBucketRequest) validateRetention(formats strfmt.Registry) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *MakeBucketRequest) validateVersioning(formats strfmt.Registry) error {
|
||||||
|
if swag.IsZero(m.Versioning) { // not required
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if m.Versioning != nil {
|
||||||
|
if err := m.Versioning.Validate(formats); err != nil {
|
||||||
|
if ve, ok := err.(*errors.Validation); ok {
|
||||||
|
return ve.ValidateName("versioning")
|
||||||
|
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||||
|
return ce.ValidateName("versioning")
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// ContextValidate validate this make bucket request based on the context it is used
|
// ContextValidate validate this make bucket request based on the context it is used
|
||||||
func (m *MakeBucketRequest) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
func (m *MakeBucketRequest) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||||
var res []error
|
var res []error
|
||||||
@@ -134,6 +157,10 @@ func (m *MakeBucketRequest) ContextValidate(ctx context.Context, formats strfmt.
|
|||||||
res = append(res, err)
|
res = append(res, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := m.contextValidateVersioning(ctx, formats); err != nil {
|
||||||
|
res = append(res, err)
|
||||||
|
}
|
||||||
|
|
||||||
if len(res) > 0 {
|
if len(res) > 0 {
|
||||||
return errors.CompositeValidationError(res...)
|
return errors.CompositeValidationError(res...)
|
||||||
}
|
}
|
||||||
@@ -172,6 +199,22 @@ func (m *MakeBucketRequest) contextValidateRetention(ctx context.Context, format
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *MakeBucketRequest) contextValidateVersioning(ctx context.Context, formats strfmt.Registry) error {
|
||||||
|
|
||||||
|
if m.Versioning != nil {
|
||||||
|
if err := m.Versioning.ContextValidate(ctx, formats); err != nil {
|
||||||
|
if ve, ok := err.(*errors.Validation); ok {
|
||||||
|
return ve.ValidateName("versioning")
|
||||||
|
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||||
|
return ce.ValidateName("versioning")
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// MarshalBinary interface implementation
|
// MarshalBinary interface implementation
|
||||||
func (m *MakeBucketRequest) MarshalBinary() ([]byte, error) {
|
func (m *MakeBucketRequest) MarshalBinary() ([]byte, error) {
|
||||||
if m == nil {
|
if m == nil {
|
||||||
|
|||||||
@@ -34,8 +34,14 @@ import (
|
|||||||
// swagger:model setBucketVersioning
|
// swagger:model setBucketVersioning
|
||||||
type SetBucketVersioning struct {
|
type SetBucketVersioning struct {
|
||||||
|
|
||||||
// versioning
|
// enabled
|
||||||
Versioning bool `json:"versioning,omitempty"`
|
Enabled bool `json:"enabled,omitempty"`
|
||||||
|
|
||||||
|
// exclude folders
|
||||||
|
ExcludeFolders bool `json:"excludeFolders,omitempty"`
|
||||||
|
|
||||||
|
// exclude prefixes
|
||||||
|
ExcludePrefixes []string `json:"excludePrefixes"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate validates this set bucket versioning
|
// Validate validates this set bucket versioning
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ export interface BucketObject {
|
|||||||
export interface MakeBucketRequest {
|
export interface MakeBucketRequest {
|
||||||
name: string;
|
name: string;
|
||||||
locking?: boolean;
|
locking?: boolean;
|
||||||
versioning?: boolean;
|
versioning?: SetBucketVersioning;
|
||||||
quota?: SetBucketQuota;
|
quota?: SetBucketQuota;
|
||||||
retention?: PutBucketRetentionRequest;
|
retention?: PutBucketRetentionRequest;
|
||||||
}
|
}
|
||||||
@@ -802,7 +802,10 @@ export interface BucketVersioningResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface SetBucketVersioning {
|
export interface SetBucketVersioning {
|
||||||
versioning?: boolean;
|
enabled?: boolean;
|
||||||
|
/** @maxLength 10 */
|
||||||
|
excludePrefixes?: string[];
|
||||||
|
excludeFolders?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BucketObLockingResponse {
|
export interface BucketObLockingResponse {
|
||||||
|
|||||||
@@ -407,6 +407,7 @@ const BucketSummary = () => {
|
|||||||
modalOpen={enableVersioningOpen}
|
modalOpen={enableVersioningOpen}
|
||||||
selectedBucket={bucketName}
|
selectedBucket={bucketName}
|
||||||
versioningInfo={versioningInfo}
|
versioningInfo={versioningInfo}
|
||||||
|
objectLockingEnabled={!!hasObjectLocking}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@@ -581,6 +582,7 @@ const BucketSummary = () => {
|
|||||||
}
|
}
|
||||||
onEdit={setBucketVersioning}
|
onEdit={setBucketVersioning}
|
||||||
isLoading={loadingVersioning}
|
isLoading={loadingVersioning}
|
||||||
|
disabled={hasObjectLocking}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{versioningInfo?.status === "Enabled" ? (
|
{versioningInfo?.status === "Enabled" ? (
|
||||||
|
|||||||
@@ -15,32 +15,54 @@
|
|||||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import React, { Fragment, useState } from "react";
|
import React, { Fragment, useState } from "react";
|
||||||
import { Box, ConfirmModalIcon } from "mds";
|
import { Box, Button, FormLayout, ModalBox, Switch } from "mds";
|
||||||
import { BucketVersioningResponse } from "api/consoleApi";
|
import { BucketVersioningResponse } from "api/consoleApi";
|
||||||
import { api } from "api";
|
import { api } from "api";
|
||||||
import { errorToHandler } from "api/errors";
|
import { errorToHandler } from "api/errors";
|
||||||
import { setErrorSnackMessage } from "../../../../systemSlice";
|
import { setErrorSnackMessage } from "../../../../systemSlice";
|
||||||
import { useAppDispatch } from "../../../../store";
|
import { useAppDispatch } from "../../../../store";
|
||||||
import VersioningInfo from "../VersioningInfo";
|
import CSVMultiSelector from "../../Common/FormComponents/CSVMultiSelector/CSVMultiSelector";
|
||||||
import ConfirmDialog from "../../Common/ModalWrapper/ConfirmDialog";
|
import { modalStyleUtils } from "../../Common/FormComponents/common/styleLibrary";
|
||||||
|
|
||||||
interface IVersioningEventProps {
|
interface IVersioningEventProps {
|
||||||
closeVersioningModalAndRefresh: (refresh: boolean) => void;
|
closeVersioningModalAndRefresh: (refresh: boolean) => void;
|
||||||
modalOpen: boolean;
|
modalOpen: boolean;
|
||||||
selectedBucket: string;
|
selectedBucket: string;
|
||||||
versioningInfo: BucketVersioningResponse | undefined;
|
versioningInfo: BucketVersioningResponse | undefined;
|
||||||
|
objectLockingEnabled: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const parseExcludedPrefixes = (
|
||||||
|
bucketVersioning: BucketVersioningResponse | undefined,
|
||||||
|
) => {
|
||||||
|
const excludedPrefixes = bucketVersioning?.excludedPrefixes;
|
||||||
|
|
||||||
|
if (excludedPrefixes) {
|
||||||
|
return excludedPrefixes.map((item) => item.prefix).join(",");
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
};
|
||||||
|
|
||||||
const EnableVersioningModal = ({
|
const EnableVersioningModal = ({
|
||||||
closeVersioningModalAndRefresh,
|
closeVersioningModalAndRefresh,
|
||||||
modalOpen,
|
modalOpen,
|
||||||
selectedBucket,
|
selectedBucket,
|
||||||
versioningInfo = {},
|
versioningInfo = {},
|
||||||
|
objectLockingEnabled,
|
||||||
}: IVersioningEventProps) => {
|
}: IVersioningEventProps) => {
|
||||||
const isVersioningEnabled = versioningInfo.status === "Enabled";
|
|
||||||
|
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
const [versioningLoading, setVersioningLoading] = useState<boolean>(false);
|
const [versioningLoading, setVersioningLoading] = useState<boolean>(false);
|
||||||
|
const [versionState, setVersionState] = useState<boolean>(
|
||||||
|
versioningInfo?.status === "Enabled",
|
||||||
|
);
|
||||||
|
const [excludeFolders, setExcludeFolders] = useState<boolean>(
|
||||||
|
!!versioningInfo?.excludeFolders,
|
||||||
|
);
|
||||||
|
const [excludedPrefixes, setExcludedPrefixes] = useState<string>(
|
||||||
|
parseExcludedPrefixes(versioningInfo),
|
||||||
|
);
|
||||||
|
|
||||||
const enableVersioning = () => {
|
const enableVersioning = () => {
|
||||||
if (versioningLoading) {
|
if (versioningLoading) {
|
||||||
@@ -50,7 +72,11 @@ const EnableVersioningModal = ({
|
|||||||
|
|
||||||
api.buckets
|
api.buckets
|
||||||
.setBucketVersioning(selectedBucket, {
|
.setBucketVersioning(selectedBucket, {
|
||||||
versioning: !isVersioningEnabled,
|
enabled: versionState,
|
||||||
|
excludeFolders: versionState ? excludeFolders : false,
|
||||||
|
excludePrefixes: versionState
|
||||||
|
? excludedPrefixes.split(",").filter((item) => item.trim() !== "")
|
||||||
|
: [],
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
setVersioningLoading(false);
|
setVersioningLoading(false);
|
||||||
@@ -62,44 +88,76 @@ const EnableVersioningModal = ({
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const resetForm = () => {
|
||||||
|
setExcludedPrefixes("");
|
||||||
|
setExcludeFolders(false);
|
||||||
|
setVersionState(false);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ConfirmDialog
|
<ModalBox
|
||||||
|
onClose={() => closeVersioningModalAndRefresh(false)}
|
||||||
|
open={modalOpen}
|
||||||
title={`Versioning on Bucket`}
|
title={`Versioning on Bucket`}
|
||||||
confirmText={isVersioningEnabled ? "Suspend" : "Enable"}
|
>
|
||||||
isOpen={modalOpen}
|
<FormLayout withBorders={false} containerPadding={false}>
|
||||||
isLoading={versioningLoading}
|
<Switch
|
||||||
titleIcon={<ConfirmModalIcon />}
|
id={"activateVersioning"}
|
||||||
onConfirm={enableVersioning}
|
label={"Versioning Status"}
|
||||||
confirmButtonProps={{
|
checked={versionState}
|
||||||
variant: "callAction",
|
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
}}
|
setVersionState(e.target.checked);
|
||||||
onClose={() => {
|
}}
|
||||||
closeVersioningModalAndRefresh(false);
|
indicatorLabels={["Enabled", "Disabled"]}
|
||||||
}}
|
/>
|
||||||
confirmationContent={
|
{versionState && !objectLockingEnabled && (
|
||||||
<Box id="alert-dialog-description">
|
<Fragment>
|
||||||
Are you sure you want to{" "}
|
<Switch
|
||||||
<strong>{isVersioningEnabled ? "suspend" : "enable"}</strong>{" "}
|
id={"excludeFolders"}
|
||||||
versioning for this bucket?
|
label={"Exclude Folders"}
|
||||||
{isVersioningEnabled && (
|
checked={excludeFolders}
|
||||||
<Fragment>
|
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
<br />
|
setExcludeFolders(e.target.checked);
|
||||||
<br />
|
}}
|
||||||
<strong>File versions won't be automatically deleted.</strong>
|
indicatorLabels={["Enabled", "Disabled"]}
|
||||||
</Fragment>
|
/>
|
||||||
)}
|
<CSVMultiSelector
|
||||||
<Box
|
elements={excludedPrefixes}
|
||||||
sx={{
|
label={"Excluded Prefixes"}
|
||||||
paddingTop: "20px",
|
name={"excludedPrefixes"}
|
||||||
}}
|
onChange={(value: string | string[]) => {
|
||||||
>
|
let valCh = "";
|
||||||
{isVersioningEnabled ? (
|
|
||||||
<VersioningInfo versioningState={versioningInfo} />
|
if (Array.isArray(value)) {
|
||||||
) : null}
|
valCh = value.join(",");
|
||||||
</Box>
|
} else {
|
||||||
|
valCh = value;
|
||||||
|
}
|
||||||
|
setExcludedPrefixes(valCh);
|
||||||
|
}}
|
||||||
|
withBorder={true}
|
||||||
|
/>
|
||||||
|
</Fragment>
|
||||||
|
)}
|
||||||
|
<Box sx={modalStyleUtils.modalButtonBar}>
|
||||||
|
<Button
|
||||||
|
id={"clear"}
|
||||||
|
type="button"
|
||||||
|
variant="regular"
|
||||||
|
color="primary"
|
||||||
|
onClick={resetForm}
|
||||||
|
label={"Clear"}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
type="submit"
|
||||||
|
variant="callAction"
|
||||||
|
onClick={enableVersioning}
|
||||||
|
id="saveTag"
|
||||||
|
label={"Save"}
|
||||||
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
}
|
</FormLayout>
|
||||||
/>
|
</ModalBox>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { Box, ValuePair, ActionLink } from "mds";
|
import { ActionLink, Box, ValuePair } from "mds";
|
||||||
import { SecureComponent } from "../../../../../common/SecureComponent";
|
import { SecureComponent } from "../../../../../common/SecureComponent";
|
||||||
|
|
||||||
import EditActionButton from "./EditActionButton";
|
import EditActionButton from "./EditActionButton";
|
||||||
@@ -28,6 +28,7 @@ type EditablePropertyItemProps = {
|
|||||||
value: any;
|
value: any;
|
||||||
onEdit: () => void;
|
onEdit: () => void;
|
||||||
secureCmpProps?: Record<any, any>;
|
secureCmpProps?: Record<any, any>;
|
||||||
|
disabled?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const SecureAction = ({
|
const SecureAction = ({
|
||||||
@@ -61,6 +62,7 @@ const EditablePropertyItem = ({
|
|||||||
property = null,
|
property = null,
|
||||||
value = null,
|
value = null,
|
||||||
onEdit,
|
onEdit,
|
||||||
|
disabled = false,
|
||||||
}: EditablePropertyItemProps) => {
|
}: EditablePropertyItemProps) => {
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
@@ -84,6 +86,7 @@ const EditablePropertyItem = ({
|
|||||||
onClick={onEdit}
|
onClick={onEdit}
|
||||||
label={value}
|
label={value}
|
||||||
sx={{ fontWeight: "bold" }}
|
sx={{ fontWeight: "bold" }}
|
||||||
|
disabled={disabled}
|
||||||
/>
|
/>
|
||||||
</SecureAction>
|
</SecureAction>
|
||||||
}
|
}
|
||||||
@@ -104,6 +107,7 @@ const EditablePropertyItem = ({
|
|||||||
height: "16px",
|
height: "16px",
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
|
disabled={disabled}
|
||||||
/>
|
/>
|
||||||
</SecureAction>
|
</SecureAction>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@@ -48,6 +48,8 @@ import SectionTitle from "../../../Common/SectionTitle";
|
|||||||
import {
|
import {
|
||||||
resetForm,
|
resetForm,
|
||||||
setEnableObjectLocking,
|
setEnableObjectLocking,
|
||||||
|
setExcludedPrefixes,
|
||||||
|
setExcludeFolders,
|
||||||
setIsDirty,
|
setIsDirty,
|
||||||
setName,
|
setName,
|
||||||
setQuota,
|
setQuota,
|
||||||
@@ -77,6 +79,7 @@ import {
|
|||||||
} from "../../../../../api/consoleApi";
|
} from "../../../../../api/consoleApi";
|
||||||
import { errorToHandler } from "../../../../../api/errors";
|
import { errorToHandler } from "../../../../../api/errors";
|
||||||
import HelpMenu from "../../../HelpMenu";
|
import HelpMenu from "../../../HelpMenu";
|
||||||
|
import CSVMultiSelector from "../../../Common/FormComponents/CSVMultiSelector/CSVMultiSelector";
|
||||||
|
|
||||||
const ErrorBox = styled.div(({ theme }) => ({
|
const ErrorBox = styled.div(({ theme }) => ({
|
||||||
color: get(theme, "signalColors.danger", "#C51B3F"),
|
color: get(theme, "signalColors.danger", "#C51B3F"),
|
||||||
@@ -102,6 +105,12 @@ const AddBucket = () => {
|
|||||||
const versioningEnabled = useSelector(
|
const versioningEnabled = useSelector(
|
||||||
(state: AppState) => state.addBucket.versioningEnabled,
|
(state: AppState) => state.addBucket.versioningEnabled,
|
||||||
);
|
);
|
||||||
|
const excludeFolders = useSelector(
|
||||||
|
(state: AppState) => state.addBucket.excludeFolders,
|
||||||
|
);
|
||||||
|
const excludedPrefixes = useSelector(
|
||||||
|
(state: AppState) => state.addBucket.excludedPrefixes,
|
||||||
|
);
|
||||||
const lockingEnabled = useSelector(
|
const lockingEnabled = useSelector(
|
||||||
(state: AppState) => state.addBucket.lockingEnabled,
|
(state: AppState) => state.addBucket.lockingEnabled,
|
||||||
);
|
);
|
||||||
@@ -346,6 +355,35 @@ const AddBucket = () => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
{versioningEnabled && distributedSetup && !lockingEnabled && (
|
||||||
|
<Fragment>
|
||||||
|
<Switch
|
||||||
|
id={"excludeFolders"}
|
||||||
|
label={"Exclude Folders"}
|
||||||
|
checked={excludeFolders}
|
||||||
|
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
dispatch(setExcludeFolders(e.target.checked));
|
||||||
|
}}
|
||||||
|
indicatorLabels={["Enabled", "Disabled"]}
|
||||||
|
/>
|
||||||
|
<CSVMultiSelector
|
||||||
|
elements={excludedPrefixes}
|
||||||
|
label={"Excluded Prefixes"}
|
||||||
|
name={"excludedPrefixes"}
|
||||||
|
onChange={(value: string | string[]) => {
|
||||||
|
let valCh = "";
|
||||||
|
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
valCh = value.join(",");
|
||||||
|
} else {
|
||||||
|
valCh = value;
|
||||||
|
}
|
||||||
|
dispatch(setExcludedPrefixes(valCh));
|
||||||
|
}}
|
||||||
|
withBorder={true}
|
||||||
|
/>
|
||||||
|
</Fragment>
|
||||||
|
)}
|
||||||
<Switch
|
<Switch
|
||||||
value="locking"
|
value="locking"
|
||||||
id="locking"
|
id="locking"
|
||||||
@@ -363,7 +401,11 @@ const AddBucket = () => {
|
|||||||
label={"Object Locking"}
|
label={"Object Locking"}
|
||||||
tooltip={
|
tooltip={
|
||||||
lockingAllowed
|
lockingAllowed
|
||||||
? ""
|
? `${
|
||||||
|
versioningEnabled
|
||||||
|
? "Exclude Folders & Exclude Prefixes options will not be available if this option is enabled."
|
||||||
|
: ""
|
||||||
|
}`
|
||||||
: permissionTooltipHelper(
|
: permissionTooltipHelper(
|
||||||
[
|
[
|
||||||
IAM_SCOPES.S3_PUT_BUCKET_VERSIONING,
|
IAM_SCOPES.S3_PUT_BUCKET_VERSIONING,
|
||||||
|
|||||||
@@ -41,13 +41,25 @@ export const addBucketAsync = createAsyncThunk(
|
|||||||
const retentionValidity = state.addBucket.retentionValidity;
|
const retentionValidity = state.addBucket.retentionValidity;
|
||||||
const distributedSetup = state.system.distributedSetup;
|
const distributedSetup = state.system.distributedSetup;
|
||||||
const siteReplicationInfo = state.system.siteReplicationInfo;
|
const siteReplicationInfo = state.system.siteReplicationInfo;
|
||||||
|
const excludeFolders = state.addBucket.excludeFolders;
|
||||||
|
const excludedPrefixes = state.addBucket.excludedPrefixes;
|
||||||
|
|
||||||
let request: MakeBucketRequest = {
|
let request: MakeBucketRequest = {
|
||||||
name: bucketName,
|
name: bucketName,
|
||||||
versioning:
|
versioning: {
|
||||||
distributedSetup && !siteReplicationInfo.enabled
|
enabled:
|
||||||
? versioningEnabled
|
distributedSetup && !siteReplicationInfo.enabled
|
||||||
: false,
|
? versioningEnabled
|
||||||
|
: false,
|
||||||
|
excludePrefixes:
|
||||||
|
distributedSetup && !siteReplicationInfo.enabled && !lockingEnabled
|
||||||
|
? excludedPrefixes.split(",").filter((item) => item.trim() !== "")
|
||||||
|
: [],
|
||||||
|
excludeFolders:
|
||||||
|
distributedSetup && !siteReplicationInfo.enabled && !lockingEnabled
|
||||||
|
? excludeFolders
|
||||||
|
: false,
|
||||||
|
},
|
||||||
locking: distributedSetup ? lockingEnabled : false,
|
locking: distributedSetup ? lockingEnabled : false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ export interface AddBucketState {
|
|||||||
retentionUnit: string;
|
retentionUnit: string;
|
||||||
retentionValidity: number;
|
retentionValidity: number;
|
||||||
navigateTo: string;
|
navigateTo: string;
|
||||||
|
excludeFolders: boolean;
|
||||||
|
excludedPrefixes: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const initialState: AddBucketState = {
|
const initialState: AddBucketState = {
|
||||||
@@ -52,6 +54,8 @@ const initialState: AddBucketState = {
|
|||||||
retentionUnit: "days",
|
retentionUnit: "days",
|
||||||
retentionValidity: 180,
|
retentionValidity: 180,
|
||||||
navigateTo: "",
|
navigateTo: "",
|
||||||
|
excludeFolders: false,
|
||||||
|
excludedPrefixes: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const addBucketsSlice = createSlice({
|
export const addBucketsSlice = createSlice({
|
||||||
@@ -81,6 +85,12 @@ export const addBucketsSlice = createSlice({
|
|||||||
state.retentionValidity = 180;
|
state.retentionValidity = 180;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
setExcludeFolders: (state, action: PayloadAction<boolean>) => {
|
||||||
|
state.excludeFolders = action.payload;
|
||||||
|
},
|
||||||
|
setExcludedPrefixes: (state, action: PayloadAction<string>) => {
|
||||||
|
state.excludedPrefixes = action.payload;
|
||||||
|
},
|
||||||
setEnableObjectLocking: (state, action: PayloadAction<boolean>) => {
|
setEnableObjectLocking: (state, action: PayloadAction<boolean>) => {
|
||||||
state.lockingEnabled = action.payload;
|
state.lockingEnabled = action.payload;
|
||||||
},
|
},
|
||||||
@@ -196,6 +206,8 @@ export const {
|
|||||||
setRetentionMode,
|
setRetentionMode,
|
||||||
setRetentionUnit,
|
setRetentionUnit,
|
||||||
setRetentionValidity,
|
setRetentionValidity,
|
||||||
|
setExcludedPrefixes,
|
||||||
|
setExcludeFolders,
|
||||||
} = addBucketsSlice.actions;
|
} = addBucketsSlice.actions;
|
||||||
|
|
||||||
export default addBucketsSlice.reducer;
|
export default addBucketsSlice.reducer;
|
||||||
|
|||||||
@@ -20,16 +20,10 @@ import React, {
|
|||||||
useEffect,
|
useEffect,
|
||||||
useRef,
|
useRef,
|
||||||
useState,
|
useState,
|
||||||
|
Fragment,
|
||||||
} from "react";
|
} from "react";
|
||||||
import get from "lodash/get";
|
import get from "lodash/get";
|
||||||
import { Theme } from "@mui/material/styles";
|
import { AddIcon, Box, HelpIcon, InputBox, InputLabel, Tooltip } from "mds";
|
||||||
import createStyles from "@mui/styles/createStyles";
|
|
||||||
import withStyles from "@mui/styles/withStyles";
|
|
||||||
import Grid from "@mui/material/Grid";
|
|
||||||
import { InputLabel, Tooltip } from "@mui/material";
|
|
||||||
import { fieldBasic, tooltipHelper } from "../common/styleLibrary";
|
|
||||||
import { AddIcon, HelpIcon } from "mds";
|
|
||||||
import InputBoxWrapper from "../InputBoxWrapper/InputBoxWrapper";
|
|
||||||
|
|
||||||
interface ICSVMultiSelector {
|
interface ICSVMultiSelector {
|
||||||
elements: string;
|
elements: string;
|
||||||
@@ -37,37 +31,10 @@ interface ICSVMultiSelector {
|
|||||||
label: string;
|
label: string;
|
||||||
tooltip?: string;
|
tooltip?: string;
|
||||||
commonPlaceholder?: string;
|
commonPlaceholder?: string;
|
||||||
classes: any;
|
|
||||||
withBorder?: boolean;
|
withBorder?: boolean;
|
||||||
onChange: (elements: string) => void;
|
onChange: (elements: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = (theme: Theme) => {
|
|
||||||
return createStyles({
|
|
||||||
...fieldBasic,
|
|
||||||
...tooltipHelper,
|
|
||||||
inputWithBorder: {
|
|
||||||
border: "1px solid #EAEAEA",
|
|
||||||
padding: 15,
|
|
||||||
height: 150,
|
|
||||||
overflowY: "auto",
|
|
||||||
position: "relative",
|
|
||||||
marginTop: 15,
|
|
||||||
flex: 1,
|
|
||||||
},
|
|
||||||
inputBoxSpacer: {
|
|
||||||
marginBottom: 7,
|
|
||||||
},
|
|
||||||
inputLabel: {
|
|
||||||
...fieldBasic.inputLabel,
|
|
||||||
margin: 0,
|
|
||||||
alignItems: "flex-start",
|
|
||||||
paddingTop: "20px",
|
|
||||||
minWidth: 162,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const CSVMultiSelector = ({
|
const CSVMultiSelector = ({
|
||||||
elements,
|
elements,
|
||||||
name,
|
name,
|
||||||
@@ -76,7 +43,6 @@ const CSVMultiSelector = ({
|
|||||||
commonPlaceholder = "",
|
commonPlaceholder = "",
|
||||||
onChange,
|
onChange,
|
||||||
withBorder = false,
|
withBorder = false,
|
||||||
classes,
|
|
||||||
}: ICSVMultiSelector) => {
|
}: ICSVMultiSelector) => {
|
||||||
const [currentElements, setCurrentElements] = useState<string[]>([""]);
|
const [currentElements, setCurrentElements] = useState<string[]>([""]);
|
||||||
const bottomList = createRef<HTMLDivElement>();
|
const bottomList = createRef<HTMLDivElement>();
|
||||||
@@ -154,55 +120,65 @@ const CSVMultiSelector = ({
|
|||||||
|
|
||||||
const inputs = currentElements.map((element, index) => {
|
const inputs = currentElements.map((element, index) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<InputBox
|
||||||
className={classes.inputBoxSpacer}
|
|
||||||
key={`csv-multi-${name}-${index.toString()}`}
|
key={`csv-multi-${name}-${index.toString()}`}
|
||||||
>
|
id={`${name}-${index.toString()}`}
|
||||||
<InputBoxWrapper
|
label={""}
|
||||||
id={`${name}-${index.toString()}`}
|
name={`${name}-${index.toString()}`}
|
||||||
label={""}
|
value={currentElements[index]}
|
||||||
name={`${name}-${index.toString()}`}
|
onChange={onChangeElement}
|
||||||
value={currentElements[index]}
|
index={index}
|
||||||
onChange={onChangeElement}
|
placeholder={commonPlaceholder}
|
||||||
index={index}
|
overlayIcon={index === currentElements.length - 1 ? <AddIcon /> : null}
|
||||||
key={`csv-${name}-${index.toString()}`}
|
overlayAction={() => {
|
||||||
placeholder={commonPlaceholder}
|
addEmptyLine(currentElements);
|
||||||
overlayIcon={
|
}}
|
||||||
index === currentElements.length - 1 ? <AddIcon /> : null
|
/>
|
||||||
}
|
|
||||||
overlayAction={() => {
|
|
||||||
addEmptyLine(currentElements);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<Fragment>
|
||||||
<Grid item xs={12} className={classes.fieldContainer}>
|
<Box sx={{ display: "flex" }} className={"inputItem"}>
|
||||||
<InputLabel className={classes.inputLabel}>
|
<InputLabel
|
||||||
|
sx={{
|
||||||
|
alignItems: "flex-start",
|
||||||
|
}}
|
||||||
|
>
|
||||||
<span>{label}</span>
|
<span>{label}</span>
|
||||||
{tooltip !== "" && (
|
{tooltip !== "" && (
|
||||||
<div className={classes.tooltipContainer}>
|
<Box
|
||||||
<Tooltip title={tooltip} placement="top-start">
|
sx={{
|
||||||
<div className={classes.tooltip}>
|
marginLeft: 5,
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
"& .min-icon": {
|
||||||
|
width: 13,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Tooltip tooltip={tooltip} placement="top">
|
||||||
|
<Box className={tooltip}>
|
||||||
<HelpIcon />
|
<HelpIcon />
|
||||||
</div>
|
</Box>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</div>
|
</Box>
|
||||||
)}
|
)}
|
||||||
</InputLabel>
|
</InputLabel>
|
||||||
<Grid
|
<Box
|
||||||
item
|
withBorders={withBorder}
|
||||||
xs={12}
|
sx={{
|
||||||
className={`${withBorder ? classes.inputWithBorder : ""}`}
|
width: "100%",
|
||||||
|
overflowY: "auto",
|
||||||
|
height: 150,
|
||||||
|
position: "relative",
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{inputs}
|
{inputs}
|
||||||
<div ref={bottomList} />
|
<div ref={bottomList} />
|
||||||
</Grid>
|
</Box>
|
||||||
</Grid>
|
</Box>
|
||||||
</React.Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
export default withStyles(styles)(CSVMultiSelector);
|
export default CSVMultiSelector;
|
||||||
|
|||||||
@@ -232,7 +232,7 @@ type MCClient interface {
|
|||||||
list(ctx context.Context, opts mc.ListOptions) <-chan *mc.ClientContent
|
list(ctx context.Context, opts mc.ListOptions) <-chan *mc.ClientContent
|
||||||
get(ctx context.Context, opts mc.GetOptions) (io.ReadCloser, *probe.Error)
|
get(ctx context.Context, opts mc.GetOptions) (io.ReadCloser, *probe.Error)
|
||||||
shareDownload(ctx context.Context, versionID string, expires time.Duration) (string, *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
|
// Interface implementation
|
||||||
@@ -265,8 +265,8 @@ func (c mcClient) deleteAllReplicationRules(ctx context.Context) *probe.Error {
|
|||||||
return c.client.RemoveReplication(ctx)
|
return c.client.RemoveReplication(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c mcClient) setVersioning(ctx context.Context, status string) *probe.Error {
|
func (c mcClient) setVersioning(ctx context.Context, status string, excludePrefix []string, excludeFolders bool) *probe.Error {
|
||||||
return c.client.SetVersion(ctx, status, []string{}, false)
|
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 {
|
func (c mcClient) remove(ctx context.Context, isIncomplete, isRemoveBucket, isBypass, forceDelete bool, contentCh <-chan *mc.ClientContent) <-chan mc.RemoveResult {
|
||||||
|
|||||||
@@ -7124,7 +7124,7 @@ func init() {
|
|||||||
"$ref": "#/definitions/putBucketRetentionRequest"
|
"$ref": "#/definitions/putBucketRetentionRequest"
|
||||||
},
|
},
|
||||||
"versioning": {
|
"versioning": {
|
||||||
"type": "boolean"
|
"$ref": "#/definitions/setBucketVersioning"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -8195,8 +8195,18 @@ func init() {
|
|||||||
"setBucketVersioning": {
|
"setBucketVersioning": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"versioning": {
|
"enabled": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"excludeFolders": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"excludePrefixes": {
|
||||||
|
"type": "array",
|
||||||
|
"maxLength": 10,
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -16257,7 +16267,7 @@ func init() {
|
|||||||
"$ref": "#/definitions/putBucketRetentionRequest"
|
"$ref": "#/definitions/putBucketRetentionRequest"
|
||||||
},
|
},
|
||||||
"versioning": {
|
"versioning": {
|
||||||
"type": "boolean"
|
"$ref": "#/definitions/setBucketVersioning"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -17328,8 +17338,18 @@ func init() {
|
|||||||
"setBucketVersioning": {
|
"setBucketVersioning": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"versioning": {
|
"enabled": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"excludeFolders": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"excludePrefixes": {
|
||||||
|
"type": "array",
|
||||||
|
"maxLength": 10,
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -188,8 +188,8 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// removeBucket deletes a bucket
|
// removeBucket deletes a bucket
|
||||||
func doSetVersioning(ctx context.Context, client MCClient, state VersionState) error {
|
func doSetVersioning(ctx context.Context, client MCClient, state VersionState, excludePrefix []string, excludeFolders bool) error {
|
||||||
err := client.setVersioning(ctx, string(state))
|
err := client.setVersioning(ctx, string(state), excludePrefix, excludeFolders)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err.Cause
|
return err.Cause
|
||||||
}
|
}
|
||||||
@@ -212,11 +212,19 @@ func setBucketVersioningResponse(session *models.Principal, params bucketApi.Set
|
|||||||
|
|
||||||
versioningState := VersionSuspend
|
versioningState := VersionSuspend
|
||||||
|
|
||||||
if params.Body.Versioning {
|
if params.Body.Enabled {
|
||||||
versioningState = VersionEnable
|
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 ErrorWithContext(ctx, fmt.Errorf("error setting versioning for bucket: %s", err))
|
||||||
}
|
}
|
||||||
return nil
|
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
|
// 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))
|
s3Client, err := newS3BucketClient(session, *br.Name, "", getClientIP(params.HTTPRequest))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, ErrorWithContext(ctx, err)
|
return nil, ErrorWithContext(ctx, err)
|
||||||
@@ -496,7 +510,18 @@ func getMakeBucketResponse(session *models.Principal, params bucketApi.MakeBucke
|
|||||||
// defining the client to be used
|
// defining the client to be used
|
||||||
amcClient := mcClient{client: s3Client}
|
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))
|
return nil, ErrorWithContext(ctx, fmt.Errorf("error setting versioning for bucket: %s", err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ var (
|
|||||||
minioSetObjectLockConfigMock func(ctx context.Context, bucketName string, mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit) error
|
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)
|
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)
|
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)
|
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
|
minioSetBucketTaggingMock func(ctx context.Context, bucketName string, tags *tags.Tags) error
|
||||||
minioRemoveBucketTaggingMock func(ctx context.Context, bucketName string) 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)
|
return minioCopyObjectMock(ctx, dst, src)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c s3ClientMock) setVersioning(ctx context.Context, state string) *probe.Error {
|
func (c s3ClientMock) setVersioning(ctx context.Context, state string, excludePrefix []string, excludeFolders bool) *probe.Error {
|
||||||
return minioSetVersioningMock(ctx, state)
|
return minioSetVersioningMock(ctx, state, excludePrefix, excludeFolders)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mc minioClientMock) GetBucketTagging(ctx context.Context, bucketName string) (*tags.Tags, error) {
|
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 {
|
type args struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
state VersionState
|
state VersionState
|
||||||
|
excludePrefix []string
|
||||||
|
excludeFolders bool
|
||||||
bucketName string
|
bucketName string
|
||||||
client s3ClientMock
|
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 {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
@@ -829,7 +831,36 @@ func Test_SetBucketVersioning(t *testing.T) {
|
|||||||
state: VersionEnable,
|
state: VersionEnable,
|
||||||
bucketName: "test",
|
bucketName: "test",
|
||||||
client: minClient,
|
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
|
return nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -842,7 +873,7 @@ func Test_SetBucketVersioning(t *testing.T) {
|
|||||||
state: VersionEnable,
|
state: VersionEnable,
|
||||||
bucketName: "test",
|
bucketName: "test",
|
||||||
client: minClient,
|
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))
|
return probe.NewError(errors.New(errorMsg))
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -854,7 +885,7 @@ func Test_SetBucketVersioning(t *testing.T) {
|
|||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
minioSetVersioningMock = tt.args.setVersioningFunc
|
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(t.Name())
|
||||||
fmt.Println("Expected:", tt.expectedError, "Error:", err)
|
fmt.Println("Expected:", tt.expectedError, "Error:", err)
|
||||||
|
|||||||
14
swagger.yml
14
swagger.yml
@@ -3756,7 +3756,7 @@ definitions:
|
|||||||
locking:
|
locking:
|
||||||
type: boolean
|
type: boolean
|
||||||
versioning:
|
versioning:
|
||||||
type: boolean
|
$ref: "#/definitions/setBucketVersioning"
|
||||||
quota:
|
quota:
|
||||||
$ref: "#/definitions/setBucketQuota"
|
$ref: "#/definitions/setBucketQuota"
|
||||||
retention:
|
retention:
|
||||||
@@ -4963,8 +4963,16 @@ definitions:
|
|||||||
setBucketVersioning:
|
setBucketVersioning:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
versioning:
|
enabled:
|
||||||
type: boolean
|
type: boolean
|
||||||
|
excludePrefixes:
|
||||||
|
type: array
|
||||||
|
maxLength: 10
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
excludeFolders:
|
||||||
|
type: boolean
|
||||||
|
|
||||||
bucketObLockingResponse:
|
bucketObLockingResponse:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
@@ -6154,4 +6162,4 @@ definitions:
|
|||||||
groups:
|
groups:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
|
|||||||
Reference in New Issue
Block a user