Skip to content

Commit aa0dc2d

Browse files
authored
chore: track terraform modules in telemetry (#15450)
Addresses coder/nexus#35. This PR: - Adds a `workspace_modules` table to track modules used by the Terraform provisioner in provisioner jobs. - Adds a `module_path` column to the `workspace_resources` table, allowing to identify which module a resource originates from. - Starts pushing this new information into telemetry. For the person reviewing this PR, do not fret about the 1,500 new lines - ~1,000 of them are auto-generated.
1 parent 968c52b commit aa0dc2d

35 files changed

+1633
-412
lines changed

coderd/database/dbauthz/dbauthz.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2666,6 +2666,20 @@ func (q *querier) GetWorkspaceByWorkspaceAppID(ctx context.Context, workspaceApp
26662666
return fetch(q.log, q.auth, q.db.GetWorkspaceByWorkspaceAppID)(ctx, workspaceAppID)
26672667
}
26682668

2669+
func (q *querier) GetWorkspaceModulesByJobID(ctx context.Context, jobID uuid.UUID) ([]database.WorkspaceModule, error) {
2670+
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceSystem); err != nil {
2671+
return nil, err
2672+
}
2673+
return q.db.GetWorkspaceModulesByJobID(ctx, jobID)
2674+
}
2675+
2676+
func (q *querier) GetWorkspaceModulesCreatedAfter(ctx context.Context, createdAt time.Time) ([]database.WorkspaceModule, error) {
2677+
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceSystem); err != nil {
2678+
return nil, err
2679+
}
2680+
return q.db.GetWorkspaceModulesCreatedAfter(ctx, createdAt)
2681+
}
2682+
26692683
func (q *querier) GetWorkspaceProxies(ctx context.Context) ([]database.WorkspaceProxy, error) {
26702684
return fetchWithPostFilter(q.auth, policy.ActionRead, func(ctx context.Context, _ interface{}) ([]database.WorkspaceProxy, error) {
26712685
return q.db.GetWorkspaceProxies(ctx)
@@ -3222,6 +3236,13 @@ func (q *querier) InsertWorkspaceBuildParameters(ctx context.Context, arg databa
32223236
return q.db.InsertWorkspaceBuildParameters(ctx, arg)
32233237
}
32243238

3239+
func (q *querier) InsertWorkspaceModule(ctx context.Context, arg database.InsertWorkspaceModuleParams) (database.WorkspaceModule, error) {
3240+
if err := q.authorizeContext(ctx, policy.ActionCreate, rbac.ResourceSystem); err != nil {
3241+
return database.WorkspaceModule{}, err
3242+
}
3243+
return q.db.InsertWorkspaceModule(ctx, arg)
3244+
}
3245+
32253246
func (q *querier) InsertWorkspaceProxy(ctx context.Context, arg database.InsertWorkspaceProxyParams) (database.WorkspaceProxy, error) {
32263247
return insert(q.log, q.auth, rbac.ResourceWorkspaceProxy, q.db.InsertWorkspaceProxy)(ctx, arg)
32273248
}

coderd/database/dbauthz/dbauthz_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2907,6 +2907,21 @@ func (s *MethodTestSuite) TestSystemFunctions() {
29072907
}
29082908
check.Args(build.ID).Asserts(rbac.ResourceSystem, policy.ActionRead).Returns(rows)
29092909
}))
2910+
s.Run("InsertWorkspaceModule", s.Subtest(func(db database.Store, check *expects) {
2911+
j := dbgen.ProvisionerJob(s.T(), db, nil, database.ProvisionerJob{
2912+
Type: database.ProvisionerJobTypeWorkspaceBuild,
2913+
})
2914+
check.Args(database.InsertWorkspaceModuleParams{
2915+
JobID: j.ID,
2916+
Transition: database.WorkspaceTransitionStart,
2917+
}).Asserts(rbac.ResourceSystem, policy.ActionCreate)
2918+
}))
2919+
s.Run("GetWorkspaceModulesByJobID", s.Subtest(func(db database.Store, check *expects) {
2920+
check.Args(uuid.New()).Asserts(rbac.ResourceSystem, policy.ActionRead)
2921+
}))
2922+
s.Run("GetWorkspaceModulesCreatedAfter", s.Subtest(func(db database.Store, check *expects) {
2923+
check.Args(dbtime.Now()).Asserts(rbac.ResourceSystem, policy.ActionRead)
2924+
}))
29102925
}
29112926

29122927
func (s *MethodTestSuite) TestNotifications() {

coderd/database/dbgen/dbgen.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,11 +657,29 @@ func WorkspaceResource(t testing.TB, db database.Store, orig database.WorkspaceR
657657
Valid: takeFirst(orig.InstanceType.Valid, false),
658658
},
659659
DailyCost: takeFirst(orig.DailyCost, 0),
660+
ModulePath: sql.NullString{
661+
String: takeFirst(orig.ModulePath.String, ""),
662+
Valid: takeFirst(orig.ModulePath.Valid, true),
663+
},
660664
})
661665
require.NoError(t, err, "insert resource")
662666
return resource
663667
}
664668

