@@ -11,6 +11,8 @@ import (
11
11
12
12
"github.com/google/uuid"
13
13
"github.com/sqlc-dev/pqtype"
14
+ "go.opentelemetry.io/otel/baggage"
15
+ "golang.org/x/xerrors"
14
16
15
17
"cdr.dev/slog"
16
18
"github.com/coder/coder/v2/coderd/database"
@@ -54,6 +56,7 @@ type BuildAuditParams[T Auditable] struct {
54
56
Status int
55
57
Action database.AuditAction
56
58
OrganizationID uuid.UUID
59
+ IP string
57
60
AdditionalFields json.RawMessage
58
61
59
62
New T
@@ -248,9 +251,7 @@ func InitRequest[T Auditable](w http.ResponseWriter, p *RequestParams) (*Request
248
251
// WorkspaceBuildAudit creates an audit log for a workspace build.
249
252
// The audit log is committed upon invocation.
250
253
func WorkspaceBuildAudit [T Auditable ](ctx context.Context , p * BuildAuditParams [T ]) {
251
- // As the audit request has not been initiated directly by a user, we omit
252
- // certain user details.
253
- ip := parseIP ("" )
254
+ ip := parseIP (p .IP )
254
255
255
256
diff := Diff (p .Audit , p .Old , p .New )
256
257
var err error
@@ -280,16 +281,70 @@ func WorkspaceBuildAudit[T Auditable](ctx context.Context, p *BuildAuditParams[T
280
281
RequestID : p .JobID ,
281
282
AdditionalFields : p .AdditionalFields ,
282
283
}
283
- exportErr : = p .Audit .Export (ctx , auditLog )
284
- if exportErr != nil {
284
+ err = p .Audit .Export (ctx , auditLog )
285
+ if err != nil {
285
286
p .Log .Error (ctx , "export audit log" ,
286
287
slog .F ("audit_log" , auditLog ),
287
288
slog .Error (err ),
288
289
)
289
- return
290
290
}
291
291
}
292
292
293
+ type WorkspaceBuildBaggage struct {
294
+ IP string
295
+ }
296
+
297
+ func (b WorkspaceBuildBaggage ) Props () ([]baggage.Property , error ) {
298
+ ipProp , err := baggage .NewKeyValueProperty ("ip" , b .IP )
299
+ if err != nil {
300
+ return nil , xerrors .Errorf ("create ip kv property: %w" , err )
301
+ }
302
+
303
+ return []baggage.Property {ipProp }, nil
304
+ }
305
+
306
+ func WorkspaceBuildBaggageFromRequest (r * http.Request ) WorkspaceBuildBaggage {
307
+ return WorkspaceBuildBaggage {IP : r .RemoteAddr }
308
+ }
309
+
310
+ type Baggage interface {
311
+ Props () ([]baggage.Property , error )
312
+ }
313
+
314
+ func BaggageToContext (ctx context.Context , d Baggage ) (context.Context , error ) {
315
+ props , err := d .Props ()
316
+ if err != nil {
317
+ return ctx , xerrors .Errorf ("create baggage properties: %w" , err )
318
+ }
319
+
320
+ m , err := baggage .NewMember ("audit" , "baggage" , props ... )
321
+ if err != nil {
322
+ return ctx , xerrors .Errorf ("create new baggage member: %w" , err )
323
+ }
324
+
325
+ b , err := baggage .New (m )
326
+ if err != nil {
327
+ return ctx , xerrors .Errorf ("create new baggage carrier: %w" , err )
328
+ }
329
+
330
+ return baggage .ContextWithBaggage (ctx , b ), nil
331
+ }
332
+
333
+ func BaggageFromContext (ctx context.Context ) WorkspaceBuildBaggage {
334
+ d := WorkspaceBuildBaggage {}
335
+ b := baggage .FromContext (ctx )
336
+ props := b .Member ("audit" ).Properties ()
337
+ for _ , prop := range props {
338
+ switch prop .Key () {
339
+ case "ip" :
340
+ d .IP , _ = prop .Value ()
341
+ default :
342
+ }
343
+ }
344
+
345
+ return d
346
+ }
347
+
293
348
func either [T Auditable , R any ](old , new T , fn func (T ) R , auditAction database.AuditAction ) R {
294
349
if ResourceID (new ) != uuid .Nil {
295
350
return fn (new )
0 commit comments