Skip to content

Commit 87ad560

Browse files
authored
feat: add groups and group members to telemetry snapshot (coder#13655)
* feat: Added in groups and groups members to telemetry snapshot * feat: adding in test to dbauthz for getting group members and groups
1 parent 58325df commit 87ad560

File tree

14 files changed

+239
-25
lines changed

14 files changed

+239
-25
lines changed

coderd/database/dbauthz/dbauthz.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1321,11 +1321,25 @@ func (q *querier) GetGroupByOrgAndName(ctx context.Context, arg database.GetGrou
13211321
return fetch(q.log, q.auth, q.db.GetGroupByOrgAndName)(ctx, arg)
13221322
}
13231323

1324-
func (q *querier) GetGroupMembers(ctx context.Context, id uuid.UUID) ([]database.User, error) {
1324+
func (q *querier) GetGroupMembers(ctx context.Context) ([]database.GroupMember, error) {
1325+
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceSystem); err != nil {
1326+
return nil, err
1327+
}
1328+
return q.db.GetGroupMembers(ctx)
1329+
}
1330+
1331+
func (q *querier) GetGroupMembersByGroupID(ctx context.Context, id uuid.UUID) ([]database.User, error) {
13251332
if _, err := q.GetGroupByID(ctx, id); err != nil { // AuthZ check
13261333
return nil, err
13271334
}
1328-
return q.db.GetGroupMembers(ctx, id)
1335+
return q.db.GetGroupMembersByGroupID(ctx, id)
1336+
}
1337+
1338+
func (q *querier) GetGroups(ctx context.Context) ([]database.Group, error) {
1339+
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceSystem); err != nil {
1340+
return nil, err
1341+
}
1342+
return q.db.GetGroups(ctx)
13291343
}
13301344

