Skip to content

chore: mark workspace apps and workspace agents as unaudited #18761

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: ethan/docs-add-connection-logs
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions coderd/audit/diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,7 @@ type Auditable interface {
database.NotificationTemplate |
idpsync.OrganizationSyncSettings |
idpsync.GroupSyncSettings |
idpsync.RoleSyncSettings |
database.WorkspaceAgent |
database.WorkspaceApp
idpsync.RoleSyncSettings
}

// Map is a map of changed fields in an audited resource. It maps field names to
Expand Down
16 changes: 0 additions & 16 deletions coderd/audit/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,6 @@ func ResourceTarget[T Auditable](tgt T) string {
return "Organization Group Sync"
case idpsync.RoleSyncSettings:
return "Organization Role Sync"
case database.WorkspaceAgent:
return typed.Name
case database.WorkspaceApp:
return typed.Slug
default:
panic(fmt.Sprintf("unknown resource %T for ResourceTarget", tgt))
}
Expand Down Expand Up @@ -192,10 +188,6 @@ func ResourceID[T Auditable](tgt T) uuid.UUID {
return noID // Org field on audit log has org id
case idpsync.RoleSyncSettings:
return noID // Org field on audit log has org id
case database.WorkspaceAgent:
return typed.ID
case database.WorkspaceApp:
return typed.ID
default:
panic(fmt.Sprintf("unknown resource %T for ResourceID", tgt))
}
Expand Down Expand Up @@ -247,10 +239,6 @@ func ResourceType[T Auditable](tgt T) database.ResourceType {
return database.ResourceTypeIdpSyncSettingsRole
case idpsync.GroupSyncSettings:
return database.ResourceTypeIdpSyncSettingsGroup
case database.WorkspaceAgent:
return database.ResourceTypeWorkspaceAgent
case database.WorkspaceApp:
return database.ResourceTypeWorkspaceApp
default:
panic(fmt.Sprintf("unknown resource %T for ResourceType", typed))
}
Expand Down Expand Up @@ -304,10 +292,6 @@ func ResourceRequiresOrgID[T Auditable]() bool {
return true
case idpsync.RoleSyncSettings:
return true
case database.WorkspaceAgent:
return true
case database.WorkspaceApp:
return true
default:
panic(fmt.Sprintf("unknown resource %T for ResourceRequiresOrgID", tgt))
}
Expand Down
110 changes: 110 additions & 0 deletions coderd/audit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/coder/coder/v2/coderd/audit"
"github.com/coder/coder/v2/coderd/coderdtest"
"github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbgen"
"github.com/coder/coder/v2/coderd/rbac"
"github.com/coder/coder/v2/codersdk"
"github.com/coder/coder/v2/provisioner/echo"
Expand Down Expand Up @@ -531,3 +532,112 @@ func completeWithAgentAndApp() *echo.Responses {
},
}
}

// TestDeprecatedConnEvents tests the deprecated connection and disconnection
// events in the audit logs. These events are no longer created, but need to be
// returned by the API.
func TestDeprecatedConnEvents(t *testing.T) {
t.Parallel()
var (
ctx = context.Background()
client, _, api = coderdtest.NewWithAPI(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
user = coderdtest.CreateFirstUser(t, client)
version = coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, completeWithAgentAndApp())
template = coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
)

coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
workspace := coderdtest.CreateWorkspace(t, client, template.ID)
workspace.LatestBuild = coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, workspace.LatestBuild.ID)

type additionalFields struct {
audit.AdditionalFields
ConnectionType string `json:"connection_type"`
}

sshFields := additionalFields{
AdditionalFields: audit.AdditionalFields{
WorkspaceName: workspace.Name,
BuildNumber: "999",
BuildReason: "initiator",
WorkspaceOwner: workspace.OwnerName,
WorkspaceID: workspace.ID,
},
ConnectionType: "SSH",
}

sshFieldsBytes, err := json.Marshal(sshFields)
require.NoError(t, err)