669+
func WorkspaceModule(t testing.TB, db database.Store, orig database.WorkspaceModule) database.WorkspaceModule {
670+
module, err := db.InsertWorkspaceModule(genCtx, database.InsertWorkspaceModuleParams{
671+
ID: takeFirst(orig.ID, uuid.New()),
672+
JobID: takeFirst(orig.JobID, uuid.New()),
673+
Transition: takeFirst(orig.Transition, database.WorkspaceTransitionStart),
674+
Source: takeFirst(orig.Source, "test-source"),
675+
Version: takeFirst(orig.Version, "v1.0.0"),
676+
Key: takeFirst(orig.Key, "test-key"),
677+
CreatedAt: takeFirst(orig.CreatedAt, dbtime.Now()),
678+
})
679+
require.NoError(t, err, "insert workspace module")
680+
return module
681+
}
682+
665683
func WorkspaceResourceMetadatums(t testing.TB, db database.Store, seed database.WorkspaceResourceMetadatum) []database.WorkspaceResourceMetadatum {
666684
meta, err := db.InsertWorkspaceResourceMetadata(genCtx, database.InsertWorkspaceResourceMetadataParams{
667685
WorkspaceResourceID: takeFirst(seed.WorkspaceResourceID, uuid.New()),

coderd/database/dbmem/dbmem.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ func New() database.Store {
7373
workspaceAgents: make([]database.WorkspaceAgent, 0),
7474
provisionerJobLogs: make([]database.ProvisionerJobLog, 0),
7575
workspaceResources: make([]database.WorkspaceResource, 0),
76+
workspaceModules: make([]database.WorkspaceModule, 0),
7677
workspaceResourceMetadata: make([]database.WorkspaceResourceMetadatum, 0),
7778
provisionerJobs: make([]database.ProvisionerJob, 0),
7879
templateVersions: make([]database.TemplateVersionTable, 0),
@@ -232,6 +233,7 @@ type data struct {
232233
workspaceBuildParameters []database.WorkspaceBuildParameter
233234
workspaceResourceMetadata []database.WorkspaceResourceMetadatum
234235
workspaceResources []database.WorkspaceResource
236+
workspaceModules []database.WorkspaceModule
235237
workspaces []database.WorkspaceTable
236238
workspaceProxies []database.WorkspaceProxy
237239
customRoles []database.CustomRole
@@ -6671,6 +6673,32 @@ func (q *FakeQuerier) GetWorkspaceByWorkspaceAppID(_ context.Context, workspaceA
66716673
return database.Workspace{}, sql.ErrNoRows
66726674
}
66736675

6676+
func (q *FakeQuerier) GetWorkspaceModulesByJobID(_ context.Context, jobID uuid.UUID) ([]database.WorkspaceModule, error) {
6677+
q.mutex.RLock()
6678+
defer q.mutex.RUnlock()
6679+
6680+
modules := make([]database.WorkspaceModule, 0)
6681+
for _, module := range q.workspaceModules {
6682+
if module.JobID == jobID {
6683+
modules = append(modules, module)
6684+
}
6685+
}
6686+
return modules, nil
6687+
}
6688+
6689+
func (q *FakeQuerier) GetWorkspaceModulesCreatedAfter(_ context.Context, createdAt time.Time) ([]database.WorkspaceModule, error) {
6690+
q.mutex.RLock()
6691+
defer q.mutex.RUnlock()
6692+
6693+
modules := make([]database.WorkspaceModule, 0)
6694+
for _, module := range q.workspaceModules {
6695+
if module.CreatedAt.After(createdAt) {
6696+
modules = append(modules, module)
6697+
}
6698+
}
6699+
return modules, nil
6700+
}
6701+
66746702
func (q *FakeQuerier) GetWorkspaceProxies(_ context.Context) ([]database.WorkspaceProxy, error) {
66756703
q.mutex.RLock()
66766704
defer q.mutex.RUnlock()
@@ -8233,6 +8261,20 @@ func (q *FakeQuerier) InsertWorkspaceBuildParameters(_ context.Context, arg data
82338261
return nil
82348262
}
82358263

8264+
func (q *FakeQuerier) InsertWorkspaceModule(_ context.Context, arg database.InsertWorkspaceModuleParams) (database.WorkspaceModule, error) {
8265+
err := validateDatabaseType(arg)
8266+
if err != nil {
8267+
return database.WorkspaceModule{}, err
8268+
}
8269+
8270+
q.mutex.Lock()
8271+
defer q.mutex.Unlock()
8272+
8273+
workspaceModule := database.WorkspaceModule(arg)
8274+
q.workspaceModules = append(q.workspaceModules, workspaceModule)
8275+
return workspaceModule, nil
8276+
}
8277+
82368278
func (q *FakeQuerier) InsertWorkspaceProxy(_ context.Context, arg database.InsertWorkspaceProxyParams) (database.WorkspaceProxy, error) {
82378279
q.mutex.Lock()
82388280
defer q.mutex.Unlock()
@@ -8283,6 +8325,7 @@ func (q *FakeQuerier) InsertWorkspaceResource(_ context.Context, arg database.In
82838325
Hide: arg.Hide,
82848326
Icon: arg.Icon,
82858327
DailyCost: arg.DailyCost,
8328+
ModulePath: arg.ModulePath,
82868329
}
82878330
q.workspaceResources = append(q.workspaceResources, resource)
82888331
return resource, nil

coderd/database/dbmetrics/querymetrics.go

Lines changed: 21 additions & 0 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: 45 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/dump.sql

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

coderd/database/foreign_key_constraint.go

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
DROP TABLE workspace_modules;
2+
3+
ALTER TABLE
4+
workspace_resources
5+
DROP COLUMN module_path;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
ALTER TABLE
2+
workspace_resources
3+
ADD
4+
COLUMN module_path TEXT;
5+
6+
CREATE TABLE workspace_modules (
7+
id uuid NOT NULL,
8+
job_id uuid NOT NULL REFERENCES provisioner_jobs (id) ON DELETE CASCADE,
9+
transition workspace_transition NOT NULL,
10+
source TEXT NOT NULL,
11+
version TEXT NOT NULL,
12+
key TEXT NOT NULL,
13+
created_at timestamp with time zone NOT NULL
14+
);
15+
16+
CREATE INDEX workspace_modules_created_at_idx ON workspace_modules (created_at);

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