Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 18a8f7e

Browse files
committed
feat: add workspace agent connect and app open audit types
Updates #15139
1 parent 6a67e2e commit 18a8f7e

File tree

14 files changed

+248
-16
lines changed

14 files changed

+248
-16
lines changed

coderd/apidoc/docs.go

+12-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/apidoc/swagger.json

+12-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/audit/diff.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ type Auditable interface {
3030
database.NotificationTemplate |
3131
idpsync.OrganizationSyncSettings |
3232
idpsync.GroupSyncSettings |
33-
idpsync.RoleSyncSettings
33+
idpsync.RoleSyncSettings |
34+
database.WorkspaceApp |
35+
database.WorkspaceAgent
3436
}
3537

3638
// Map is a map of changed fields in an audited resource. It maps field names to

coderd/audit/request.go

+12
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,10 @@ func ResourceTarget[T Auditable](tgt T) string {
128128
return "Organization Group Sync"
129129
case idpsync.RoleSyncSettings:
130130
return "Organization Role Sync"
131+
case database.WorkspaceApp:
132+
return typed.Slug
133+
case database.WorkspaceAgent:
134+
return typed.Name
131135
default:
132136
panic(fmt.Sprintf("unknown resource %T for ResourceTarget", tgt))
133137
}
@@ -187,6 +191,10 @@ func ResourceID[T Auditable](tgt T) uuid.UUID {
187191
return noID // Org field on audit log has org id
188192
case idpsync.RoleSyncSettings:
189193
return noID // Org field on audit log has org id
194+
case database.WorkspaceAgent:
195+
return typed.ID
196+
case database.WorkspaceApp:
197+
return typed.ID
190198
default:
191199
panic(fmt.Sprintf("unknown resource %T for ResourceID", tgt))
192200
}
@@ -238,6 +246,10 @@ func ResourceType[T Auditable](tgt T) database.ResourceType {
238246
return database.ResourceTypeIdpSyncSettingsRole
239247
case idpsync.GroupSyncSettings:
240248
return database.ResourceTypeIdpSyncSettingsGroup
249+
case database.WorkspaceAgent:
250+
return database.ResourceTypeWorkspaceAgent
251+
case database.WorkspaceApp:
252+
return database.ResourceTypeWorkspaceApp
241253
default:
242254
panic(fmt.Sprintf("unknown resource %T for ResourceType", typed))
243255
}

coderd/audit_test.go

+98-3
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ import (
1717
"github.com/coder/coder/v2/coderd/database"
1818
"github.com/coder/coder/v2/coderd/rbac"
1919
"github.com/coder/coder/v2/codersdk"
20+
"github.com/coder/coder/v2/provisioner/echo"
21+
"github.com/coder/coder/v2/provisionersdk/proto"
2022
)
2123

2224
func TestAuditLogs(t *testing.T) {
@@ -229,12 +231,13 @@ func TestAuditLogsFilter(t *testing.T) {
229231
ctx = context.Background()
230232
client = coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
231233
user = coderdtest.CreateFirstUser(t, client)
232-
version = coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
234+
version = coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, completeWithAgentAndApp())
233235
template = coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
234236
)
235237

236238
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
237239
workspace := coderdtest.CreateWorkspace(t, client, template.ID)
240+
workspace.LatestBuild = coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, workspace.LatestBuild.ID)
238241

