mirror of
https://github.com/versity/versitygw.git
synced 2026-09-03 22:56:55 +00:00
fix: Added the implementation to automatically enable bucket versioning when enabling object lock. Added error response when attempting to set bucket versioning status to Suspended when object lock is enabled
This commit is contained in:
+23
-2
@@ -325,6 +325,15 @@ func (p *Posix) CreateBucket(ctx context.Context, input *s3.CreateBucketInput, a
|
||||
}
|
||||
|
||||
if input.ObjectLockEnabledForBucket != nil && *input.ObjectLockEnabledForBucket {
|
||||
// First enable bucket versioning
|
||||
// Bucket versioning is enabled automatically with object lock
|
||||
if p.versioningEnabled() {
|
||||
err = p.PutBucketVersioning(ctx, bucket, types.BucketVersioningStatusEnabled)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
defaultLock := auth.BucketLockConfig{
|
||||
Enabled: true,
|
||||
@@ -437,7 +446,7 @@ func (p *Posix) DeleteBucketOwnershipControls(_ context.Context, bucket string)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Posix) PutBucketVersioning(_ context.Context, bucket string, status types.BucketVersioningStatus) error {
|
||||
func (p *Posix) PutBucketVersioning(ctx context.Context, bucket string, status types.BucketVersioningStatus) error {
|
||||
if !p.versioningEnabled() {
|
||||
//TODO: Maybe we need to return our custom error here?
|
||||
return nil
|
||||
@@ -457,6 +466,18 @@ func (p *Posix) PutBucketVersioning(_ context.Context, bucket string, status typ
|
||||
// '1' maps to 'Enabled'
|
||||
versioning = []byte{1}
|
||||
case types.BucketVersioningStatusSuspended:
|
||||
lockRaw, err := p.GetObjectLockConfiguration(ctx, bucket)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
lockStatus, err := auth.ParseBucketLockConfigurationOutput(lockRaw)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if lockStatus.ObjectLockEnabled == types.ObjectLockEnabledEnabled {
|
||||
return s3err.GetAPIError(s3err.ErrSuspendedVersioningNotAllowed)
|
||||
}
|
||||
|
||||
// '0' maps to 'Suspended'
|
||||
versioning = []byte{0}
|
||||
}
|
||||
@@ -3409,7 +3430,7 @@ func (p *Posix) DeleteBucketPolicy(ctx context.Context, bucket string) error {
|
||||
return p.PutBucketPolicy(ctx, bucket, nil)
|
||||
}
|
||||
|
||||
func (p *Posix) PutObjectLockConfiguration(_ context.Context, bucket string, config []byte) error {
|
||||
func (p *Posix) PutObjectLockConfiguration(ctx context.Context, bucket string, config []byte) error {
|
||||
_, err := os.Stat(bucket)
|
||||
if errors.Is(err, fs.ErrNotExist) {
|
||||
return s3err.GetAPIError(s3err.ErrNoSuchBucket)
|
||||
|
||||
@@ -134,6 +134,7 @@ const (
|
||||
ErrKeyTooLong
|
||||
ErrInvalidVersionId
|
||||
ErrNoSuchVersion
|
||||
ErrSuspendedVersioningNotAllowed
|
||||
|
||||
// Non-AWS errors
|
||||
ErrExistingObjectIsDirectory
|
||||
@@ -537,6 +538,11 @@ var errorCodeResponse = map[ErrorCode]APIError{
|
||||
Description: "The specified version does not exist.",
|
||||
HTTPStatusCode: http.StatusNotFound,
|
||||
},
|
||||
ErrSuspendedVersioningNotAllowed: {
|
||||
Code: "InvalidBucketState",
|
||||
Description: "An Object Lock configuration is present on this bucket, so the versioning state cannot be changed.",
|
||||
HTTPStatusCode: http.StatusBadRequest,
|
||||
},
|
||||
|
||||
// non aws errors
|
||||
ErrExistingObjectIsDirectory: {
|
||||
|
||||
@@ -553,6 +553,9 @@ func TestVersioning(s *S3Conf) {
|
||||
Versioning_Multipart_Upload_overwrite_an_object(s)
|
||||
Versioning_UploadPartCopy_non_existing_versionId(s)
|
||||
Versioning_UploadPartCopy_from_an_object_version(s)
|
||||
// Object lock configuration
|
||||
Versioning_Enable_object_lock(s)
|
||||
Versioning_status_switch_to_suspended_with_object_lock(s)
|
||||
// Object-Lock Retention
|
||||
Versionsin_PutObjectRetention_invalid_versionId(s)
|
||||
Versioning_GetObjectRetention_invalid_versionId(s)
|
||||
@@ -912,6 +915,8 @@ func GetIntTests() IntTests {
|
||||
"Versioning_Multipart_Upload_overwrite_an_object": Versioning_Multipart_Upload_overwrite_an_object,
|
||||
"Versioning_UploadPartCopy_non_existing_versionId": Versioning_UploadPartCopy_non_existing_versionId,
|
||||
"Versioning_UploadPartCopy_from_an_object_version": Versioning_UploadPartCopy_from_an_object_version,
|
||||
"Versioning_Enable_object_lock": Versioning_Enable_object_lock,
|
||||
"Versioning_status_switch_to_suspended_with_object_lock": Versioning_status_switch_to_suspended_with_object_lock,
|
||||
"Versionsin_PutObjectRetention_invalid_versionId": Versionsin_PutObjectRetention_invalid_versionId,
|
||||
"Versioning_GetObjectRetention_invalid_versionId": Versioning_GetObjectRetention_invalid_versionId,
|
||||
"Versioning_Put_GetObjectRetention_success": Versioning_Put_GetObjectRetention_success,
|
||||
|
||||
@@ -11746,6 +11746,45 @@ func Versioning_UploadPartCopy_from_an_object_version(s *S3Conf) error {
|
||||
}, withVersioning())
|
||||
}
|
||||
|
||||
func Versioning_Enable_object_lock(s *S3Conf) error {
|
||||
testName := "Versioning_Enable_object_lock"
|
||||
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
|
||||
res, err := s3client.GetBucketVersioning(ctx, &s3.GetBucketVersioningInput{
|
||||
Bucket: &bucket,
|
||||
})
|
||||
cancel()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if res.Status != types.BucketVersioningStatusEnabled {
|
||||
return fmt.Errorf("expected the bucket versioning status to be %v, instead got %v", types.BucketVersioningStatusEnabled, res.Status)
|
||||
}
|
||||
|
||||
return nil
|
||||
}, withLock())
|
||||
}
|
||||
|
||||
func Versioning_status_switch_to_suspended_with_object_lock(s *S3Conf) error {
|
||||
testName := "Versioning_status_switch_to_suspended_with_object_lock"
|
||||
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
|
||||
_, err := s3client.PutBucketVersioning(ctx, &s3.PutBucketVersioningInput{
|
||||
Bucket: &bucket,
|
||||
VersioningConfiguration: &types.VersioningConfiguration{
|
||||
Status: types.BucketVersioningStatusSuspended,
|
||||
},
|
||||
})
|
||||
cancel()
|
||||
if err := checkApiErr(err, s3err.GetAPIError(s3err.ErrSuspendedVersioningNotAllowed)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}, withLock())
|
||||
}
|
||||
|
||||
func Versionsin_PutObjectRetention_invalid_versionId(s *S3Conf) error {
|
||||
testName := "Versionsin_PutObjectRetention_invalid_versionId"
|
||||
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
|
||||
|
||||
Reference in New Issue
Block a user