From 45afcc668aaa8a0fa2d7f873964c0414239a50d1 Mon Sep 17 00:00:00 2001 From: Sas Swart Date: Wed, 22 Jan 2025 07:27:10 +0000 Subject: [PATCH] Review notes and test fixing --- coderd/database/dbauthz/dbauthz_test.go | 11 ++-- coderd/database/dbmem/dbmem.go | 9 +-- coderd/database/dump.sql | 6 +- coderd/database/foreign_key_constraint.go | 1 + ...00288_workspace_parameter_presets.down.sql | 6 +- .../000288_workspace_parameter_presets.up.sql | 16 +++--- .../000288_workspace_parameter_presets.up.sql | 29 +++++----- coderd/database/models.go | 9 ++- coderd/database/queries.sql.go | 55 ++++++------------- coderd/database/queries/presets.sql | 19 ++++--- docs/admin/security/audit-logs.md | 4 +- 11 files changed, 76 insertions(+), 89 deletions(-) diff --git a/coderd/database/dbauthz/dbauthz_test.go b/coderd/database/dbauthz/dbauthz_test.go index 8e4d0aabe5..dcfed4065c 100644 --- a/coderd/database/dbauthz/dbauthz_test.go +++ b/coderd/database/dbauthz/dbauthz_test.go @@ -3741,7 +3741,7 @@ func (s *MethodTestSuite) TestSystemFunctions() { OrganizationID: org.ID, CreatedBy: user.ID, }) - _, err := db.InsertPreset(context.Background(), database.InsertPresetParams{ + preset, err := db.InsertPreset(context.Background(), database.InsertPresetParams{ TemplateVersionID: templateVersion.ID, Name: "test", }) @@ -3754,10 +3754,11 @@ func (s *MethodTestSuite) TestSystemFunctions() { OrganizationID: org.ID, }) workspaceBuild := dbgen.WorkspaceBuild(s.T(), db, database.WorkspaceBuild{ - WorkspaceID: workspace.ID, - TemplateVersionID: templateVersion.ID, - InitiatorID: user.ID, - JobID: job.ID, + WorkspaceID: workspace.ID, + TemplateVersionID: templateVersion.ID, + TemplateVersionPresetID: uuid.NullUUID{UUID: preset.ID, Valid: true}, + InitiatorID: user.ID, + JobID: job.ID, }) require.NoError(s.T(), err) db.GetPresetByWorkspaceBuildID(context.Background(), workspaceBuild.ID) diff --git a/coderd/database/dbmem/dbmem.go b/coderd/database/dbmem/dbmem.go index 0d5a0ca425..906cdf1a6f 100644 --- a/coderd/database/dbmem/dbmem.go +++ b/coderd/database/dbmem/dbmem.go @@ -3791,10 +3791,9 @@ func (q *FakeQuerier) GetPresetByWorkspaceBuildID(_ context.Context, workspaceBu for _, preset := range q.presets { if preset.TemplateVersionID == workspaceBuild.TemplateVersionID { return database.GetPresetByWorkspaceBuildIDRow{ - ID: uuid.NullUUID{UUID: preset.ID, Valid: true}, - Name: sql.NullString{String: preset.Name, Valid: true}, - CreatedAt: sql.NullTime{Time: preset.CreatedAt, Valid: true}, - UpdatedAt: preset.UpdatedAt, + ID: preset.ID, + Name: preset.Name, + CreatedAt: preset.CreatedAt, }, nil } } @@ -3830,7 +3829,6 @@ func (q *FakeQuerier) GetPresetsByTemplateVersionID(_ context.Context, templateV ID: preset.ID, Name: preset.Name, CreatedAt: preset.CreatedAt, - UpdatedAt: preset.UpdatedAt, }) } } @@ -8116,7 +8114,6 @@ func (q *FakeQuerier) InsertPreset(_ context.Context, arg database.InsertPresetP TemplateVersionID: arg.TemplateVersionID, Name: arg.Name, CreatedAt: arg.CreatedAt, - UpdatedAt: arg.UpdatedAt, } q.presets = append(q.presets, preset) return preset, nil diff --git a/coderd/database/dump.sql b/coderd/database/dump.sql index d0f3f1fc84..20e7d14b57 100644 --- a/coderd/database/dump.sql +++ b/coderd/database/dump.sql @@ -1276,8 +1276,7 @@ CREATE TABLE template_version_presets ( id uuid DEFAULT gen_random_uuid() NOT NULL, template_version_id uuid NOT NULL, name text NOT NULL, - created_at timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL, - updated_at timestamp with time zone + created_at timestamp with time zone DEFAULT CURRENT_TIMESTAMP NOT NULL ); CREATE TABLE template_version_variables ( @@ -2560,6 +2559,9 @@ ALTER TABLE ONLY workspace_builds ALTER TABLE ONLY workspace_builds ADD CONSTRAINT workspace_builds_template_version_id_fkey FOREIGN KEY (template_version_id) REFERENCES template_versions(id) ON DELETE CASCADE; +ALTER TABLE ONLY workspace_builds + ADD CONSTRAINT workspace_builds_template_version_preset_id_fkey FOREIGN KEY (template_version_preset_id) REFERENCES template_version_presets(id) ON DELETE SET NULL; + ALTER TABLE ONLY workspace_builds ADD CONSTRAINT workspace_builds_workspace_id_fkey FOREIGN KEY (workspace_id) REFERENCES workspaces(id) ON DELETE CASCADE; diff --git a/coderd/database/foreign_key_constraint.go b/coderd/database/foreign_key_constraint.go index f6302ed685..1d94cd0075 100644 --- a/coderd/database/foreign_key_constraint.go +++ b/coderd/database/foreign_key_constraint.go @@ -70,6 +70,7 @@ const ( ForeignKeyWorkspaceBuildParametersWorkspaceBuildID ForeignKeyConstraint = "workspace_build_parameters_workspace_build_id_fkey" // ALTER TABLE ONLY workspace_build_parameters ADD CONSTRAINT workspace_build_parameters_workspace_build_id_fkey FOREIGN KEY (workspace_build_id) REFERENCES workspace_builds(id) ON DELETE CASCADE; ForeignKeyWorkspaceBuildsJobID ForeignKeyConstraint = "workspace_builds_job_id_fkey" // ALTER TABLE ONLY workspace_builds ADD CONSTRAINT workspace_builds_job_id_fkey FOREIGN KEY (job_id) REFERENCES provisioner_jobs(id) ON DELETE CASCADE; ForeignKeyWorkspaceBuildsTemplateVersionID ForeignKeyConstraint = "workspace_builds_template_version_id_fkey" // ALTER TABLE ONLY workspace_builds ADD CONSTRAINT workspace_builds_template_version_id_fkey FOREIGN KEY (template_version_id) REFERENCES template_versions(id) ON DELETE CASCADE; + ForeignKeyWorkspaceBuildsTemplateVersionPresetID ForeignKeyConstraint = "workspace_builds_template_version_preset_id_fkey" // ALTER TABLE ONLY workspace_builds ADD CONSTRAINT workspace_builds_template_version_preset_id_fkey FOREIGN KEY (template_version_preset_id) REFERENCES template_version_presets(id) ON DELETE SET NULL; ForeignKeyWorkspaceBuildsWorkspaceID ForeignKeyConstraint = "workspace_builds_workspace_id_fkey" // ALTER TABLE ONLY workspace_builds ADD CONSTRAINT workspace_builds_workspace_id_fkey FOREIGN KEY (workspace_id) REFERENCES workspaces(id) ON DELETE CASCADE; ForeignKeyWorkspaceModulesJobID ForeignKeyConstraint = "workspace_modules_job_id_fkey" // ALTER TABLE ONLY workspace_modules ADD CONSTRAINT workspace_modules_job_id_fkey FOREIGN KEY (job_id) REFERENCES provisioner_jobs(id) ON DELETE CASCADE; ForeignKeyWorkspaceResourceMetadataWorkspaceResourceID ForeignKeyConstraint = "workspace_resource_metadata_workspace_resource_id_fkey" // ALTER TABLE ONLY workspace_resource_metadata ADD CONSTRAINT workspace_resource_metadata_workspace_resource_id_fkey FOREIGN KEY (workspace_resource_id) REFERENCES workspace_resources(id) ON DELETE CASCADE; diff --git a/coderd/database/migrations/000288_workspace_parameter_presets.down.sql b/coderd/database/migrations/000288_workspace_parameter_presets.down.sql index 12705d34b6..487c4b1ab6 100644 --- a/coderd/database/migrations/000288_workspace_parameter_presets.down.sql +++ b/coderd/database/migrations/000288_workspace_parameter_presets.down.sql @@ -1,4 +1,8 @@ --- Recreate the view to exclude the new column. +-- DROP the workspace_build_with_user view so that we can recreate without +-- workspace_builds.template_version_preset_id below. We need to drop the view +-- before dropping workspace_builds.template_version_preset_id because the view +-- references it. We can only recreate the view after dropping the column, +-- because the view needs to be created without the column. DROP VIEW workspace_build_with_user; ALTER TABLE workspace_builds diff --git a/coderd/database/migrations/000288_workspace_parameter_presets.up.sql b/coderd/database/migrations/000288_workspace_parameter_presets.up.sql index 6b7e1b427a..a44450c885 100644 --- a/coderd/database/migrations/000288_workspace_parameter_presets.up.sql +++ b/coderd/database/migrations/000288_workspace_parameter_presets.up.sql @@ -2,16 +2,9 @@ CREATE TABLE template_version_presets ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), template_version_id UUID NOT NULL, - -- TODO (sasswart): TEXT vs VARCHAR? Check with Mr Kopping. - -- TODO (sasswart): A comment on the presets RFC mentioned that we may need to - -- aggregate presets by name because we want statistics for related presets across - -- template versions. This makes me uncomfortable. It couples constraints to a user - -- facing field that could be avoided. name TEXT NOT NULL, created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, - -- TODO (sasswart): What do we need updated_at for? Is it worth it to have a history table? -- TODO (sasswart): Will auditing have any relevance to presets? - updated_at TIMESTAMP WITH TIME ZONE, FOREIGN KEY (template_version_id) REFERENCES template_versions (id) ON DELETE CASCADE ); @@ -30,6 +23,15 @@ CREATE TABLE template_version_preset_parameters ALTER TABLE workspace_builds ADD COLUMN template_version_preset_id UUID NULL; +ALTER TABLE workspace_builds +ADD CONSTRAINT workspace_builds_template_version_preset_id_fkey +FOREIGN KEY (template_version_preset_id) +REFERENCES template_version_presets (id) +-- TODO (sasswart): SET NULL might not be the best choice here. The rest of the hierarchy has ON DELETE CASCADE. +-- We don't want CASCADE here, because we don't want to delete the workspace build if the preset is deleted. +-- However, do we want to lose record of the preset id for a workspace build? +ON DELETE SET NULL; + -- Recreate the view to include the new column. DROP VIEW workspace_build_with_user; CREATE VIEW diff --git a/coderd/database/migrations/testdata/fixtures/000288_workspace_parameter_presets.up.sql b/coderd/database/migrations/testdata/fixtures/000288_workspace_parameter_presets.up.sql index 733134ea8b..0e07069ec1 100644 --- a/coderd/database/migrations/testdata/fixtures/000288_workspace_parameter_presets.up.sql +++ b/coderd/database/migrations/testdata/fixtures/000288_workspace_parameter_presets.up.sql @@ -6,28 +6,29 @@ VALUES ('d3fd38d2-ffc3-4ec2-8cfc-9c8dab6d9a74', 'Test Org', 'Test Organization', INSERT INTO users (id, email, username, created_at, updated_at, status, rbac_roles, login_type, hashed_password) VALUES ('1f573504-f7a0-4498-8b81-2e1939f3c4a2', 'test@coder.com', 'testuser', now(), now(), 'active', '{}', 'password', 'password'); --- Template -INSERT INTO templates (id, created_by, organization_id, created_at, updated_at, deleted, name, provisioner, active_version_id, description) -VALUES ('0bd0713b-176a-4864-a58b-546a1b021025', '1f573504-f7a0-4498-8b81-2e1939f3c4a2', 'd3fd38d2-ffc3-4ec2-8cfc-9c8dab6d9a74', now(), now(), false, 'test-template', 'terraform', null, 'Test template'); +-- Provisioner Job +INSERT INTO provisioner_jobs (id, organization_id, created_at, updated_at, initiator_id, provisioner, storage_method, type, input, file_id) +VALUES ('50ebe702-82e5-4053-859d-c24a3b742b57', 'd3fd38d2-ffc3-4ec2-8cfc-9c8dab6d9a74', now(), now(), '1f573504-f7a0-4498-8b81-2e1939f3c4a2', 'echo', 'file', 'template_version_import', '{}', '00000000-82e5-4053-859d-c24a3b742b57'); -- Template Version -INSERT INTO template_versions (id, template_id, organization_id, created_by, created_at, updated_at, name, job_id, readme, message) -VALUES ('f1276e15-01cd-406d-8ea5-64f113a79601', '0bd0713b-176a-4864-a58b-546a1b021025', 'd3fd38d2-ffc3-4ec2-8cfc-9c8dab6d9a74', '1f573504-f7a0-4498-8b81-2e1939f3c4a2', now(), now(), 'test-version', null, '', ''); +INSERT INTO template_versions (id, organization_id, created_by, created_at, updated_at, name, job_id, readme, message) +VALUES ('f1276e15-01cd-406d-8ea5-64f113a79601', 'd3fd38d2-ffc3-4ec2-8cfc-9c8dab6d9a74', '1f573504-f7a0-4498-8b81-2e1939f3c4a2', now(), now(), 'test-version', '50ebe702-82e5-4053-859d-c24a3b742b57', '', ''); +-- Template +INSERT INTO templates (id, created_by, organization_id, created_at, updated_at, deleted, name, provisioner, active_version_id, description) +VALUES ('0bd0713b-176a-4864-a58b-546a1b021025', '1f573504-f7a0-4498-8b81-2e1939f3c4a2', 'd3fd38d2-ffc3-4ec2-8cfc-9c8dab6d9a74', now(), now(), false, 'test-template', 'terraform', 'f1276e15-01cd-406d-8ea5-64f113a79601', 'Test template'); + +UPDATE templates SET active_version_id = 'f1276e15-01cd-406d-8ea5-64f113a79601' WHERE id = '0bd0713b-176a-4864-a58b-546a1b021025'; -- Workspace INSERT INTO workspaces (id, organization_id, owner_id, template_id, created_at, updated_at, name, deleted, automatic_updates) VALUES ('8cb0b7c4-47b5-4bfc-ad92-88ccc61f3c12', 'd3fd38d2-ffc3-4ec2-8cfc-9c8dab6d9a74', '1f573504-f7a0-4498-8b81-2e1939f3c4a2', '0bd0713b-176a-4864-a58b-546a1b021025', now(), now(), 'test-workspace', false, 'never'); --- Provisioner Job -INSERT INTO provisioner_jobs (id, organization_id, created_at, updated_at, status, worker_id, error, started_at) -VALUES ('50ebe702-82e5-4053-859d-c24a3b742b57', 'd3fd38d2-ffc3-4ec2-8cfc-9c8dab6d9a74', now(), now(), 'pending', null, null, null); - -- Workspace Build -INSERT INTO workspace_builds (id, workspace_id, template_version_id, initiator_id, job_id, created_at, updated_at, transition, reason) -VALUES ('83b28647-743c-4649-b226-f2be697ca06c', '8cb0b7c4-47b5-4bfc-ad92-88ccc61f3c12', 'f1276e15-01cd-406d-8ea5-64f113a79601', '1f573504-f7a0-4498-8b81-2e1939f3c4a2', '50ebe702-82e5-4053-859d-c24a3b742b57', now(), now(), 'start', 'initiator'); +INSERT INTO workspace_builds (id, workspace_id, template_version_id, initiator_id, job_id, created_at, updated_at, transition, reason, build_number) +VALUES ('83b28647-743c-4649-b226-f2be697ca06c', '8cb0b7c4-47b5-4bfc-ad92-88ccc61f3c12', 'f1276e15-01cd-406d-8ea5-64f113a79601', '1f573504-f7a0-4498-8b81-2e1939f3c4a2', '50ebe702-82e5-4053-859d-c24a3b742b57', now(), now(), 'start', 'initiator', 45); -- Template Version Presets -INSERT INTO template_version_presets (id, template_version_id, name, created_at, updated_at, description) +INSERT INTO template_version_presets (id, template_version_id, name, created_at) VALUES - ('575a0fbb-cc3e-4709-ae9f-d1a3f365909c', 'f1276e15-01cd-406d-8ea5-64f113a79601', 'test', now(), now(), 'Test preset'), - ('2c76596d-436d-42eb-a38c-8d5a70497030', 'f1276e15-01cd-406d-8ea5-64f113a79601', 'test', now(), now(), 'Test preset'); + ('575a0fbb-cc3e-4709-ae9f-d1a3f365909c', 'f1276e15-01cd-406d-8ea5-64f113a79601', 'test', now()), + ('2c76596d-436d-42eb-a38c-8d5a70497030', 'f1276e15-01cd-406d-8ea5-64f113a79601', 'test', now()); diff --git a/coderd/database/models.go b/coderd/database/models.go index 5250f2c553..fc11e1f4f5 100644 --- a/coderd/database/models.go +++ b/coderd/database/models.go @@ -2955,11 +2955,10 @@ type TemplateVersionParameter struct { } type TemplateVersionPreset struct { - ID uuid.UUID `db:"id" json:"id"` - TemplateVersionID uuid.UUID `db:"template_version_id" json:"template_version_id"` - Name string `db:"name" json:"name"` - CreatedAt time.Time `db:"created_at" json:"created_at"` - UpdatedAt sql.NullTime `db:"updated_at" json:"updated_at"` + ID uuid.UUID `db:"id" json:"id"` + TemplateVersionID uuid.UUID `db:"template_version_id" json:"template_version_id"` + Name string `db:"name" json:"name"` + CreatedAt time.Time `db:"created_at" json:"created_at"` } type TemplateVersionPresetParameter struct { diff --git a/coderd/database/queries.sql.go b/coderd/database/queries.sql.go index 8c144d8d46..c8150d74f7 100644 --- a/coderd/database/queries.sql.go +++ b/coderd/database/queries.sql.go @@ -5399,31 +5399,24 @@ const getPresetByWorkspaceBuildID = `-- name: GetPresetByWorkspaceBuildID :one SELECT template_version_presets.id, template_version_presets.name, - template_version_presets.created_at, - template_version_presets.updated_at + template_version_presets.created_at FROM workspace_builds - LEFT JOIN template_version_presets ON workspace_builds.template_version_preset_id = template_version_presets.id + INNER JOIN template_version_presets ON workspace_builds.template_version_preset_id = template_version_presets.id WHERE workspace_builds.id = $1 ` type GetPresetByWorkspaceBuildIDRow struct { - ID uuid.NullUUID `db:"id" json:"id"` - Name sql.NullString `db:"name" json:"name"` - CreatedAt sql.NullTime `db:"created_at" json:"created_at"` - UpdatedAt sql.NullTime `db:"updated_at" json:"updated_at"` + ID uuid.UUID `db:"id" json:"id"` + Name string `db:"name" json:"name"` + CreatedAt time.Time `db:"created_at" json:"created_at"` } func (q *sqlQuerier) GetPresetByWorkspaceBuildID(ctx context.Context, workspaceBuildID uuid.UUID) (GetPresetByWorkspaceBuildIDRow, error) { row := q.db.QueryRowContext(ctx, getPresetByWorkspaceBuildID, workspaceBuildID) var i GetPresetByWorkspaceBuildIDRow - err := row.Scan( - &i.ID, - &i.Name, - &i.CreatedAt, - &i.UpdatedAt, - ) + err := row.Scan(&i.ID, &i.Name, &i.CreatedAt) return i, err } @@ -5471,8 +5464,7 @@ const getPresetsByTemplateVersionID = `-- name: GetPresetsByTemplateVersionID :m SELECT id, name, - created_at, - updated_at + created_at FROM template_version_presets WHERE @@ -5480,10 +5472,9 @@ WHERE ` type GetPresetsByTemplateVersionIDRow struct { - ID uuid.UUID `db:"id" json:"id"` - Name string `db:"name" json:"name"` - CreatedAt time.Time `db:"created_at" json:"created_at"` - UpdatedAt sql.NullTime `db:"updated_at" json:"updated_at"` + ID uuid.UUID `db:"id" json:"id"` + Name string `db:"name" json:"name"` + CreatedAt time.Time `db:"created_at" json:"created_at"` } func (q *sqlQuerier) GetPresetsByTemplateVersionID(ctx context.Context, templateVersionID uuid.UUID) ([]GetPresetsByTemplateVersionIDRow, error) { @@ -5495,12 +5486,7 @@ func (q *sqlQuerier) GetPresetsByTemplateVersionID(ctx context.Context, template var items []GetPresetsByTemplateVersionIDRow for rows.Next() { var i GetPresetsByTemplateVersionIDRow - if err := rows.Scan( - &i.ID, - &i.Name, - &i.CreatedAt, - &i.UpdatedAt, - ); err != nil { + if err := rows.Scan(&i.ID, &i.Name, &i.CreatedAt); err != nil { return nil, err } items = append(items, i) @@ -5516,32 +5502,25 @@ func (q *sqlQuerier) GetPresetsByTemplateVersionID(ctx context.Context, template const insertPreset = `-- name: InsertPreset :one INSERT INTO - template_version_presets (template_version_id, name, created_at, updated_at) + template_version_presets (template_version_id, name, created_at) VALUES - ($1, $2, $3, $4) RETURNING id, template_version_id, name, created_at, updated_at + ($1, $2, $3) RETURNING id, template_version_id, name, created_at ` type InsertPresetParams struct { - TemplateVersionID uuid.UUID `db:"template_version_id" json:"template_version_id"` - Name string `db:"name" json:"name"` - CreatedAt time.Time `db:"created_at" json:"created_at"` - UpdatedAt sql.NullTime `db:"updated_at" json:"updated_at"` + TemplateVersionID uuid.UUID `db:"template_version_id" json:"template_version_id"` + Name string `db:"name" json:"name"` + CreatedAt time.Time `db:"created_at" json:"created_at"` } func (q *sqlQuerier) InsertPreset(ctx context.Context, arg InsertPresetParams) (TemplateVersionPreset, error) { - row := q.db.QueryRowContext(ctx, insertPreset, - arg.TemplateVersionID, - arg.Name, - arg.CreatedAt, - arg.UpdatedAt, - ) + row := q.db.QueryRowContext(ctx, insertPreset, arg.TemplateVersionID, arg.Name, arg.CreatedAt) var i TemplateVersionPreset err := row.Scan( &i.ID, &i.TemplateVersionID, &i.Name, &i.CreatedAt, - &i.UpdatedAt, ) return i, err } diff --git a/coderd/database/queries/presets.sql b/coderd/database/queries/presets.sql index fe1b905b73..469591f8a4 100644 --- a/coderd/database/queries/presets.sql +++ b/coderd/database/queries/presets.sql @@ -1,21 +1,23 @@ -- name: InsertPreset :one INSERT INTO - template_version_presets (template_version_id, name, created_at, updated_at) + template_version_presets (template_version_id, name, created_at) VALUES - (@template_version_id, @name, @created_at, @updated_at) RETURNING *; + (@template_version_id, @name, @created_at) RETURNING *; -- InsertPresetParameter :one INSERT INTO template_version_preset_parameters (template_version_preset_id, name, value) -VALUES - (@template_version_preset_id, @name, @value) RETURNING *; +SELECT + @template_version_preset_id, + unnest(@name), + unnest(@value) +RETURNING *; -- name: GetPresetsByTemplateVersionID :many SELECT id, name, - created_at, - updated_at + created_at FROM template_version_presets WHERE @@ -25,11 +27,10 @@ WHERE SELECT template_version_presets.id, template_version_presets.name, - template_version_presets.created_at, - template_version_presets.updated_at + template_version_presets.created_at FROM workspace_builds - LEFT JOIN template_version_presets ON workspace_builds.template_version_preset_id = template_version_presets.id + INNER JOIN template_version_presets ON workspace_builds.template_version_preset_id = template_version_presets.id WHERE workspace_builds.id = @workspace_build_id; diff --git a/docs/admin/security/audit-logs.md b/docs/admin/security/audit-logs.md index a6b9f69daf..2131e7746d 100644 --- a/docs/admin/security/audit-logs.md +++ b/docs/admin/security/audit-logs.md @@ -29,9 +29,9 @@ We track the following resources: | Template
write, delete | |
FieldTracked
active_version_idtrue
activity_bumptrue
allow_user_autostarttrue
allow_user_autostoptrue
allow_user_cancel_workspace_jobstrue
autostart_block_days_of_weektrue
autostop_requirement_days_of_weektrue
autostop_requirement_weekstrue
created_atfalse
created_bytrue
created_by_avatar_urlfalse
created_by_usernamefalse
default_ttltrue
deletedfalse
deprecatedtrue
descriptiontrue
display_nametrue
failure_ttltrue
group_acltrue
icontrue
idtrue
max_port_sharing_leveltrue
nametrue
organization_display_namefalse
organization_iconfalse
organization_idfalse
organization_namefalse
provisionertrue
require_active_versiontrue
time_til_dormanttrue
time_til_dormant_autodeletetrue
updated_atfalse
user_acltrue
| | TemplateVersion
create, write | |
FieldTracked
archivedtrue
created_atfalse
created_bytrue
created_by_avatar_urlfalse
created_by_usernamefalse
external_auth_providersfalse
idtrue
job_idfalse
messagefalse
nametrue
organization_idfalse
readmetrue
source_example_idfalse
template_idtrue
updated_atfalse
| | User
create, write, delete | |
FieldTracked
avatar_urlfalse
created_atfalse
deletedtrue
emailtrue
github_com_user_idfalse
hashed_one_time_passcodefalse
hashed_passwordtrue
idtrue
last_seen_atfalse
login_typetrue
nametrue
one_time_passcode_expires_attrue
quiet_hours_scheduletrue
rbac_rolestrue
statustrue
theme_preferencefalse
updated_atfalse
usernametrue
| -| WorkspaceBuild
start, stop | |
FieldTracked
build_numberfalse
created_atfalse
daily_costfalse
deadlinefalse
idfalse
initiator_by_avatar_urlfalse
initiator_by_usernamefalse
initiator_idfalse
job_idfalse
max_deadlinefalse
provisioner_statefalse
reasonfalse
template_version_idtrue
transitionfalse
updated_atfalse
workspace_idfalse
| +| WorkspaceBuild
start, stop | |
FieldTracked
build_numberfalse
created_atfalse
daily_costfalse
deadlinefalse
idfalse
initiator_by_avatar_urlfalse
initiator_by_usernamefalse
initiator_idfalse
job_idfalse
max_deadlinefalse
provisioner_statefalse
reasonfalse
template_version_idtrue
template_version_preset_idfalse
transitionfalse
updated_atfalse
workspace_idfalse
| | WorkspaceProxy
| |
FieldTracked
created_attrue
deletedfalse
derp_enabledtrue
derp_onlytrue
display_nametrue
icontrue
idtrue
nametrue
region_idtrue
token_hashed_secrettrue
updated_atfalse
urltrue
versiontrue
wildcard_hostnametrue
| -| WorkspaceTable
| |
FieldTracked
automatic_updatestrue
autostart_scheduletrue
created_atfalse
deletedfalse
deleting_attrue
dormant_attrue
favoritetrue
idtrue
last_used_atfalse
nametrue
next_start_attrue
organization_idfalse
owner_idtrue
template_idtrue
template_version_preset_idfalse
ttltrue
updated_atfalse
| +| WorkspaceTable
| |
FieldTracked
automatic_updatestrue
autostart_scheduletrue
created_atfalse
deletedfalse
deleting_attrue
dormant_attrue
favoritetrue
idtrue
last_used_atfalse
nametrue
next_start_attrue
organization_idfalse
owner_idtrue
template_idtrue
ttltrue
updated_atfalse
|