Skip to content

Commit

Permalink
satellite/metainfo: account for versioning opt in
Browse files Browse the repository at this point in the history
This change accounts for whether a user has been prompted for and
whether they opted a project in to versioning beta. This happens on
SetVersioning and CreateBucket.

Related: #6872

Change-Id: I351795c33861ed3dfc6c250dac3b4f639a5d755b
  • Loading branch information
wilfred-asomanii authored and Storj Robot committed Apr 5, 2024
1 parent 8ed604a commit d601509
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 21 deletions.
22 changes: 15 additions & 7 deletions satellite/metainfo/config.go
Expand Up @@ -11,6 +11,7 @@ import (

"storj.io/common/memory"
"storj.io/common/uuid"
"storj.io/storj/satellite/console"
"storj.io/storj/satellite/metabase"
"storj.io/uplink/private/eestream"
)
Expand Down Expand Up @@ -186,16 +187,23 @@ func NewExtendedConfig(config Config) (_ ExtendedConfig, err error) {
}

// UseBucketLevelObjectVersioningByProject checks if UseBucketLevelObjectVersioning should be enabled for specific project.
func (ec ExtendedConfig) UseBucketLevelObjectVersioningByProject(projectID uuid.UUID) bool {
func (ec ExtendedConfig) UseBucketLevelObjectVersioningByProject(project *console.Project) bool {
// if its globally enabled don't look at projects
if ec.UseBucketLevelObjectVersioning {
return true
}
for _, p := range ec.useBucketLevelObjectVersioningProjects {
if p == projectID {
if !ec.UseBucketLevelObjectVersioning {
for _, p := range ec.useBucketLevelObjectVersioningProjects {
if p == project.ID {
return true
}
}
// account for whether the project has opted in to versioning beta
if !project.PromptedForVersioningBeta {
return false
} else if project.PromptedForVersioningBeta && project.DefaultVersioning != console.VersioningUnsupported {
return true
} else {
return false
}
}

return false
return true
}
55 changes: 44 additions & 11 deletions satellite/metainfo/config_test.go
Expand Up @@ -10,7 +10,7 @@ import (

"storj.io/common/memory"
"storj.io/common/testrand"
"storj.io/common/uuid"
"storj.io/storj/satellite/console"
"storj.io/storj/satellite/metainfo"
)

Expand Down Expand Up @@ -100,27 +100,60 @@ func TestRSConfigValidation(t *testing.T) {
}

func TestExtendedConfig_UseBucketLevelObjectVersioning(t *testing.T) {
projectA := testrand.UUID()
projectB := testrand.UUID()
projectC := testrand.UUID()
projectA := &console.Project{
ID: testrand.UUID(),
}
projectB := &console.Project{
ID: testrand.UUID(),
}

// 1. Versioning globally enabled
config, err := metainfo.NewExtendedConfig(metainfo.Config{
UseBucketLevelObjectVersioning: true,
})
require.NoError(t, err)
require.True(t, config.UseBucketLevelObjectVersioningByProject(projectA))
require.True(t, config.UseBucketLevelObjectVersioningByProject(projectB))

// 2.1. Versioning disabled globally, but enabled for project A (closed beta)
config, err = metainfo.NewExtendedConfig(metainfo.Config{
UseBucketLevelObjectVersioning: false,
UseBucketLevelObjectVersioningProjects: []string{
projectA.String(),
projectB.String(),
projectA.ID.String(),
},
})
require.NoError(t, err)

require.True(t, config.UseBucketLevelObjectVersioningByProject(projectA))
require.True(t, config.UseBucketLevelObjectVersioningByProject(projectB))
require.False(t, config.UseBucketLevelObjectVersioningByProject(projectC))
require.False(t, config.UseBucketLevelObjectVersioningByProject(projectB))

// 2.2. Versioning disabled globally, but enabled for project B (closed beta)
config, err = metainfo.NewExtendedConfig(metainfo.Config{
UseBucketLevelObjectVersioning: false,
UseBucketLevelObjectVersioningProjects: []string{
"01000000-0000-0000-0000-000000000000",
projectB.ID.String(),
},
})
require.NoError(t, err)
require.True(t, config.UseBucketLevelObjectVersioningByProject(uuid.UUID{1}))
require.False(t, config.UseBucketLevelObjectVersioningByProject(projectA))
require.True(t, config.UseBucketLevelObjectVersioningByProject(projectB))

// 3. Versioning disabled globally
config, err = metainfo.NewExtendedConfig(metainfo.Config{
UseBucketLevelObjectVersioning: false,
})
require.NoError(t, err)

// 3.1. Project A is prompted for versioning beta, but has not opted in
projectA.PromptedForVersioningBeta = true
projectA.DefaultVersioning = console.VersioningUnsupported
// 3.2. Project B is prompted for versioning beta, and has opted in
projectB.PromptedForVersioningBeta = true
projectB.DefaultVersioning = console.Unversioned
require.False(t, config.UseBucketLevelObjectVersioningByProject(projectA))
require.True(t, config.UseBucketLevelObjectVersioningByProject(projectB))

// 3.3. Project A is not prompted for versioning beta
projectA.PromptedForVersioningBeta = false
projectA.DefaultVersioning = console.Unversioned
require.False(t, config.UseBucketLevelObjectVersioningByProject(projectA))
}
9 changes: 7 additions & 2 deletions satellite/metainfo/endpoint_bucket.go
Expand Up @@ -133,7 +133,12 @@ func (endpoint *Endpoint) SetBucketVersioning(ctx context.Context, req *pb.SetBu
}
endpoint.usageTracking(keyInfo, req.Header, fmt.Sprintf("%T", req))

if !endpoint.config.UseBucketLevelObjectVersioningByProject(keyInfo.ProjectID) {
project, err := endpoint.projects.Get(ctx, keyInfo.ProjectID)
if err != nil {
return nil, err
}

if !endpoint.config.UseBucketLevelObjectVersioningByProject(project) {
return nil, rpcstatus.Error(rpcstatus.PermissionDenied, "versioning not allowed for this project")
}
if req.Versioning {
Expand Down Expand Up @@ -209,7 +214,7 @@ func (endpoint *Endpoint) CreateBucket(ctx context.Context, req *pb.BucketCreate
}
bucketReq.Placement = project.DefaultPlacement

if endpoint.config.UseBucketLevelObjectVersioningByProject(keyInfo.ProjectID) {
if endpoint.config.UseBucketLevelObjectVersioningByProject(project) {
defaultVersioning, err := endpoint.projects.GetDefaultVersioning(ctx, keyInfo.ProjectID)
if err != nil {
return nil, err
Expand Down
9 changes: 8 additions & 1 deletion satellite/metainfo/endpoint_object.go
Expand Up @@ -1676,7 +1676,11 @@ func (endpoint *Endpoint) DeleteCommittedObject(
if len(version) == 0 {
versioned := false
suspended := false
if endpoint.config.UseBucketLevelObjectVersioningByProject(projectID) {
project, err := endpoint.projects.Get(ctx, projectID)
if err != nil {
return nil, Error.Wrap(err)
}
if endpoint.config.UseBucketLevelObjectVersioningByProject(project) {
// TODO(ver): for production we need to avoid somehow additional GetBucket call
bucket, err := endpoint.buckets.GetBucket(ctx, []byte(bucket), projectID)
if err != nil {
Expand All @@ -1696,6 +1700,9 @@ func (endpoint *Endpoint) DeleteCommittedObject(
Versioned: versioned,
Suspended: suspended,
})
if err != nil {
return nil, Error.Wrap(err)
}
} else {
var sv metabase.StreamVersionID
sv, err = metabase.StreamVersionIDFromBytes(version)
Expand Down

0 comments on commit d601509

Please sign in to comment.