satellite/console: allow user to update project when limits are above paid defaults
When a user's bandwidth/storage limits are manually set to exceed the paid tier defaults, attempting to update their project via the satellite UI (e.g. to change the name/description) would result in an error. This change modifies the limit checks for updating a project to remove this issue. https://github.com/storj/storj/issues/4892 Change-Id: I48853a3289b0ac51587f268a18c1b25743123fcf
This commit is contained in:
parent
d72f9525d4
commit
c237468ac9
@ -1550,7 +1550,7 @@ func (s *Service) GenDeleteProject(ctx context.Context, projectID uuid.UUID) (ht
|
||||
}
|
||||
|
||||
// UpdateProject is a method for updating project name and description by id.
|
||||
func (s *Service) UpdateProject(ctx context.Context, projectID uuid.UUID, projectInfo ProjectInfo) (p *Project, err error) {
|
||||
func (s *Service) UpdateProject(ctx context.Context, projectID uuid.UUID, updatedProject ProjectInfo) (p *Project, err error) {
|
||||
defer mon.Task()(&ctx)(&err)
|
||||
|
||||
user, err := s.getUserAndAuditLog(ctx, "update project name and description", zap.String("projectID", projectID.String()))
|
||||
@ -1558,7 +1558,7 @@ func (s *Service) UpdateProject(ctx context.Context, projectID uuid.UUID, projec
|
||||
return nil, Error.Wrap(err)
|
||||
}
|
||||
|
||||
err = ValidateNameAndDescription(projectInfo.Name, projectInfo.Description)
|
||||
err = ValidateNameAndDescription(updatedProject.Name, updatedProject.Description)
|
||||
if err != nil {
|
||||
return nil, Error.Wrap(err)
|
||||
}
|
||||
@ -1568,8 +1568,8 @@ func (s *Service) UpdateProject(ctx context.Context, projectID uuid.UUID, projec
|
||||
return nil, Error.Wrap(err)
|
||||
}
|
||||
project := isMember.project
|
||||
project.Name = projectInfo.Name
|
||||
project.Description = projectInfo.Description
|
||||
project.Name = updatedProject.Name
|
||||
project.Description = updatedProject.Description
|
||||
|
||||
if user.PaidTier {
|
||||
if project.BandwidthLimit != nil && *project.BandwidthLimit == 0 {
|
||||
@ -1578,15 +1578,15 @@ func (s *Service) UpdateProject(ctx context.Context, projectID uuid.UUID, projec
|
||||
if project.StorageLimit != nil && *project.StorageLimit == 0 {
|
||||
return nil, Error.New("current storage limit for project is set to 0 (updating disabled)")
|
||||
}
|
||||
if projectInfo.StorageLimit <= 0 || projectInfo.BandwidthLimit <= 0 {
|
||||
if updatedProject.StorageLimit <= 0 || updatedProject.BandwidthLimit <= 0 {
|
||||
return nil, Error.New("project limits must be greater than 0")
|
||||
}
|
||||
|
||||
if projectInfo.StorageLimit > s.config.UsageLimits.Storage.Paid {
|
||||
if updatedProject.StorageLimit > s.config.UsageLimits.Storage.Paid && updatedProject.StorageLimit > *project.StorageLimit {
|
||||
return nil, Error.New("specified storage limit exceeds allowed maximum for current tier")
|
||||
}
|
||||
|
||||
if projectInfo.BandwidthLimit > s.config.UsageLimits.Bandwidth.Paid {
|
||||
if updatedProject.BandwidthLimit > s.config.UsageLimits.Bandwidth.Paid && updatedProject.BandwidthLimit > *project.BandwidthLimit {
|
||||
return nil, Error.New("specified bandwidth limit exceeds allowed maximum for current tier")
|
||||
}
|
||||
|
||||
@ -1594,7 +1594,7 @@ func (s *Service) UpdateProject(ctx context.Context, projectID uuid.UUID, projec
|
||||
if err != nil {
|
||||
return nil, Error.Wrap(err)
|
||||
}
|
||||
if projectInfo.StorageLimit.Int64() < storageUsed {
|
||||
if updatedProject.StorageLimit.Int64() < storageUsed {
|
||||
return nil, Error.New("cannot set storage limit below current usage")
|
||||
}
|
||||
|
||||
@ -1602,14 +1602,14 @@ func (s *Service) UpdateProject(ctx context.Context, projectID uuid.UUID, projec
|
||||
if err != nil {
|
||||
return nil, Error.Wrap(err)
|
||||
}
|
||||
if projectInfo.BandwidthLimit.Int64() < bandwidthUsed {
|
||||
if updatedProject.BandwidthLimit.Int64() < bandwidthUsed {
|
||||
return nil, Error.New("cannot set bandwidth limit below current usage")
|
||||
}
|
||||
|
||||
project.StorageLimit = new(memory.Size)
|
||||
*project.StorageLimit = projectInfo.StorageLimit
|
||||
*project.StorageLimit = updatedProject.StorageLimit
|
||||
project.BandwidthLimit = new(memory.Size)
|
||||
*project.BandwidthLimit = projectInfo.BandwidthLimit
|
||||
*project.BandwidthLimit = updatedProject.BandwidthLimit
|
||||
}
|
||||
|
||||
err = s.store.Projects().Update(ctx, project)
|
||||
@ -1672,14 +1672,14 @@ func (s *Service) GenUpdateProject(ctx context.Context, projectID uuid.UUID, pro
|
||||
}
|
||||
}
|
||||
|
||||
if projectInfo.StorageLimit > s.config.UsageLimits.Storage.Paid {
|
||||
if projectInfo.StorageLimit > s.config.UsageLimits.Storage.Paid && projectInfo.StorageLimit > *project.StorageLimit {
|
||||
return nil, api.HTTPError{
|
||||
Status: http.StatusBadRequest,
|
||||
Err: Error.New("specified storage limit exceeds allowed maximum for current tier"),
|
||||
}
|
||||
}
|
||||
|
||||
if projectInfo.BandwidthLimit > s.config.UsageLimits.Bandwidth.Paid {
|
||||
if projectInfo.BandwidthLimit > s.config.UsageLimits.Bandwidth.Paid && projectInfo.BandwidthLimit > *project.BandwidthLimit {
|
||||
return nil, api.HTTPError{
|
||||
Status: http.StatusBadRequest,
|
||||
Err: Error.New("specified bandwidth limit exceeds allowed maximum for current tier"),
|
||||
|
@ -382,6 +382,81 @@ func TestPaidTier(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
// TestUpdateProjectExceedsLimits ensures that a project with limits manually set above the defaults can be updated.
|
||||
func TestUpdateProjectExceedsLimits(t *testing.T) {
|
||||
usageConfig := console.UsageLimitsConfig{
|
||||
Storage: console.StorageLimitConfig{
|
||||
Free: memory.GB,
|
||||
Paid: memory.TB,
|
||||
},
|
||||
Bandwidth: console.BandwidthLimitConfig{
|
||||
Free: 2 * memory.GB,
|
||||
Paid: 2 * memory.TB,
|
||||
},
|
||||
Segment: console.SegmentLimitConfig{
|
||||
Free: 10,
|
||||
Paid: 50,
|
||||
},
|
||||
Project: console.ProjectLimitConfig{
|
||||
Free: 1,
|
||||
Paid: 3,
|
||||
},
|
||||
}
|
||||
|
||||
testplanet.Run(t, testplanet.Config{
|
||||
SatelliteCount: 1, StorageNodeCount: 0, UplinkCount: 1,
|
||||
Reconfigure: testplanet.Reconfigure{
|
||||
Satellite: func(log *zap.Logger, index int, config *satellite.Config) {
|
||||
config.Console.UsageLimits = usageConfig
|
||||
},
|
||||
},
|
||||
}, func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet) {
|
||||
sat := planet.Satellites[0]
|
||||
service := sat.API.Console.Service
|
||||
projectID := planet.Uplinks[0].Projects[0].ID
|
||||
|
||||
updatedName := "newName"
|
||||
updatedDescription := "newDescription"
|
||||
updatedStorageLimit := memory.Size(100) + memory.TB
|
||||
updatedBandwidthLimit := memory.Size(100) + memory.TB
|
||||
|
||||
proj, err := sat.API.DB.Console().Projects().Get(ctx, projectID)
|
||||
require.NoError(t, err)
|
||||
|
||||
userCtx1, err := sat.UserContext(ctx, proj.OwnerID)
|
||||
require.NoError(t, err)
|
||||
|
||||
// project should have free tier usage limits
|
||||
require.Equal(t, usageConfig.Storage.Free, *proj.StorageLimit)
|
||||
require.Equal(t, usageConfig.Bandwidth.Free, *proj.BandwidthLimit)
|
||||
require.Equal(t, usageConfig.Segment.Free, *proj.SegmentLimit)
|
||||
|
||||
// update project name should succeed
|
||||
_, err = service.UpdateProject(userCtx1, projectID, console.ProjectInfo{
|
||||
Name: updatedName,
|
||||
Description: updatedDescription,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
// manually set project limits above defaults
|
||||
proj1, err := sat.API.DB.Console().Projects().Get(ctx, projectID)
|
||||
require.NoError(t, err)
|
||||
proj1.StorageLimit = new(memory.Size)
|
||||
*proj1.StorageLimit = updatedStorageLimit
|
||||
proj1.BandwidthLimit = new(memory.Size)
|
||||
*proj1.BandwidthLimit = updatedBandwidthLimit
|
||||
err = sat.DB.Console().Projects().Update(ctx, proj1)
|
||||
require.NoError(t, err)
|
||||
|
||||
// try to update project name should succeed
|
||||
_, err = service.UpdateProject(userCtx1, projectID, console.ProjectInfo{
|
||||
Name: "updatedName",
|
||||
Description: "updatedDescription",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestMFA(t *testing.T) {
|
||||
testplanet.Run(t, testplanet.Config{
|
||||
SatelliteCount: 1, StorageNodeCount: 0, UplinkCount: 0,
|
||||
|
Loading…
Reference in New Issue
Block a user