feat(ops-api/audit): annotate audit log IP with region lookup
Add an IPRegionResolver wrapping the ip2region xdb library and attach it to AuditService so each appended event records both the raw IP and a resolved region in a new ops.audit_logs.ip_region column. Loopback and private addresses short-circuit to local labels; missing xdb data or lookup errors degrade silently so auditing keeps working without it. The ops console audit view shows the region beneath the IP. Bundle the v4/v6 xdb data under internal/ops/app/ipregiondata so the resolver works out of the box, with config paths/env overrides for swapping in updated data sets. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -33,15 +33,16 @@ func (r *AuditRepository) Append(ctx context.Context, e domain.AuditEvent) error
|
||||
targetType = nullableString(e.TargetType)
|
||||
targetID = nullableString(e.TargetID)
|
||||
ip = nullableString(e.IP)
|
||||
ipRegion = nullableString(e.IPRegion)
|
||||
ua = nullableString(e.UserAgent)
|
||||
reqID = nullableString(e.RequestID)
|
||||
)
|
||||
|
||||
_, err := r.pool.Exec(ctx, `
|
||||
INSERT INTO ops.audit_logs
|
||||
(operator_id, operator_name, action, target_type, target_id, metadata, ip, user_agent, request_id)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)`,
|
||||
e.OperatorID, operatorName, e.Action, targetType, targetID, metaBytes, ip, ua, reqID)
|
||||
(operator_id, operator_name, action, target_type, target_id, metadata, ip, ip_region, user_agent, request_id)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)`,
|
||||
e.OperatorID, operatorName, e.Action, targetType, targetID, metaBytes, ip, ipRegion, ua, reqID)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -86,7 +87,7 @@ func (r *AuditRepository) List(ctx context.Context, f domain.AuditLogFilter) ([]
|
||||
|
||||
rows, err := r.pool.Query(ctx, fmt.Sprintf(`
|
||||
SELECT id, operator_id, operator_name, action, target_type, target_id,
|
||||
metadata, ip, user_agent, request_id, created_at
|
||||
metadata, ip, ip_region, user_agent, request_id, created_at
|
||||
FROM ops.audit_logs
|
||||
WHERE %s
|
||||
ORDER BY created_at DESC, id DESC
|
||||
@@ -104,8 +105,8 @@ func (r *AuditRepository) List(ctx context.Context, f domain.AuditLogFilter) ([]
|
||||
)
|
||||
if err := rows.Scan(
|
||||
&log.ID, &log.OperatorID, &log.OperatorName, &log.Action,
|
||||
&log.TargetType, &log.TargetID, &metaRaw, &log.IP, &log.UserAgent,
|
||||
&log.RequestID, &log.CreatedAt,
|
||||
&log.TargetType, &log.TargetID, &metaRaw, &log.IP, &log.IPRegion,
|
||||
&log.UserAgent, &log.RequestID, &log.CreatedAt,
|
||||
); err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user