Skip to content

Commit 04f0510

Browse files
authored
feat(coderd/database): add template_usage_stats table and rollup query (#12664)
Add `template_usage_stats` table for aggregating tempalte usage data. Data is rolled up by the `UpsertTemplateUsageStats` query, which fetches data from the `workspace_agent_stats` and `workspace_app_stats` tables.
1 parent a6b8f38 commit 04f0510

File tree

16 files changed

+1459
-0
lines changed

16 files changed

+1459
-0
lines changed

coderd/database/dbauthz/dbauthz.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1617,6 +1617,29 @@ func (q *querier) GetTemplateParameterInsights(ctx context.Context, arg database
16171617
return q.db.GetTemplateParameterInsights(ctx, arg)
16181618
}
16191619

1620+
func (q *querier) GetTemplateUsageStats(ctx context.Context, arg database.GetTemplateUsageStatsParams) ([]database.TemplateUsageStat, error) {
1621+
// Used by dbrollup tests, use same safe-guard as other insights endpoints.
1622+
// For auditors, check read template_insights, and fall back to update template.
1623+
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceTemplateInsights); err != nil {
1624+
for _, templateID := range arg.TemplateIDs {
1625+
template, err := q.db.GetTemplateByID(ctx, templateID)
1626+
if err != nil {
1627+
return nil, err
1628+
}
1629+
1630+
if err := q.authorizeContext(ctx, rbac.ActionUpdate, template); err != nil {
1631+
return nil, err
1632+
}
1633+
}
1634+
if len(arg.TemplateIDs) == 0 {
1635+
if err := q.authorizeContext(ctx, rbac.ActionUpdate, rbac.ResourceTemplate.All()); err != nil {
1636+
return nil, err
1637+
}
1638+
}
1639+
}
1640+
return q.db.GetTemplateUsageStats(ctx, arg)
1641+
}
1642+
16201643
func (q *querier) GetTemplateVersionByID(ctx context.Context, tvid uuid.UUID) (database.TemplateVersion, error) {
16211644
tv, err := q.db.GetTemplateVersionByID(ctx, tvid)
16221645
if err != nil {
@@ -3413,6 +3436,13 @@ func (q *querier) UpsertTailnetTunnel(ctx context.Context, arg database.UpsertTa
34133436
return q.db.UpsertTailnetTunnel(ctx, arg)
34143437
}
34153438

3439+
func (q *querier) UpsertTemplateUsageStats(ctx context.Context) error {
3440+
if err := q.authorizeContext(ctx, rbac.ActionUpdate, rbac.ResourceSystem); err != nil {
3441+
return err
3442+
}
3443+
return q.db.UpsertTemplateUsageStats(ctx)
3444+
}
3445+
34163446
func (q *querier) UpsertWorkspaceAgentPortShare(ctx context.Context, arg database.UpsertWorkspaceAgentPortShareParams) (database.WorkspaceAgentPortShare, error) {
34173447
workspace, err := q.db.GetWorkspaceByID(ctx, arg.WorkspaceID)
34183448
if err != nil {

coderd/database/dbauthz/dbauthz_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -956,6 +956,12 @@ func (s *MethodTestSuite) TestTemplate() {
956956
s.Run("GetTemplateAppInsightsByTemplate", s.Subtest(func(db database.Store, check *expects) {
957957
check.Args(database.GetTemplateAppInsightsByTemplateParams{}).Asserts(rbac.ResourceTemplateInsights, rbac.ActionRead)
958958
}))
959+
s.Run("GetTemplateUsageStats", s.Subtest(func(db database.Store, check *expects) {
960+
check.Args(database.GetTemplateUsageStatsParams{}).Asserts(rbac.ResourceTemplateInsights, rbac.ActionRead).Errors(sql.ErrNoRows)
961+
}))
962+
s.Run("UpsertTemplateUsageStats", s.Subtest(func(db database.Store, check *expects) {
963+
check.Asserts(rbac.ResourceSystem, rbac.ActionUpdate)
964+
}))
959965
}
960966

961967
func (s *MethodTestSuite) TestUser() {

0 commit comments

Comments
 (0)