mirror of
https://github.com/versity/versitygw.git
synced 2026-01-07 12:15:18 +00:00
All the integration tests used to be in a single file, which had become large, messy, and difficult to maintain. These changes split `tests.go` into multiple files, organized by logical test groups.
744 lines
21 KiB
Go
744 lines
21 KiB
Go
// Copyright 2023 Versity Software
|
|
// This file is licensed under the Apache License, Version 2.0
|
|
// (the "License"); you may not use this file except in compliance
|
|
// with the License. You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing,
|
|
// software distributed under the License is distributed on an
|
|
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
// KIND, either express or implied. See the License for the
|
|
// specific language governing permissions and limitations
|
|
// under the License.
|
|
|
|
package integration
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/aws/aws-sdk-go-v2/service/s3"
|
|
"github.com/aws/aws-sdk-go-v2/service/s3/types"
|
|
"github.com/versity/versitygw/s3err"
|
|
)
|
|
|
|
func WORMProtection_bucket_object_lock_configuration_compliance_mode(s *S3Conf) error {
|
|
testName := "WORMProtection_bucket_object_lock_configuration_compliance_mode"
|
|
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
|
|
var days int32 = 10
|
|
object := "my-obj"
|
|
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
|
|
_, err := s3client.PutObjectLockConfiguration(ctx, &s3.PutObjectLockConfigurationInput{
|
|
Bucket: &bucket,
|
|
ObjectLockConfiguration: &types.ObjectLockConfiguration{
|
|
ObjectLockEnabled: types.ObjectLockEnabledEnabled,
|
|
Rule: &types.ObjectLockRule{
|
|
DefaultRetention: &types.DefaultRetention{
|
|
Mode: types.ObjectLockRetentionModeCompliance,
|
|
Days: &days,
|
|
},
|
|
},
|
|
},
|
|
})
|
|
cancel()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
_, err = putObjects(s3client, []string{object}, bucket)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := checkWORMProtection(s3client, bucket, object); err != nil {
|
|
return err
|
|
}
|
|
return cleanupLockedObjects(s3client, bucket, []objToDelete{{key: object, isCompliance: true}})
|
|
}, withLock())
|
|
}
|
|
|
|
func WORMProtection_bucket_object_lock_configuration_governance_mode(s *S3Conf) error {
|
|
testName := "WORMProtection_bucket_object_lock_configuration_governance_mode"
|
|
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
|
|
var days int32 = 10
|
|
object := "my-obj"
|
|
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
|
|
_, err := s3client.PutObjectLockConfiguration(ctx, &s3.PutObjectLockConfigurationInput{
|
|
Bucket: &bucket,
|
|
ObjectLockConfiguration: &types.ObjectLockConfiguration{
|
|
ObjectLockEnabled: types.ObjectLockEnabledEnabled,
|
|
Rule: &types.ObjectLockRule{
|
|
DefaultRetention: &types.DefaultRetention{
|
|
Mode: types.ObjectLockRetentionModeGovernance,
|
|
Days: &days,
|
|
},
|
|
},
|
|
},
|
|
})
|
|
cancel()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
_, err = putObjects(s3client, []string{object}, bucket)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := checkWORMProtection(s3client, bucket, object); err != nil {
|
|
return err
|
|
}
|
|
return cleanupLockedObjects(s3client, bucket, []objToDelete{{key: object}})
|
|
}, withLock())
|
|
}
|
|
|
|
func WORMProtection_bucket_object_lock_governance_bypass_delete(s *S3Conf) error {
|
|
testName := "WORMProtection_bucket_object_lock_governance_bypass_delete"
|
|
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
|
|
var days int32 = 10
|
|
object := "my-obj"
|
|
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
|
|
_, err := s3client.PutObjectLockConfiguration(ctx, &s3.PutObjectLockConfigurationInput{
|
|
Bucket: &bucket,
|
|
ObjectLockConfiguration: &types.ObjectLockConfiguration{
|
|
ObjectLockEnabled: types.ObjectLockEnabledEnabled,
|
|
Rule: &types.ObjectLockRule{
|
|
DefaultRetention: &types.DefaultRetention{
|
|
Mode: types.ObjectLockRetentionModeGovernance,
|
|
Days: &days,
|
|
},
|
|
},
|
|
},
|
|
})
|
|
cancel()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
_, err = putObjects(s3client, []string{object}, bucket)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
policy := genPolicyDoc("Allow", `"*"`, `["s3:BypassGovernanceRetention"]`, fmt.Sprintf(`"arn:aws:s3:::%v/*"`, bucket))
|
|
bypass := true
|
|
|
|
ctx, cancel = context.WithTimeout(context.Background(), shortTimeout)
|
|
_, err = s3client.PutBucketPolicy(ctx, &s3.PutBucketPolicyInput{
|
|
Bucket: &bucket,
|
|
Policy: &policy,
|
|
})
|
|
cancel()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
ctx, cancel = context.WithTimeout(context.Background(), shortTimeout)
|
|
_, err = s3client.DeleteObject(ctx, &s3.DeleteObjectInput{
|
|
Bucket: &bucket,
|
|
Key: &object,
|
|
BypassGovernanceRetention: &bypass,
|
|
})
|
|
cancel()
|
|
return err
|
|
}, withLock())
|
|
}
|
|
|
|
func WORMProtection_bucket_object_lock_governance_bypass_delete_multiple(s *S3Conf) error {
|
|
testName := "WORMProtection_bucket_object_lock_governance_bypass_delete_multiple"
|
|
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
|
|
var days int32 = 10
|
|
obj1, obj2, obj3 := "my-obj-1", "my-obj-2", "my-obj-3"
|
|
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
|
|
_, err := s3client.PutObjectLockConfiguration(ctx, &s3.PutObjectLockConfigurationInput{
|
|
Bucket: &bucket,
|
|
ObjectLockConfiguration: &types.ObjectLockConfiguration{
|
|
ObjectLockEnabled: types.ObjectLockEnabledEnabled,
|
|
Rule: &types.ObjectLockRule{
|
|
DefaultRetention: &types.DefaultRetention{
|
|
Mode: types.ObjectLockRetentionModeGovernance,
|
|
Days: &days,
|
|
},
|
|
},
|
|
},
|
|
})
|
|
cancel()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
_, err = putObjects(s3client, []string{obj1, obj2, obj3}, bucket)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
policy := genPolicyDoc("Allow", `"*"`, `["s3:BypassGovernanceRetention"]`, fmt.Sprintf(`"arn:aws:s3:::%v/*"`, bucket))
|
|
bypass := true
|
|
|
|
ctx, cancel = context.WithTimeout(context.Background(), shortTimeout)
|
|
_, err = s3client.PutBucketPolicy(ctx, &s3.PutBucketPolicyInput{
|
|
Bucket: &bucket,
|
|
Policy: &policy,
|
|
})
|
|
cancel()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
ctx, cancel = context.WithTimeout(context.Background(), shortTimeout)
|
|
_, err = s3client.DeleteObjects(ctx, &s3.DeleteObjectsInput{
|
|
Bucket: &bucket,
|
|
BypassGovernanceRetention: &bypass,
|
|
Delete: &types.Delete{
|
|
Objects: []types.ObjectIdentifier{
|
|
{
|
|
Key: &obj1,
|
|
},
|
|
{
|
|
Key: &obj2,
|
|
},
|
|
{
|
|
Key: &obj3,
|
|
},
|
|
},
|
|
},
|
|
})
|
|
cancel()
|
|
return err
|
|
}, withLock())
|
|
}
|
|
|
|
func WORMProtection_object_lock_retention_compliance_locked(s *S3Conf) error {
|
|
testName := "WORMProtection_object_lock_retention_compliance_locked"
|
|
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
|
|
object := "my-obj"
|
|
|
|
_, err := putObjects(s3client, []string{object}, bucket)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
date := time.Now().Add(time.Hour * 3)
|
|
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
|
|
_, err = s3client.PutObjectRetention(ctx, &s3.PutObjectRetentionInput{
|
|
Bucket: &bucket,
|
|
Key: &object,
|
|
Retention: &types.ObjectLockRetention{
|
|
Mode: types.ObjectLockRetentionModeCompliance,
|
|
RetainUntilDate: &date,
|
|
},
|
|
})
|
|
cancel()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := checkWORMProtection(s3client, bucket, object); err != nil {
|
|
return err
|
|
}
|
|
|
|
return cleanupLockedObjects(s3client, bucket, []objToDelete{{key: object, isCompliance: true}})
|
|
}, withLock())
|
|
}
|
|
|
|
func WORMProtection_object_lock_retention_governance_locked(s *S3Conf) error {
|
|
testName := "WORMProtection_object_lock_retention_governance_locked"
|
|
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
|
|
object := "my-obj"
|
|
|
|
_, err := putObjects(s3client, []string{object}, bucket)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
date := time.Now().Add(time.Hour * 3)
|
|
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
|
|
_, err = s3client.PutObjectRetention(ctx, &s3.PutObjectRetentionInput{
|
|
Bucket: &bucket,
|
|
Key: &object,
|
|
Retention: &types.ObjectLockRetention{
|
|
Mode: types.ObjectLockRetentionModeGovernance,
|
|
RetainUntilDate: &date,
|
|
},
|
|
})
|
|
cancel()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := checkWORMProtection(s3client, bucket, object); err != nil {
|
|
return err
|
|
}
|
|
return cleanupLockedObjects(s3client, bucket, []objToDelete{{key: object}})
|
|
}, withLock())
|
|
}
|
|
|
|
func WORMProtection_object_lock_retention_governance_bypass_overwrite_put(s *S3Conf) error {
|
|
testName := "WORMProtection_object_lock_retention_governance_bypass_overwrite_put"
|
|
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
|
|
object := "my-obj"
|
|
|
|
_, err := putObjects(s3client, []string{object}, bucket)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = lockObject(s3client, objectLockModeGovernance, bucket, object, "")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
policy := genPolicyDoc("Allow", fmt.Sprintf(`"%s"`, s.awsID), `["s3:BypassGovernanceRetention"]`, fmt.Sprintf(`"arn:aws:s3:::%v/*"`, bucket))
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
|
|
_, err = s3client.PutBucketPolicy(ctx, &s3.PutBucketPolicyInput{
|
|
Bucket: &bucket,
|
|
Policy: &policy,
|
|
})
|
|
cancel()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
ctx, cancel = context.WithTimeout(context.Background(), shortTimeout)
|
|
_, err = s3client.PutObject(ctx, &s3.PutObjectInput{
|
|
Bucket: &bucket,
|
|
Key: &object,
|
|
})
|
|
cancel()
|
|
return err
|
|
}, withLock())
|
|
}
|
|
|
|
func WORMProtection_object_lock_retention_governance_bypass_overwrite_mp(s *S3Conf) error {
|
|
testName := "WORMProtection_object_lock_retention_governance_bypass_overwrite_mp"
|
|
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
|
|
object := "my-obj"
|
|
|
|
_, err := putObjects(s3client, []string{object}, bucket)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = lockObject(s3client, objectLockModeGovernance, bucket, object, "")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
policy := genPolicyDoc("Allow", fmt.Sprintf(`"%s"`, s.awsID), `["s3:BypassGovernanceRetention"]`, fmt.Sprintf(`"arn:aws:s3:::%v/*"`, bucket))
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
|
|
_, err = s3client.PutBucketPolicy(ctx, &s3.PutBucketPolicyInput{
|
|
Bucket: &bucket,
|
|
Policy: &policy,
|
|
})
|
|
cancel()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// overwrite the locked object with a new object with mp
|
|
mp, err := createMp(s3client, bucket, object)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
dataLen := int64(10)
|
|
|
|
parts, _, err := uploadParts(s3client, dataLen, 1, bucket, object, *mp.UploadId)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
part := parts[0]
|
|
|
|
ctx, cancel = context.WithTimeout(context.Background(), shortTimeout)
|
|
_, err = s3client.CompleteMultipartUpload(ctx, &s3.CompleteMultipartUploadInput{
|
|
Bucket: &bucket,
|
|
Key: &object,
|
|
MultipartUpload: &types.CompletedMultipartUpload{
|
|
Parts: []types.CompletedPart{
|
|
{
|
|
ETag: part.ETag,
|
|
PartNumber: part.PartNumber,
|
|
ChecksumCRC64NVME: part.ChecksumCRC64NVME,
|
|
},
|
|
},
|
|
},
|
|
UploadId: mp.UploadId,
|
|
})
|
|
cancel()
|
|
return err
|
|
}, withLock())
|
|
}
|
|
|
|
func WORMProtection_object_lock_retention_governance_bypass_overwrite_copy(s *S3Conf) error {
|
|
testName := "WORMProtection_object_lock_retention_governance_bypass_overwrite_copy"
|
|
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
|
|
object := "my-obj"
|
|
|
|
_, err := putObjects(s3client, []string{object}, bucket)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = lockObject(s3client, objectLockModeGovernance, bucket, object, "")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
policy := genPolicyDoc("Allow", fmt.Sprintf(`"%s"`, s.awsID), `["s3:BypassGovernanceRetention"]`, fmt.Sprintf(`"arn:aws:s3:::%v/*"`, bucket))
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
|
|
_, err = s3client.PutBucketPolicy(ctx, &s3.PutBucketPolicyInput{
|
|
Bucket: &bucket,
|
|
Policy: &policy,
|
|
})
|
|
cancel()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
srcObj := "source-object"
|
|
_, err = putObjects(s3client, []string{srcObj}, bucket)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// overwrite the locked object with a new object with CopyObject
|
|
ctx, cancel = context.WithTimeout(context.Background(), shortTimeout)
|
|
_, err = s3client.CopyObject(ctx, &s3.CopyObjectInput{
|
|
Bucket: &bucket,
|
|
Key: &object,
|
|
CopySource: getPtr(fmt.Sprintf("%s/%s", bucket, srcObj)),
|
|
})
|
|
cancel()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return err
|
|
}, withLock())
|
|
}
|
|
|
|
func WORMProtection_unable_to_overwrite_locked_object_put(s *S3Conf) error {
|
|
testName := "WORMProtection_unable_to_overwrite_locked_object_put"
|
|
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
|
|
object := "my-obj"
|
|
_, err := putObjects(s3client, []string{object}, bucket)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = lockObject(s3client, objectLockModeLegalHold, bucket, object, "")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
_, err = putObjects(s3client, []string{object}, bucket)
|
|
if err := checkApiErr(err, s3err.GetAPIError(s3err.ErrObjectLocked)); err != nil {
|
|
return err
|
|
}
|
|
return cleanupLockedObjects(s3client, bucket, []objToDelete{
|
|
{
|
|
key: object,
|
|
removeOnlyLeglHold: true,
|
|
},
|
|
})
|
|
}, withLock())
|
|
}
|
|
|
|
func WORMProtection_unable_to_overwrite_locked_object_copy(s *S3Conf) error {
|
|
testName := "WORMProtection_unable_to_overwrite_locked_object_copy"
|
|
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
|
|
object := "my-obj"
|
|
|
|
_, err := putObjects(s3client, []string{object}, bucket)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = lockObject(s3client, objectLockModeLegalHold, bucket, object, "")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
srcObj := "source-object"
|
|
_, err = putObjects(s3client, []string{srcObj}, bucket)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// overwrite the locked object with a new object with CopyObject
|
|
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
|
|
_, err = s3client.CopyObject(ctx, &s3.CopyObjectInput{
|
|
Bucket: &bucket,
|
|
Key: &object,
|
|
CopySource: getPtr(fmt.Sprintf("%s/%s", bucket, srcObj)),
|
|
})
|
|
cancel()
|
|
if err := checkApiErr(err, s3err.GetAPIError(s3err.ErrObjectLocked)); err != nil {
|
|
return err
|
|
}
|
|
return cleanupLockedObjects(s3client, bucket, []objToDelete{
|
|
{
|
|
key: object,
|
|
removeOnlyLeglHold: true,
|
|
},
|
|
})
|
|
}, withLock())
|
|
}
|
|
|
|
func WORMProtection_unable_to_overwrite_locked_object_mp(s *S3Conf) error {
|
|
testName := "WORMProtection_unable_to_overwrite_locked_object_mp"
|
|
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
|
|
object := "my-obj"
|
|
|
|
_, err := putObjects(s3client, []string{object}, bucket)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = lockObject(s3client, objectLockModeLegalHold, bucket, object, "")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
mp, err := createMp(s3client, bucket, object)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
dataLen := int64(10)
|
|
|
|
parts, _, err := uploadParts(s3client, dataLen, 1, bucket, object, *mp.UploadId)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
part := parts[0]
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
|
|
_, err = s3client.CompleteMultipartUpload(ctx, &s3.CompleteMultipartUploadInput{
|
|
Bucket: &bucket,
|
|
Key: &object,
|
|
MultipartUpload: &types.CompletedMultipartUpload{
|
|
Parts: []types.CompletedPart{
|
|
{
|
|
ETag: part.ETag,
|
|
PartNumber: part.PartNumber,
|
|
ChecksumCRC64NVME: part.ChecksumCRC64NVME,
|
|
},
|
|
},
|
|
},
|
|
UploadId: mp.UploadId,
|
|
})
|
|
cancel()
|
|
if err := checkApiErr(err, s3err.GetAPIError(s3err.ErrObjectLocked)); err != nil {
|
|
return err
|
|
}
|
|
return cleanupLockedObjects(s3client, bucket, []objToDelete{
|
|
{
|
|
key: object,
|
|
removeOnlyLeglHold: true,
|
|
},
|
|
})
|
|
}, withLock())
|
|
}
|
|
|
|
func WORMProtection_object_lock_retention_governance_bypass_delete(s *S3Conf) error {
|
|
testName := "WORMProtection_object_lock_retention_governance_bypass_delete"
|
|
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
|
|
object := "my-obj"
|
|
|
|
_, err := putObjects(s3client, []string{object}, bucket)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
date := time.Now().Add(time.Hour * 3)
|
|
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
|
|
_, err = s3client.PutObjectRetention(ctx, &s3.PutObjectRetentionInput{
|
|
Bucket: &bucket,
|
|
Key: &object,
|
|
Retention: &types.ObjectLockRetention{
|
|
Mode: types.ObjectLockRetentionModeGovernance,
|
|
RetainUntilDate: &date,
|
|
},
|
|
})
|
|
cancel()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
policy := genPolicyDoc("Allow", `"*"`, `["s3:BypassGovernanceRetention"]`, fmt.Sprintf(`"arn:aws:s3:::%v/*"`, bucket))
|
|
bypass := true
|
|
|
|
ctx, cancel = context.WithTimeout(context.Background(), shortTimeout)
|
|
_, err = s3client.PutBucketPolicy(ctx, &s3.PutBucketPolicyInput{
|
|
Bucket: &bucket,
|
|
Policy: &policy,
|
|
})
|
|
cancel()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
ctx, cancel = context.WithTimeout(context.Background(), shortTimeout)
|
|
_, err = s3client.DeleteObject(ctx, &s3.DeleteObjectInput{
|
|
Bucket: &bucket,
|
|
Key: &object,
|
|
BypassGovernanceRetention: &bypass,
|
|
})
|
|
cancel()
|
|
return err
|
|
}, withLock())
|
|
}
|
|
|
|
func WORMProtection_object_lock_retention_governance_bypass_delete_mul(s *S3Conf) error {
|
|
testName := "WORMProtection_object_lock_retention_governance_bypass_delete_mul"
|
|
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
|
|
objs := []string{"my-obj-1", "my-obj2", "my-obj-3"}
|
|
|
|
_, err := putObjects(s3client, objs, bucket)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, obj := range objs {
|
|
o := obj
|
|
date := time.Now().Add(time.Hour * 3)
|
|
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
|
|
_, err := s3client.PutObjectRetention(ctx, &s3.PutObjectRetentionInput{
|
|
Bucket: &bucket,
|
|
Key: &o,
|
|
Retention: &types.ObjectLockRetention{
|
|
Mode: types.ObjectLockRetentionModeGovernance,
|
|
RetainUntilDate: &date,
|
|
},
|
|
})
|
|
cancel()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
policy := genPolicyDoc("Allow", `"*"`, `["s3:BypassGovernanceRetention"]`, fmt.Sprintf(`"arn:aws:s3:::%v/*"`, bucket))
|
|
bypass := true
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
|
|
_, err = s3client.PutBucketPolicy(ctx, &s3.PutBucketPolicyInput{
|
|
Bucket: &bucket,
|
|
Policy: &policy,
|
|
})
|
|
cancel()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
ctx, cancel = context.WithTimeout(context.Background(), shortTimeout)
|
|
_, err = s3client.DeleteObjects(ctx, &s3.DeleteObjectsInput{
|
|
Bucket: &bucket,
|
|
BypassGovernanceRetention: &bypass,
|
|
Delete: &types.Delete{
|
|
Objects: []types.ObjectIdentifier{
|
|
{
|
|
Key: &objs[0],
|
|
},
|
|
{
|
|
Key: &objs[1],
|
|
},
|
|
{
|
|
Key: &objs[2],
|
|
},
|
|
},
|
|
},
|
|
})
|
|
cancel()
|
|
return err
|
|
}, withLock())
|
|
}
|
|
|
|
func WORMProtection_object_lock_legal_hold_locked(s *S3Conf) error {
|
|
testName := "WORMProtection_object_lock_legal_hold_locked"
|
|
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
|
|
object := "my-obj"
|
|
|
|
_, err := putObjects(s3client, []string{object}, bucket)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
|
|
_, err = s3client.PutObjectLegalHold(ctx, &s3.PutObjectLegalHoldInput{
|
|
Bucket: &bucket,
|
|
Key: &object,
|
|
LegalHold: &types.ObjectLockLegalHold{
|
|
Status: types.ObjectLockLegalHoldStatusOn,
|
|
},
|
|
})
|
|
cancel()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
_, err = putObjects(s3client, []string{object}, bucket)
|
|
if err := checkApiErr(err, s3err.GetAPIError(s3err.ErrObjectLocked)); err != nil {
|
|
return err
|
|
}
|
|
|
|
return cleanupLockedObjects(s3client, bucket, []objToDelete{{key: object, removeOnlyLeglHold: true}})
|
|
}, withLock())
|
|
}
|
|
|
|
func WORMProtection_root_bypass_governance_retention_delete_object(s *S3Conf) error {
|
|
testName := "WORMProtection_root_bypass_governance_retention_delete_object"
|
|
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
|
|
obj := "my-obj"
|
|
_, err := putObjects(s3client, []string{obj}, bucket)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
retDate := time.Now().Add(time.Hour * 48)
|
|
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
|
|
_, err = s3client.PutObjectRetention(ctx, &s3.PutObjectRetentionInput{
|
|
Bucket: &bucket,
|
|
Key: &obj,
|
|
Retention: &types.ObjectLockRetention{
|
|
Mode: types.ObjectLockRetentionModeGovernance,
|
|
RetainUntilDate: &retDate,
|
|
},
|
|
})
|
|
cancel()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := checkWORMProtection(s3client, bucket, obj); err != nil {
|
|
return err
|
|
}
|
|
|
|
policy := genPolicyDoc("Allow", fmt.Sprintf(`"%v"`, s.awsID), `["s3:BypassGovernanceRetention"]`, fmt.Sprintf(`"arn:aws:s3:::%v/*"`, bucket))
|
|
|
|
ctx, cancel = context.WithTimeout(context.Background(), shortTimeout)
|
|
_, err = s3client.PutBucketPolicy(ctx, &s3.PutBucketPolicyInput{
|
|
Bucket: &bucket,
|
|
Policy: &policy,
|
|
})
|
|
cancel()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
bypass := true
|
|
ctx, cancel = context.WithTimeout(context.Background(), shortTimeout)
|
|
_, err = s3client.DeleteObject(ctx, &s3.DeleteObjectInput{
|
|
Bucket: &bucket,
|
|
Key: &obj,
|
|
BypassGovernanceRetention: &bypass,
|
|
})
|
|
cancel()
|
|
return err
|
|
}, withLock())
|
|
}
|