appFields := audit.AdditionalFields{
WorkspaceName: workspace.Name,
// Deliberately empty
BuildNumber: "",
BuildReason: "",
WorkspaceOwner: workspace.OwnerName,
WorkspaceID: workspace.ID,
}

appFieldsBytes, err := json.Marshal(appFields)
require.NoError(t, err)

dbgen.AuditLog(t, api.Database, database.AuditLog{
OrganizationID: user.OrganizationID,
Action: database.AuditActionConnect,
ResourceType: database.ResourceTypeWorkspaceAgent,
ResourceID: workspace.LatestBuild.Resources[0].Agents[0].ID,
ResourceTarget: workspace.LatestBuild.Resources[0].Agents[0].Name,
Time: time.Date(2022, 8, 15, 14, 30, 45, 100, time.UTC), // 2022-8-15 14:30:45
AdditionalFields: sshFieldsBytes,
})

dbgen.AuditLog(t, api.Database, database.AuditLog{
OrganizationID: user.OrganizationID,
Action: database.AuditActionDisconnect,
ResourceType: database.ResourceTypeWorkspaceAgent,
ResourceID: workspace.LatestBuild.Resources[0].Agents[0].ID,
ResourceTarget: workspace.LatestBuild.Resources[0].Agents[0].Name,
Time: time.Date(2022, 8, 15, 14, 35, 0o0, 100, time.UTC), // 2022-8-15 14:35:00
AdditionalFields: sshFieldsBytes,
})

dbgen.AuditLog(t, api.Database, database.AuditLog{
OrganizationID: user.OrganizationID,
UserID: user.UserID,
Action: database.AuditActionOpen,
ResourceType: database.ResourceTypeWorkspaceApp,
ResourceID: workspace.LatestBuild.Resources[0].Agents[0].Apps[0].ID,
ResourceTarget: workspace.LatestBuild.Resources[0].Agents[0].Apps[0].Slug,
Time: time.Date(2022, 8, 15, 14, 30, 45, 100, time.UTC), // 2022-8-15 14:30:45
AdditionalFields: appFieldsBytes,
})

connLog, err := client.AuditLogs(ctx, codersdk.AuditLogsRequest{
SearchQuery: "action:connect",
})
require.NoError(t, err)
require.Len(t, connLog.AuditLogs, 1)
var sshOutFields additionalFields
err = json.Unmarshal(connLog.AuditLogs[0].AdditionalFields, &sshOutFields)
require.NoError(t, err)
require.Equal(t, sshFields, sshOutFields)

dcLog, err := client.AuditLogs(ctx, codersdk.AuditLogsRequest{
SearchQuery: "action:disconnect",
})
require.NoError(t, err)
require.Len(t, dcLog.AuditLogs, 1)
err = json.Unmarshal(dcLog.AuditLogs[0].AdditionalFields, &sshOutFields)
require.NoError(t, err)
require.Equal(t, sshFields, sshOutFields)

openLog, err := client.AuditLogs(ctx, codersdk.AuditLogsRequest{
SearchQuery: "action:open",
})
require.NoError(t, err)
require.Len(t, openLog.AuditLogs, 1)
var appOutFields audit.AdditionalFields
err = json.Unmarshal(openLog.AuditLogs[0].AdditionalFields, &appOutFields)
require.NoError(t, err)
require.Equal(t, appFields, appOutFields)
}
2 changes: 1 addition & 1 deletion coderd/database/dbgen/dbgen.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func AuditLog(t testing.TB, db database.Store, seed database.AuditLog) database.
Action: takeFirst(seed.Action, database.AuditActionCreate),
Diff: takeFirstSlice(seed.Diff, []byte("{}")),
StatusCode: takeFirst(seed.StatusCode, 200),
AdditionalFields: takeFirstSlice(seed.Diff, []byte("{}")),
AdditionalFields: takeFirstSlice(seed.AdditionalFields, []byte("{}")),
RequestID: takeFirst(seed.RequestID, uuid.New()),
ResourceIcon: takeFirst(seed.ResourceIcon, ""),
})
Expand Down
Loading
Loading