239242
// Create two logs with "Create"
240243
err := client.CreateTestAuditLog(ctx, codersdk.CreateTestAuditLogRequest{
@@ -279,6 +282,28 @@ func TestAuditLogsFilter(t *testing.T) {
279282
})
280283
require.NoError(t, err)
281284

285+
for _, resource := range workspace.LatestBuild.Resources {
286+
t.Logf("Resource: %#v", resource)
287+
}
288+
289+
// Create one log with "Connect"
290+
err = client.CreateTestAuditLog(ctx, codersdk.CreateTestAuditLogRequest{
291+
Action: codersdk.AuditActionConnect,
292+
ResourceType: codersdk.ResourceTypeWorkspaceAgent,
293+
ResourceID: workspace.LatestBuild.Resources[0].Agents[0].ID,
294+
Time: time.Date(2022, 8, 15, 14, 30, 45, 100, time.UTC), // 2022-8-15 14:30:45
295+
})
296+
require.NoError(t, err)
297+
298+
// Create one log with "Open"
299+
err = client.CreateTestAuditLog(ctx, codersdk.CreateTestAuditLogRequest{
300+
Action: codersdk.AuditActionOpen,
301+
ResourceType: codersdk.ResourceTypeWorkspaceApp,
302+
ResourceID: workspace.LatestBuild.Resources[0].Agents[0].Apps[0].ID,
303+
Time: time.Date(2022, 8, 15, 14, 30, 45, 100, time.UTC), // 2022-8-15 14:30:45
304+
})
305+
require.NoError(t, err)
306+
282307
// Test cases
283308
testCases := []struct {
284309
Name string
@@ -309,12 +334,12 @@ func TestAuditLogsFilter(t *testing.T) {
309334
{
310335
Name: "FilterByEmail",
311336
SearchQuery: "email:" + coderdtest.FirstUserParams.Email,
312-
ExpectedResult: 5,
337+
ExpectedResult: 7,
313338
},
314339
{
315340
Name: "FilterByUsername",
316341
SearchQuery: "username:" + coderdtest.FirstUserParams.Username,
317-
ExpectedResult: 5,
342+
ExpectedResult: 7,
318343
},
319344
{
320345
Name: "FilterByResourceID",
@@ -366,6 +391,16 @@ func TestAuditLogsFilter(t *testing.T) {
366391
SearchQuery: "resource_type:workspace_build action:start build_reason:initiator",
367392
ExpectedResult: 1,
368393
},
394+
{
395+
Name: "FilterOnWorkspaceAgentConnect",
396+
SearchQuery: "resource_type:workspace_agent action:connect",
397+
ExpectedResult: 1,
398+
},
399+
{
400+
Name: "FilterOnWorkspaceAppOpen",
401+
SearchQuery: "resource_type:workspace_app action:open",
402+
ExpectedResult: 1,
403+
},
369404
}
370405

371406
for _, testCase := range testCases {
@@ -387,3 +422,63 @@ func TestAuditLogsFilter(t *testing.T) {
387422
}
388423
})
389424
}
425+
426+
func completeWithAgentAndApp() *echo.Responses {
427+
return &echo.Responses{
428+
Parse: echo.ParseComplete,
429+
ProvisionPlan: []*proto.Response{
430+
{
431+
Type: &proto.Response_Plan{
432+
Plan: &proto.PlanComplete{
433+
Resources: []*proto.Resource{
434+
{
435+
Type: "compute",
436+
Name: "main",
437+
Agents: []*proto.Agent{
438+
{
439+
Name: "smith",
440+
OperatingSystem: "linux",
441+
Architecture: "i386",
442+
Apps: []*proto.App{
443+
{
444+
Slug: "app",
445+
DisplayName: "App",
446+
},
447+
},
448+
},
449+
},
450+
},
451+
},
452+
},
453+
},
454+
},
455+
},
456+
ProvisionApply: []*proto.Response{
457+
{
458+
Type: &proto.Response_Apply{
459+
Apply: &proto.ApplyComplete{
460+
Resources: []*proto.Resource{
461+
{
462+
Type: "compute",
463+
Name: "main",
464+
Agents: []*proto.Agent{
465+
{
466+
Name: "smith",
467+
OperatingSystem: "linux",
468+
Architecture: "i386",
469+
Apps: []*proto.App{
470+
{
471+
Slug: "app",
472+
DisplayName: "App",
473+
},
474+
},
475+
},
476+
},
477+
},
478+
},
479+
},
480+
},
481+
},
482+
},
483+
}
484+
}

coderd/database/dump.sql

+6-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
-- No-op, enum values can't be dropped.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
-- Add new audit types for connect and open actions.
2+
ALTER TYPE audit_action
3+
ADD VALUE IF NOT EXISTS 'connect';
4+
ALTER TYPE resource_type
5+
ADD VALUE IF NOT EXISTS 'workspace_agent';
6+
ALTER TYPE audit_action
7+
ADD VALUE IF NOT EXISTS 'open';
8+
ALTER TYPE resource_type
9+
ADD VALUE IF NOT EXISTS 'workspace_app';

coderd/database/models.go

+14-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)