Skip to content

Commit a359879

Browse files
authored
chore: scope workspace quotas to organizations (#14352)
* chore: scope workspace quotas to organizations Quotas are now a function of (user_id, organization_id). They are still sourced from groups. Deprecate the old api endpoint.
1 parent fa73331 commit a359879

File tree

16 files changed

+309
-68
lines changed

16 files changed

+309
-68
lines changed

coderd/apidoc/docs.go

Lines changed: 45 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/apidoc/swagger.json

Lines changed: 41 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/dbauthz/dbauthz.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1823,20 +1823,20 @@ func (q *querier) GetProvisionerLogsAfterID(ctx context.Context, arg database.Ge
18231823
return q.db.GetProvisionerLogsAfterID(ctx, arg)
18241824
}
18251825

1826-
func (q *querier) GetQuotaAllowanceForUser(ctx context.Context, userID uuid.UUID) (int64, error) {
1827-
err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceUserObject(userID))
1826+
func (q *querier) GetQuotaAllowanceForUser(ctx context.Context, params database.GetQuotaAllowanceForUserParams) (int64, error) {
1827+
err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceUserObject(params.UserID))
18281828
if err != nil {
18291829
return -1, err
18301830
}
1831-
return q.db.GetQuotaAllowanceForUser(ctx, userID)
1831+
return q.db.GetQuotaAllowanceForUser(ctx, params)
18321832
}
18331833

1834-
func (q *querier) GetQuotaConsumedForUser(ctx context.Context, userID uuid.UUID) (int64, error) {
1835-
err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceUserObject(userID))
1834+
func (q *querier) GetQuotaConsumedForUser(ctx context.Context, params database.GetQuotaConsumedForUserParams) (int64, error) {
1835+
err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceUserObject(params.OwnerID))
18361836
if err != nil {
18371837
return -1, err
18381838
}
1839-
return q.db.GetQuotaConsumedForUser(ctx, userID)
1839+
return q.db.GetQuotaConsumedForUser(ctx, params)
18401840
}
18411841

18421842
func (q *querier) GetReplicaByID(ctx context.Context, id uuid.UUID) (database.Replica, error) {

coderd/database/dbauthz/dbauthz_test.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1075,11 +1075,17 @@ func (s *MethodTestSuite) TestUser() {
10751075
}))
10761076
s.Run("GetQuotaAllowanceForUser", s.Subtest(func(db database.Store, check *expects) {
10771077
u := dbgen.User(s.T(), db, database.User{})
1078-
check.Args(u.ID).Asserts(u, policy.ActionRead).Returns(int64(0))
1078+
check.Args(database.GetQuotaAllowanceForUserParams{
1079+
UserID: u.ID,
1080+
OrganizationID: uuid.New(),
1081+
}).Asserts(u, policy.ActionRead).Returns(int64(0))
10791082
}))
10801083
s.Run("GetQuotaConsumedForUser", s.Subtest(func(db database.Store, check *expects) {
10811084
u := dbgen.User(s.T(), db, database.User{})
1082-
check.Args(u.ID).Asserts(u, policy.ActionRead).Returns(int64(0))
1085+
check.Args(database.GetQuotaConsumedForUserParams{
1086+
OwnerID: u.ID,
1087+
OrganizationID: uuid.New(),
1088+
}).Asserts(u, policy.ActionRead).Returns(int64(0))
10831089
}))
10841090
s.Run("GetUserByEmailOrUsername", s.Subtest(func(db database.Store, check *expects) {
10851091
u := dbgen.User(s.T(), db, database.User{})

coderd/database/dbmem/dbmem.go

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3314,13 +3314,13 @@ func (q *FakeQuerier) GetProvisionerLogsAfterID(_ context.Context, arg database.
33143314
return logs, nil
33153315
}
33163316

3317-
func (q *FakeQuerier) GetQuotaAllowanceForUser(_ context.Context, userID uuid.UUID) (int64, error) {
3317+
func (q *FakeQuerier) GetQuotaAllowanceForUser(_ context.Context, params database.GetQuotaAllowanceForUserParams) (int64, error) {
33183318
q.mutex.RLock()
33193319
defer q.mutex.RUnlock()
33203320

33213321
var sum int64
33223322
for _, member := range q.groupMembers {
3323-
if member.UserID != userID {
3323+
if member.UserID != params.UserID {
33243324
continue
33253325
}
33263326
if _, err := q.getOrganizationByIDNoLock(member.GroupID); err == nil {
@@ -3340,27 +3340,33 @@ func (q *FakeQuerier) GetQuotaAllowanceForUser(_ context.Context, userID uuid.UU
33403340
// Grab the quota for the Everyone group iff the user is a member of
33413341
// said organization.
33423342
for _, mem := range q.organizationMembers {
3343-
if mem.UserID != userID {
3343+
if mem.UserID != params.UserID {
33443344
continue
33453345
}
33463346

33473347
group, err := q.getGroupByIDNoLock(context.Background(), mem.OrganizationID)
33483348
if err != nil {
33493349
return -1, xerrors.Errorf("failed to get everyone group for org %q", mem.OrganizationID.String())
33503350
}
3351+
if group.OrganizationID != params.OrganizationID {
3352+
continue
3353+
}
33513354
sum += int64(group.QuotaAllowance)
33523355
}
33533356

33543357
return sum, nil
33553358
}
33563359

3357-
func (q *FakeQuerier) GetQuotaConsumedForUser(_ context.Context, userID uuid.UUID) (int64, error) {
3360+
func (q *FakeQuerier) GetQuotaConsumedForUser(_ context.Context, params database.GetQuotaConsumedForUserParams) (int64, error) {
33583361
q.mutex.RLock()
33593362
defer q.mutex.RUnlock()
33603363

33613364
var sum int64
33623365
for _, workspace := range q.workspaces {
3363-
if workspace.OwnerID != userID {
3366+
if workspace.OwnerID != params.OwnerID {
3367+
continue
3368+
}
3369+
if workspace.OrganizationID != params.OrganizationID {
33643370
continue
33653371
}
33663372
if workspace.Deleted {

coderd/database/dbmetrics/dbmetrics.go

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/dbmock/dbmock.go

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/querier.go

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/querier_test.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,10 @@ func TestWorkspaceQuotas(t *testing.T) {
604604
db2sdk.List([]database.OrganizationMember{memOne, memTwo}, orgMemberIDs))
605605

606606
// Check the quota is correct.
607-
allowance, err := db.GetQuotaAllowanceForUser(ctx, one.ID)
607+
allowance, err := db.GetQuotaAllowanceForUser(ctx, database.GetQuotaAllowanceForUserParams{
608+
UserID: one.ID,
609+
OrganizationID: org.ID,
610+
})
608611
require.NoError(t, err)
609612
require.Equal(t, int64(50), allowance)
610613

@@ -617,7 +620,10 @@ func TestWorkspaceQuotas(t *testing.T) {
617620
require.NoError(t, err)
618621

619622
// Ensure allowance remains the same
620-
allowance, err = db.GetQuotaAllowanceForUser(ctx, one.ID)
623+
allowance, err = db.GetQuotaAllowanceForUser(ctx, database.GetQuotaAllowanceForUserParams{
624+
UserID: one.ID,
625+
OrganizationID: org.ID,
626+
})
621627
require.NoError(t, err)
622628
require.Equal(t, int64(50), allowance)
623629
})

coderd/database/queries.sql.go

Lines changed: 22 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy