Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit145faf4

Browse files
authored
adding workspace_build resource (#4636)
* adding workspace_build resource* added migration* added migration for audit_actions* fix keyword* got rid oof diffs for workspace builds* adding workspace name to string* renamed migrations* fixed lint* pass throough AdditionalFields and fix tests* no need to pass through each handler* cleaned up migrations
1 parent3e08bb4 commit145faf4

File tree

13 files changed

+126
-31
lines changed

13 files changed

+126
-31
lines changed

‎coderd/audit.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,12 +219,26 @@ func convertAuditLog(dblog database.GetAuditLogsOffsetRow) codersdk.AuditLog {
219219
}
220220
}
221221

222+
typeWorkspaceResourceInfostruct {
223+
WorkspaceNamestring
224+
}
225+
222226
funcauditLogDescription(alog database.GetAuditLogsOffsetRow)string {
223227
str:=fmt.Sprintf("{user} %s %s",
224228
codersdk.AuditAction(alog.Action).FriendlyString(),
225229
codersdk.ResourceType(alog.ResourceType).FriendlyString(),
226230
)
227231

232+
// Strings for build updates follow the below format:
233+
// "{user} started workspace build for workspace {target}"
234+
// where target is a workspace instead of the workspace build
235+
ifalog.ResourceType==database.ResourceTypeWorkspaceBuild {
236+
workspaceBytes:= []byte(alog.AdditionalFields)
237+
varworkspaceResourceInfoWorkspaceResourceInfo
238+
_=json.Unmarshal(workspaceBytes,&workspaceResourceInfo)
239+
str+=" for workspace "+workspaceResourceInfo.WorkspaceName
240+
}
241+
228242
// We don't display the name for git ssh keys. It's fairly long and doesn't
229243
// make too much sense to display.
230244
ifalog.ResourceType!=database.ResourceTypeGitSshKey {
@@ -288,6 +302,8 @@ func resourceTypeFromString(resourceTypeString string) string {
288302
returnresourceTypeString
289303
casecodersdk.ResourceTypeWorkspace:
290304
returnresourceTypeString
305+
casecodersdk.ResourceTypeWorkspaceBuild:
306+
returnresourceTypeString
291307
casecodersdk.ResourceTypeGitSSHKey:
292308
returnresourceTypeString
293309
casecodersdk.ResourceTypeAPIKey:

‎coderd/audit/diff.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ type Auditable interface {
1515
database.TemplateVersion|
1616
database.User|
1717
database.Workspace|
18+
database.WorkspaceBuild|
1819
database.GitSSHKey|
1920
database.Group
2021
}

‎coderd/audit/request.go

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,9 @@ type RequestParams struct {
2020
AuditAuditor
2121
Log slog.Logger
2222

23-
Request*http.Request
24-
Action database.AuditAction
23+
Request*http.Request
24+
Action database.AuditAction
25+
AdditionalFields json.RawMessage
2526
}
2627

2728
typeRequest[TAuditable]struct {
@@ -43,6 +44,9 @@ func ResourceTarget[T Auditable](tgt T) string {
4344
returntyped.Username
4445
case database.Workspace:
4546
returntyped.Name
47+
case database.WorkspaceBuild:
48+
// this isn't used
49+
returnstring(typed.BuildNumber)
4650
case database.GitSSHKey:
4751
returntyped.PublicKey
4852
case database.Group:
@@ -64,6 +68,8 @@ func ResourceID[T Auditable](tgt T) uuid.UUID {
6468
returntyped.ID
6569
case database.Workspace:
6670
returntyped.ID
71+
case database.WorkspaceBuild:
72+
returntyped.ID
6773
case database.GitSSHKey:
6874
returntyped.UserID
6975
case database.Group:
@@ -85,6 +91,8 @@ func ResourceType[T Auditable](tgt T) database.ResourceType {
8591
returndatabase.ResourceTypeUser
8692
case database.Workspace:
8793
returndatabase.ResourceTypeWorkspace
94+
case database.WorkspaceBuild:
95+
returndatabase.ResourceTypeWorkspaceBuild
8896
case database.GitSSHKey:
8997
returndatabase.ResourceTypeGitSshKey
9098
case database.Group:
@@ -129,6 +137,10 @@ func InitRequest[T Auditable](w http.ResponseWriter, p *RequestParams) (*Request
129137
}
130138
}
131139

140+
ifp.AdditionalFields==nil {
141+
p.AdditionalFields=json.RawMessage("{}")
142+
}
143+
132144
ip:=parseIP(p.Request.RemoteAddr)
133145
err:=p.Audit.Export(ctx, database.AuditLog{
134146
ID:uuid.New(),
@@ -143,7 +155,7 @@ func InitRequest[T Auditable](w http.ResponseWriter, p *RequestParams) (*Request
143155
Diff:diffRaw,
144156
StatusCode:int32(sw.Status),
145157
RequestID:httpmw.RequestID(p.Request),
146-
AdditionalFields:json.RawMessage("{}"),
158+
AdditionalFields:p.AdditionalFields,
147159
})
148160
iferr!=nil {
149161
p.Log.Error(logCtx,"export audit log",slog.Error(err))

‎coderd/database/dump.sql

Lines changed: 5 additions & 2 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
-- It's not possible to drop enum values from enum types, so the UP has "IF NOT
2+
-- EXISTS".
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
ALTERTYPE audit_action ADD VALUE IF NOT EXISTS'start';
2+
ALTERTYPE audit_action ADD VALUE IF NOT EXISTS'stop';
3+
4+
ALTERTYPE resource_type ADD VALUE IF NOT EXISTS'workspace_build';

‎coderd/database/models.go

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/workspacebuilds.go

Lines changed: 44 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -278,28 +278,59 @@ func (api *API) postWorkspaceBuilds(rw http.ResponseWriter, r *http.Request) {
278278
return
279279
}
280280

281-
// we only want to create audit logs for delete builds right now
281+
auditor:=api.Auditor.Load()
282+
283+
// if user deletes a workspace, audit the workspace
282284
ifaction==rbac.ActionDelete {
283-
var (
284-
auditor=api.Auditor.Load()
285-
aReq,commitAudit=audit.InitRequest[database.Workspace](rw,&audit.RequestParams{
286-
Audit:*auditor,
287-
Log:api.Logger,
288-
Request:r,
289-
Action:database.AuditActionDelete,
290-
})
291-
)
285+
aReq,commitAudit:=audit.InitRequest[database.Workspace](rw,&audit.RequestParams{
286+
Audit:*auditor,
287+
Log:api.Logger,
288+
Request:r,
289+
Action:database.AuditActionDelete,
290+
})
292291

293292
defercommitAudit()
294293
aReq.Old=workspace
295294
}
296295

296+
latestBuild,latestBuildErr:=api.Database.GetLatestWorkspaceBuildByWorkspaceID(ctx,workspace.ID)
297+
298+
// if a user starts/stops a workspace, audit the workspace build
299+
ifaction==rbac.ActionUpdate {
300+
varauditAction database.AuditAction
301+
ifcreateBuild.Transition==codersdk.WorkspaceTransitionStart {
302+
auditAction=database.AuditActionStart
303+
}elseifcreateBuild.Transition==codersdk.WorkspaceTransitionStop {
304+
auditAction=database.AuditActionStop
305+
}else {
306+
auditAction=database.AuditActionWrite
307+
}
308+
309+
// We pass the workspace name to the Auditor so that it
310+
// can form a friendly string for the user.
311+
workspaceResourceInfo:=map[string]string{
312+
"workspaceName":workspace.Name,
313+
}
314+
315+
wriBytes,_:=json.Marshal(workspaceResourceInfo)
316+
317+
aReq,commitAudit:=audit.InitRequest[database.WorkspaceBuild](rw,&audit.RequestParams{
318+
Audit:*auditor,
319+
Log:api.Logger,
320+
Request:r,
321+
Action:auditAction,
322+
AdditionalFields:wriBytes,
323+
})
324+
325+
defercommitAudit()
326+
aReq.Old=latestBuild
327+
}
328+
297329
ifcreateBuild.TemplateVersionID==uuid.Nil {
298-
latestBuild,err:=api.Database.GetLatestWorkspaceBuildByWorkspaceID(ctx,workspace.ID)
299-
iferr!=nil {
330+
iflatestBuildErr!=nil {
300331
httpapi.Write(ctx,rw,http.StatusInternalServerError, codersdk.Response{
301332
Message:"Internal error fetching the latest workspace build.",
302-
Detail:err.Error(),
333+
Detail:latestBuildErr.Error(),
303334
})
304335
return
305336
}

‎coderd/workspacebuilds_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,6 @@ func TestWorkspaceBuildStatus(t *testing.T) {
579579
require.EqualValues(t,codersdk.WorkspaceStatusDeleted,workspace.LatestBuild.Status)
580580

581581
// assert an audit log has been created for deletion
582-
require.Len(t,auditor.AuditLogs,5)
583-
assert.Equal(t,database.AuditActionDelete,auditor.AuditLogs[4].Action)
582+
require.Len(t,auditor.AuditLogs,7)
583+
assert.Equal(t,database.AuditActionDelete,auditor.AuditLogs[6].Action)
584584
}

‎codersdk/audit.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ const (
1919
ResourceTypeTemplateVersionResourceType="template_version"
2020
ResourceTypeUserResourceType="user"
2121
ResourceTypeWorkspaceResourceType="workspace"
22+
ResourceTypeWorkspaceBuildResourceType="workspace_build"
2223
ResourceTypeGitSSHKeyResourceType="git_ssh_key"
2324
ResourceTypeAPIKeyResourceType="api_key"
2425
ResourceTypeGroupResourceType="group"
@@ -36,6 +37,8 @@ func (r ResourceType) FriendlyString() string {
3637
return"user"
3738
caseResourceTypeWorkspace:
3839
return"workspace"
40+
caseResourceTypeWorkspaceBuild:
41+
return"workspace build"
3942
caseResourceTypeGitSSHKey:
4043
return"git ssh key"
4144
caseResourceTypeAPIKey:
@@ -53,6 +56,8 @@ const (
5356
AuditActionCreateAuditAction="create"
5457
AuditActionWriteAuditAction="write"
5558
AuditActionDeleteAuditAction="delete"
59+
AuditActionStartAuditAction="start"
60+
AuditActionStopAuditAction="stop"
5661
)
5762

5863
func (aAuditAction)FriendlyString()string {
@@ -63,6 +68,10 @@ func (a AuditAction) FriendlyString() string {
6368
return"updated"
6469
caseAuditActionDelete:
6570
return"deleted"
71+
caseAuditActionStart:
72+
return"started"
73+
caseAuditActionStop:
74+
return"stopped"
6675
default:
6776
return"unknown"
6877
}

‎enterprise/audit/table.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,21 @@ var AuditableResources = auditMap(map[any]map[string]Action{
103103
"ttl":ActionTrack,
104104
"last_used_at":ActionIgnore,
105105
},
106+
// We don't show any diff for the WorkspaceBuild resource
107+
&database.WorkspaceBuild{}: {
108+
"id":ActionIgnore,
109+
"created_at":ActionIgnore,
110+
"updated_at":ActionIgnore,
111+
"workspace_id":ActionIgnore,
112+
"template_version_id":ActionIgnore,
113+
"build_number":ActionIgnore,
114+
"transition":ActionIgnore,
115+
"initiator_id":ActionIgnore,
116+
"provisioner_state":ActionIgnore,
117+
"job_id":ActionIgnore,
118+
"deadline":ActionIgnore,
119+
"reason":ActionIgnore,
120+
},
106121
&database.Group{}: {
107122
"id":ActionTrack,
108123
"name":ActionTrack,

‎site/src/api/typesGenerated.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -915,7 +915,7 @@ export interface WorkspacesRequest extends Pagination {
915915
exporttypeAPIKeyScope="all"|"application_connect"
916916

917917
// From codersdk/audit.go
918-
exporttypeAuditAction="create"|"delete"|"write"
918+
exporttypeAuditAction="create"|"delete"|"start"|"stop"|"write"
919919

920920
// From codersdk/workspacebuilds.go
921921
exporttypeBuildReason="autostart"|"autostop"|"initiator"
@@ -975,6 +975,7 @@ export type ResourceType =
975975
|"template_version"
976976
|"user"
977977
|"workspace"
978+
|"workspace_build"
978979

979980
// From codersdk/sse.go
980981
exporttypeServerSentEventType="data"|"error"|"ping"

‎site/src/components/AuditLogRow/AuditLogRow.tsx

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -130,13 +130,11 @@ export const AuditLogRow: React.FC<AuditLogRowProps> = ({
130130
</Stack>
131131
</Stack>
132132

133-
<div
134-
className={
135-
shouldDisplayDiff ?undefined :styles.disabledDropdownIcon
136-
}
137-
>
138-
{isDiffOpen ?<CloseDropdown/> :<OpenDropdown/>}
139-
</div>
133+
{shouldDisplayDiff ?(
134+
<div>{isDiffOpen ?<CloseDropdown/> :<OpenDropdown/>}</div>
135+
) :(
136+
<divclassName={styles.columnWithoutDiff}></div>
137+
)}
140138
</Stack>
141139

142140
{shouldDisplayDiff&&(
@@ -190,8 +188,8 @@ const useStyles = makeStyles((theme) => ({
190188
color:theme.palette.text.secondary,
191189
whiteSpace:"nowrap",
192190
},
193-
194-
disabledDropdownIcon:{
195-
opacity:0.5,
191+
// offset the absence of the arrow icon on diff-less logs
192+
columnWithoutDiff:{
193+
marginLeft:"24px",
196194
},
197195
}))

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp