mirror of
https://github.com/coder/coder.git
synced 2025-07-18 14:17:22 +00:00
chore: mark workspace apps and workspace agents as unaudited (#18761)
The main goal of this PR is to remove Workspace Apps and Workspace Agents from the auto-generated audit log documentation, that incorrectly claims they are audited resources (no longer true with the addition of the connection log). Though I believe we haven't touched any codepaths for returning audit logs, this PR also adds a test that ensures we continue to return *existing* connection, disconnect and open events correctly from the audit log API.
This commit is contained in:
@ -31,9 +31,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
|
||||
|
@ -131,10 +131,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))
|
||||
}
|
||||
@ -197,10 +193,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))
|
||||
}
|
||||
@ -254,10 +246,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))
|
||||
}
|
||||
@ -314,10 +302,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))
|
||||
}
|
||||
|
@ -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"
|
||||
@ -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)
|
||||
}
|
||||
|
@ -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, ""),
|
||||
})
|
||||
|
@ -30,8 +30,6 @@ We track the following resources:
|
||||
| Template<br><i>write, delete</i> | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>active_version_id</td><td>true</td></tr><tr><td>activity_bump</td><td>true</td></tr><tr><td>allow_user_autostart</td><td>true</td></tr><tr><td>allow_user_autostop</td><td>true</td></tr><tr><td>allow_user_cancel_workspace_jobs</td><td>true</td></tr><tr><td>autostart_block_days_of_week</td><td>true</td></tr><tr><td>autostop_requirement_days_of_week</td><td>true</td></tr><tr><td>autostop_requirement_weeks</td><td>true</td></tr><tr><td>created_at</td><td>false</td></tr><tr><td>created_by</td><td>true</td></tr><tr><td>created_by_avatar_url</td><td>false</td></tr><tr><td>created_by_name</td><td>false</td></tr><tr><td>created_by_username</td><td>false</td></tr><tr><td>default_ttl</td><td>true</td></tr><tr><td>deleted</td><td>false</td></tr><tr><td>deprecated</td><td>true</td></tr><tr><td>description</td><td>true</td></tr><tr><td>display_name</td><td>true</td></tr><tr><td>failure_ttl</td><td>true</td></tr><tr><td>group_acl</td><td>true</td></tr><tr><td>icon</td><td>true</td></tr><tr><td>id</td><td>true</td></tr><tr><td>max_port_sharing_level</td><td>true</td></tr><tr><td>name</td><td>true</td></tr><tr><td>organization_display_name</td><td>false</td></tr><tr><td>organization_icon</td><td>false</td></tr><tr><td>organization_id</td><td>false</td></tr><tr><td>organization_name</td><td>false</td></tr><tr><td>provisioner</td><td>true</td></tr><tr><td>require_active_version</td><td>true</td></tr><tr><td>time_til_dormant</td><td>true</td></tr><tr><td>time_til_dormant_autodelete</td><td>true</td></tr><tr><td>updated_at</td><td>false</td></tr><tr><td>use_classic_parameter_flow</td><td>true</td></tr><tr><td>user_acl</td><td>true</td></tr></tbody></table> |
|
||||
| TemplateVersion<br><i>create, write</i> | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>archived</td><td>true</td></tr><tr><td>created_at</td><td>false</td></tr><tr><td>created_by</td><td>true</td></tr><tr><td>created_by_avatar_url</td><td>false</td></tr><tr><td>created_by_name</td><td>false</td></tr><tr><td>created_by_username</td><td>false</td></tr><tr><td>external_auth_providers</td><td>false</td></tr><tr><td>has_ai_task</td><td>false</td></tr><tr><td>id</td><td>true</td></tr><tr><td>job_id</td><td>false</td></tr><tr><td>message</td><td>false</td></tr><tr><td>name</td><td>true</td></tr><tr><td>organization_id</td><td>false</td></tr><tr><td>readme</td><td>true</td></tr><tr><td>source_example_id</td><td>false</td></tr><tr><td>template_id</td><td>true</td></tr><tr><td>updated_at</td><td>false</td></tr></tbody></table> |
|
||||
| User<br><i>create, write, delete</i> | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>avatar_url</td><td>false</td></tr><tr><td>created_at</td><td>false</td></tr><tr><td>deleted</td><td>true</td></tr><tr><td>email</td><td>true</td></tr><tr><td>github_com_user_id</td><td>false</td></tr><tr><td>hashed_one_time_passcode</td><td>false</td></tr><tr><td>hashed_password</td><td>true</td></tr><tr><td>id</td><td>true</td></tr><tr><td>is_system</td><td>true</td></tr><tr><td>last_seen_at</td><td>false</td></tr><tr><td>login_type</td><td>true</td></tr><tr><td>name</td><td>true</td></tr><tr><td>one_time_passcode_expires_at</td><td>true</td></tr><tr><td>quiet_hours_schedule</td><td>true</td></tr><tr><td>rbac_roles</td><td>true</td></tr><tr><td>status</td><td>true</td></tr><tr><td>updated_at</td><td>false</td></tr><tr><td>username</td><td>true</td></tr></tbody></table> |
|
||||
| WorkspaceAgent<br><i>connect, disconnect</i> | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>api_key_scope</td><td>false</td></tr><tr><td>api_version</td><td>false</td></tr><tr><td>architecture</td><td>false</td></tr><tr><td>auth_instance_id</td><td>false</td></tr><tr><td>auth_token</td><td>false</td></tr><tr><td>connection_timeout_seconds</td><td>false</td></tr><tr><td>created_at</td><td>false</td></tr><tr><td>deleted</td><td>false</td></tr><tr><td>directory</td><td>false</td></tr><tr><td>disconnected_at</td><td>false</td></tr><tr><td>display_apps</td><td>false</td></tr><tr><td>display_order</td><td>false</td></tr><tr><td>environment_variables</td><td>false</td></tr><tr><td>expanded_directory</td><td>false</td></tr><tr><td>first_connected_at</td><td>false</td></tr><tr><td>id</td><td>false</td></tr><tr><td>instance_metadata</td><td>false</td></tr><tr><td>last_connected_at</td><td>false</td></tr><tr><td>last_connected_replica_id</td><td>false</td></tr><tr><td>lifecycle_state</td><td>false</td></tr><tr><td>logs_length</td><td>false</td></tr><tr><td>logs_overflowed</td><td>false</td></tr><tr><td>motd_file</td><td>false</td></tr><tr><td>name</td><td>false</td></tr><tr><td>operating_system</td><td>false</td></tr><tr><td>parent_id</td><td>false</td></tr><tr><td>ready_at</td><td>false</td></tr><tr><td>resource_id</td><td>false</td></tr><tr><td>resource_metadata</td><td>false</td></tr><tr><td>started_at</td><td>false</td></tr><tr><td>subsystems</td><td>false</td></tr><tr><td>troubleshooting_url</td><td>false</td></tr><tr><td>updated_at</td><td>false</td></tr><tr><td>version</td><td>false</td></tr></tbody></table> |
|
||||
| WorkspaceApp<br><i>open, close</i> | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>agent_id</td><td>false</td></tr><tr><td>command</td><td>false</td></tr><tr><td>created_at</td><td>false</td></tr><tr><td>display_group</td><td>false</td></tr><tr><td>display_name</td><td>false</td></tr><tr><td>display_order</td><td>false</td></tr><tr><td>external</td><td>false</td></tr><tr><td>health</td><td>false</td></tr><tr><td>healthcheck_interval</td><td>false</td></tr><tr><td>healthcheck_threshold</td><td>false</td></tr><tr><td>healthcheck_url</td><td>false</td></tr><tr><td>hidden</td><td>false</td></tr><tr><td>icon</td><td>false</td></tr><tr><td>id</td><td>false</td></tr><tr><td>open_in</td><td>false</td></tr><tr><td>sharing_level</td><td>false</td></tr><tr><td>slug</td><td>false</td></tr><tr><td>subdomain</td><td>false</td></tr><tr><td>url</td><td>false</td></tr></tbody></table> |
|
||||
| WorkspaceBuild<br><i>start, stop</i> | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>ai_task_sidebar_app_id</td><td>false</td></tr><tr><td>build_number</td><td>false</td></tr><tr><td>created_at</td><td>false</td></tr><tr><td>daily_cost</td><td>false</td></tr><tr><td>deadline</td><td>false</td></tr><tr><td>has_ai_task</td><td>false</td></tr><tr><td>id</td><td>false</td></tr><tr><td>initiator_by_avatar_url</td><td>false</td></tr><tr><td>initiator_by_name</td><td>false</td></tr><tr><td>initiator_by_username</td><td>false</td></tr><tr><td>initiator_id</td><td>false</td></tr><tr><td>job_id</td><td>false</td></tr><tr><td>max_deadline</td><td>false</td></tr><tr><td>provisioner_state</td><td>false</td></tr><tr><td>reason</td><td>false</td></tr><tr><td>template_version_id</td><td>true</td></tr><tr><td>template_version_preset_id</td><td>false</td></tr><tr><td>transition</td><td>false</td></tr><tr><td>updated_at</td><td>false</td></tr><tr><td>workspace_id</td><td>false</td></tr></tbody></table> |
|
||||
| WorkspaceProxy<br><i></i> | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>created_at</td><td>true</td></tr><tr><td>deleted</td><td>false</td></tr><tr><td>derp_enabled</td><td>true</td></tr><tr><td>derp_only</td><td>true</td></tr><tr><td>display_name</td><td>true</td></tr><tr><td>icon</td><td>true</td></tr><tr><td>id</td><td>true</td></tr><tr><td>name</td><td>true</td></tr><tr><td>region_id</td><td>true</td></tr><tr><td>token_hashed_secret</td><td>true</td></tr><tr><td>updated_at</td><td>false</td></tr><tr><td>url</td><td>true</td></tr><tr><td>version</td><td>true</td></tr><tr><td>wildcard_hostname</td><td>true</td></tr></tbody></table> |
|
||||
| WorkspaceTable<br><i></i> | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>automatic_updates</td><td>true</td></tr><tr><td>autostart_schedule</td><td>true</td></tr><tr><td>created_at</td><td>false</td></tr><tr><td>deleted</td><td>false</td></tr><tr><td>deleting_at</td><td>true</td></tr><tr><td>dormant_at</td><td>true</td></tr><tr><td>favorite</td><td>true</td></tr><tr><td>id</td><td>true</td></tr><tr><td>last_used_at</td><td>false</td></tr><tr><td>name</td><td>true</td></tr><tr><td>next_start_at</td><td>true</td></tr><tr><td>organization_id</td><td>false</td></tr><tr><td>owner_id</td><td>true</td></tr><tr><td>template_id</td><td>true</td></tr><tr><td>ttl</td><td>true</td></tr><tr><td>updated_at</td><td>false</td></tr></tbody></table> |
|
||||
@ -91,16 +89,16 @@ log entry:
|
||||
"ts": "2023-06-13T03:45:37.294730279Z",
|
||||
"level": "INFO",
|
||||
"msg": "audit_log",
|
||||
"caller": "/home/runner/work/coder/coder/enterprise/audit/backends/slog.go:36",
|
||||
"func": "github.com/coder/coder/enterprise/audit/backends.slogBackend.Export",
|
||||
"caller": "/home/coder/coder/enterprise/audit/backends/slog.go:38",
|
||||
"func": "github.com/coder/coder/v2/enterprise/audit/backends.(*SlogExporter).ExportStruct",
|
||||
"logger_names": ["coderd"],
|
||||
"fields": {
|
||||
"ID": "033a9ffa-b54d-4c10-8ec3-2aaf9e6d741a",
|
||||
"Time": "2023-06-13T03:45:37.288506Z",
|
||||
"UserID": "6c405053-27e3-484a-9ad7-bcb64e7bfde6",
|
||||
"OrganizationID": "00000000-0000-0000-0000-000000000000",
|
||||
"Ip": "{IPNet:{IP:\u003cnil\u003e Mask:\u003cnil\u003e} Valid:false}",
|
||||
"UserAgent": "{String: Valid:false}",
|
||||
"Ip": null,
|
||||
"UserAgent": null,
|
||||
"ResourceType": "workspace_build",
|
||||
"ResourceID": "ca5647e0-ef50-4202-a246-717e04447380",
|
||||
"ResourceTarget": "",
|
||||
|
@ -27,8 +27,6 @@ var AuditActionMap = map[string][]codersdk.AuditAction{
|
||||
"Group": {codersdk.AuditActionCreate, codersdk.AuditActionWrite, codersdk.AuditActionDelete},
|
||||
"APIKey": {codersdk.AuditActionLogin, codersdk.AuditActionLogout, codersdk.AuditActionRegister, codersdk.AuditActionCreate, codersdk.AuditActionDelete},
|
||||
"License": {codersdk.AuditActionCreate, codersdk.AuditActionDelete},
|
||||
"WorkspaceAgent": {codersdk.AuditActionConnect, codersdk.AuditActionDisconnect},
|
||||
"WorkspaceApp": {codersdk.AuditActionOpen, codersdk.AuditActionClose},
|
||||
}
|
||||
|
||||
type Action string
|
||||
@ -343,63 +341,6 @@ var auditableResourcesTypes = map[any]map[string]Action{
|
||||
"field": ActionTrack,
|
||||
"mapping": ActionTrack,
|
||||
},
|
||||
&database.WorkspaceAgent{}: {
|
||||
"id": ActionIgnore,
|
||||
"created_at": ActionIgnore,
|
||||
"updated_at": ActionIgnore,
|
||||
"name": ActionIgnore,
|
||||
"first_connected_at": ActionIgnore,
|
||||
"last_connected_at": ActionIgnore,
|
||||
"disconnected_at": ActionIgnore,
|
||||
"resource_id": ActionIgnore,
|
||||
"auth_token": ActionIgnore,
|
||||
"auth_instance_id": ActionIgnore,
|
||||
"architecture": ActionIgnore,
|
||||
"environment_variables": ActionIgnore,
|
||||
"operating_system": ActionIgnore,
|
||||
"instance_metadata": ActionIgnore,
|
||||
"resource_metadata": ActionIgnore,
|
||||
"directory": ActionIgnore,
|
||||
"version": ActionIgnore,
|
||||
"last_connected_replica_id": ActionIgnore,
|
||||
"connection_timeout_seconds": ActionIgnore,
|
||||
"troubleshooting_url": ActionIgnore,
|
||||
"motd_file": ActionIgnore,
|
||||
"lifecycle_state": ActionIgnore,
|
||||
"expanded_directory": ActionIgnore,
|
||||
"logs_length": ActionIgnore,
|
||||
"logs_overflowed": ActionIgnore,
|
||||
"started_at": ActionIgnore,
|
||||
"ready_at": ActionIgnore,
|
||||
"subsystems": ActionIgnore,
|
||||
"display_apps": ActionIgnore,
|
||||
"api_version": ActionIgnore,
|
||||
"display_order": ActionIgnore,
|
||||
"parent_id": ActionIgnore,
|
||||
"api_key_scope": ActionIgnore,
|
||||
"deleted": ActionIgnore,
|
||||
},
|
||||
&database.WorkspaceApp{}: {
|
||||
"id": ActionIgnore,
|
||||
"created_at": ActionIgnore,
|
||||
"agent_id": ActionIgnore,
|
||||
"display_name": ActionIgnore,
|
||||
"icon": ActionIgnore,
|
||||
"command": ActionIgnore,
|
||||
"url": ActionIgnore,
|
||||
"healthcheck_url": ActionIgnore,
|
||||
"healthcheck_interval": ActionIgnore,
|
||||
"healthcheck_threshold": ActionIgnore,
|
||||
"health": ActionIgnore,
|
||||
"subdomain": ActionIgnore,
|
||||
"sharing_level": ActionIgnore,
|
||||
"slug": ActionIgnore,
|
||||
"external": ActionIgnore,
|
||||
"display_group": ActionIgnore,
|
||||
"display_order": ActionIgnore,
|
||||
"hidden": ActionIgnore,
|
||||
"open_in": ActionIgnore,
|
||||
},
|
||||
}
|
||||
|
||||
// auditMap converts a map of struct pointers to a map of struct names as
|
||||
|
Reference in New Issue
Block a user