diff --git a/api/handler/lifecycle.go b/api/handler/lifecycle.go index e559365..3aa3ccc 100644 --- a/api/handler/lifecycle.go +++ b/api/handler/lifecycle.go @@ -17,6 +17,7 @@ import ( "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/util" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap" + "github.com/google/uuid" ) const ( @@ -145,7 +146,16 @@ func checkLifecycleConfiguration(ctx context.Context, cfg *data.LifecycleConfigu ids := make(map[string]struct{}, len(cfg.Rules)) for i, rule := range cfg.Rules { - if _, ok := ids[rule.ID]; ok && rule.ID != "" { + if rule.ID == "" { + id, err := uuid.NewRandom() + if err != nil { + return fmt.Errorf("generate uuid: %w", err) + } + cfg.Rules[i].ID = id.String() + rule.ID = id.String() + } + + if _, ok := ids[rule.ID]; ok { return fmt.Errorf("%w: duplicate 'ID': %s", apierr.GetAPIError(apierr.ErrInvalidArgument), rule.ID) } ids[rule.ID] = struct{}{} diff --git a/api/handler/lifecycle_test.go b/api/handler/lifecycle_test.go index e667170..3884126 100644 --- a/api/handler/lifecycle_test.go +++ b/api/handler/lifecycle_test.go @@ -425,6 +425,36 @@ func TestPutBucketLifecycleConfiguration(t *testing.T) { } } +func TestPutBucketLifecycleIDGeneration(t *testing.T) { + hc := prepareHandlerContext(t) + + bktName := "bucket-lifecycle-id" + createBucket(hc, bktName) + + lifecycle := &data.LifecycleConfiguration{ + Rules: []data.LifecycleRule{ + { + Status: data.LifecycleStatusEnabled, + Expiration: &data.LifecycleExpiration{ + Days: ptr(21), + }, + }, + { + Status: data.LifecycleStatusEnabled, + AbortIncompleteMultipartUpload: &data.AbortIncompleteMultipartUpload{ + DaysAfterInitiation: ptr(14), + }, + }, + }, + } + + putBucketLifecycleConfiguration(hc, bktName, lifecycle) + cfg := getBucketLifecycleConfiguration(hc, bktName) + require.Len(t, cfg.Rules, 2) + require.NotEmpty(t, cfg.Rules[0].ID) + require.NotEmpty(t, cfg.Rules[1].ID) +} + func TestPutBucketLifecycleInvalidMD5(t *testing.T) { hc := prepareHandlerContext(t)