Skip to content

Commit a359879

Browse files
authored
chore: scope workspace quotas to organizations (coder#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)