13311345
func (q *querier) GetGroupsByOrganizationAndUserID(ctx context.Context, arg database.GetGroupsByOrganizationAndUserIDParams) ([]database.Group, error) {

coderd/database/dbauthz/dbauthz_test.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,11 +314,19 @@ func (s *MethodTestSuite) TestGroup() {
314314
Name: g.Name,
315315
}).Asserts(g, policy.ActionRead).Returns(g)
316316
}))
317-
s.Run("GetGroupMembers", s.Subtest(func(db database.Store, check *expects) {
317+
s.Run("GetGroupMembersByGroupID", s.Subtest(func(db database.Store, check *expects) {
318318
g := dbgen.Group(s.T(), db, database.Group{})
319319
_ = dbgen.GroupMember(s.T(), db, database.GroupMember{})
320320
check.Args(g.ID).Asserts(g, policy.ActionRead)
321321
}))
322+
s.Run("GetGroupMembers", s.Subtest(func(db database.Store, check *expects) {
323+
_ = dbgen.GroupMember(s.T(), db, database.GroupMember{})
324+
check.Asserts(rbac.ResourceSystem, policy.ActionRead)
325+
}))
326+
s.Run("GetGroups", s.Subtest(func(db database.Store, check *expects) {
327+
_ = dbgen.Group(s.T(), db, database.Group{})
328+
check.Asserts(rbac.ResourceSystem, policy.ActionRead)
329+
}))
322330
s.Run("GetGroupsByOrganizationAndUserID", s.Subtest(func(db database.Store, check *expects) {
323331
g := dbgen.Group(s.T(), db, database.Group{})
324332
gm := dbgen.GroupMember(s.T(), db, database.GroupMember{GroupID: g.ID})

coderd/database/dbgen/dbgen_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ func TestGenerator(t *testing.T) {
105105
exp := []database.User{u}
106106
dbgen.GroupMember(t, db, database.GroupMember{GroupID: g.ID, UserID: u.ID})
107107

108-
require.Equal(t, exp, must(db.GetGroupMembers(context.Background(), g.ID)))
108+
require.Equal(t, exp, must(db.GetGroupMembersByGroupID(context.Background(), g.ID)))
109109
})
110110

111111
t.Run("Organization", func(t *testing.T) {

coderd/database/dbmem/dbmem.go

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2370,7 +2370,16 @@ func (q *FakeQuerier) GetGroupByOrgAndName(_ context.Context, arg database.GetGr
23702370
return database.Group{}, sql.ErrNoRows
23712371
}
23722372

2373-
func (q *FakeQuerier) GetGroupMembers(_ context.Context, id uuid.UUID) ([]database.User, error) {
2373+
func (q *FakeQuerier) GetGroupMembers(_ context.Context) ([]database.GroupMember, error) {
2374+
q.mutex.RLock()
2375+
defer q.mutex.RUnlock()
2376+
2377+
out := make([]database.GroupMember, len(q.groupMembers))
2378+
copy(out, q.groupMembers)
2379+
return out, nil
2380+
}
2381+
2382+
func (q *FakeQuerier) GetGroupMembersByGroupID(_ context.Context, id uuid.UUID) ([]database.User, error) {
23742383
q.mutex.RLock()
23752384
defer q.mutex.RUnlock()
23762385

@@ -2399,6 +2408,15 @@ func (q *FakeQuerier) GetGroupMembers(_ context.Context, id uuid.UUID) ([]databa
23992408
return users, nil
24002409
}
24012410

2411+
func (q *FakeQuerier) GetGroups(_ context.Context) ([]database.Group, error) {
2412+
q.mutex.RLock()
2413+
defer q.mutex.RUnlock()
2414+
2415+
out := make([]database.Group, len(q.groups))
2416+
copy(out, q.groups)
2417+
return out, nil
2418+
}
2419+
24022420
func (q *FakeQuerier) GetGroupsByOrganizationAndUserID(_ context.Context, arg database.GetGroupsByOrganizationAndUserIDParams) ([]database.Group, error) {
24032421
err := validateDatabaseType(arg)
24042422
if err != nil {

coderd/database/dbmetrics/dbmetrics.go

Lines changed: 16 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: 35 additions & 5 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: 3 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries.sql.go

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

coderd/database/queries/groupmembers.sql

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
-- name: GetGroupMembers :many
2+
SELECT * FROM group_members;
3+
4+
-- name: GetGroupMembersByGroupID :many
25
SELECT
36
users.*
47
FROM

coderd/database/queries/groups.sql

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
-- name: GetGroups :many
2+
SELECT * FROM groups;
3+
14
-- name: GetGroupByID :one
25
SELECT
36
*

coderd/telemetry/telemetry.go

Lines changed: 59 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -344,9 +344,6 @@ func (r *remoteReporter) createSnapshot() (*Snapshot, error) {
344344
users := database.ConvertUserRows(userRows)
345345
var firstUser database.User
346346
for _, dbUser := range users {
347-
if dbUser.Status != database.UserStatusActive {
348-
continue
349-
}
350347
if firstUser.CreatedAt.IsZero() {
351348
firstUser = dbUser
352349
}
@@ -366,6 +363,28 @@ func (r *remoteReporter) createSnapshot() (*Snapshot, error) {
366363
}
367364
return nil
368365
})
366+
eg.Go(func() error {
367+
groups, err := r.options.Database.GetGroups(ctx)
368+
if err != nil {
369+
return xerrors.Errorf("get groups: %w", err)
370+
}
371+
snapshot.Groups = make([]Group, 0, len(groups))
372+
for _, group := range groups {
373+
snapshot.Groups = append(snapshot.Groups, ConvertGroup(group))
374+
}
375+
return nil
376+
})
377+
eg.Go(func() error {
378+
groupMembers, err := r.options.Database.GetGroupMembers(ctx)
379+
if err != nil {
380+
return xerrors.Errorf("get groups: %w", err)
381+
}
382+
snapshot.GroupMembers = make([]GroupMember, 0, len(groupMembers))
383+
for _, member := range groupMembers {
384+
snapshot.GroupMembers = append(snapshot.GroupMembers, ConvertGroupMember(member))
385+
}
386+
return nil
387+
})
369388
eg.Go(func() error {
370389
workspaceRows, err := r.options.Database.GetWorkspaces(ctx, database.GetWorkspacesParams{})
371390
if err != nil {
@@ -642,6 +661,26 @@ func ConvertUser(dbUser database.User) User {
642661
EmailHashed: emailHashed,
643662
RBACRoles: dbUser.RBACRoles,
644663
CreatedAt: dbUser.CreatedAt,
664+
Status: dbUser.Status,
665+
}
666+
}
667+
668+
func ConvertGroup(group database.Group) Group {
669+
return Group{
670+
ID: group.ID,
671+
Name: group.Name,
672+
OrganizationID: group.OrganizationID,
673+
AvatarURL: group.AvatarURL,
674+
QuotaAllowance: group.QuotaAllowance,
675+
DisplayName: group.DisplayName,
676+
Source: group.Source,
677+
}
678+
}
679+
680+
func ConvertGroupMember(member database.GroupMember) GroupMember {
681+
return GroupMember{
682+
GroupID: member.GroupID,
683+
UserID: member.UserID,
645684
}
646685
}
647686

@@ -746,6 +785,8 @@ type Snapshot struct {
746785
TemplateVersions []TemplateVersion `json:"template_versions"`
747786
Templates []Template `json:"templates"`
748787
Users []User `json:"users"`
788+
Groups []Group `json:"groups"`
789+
GroupMembers []GroupMember `json:"group_members"`
749790
WorkspaceAgentStats []WorkspaceAgentStat `json:"workspace_agent_stats"`
750791
WorkspaceAgents []WorkspaceAgent `json:"workspace_agents"`
751792
WorkspaceApps []WorkspaceApp `json:"workspace_apps"`
@@ -797,6 +838,21 @@ type User struct {
797838
Status database.UserStatus `json:"status"`
798839
}
799840

841+
type Group struct {
842+
ID uuid.UUID `json:"id"`
843+
Name string `json:"name"`
844+
OrganizationID uuid.UUID `json:"organization_id"`
845+
AvatarURL string `json:"avatar_url"`
846+
QuotaAllowance int32 `json:"quota_allowance"`
847+
DisplayName string `json:"display_name"`
848+
Source database.GroupSource `json:"source"`
849+
}
850+
851+
type GroupMember struct {
852+
UserID uuid.UUID `json:"user_id"`
853+
GroupID uuid.UUID `json:"group_id"`
854+
}
855+
800856
type WorkspaceResource struct {
801857
ID uuid.UUID `json:"id"`
802858
CreatedAt time.Time `json:"created_at"`

0 commit comments

Comments
 (0)