mirror of
https://github.com/coder/coder.git
synced 2026-10-30 18:12:29 +08:00
feat: add a per-template workspace rename setting (#27558)
This commit is contained in:
-7
@@ -17,13 +17,6 @@ SUBCOMMANDS:
|
||||
PostgreSQL deployment.
|
||||
|
||||
OPTIONS:
|
||||
--allow-workspace-renames bool, $CODER_ALLOW_WORKSPACE_RENAMES (default: false)
|
||||
Allow users to rename their workspaces. WARNING: Renaming a workspace
|
||||
can cause Terraform resources that depend on the workspace name to be
|
||||
destroyed and recreated, potentially causing data loss. Only enable
|
||||
this if your templates do not use workspace names in resource
|
||||
identifiers, or if you understand the risks.
|
||||
|
||||
--cache-dir string, $CODER_CACHE_DIRECTORY (default: [cache dir])
|
||||
The directory to cache temporary files. If unspecified and
|
||||
$CACHE_DIRECTORY is set, it will be used for compatibility with
|
||||
|
||||
+4
-4
@@ -635,10 +635,10 @@ userQuietHoursSchedule:
|
||||
# change their quiet hours schedule and the site default is always used.
|
||||
# (default: true, type: bool)
|
||||
allowCustomQuietHours: true
|
||||
# Allow users to rename their workspaces. WARNING: Renaming a workspace can cause
|
||||
# Terraform resources that depend on the workspace name to be destroyed and
|
||||
# recreated, potentially causing data loss. Only enable this if your templates do
|
||||
# not use workspace names in resource identifiers, or if you understand the risks.
|
||||
# Deprecated: use the per-template "Allow workspace renames" setting instead.
|
||||
# While set, it force-enables renames for every template in the deployment.
|
||||
# WARNING: Renaming a workspace can cause Terraform resources that depend on the
|
||||
# workspace name to be destroyed and recreated, potentially causing data loss.
|
||||
# (default: false, type: bool)
|
||||
allowWorkspaceRenames: false
|
||||
# Configure how emails are sent.
|
||||
|
||||
Generated
+14
@@ -20753,6 +20753,10 @@ const docTemplate = `{
|
||||
"description": "Allow users to cancel in-progress workspace jobs.\n*bool as the default value is \"true\".",
|
||||
"type": "boolean"
|
||||
},
|
||||
"allow_workspace_renames": {
|
||||
"description": "AllowWorkspaceRenames permits users to rename workspaces built from this\ntemplate. Renaming can be destructive for templates whose Terraform\nreferences the workspace name, so this defaults to false.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"autostart_requirement": {
|
||||
"description": "AutostartRequirement allows optionally specifying the autostart allowed days\nfor workspaces created from this template. This is an enterprise feature.",
|
||||
"allOf": [
|
||||
@@ -21678,6 +21682,7 @@ const docTemplate = `{
|
||||
"$ref": "#/definitions/codersdk.AIConfig"
|
||||
},
|
||||
"allow_workspace_renames": {
|
||||
"description": "Deprecated: Use the per-template allow_workspace_renames setting instead.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"autobuild_poll_interval": {
|
||||
@@ -26543,6 +26548,10 @@ const docTemplate = `{
|
||||
"allow_user_cancel_workspace_jobs": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"allow_workspace_renames": {
|
||||
"description": "AllowWorkspaceRenames permits users to rename workspaces built from this\ntemplate. Renaming can be destructive for templates whose Terraform\nreferences the workspace name.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"autostart_requirement": {
|
||||
"$ref": "#/definitions/codersdk.TemplateAutostartRequirement"
|
||||
},
|
||||
@@ -28102,6 +28111,10 @@ const docTemplate = `{
|
||||
"allow_user_cancel_workspace_jobs": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"allow_workspace_renames": {
|
||||
"description": "AllowWorkspaceRenames permits users to rename workspaces built from this\ntemplate. Renaming can be destructive for templates whose Terraform\nreferences the workspace name.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"autostart_requirement": {
|
||||
"$ref": "#/definitions/codersdk.TemplateAutostartRequirement"
|
||||
},
|
||||
@@ -29139,6 +29152,7 @@ const docTemplate = `{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"allow_renames": {
|
||||
"description": "AllowRenames is the effective rename permission for this workspace,\nderived from the template's allow_workspace_renames setting and the\ndeprecated deployment-wide flag.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"automatic_updates": {
|
||||
|
||||
Generated
+14
@@ -18828,6 +18828,10 @@
|
||||
"description": "Allow users to cancel in-progress workspace jobs.\n*bool as the default value is \"true\".",
|
||||
"type": "boolean"
|
||||
},
|
||||
"allow_workspace_renames": {
|
||||
"description": "AllowWorkspaceRenames permits users to rename workspaces built from this\ntemplate. Renaming can be destructive for templates whose Terraform\nreferences the workspace name, so this defaults to false.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"autostart_requirement": {
|
||||
"description": "AutostartRequirement allows optionally specifying the autostart allowed days\nfor workspaces created from this template. This is an enterprise feature.",
|
||||
"allOf": [
|
||||
@@ -19717,6 +19721,7 @@
|
||||
"$ref": "#/definitions/codersdk.AIConfig"
|
||||
},
|
||||
"allow_workspace_renames": {
|
||||
"description": "Deprecated: Use the per-template allow_workspace_renames setting instead.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"autobuild_poll_interval": {
|
||||
@@ -24405,6 +24410,10 @@
|
||||
"allow_user_cancel_workspace_jobs": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"allow_workspace_renames": {
|
||||
"description": "AllowWorkspaceRenames permits users to rename workspaces built from this\ntemplate. Renaming can be destructive for templates whose Terraform\nreferences the workspace name.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"autostart_requirement": {
|
||||
"$ref": "#/definitions/codersdk.TemplateAutostartRequirement"
|
||||
},
|
||||
@@ -25876,6 +25885,10 @@
|
||||
"allow_user_cancel_workspace_jobs": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"allow_workspace_renames": {
|
||||
"description": "AllowWorkspaceRenames permits users to rename workspaces built from this\ntemplate. Renaming can be destructive for templates whose Terraform\nreferences the workspace name.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"autostart_requirement": {
|
||||
"$ref": "#/definitions/codersdk.TemplateAutostartRequirement"
|
||||
},
|
||||
@@ -26862,6 +26875,7 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"allow_renames": {
|
||||
"description": "AllowRenames is the effective rename permission for this workspace,\nderived from the template's allow_workspace_renames setting and the\ndeprecated deployment-wide flag.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"automatic_updates": {
|
||||
|
||||
@@ -596,6 +596,7 @@ func Template(t testing.TB, db database.Store, seed database.Template) database.
|
||||
UseClassicParameterFlow: takeFirst(seed.UseClassicParameterFlow, false),
|
||||
CorsBehavior: takeFirst(seed.CorsBehavior, database.CorsBehaviorSimple),
|
||||
AgentsAllowed: seed.AgentsAllowed,
|
||||
AllowWorkspaceRenames: seed.AllowWorkspaceRenames,
|
||||
})
|
||||
require.NoError(t, err, "insert template")
|
||||
|
||||
|
||||
Generated
+5
-1
@@ -3571,7 +3571,8 @@ CREATE TABLE templates (
|
||||
cors_behavior cors_behavior DEFAULT 'simple'::cors_behavior NOT NULL,
|
||||
disable_module_cache boolean DEFAULT false NOT NULL,
|
||||
time_til_autostop_notify bigint DEFAULT 0 NOT NULL,
|
||||
agents_allowed boolean DEFAULT true NOT NULL
|
||||
agents_allowed boolean DEFAULT true NOT NULL,
|
||||
allow_workspace_renames boolean DEFAULT false NOT NULL
|
||||
);
|
||||
|
||||
COMMENT ON COLUMN templates.default_ttl IS 'The default duration for autostop for workspaces created from this template.';
|
||||
@@ -3598,6 +3599,8 @@ COMMENT ON COLUMN templates.time_til_autostop_notify IS 'How long before the wor
|
||||
|
||||
COMMENT ON COLUMN templates.agents_allowed IS 'Whether Coder Agents can create workspaces using this template.';
|
||||
|
||||
COMMENT ON COLUMN templates.allow_workspace_renames IS 'Whether workspaces built from this template may be renamed. Renaming can be destructive for templates whose Terraform references the workspace name.';
|
||||
|
||||
CREATE VIEW template_with_names AS
|
||||
SELECT templates.id,
|
||||
templates.created_at,
|
||||
@@ -3632,6 +3635,7 @@ CREATE VIEW template_with_names AS
|
||||
templates.disable_module_cache,
|
||||
templates.time_til_autostop_notify,
|
||||
templates.agents_allowed,
|
||||
templates.allow_workspace_renames,
|
||||
COALESCE(visible_users.avatar_url, ''::text) AS created_by_avatar_url,
|
||||
COALESCE(visible_users.username, ''::text) AS created_by_username,
|
||||
COALESCE(visible_users.name, ''::text) AS created_by_name,
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
DROP VIEW template_with_names;
|
||||
|
||||
ALTER TABLE templates DROP COLUMN allow_workspace_renames;
|
||||
|
||||
CREATE VIEW template_with_names AS
|
||||
SELECT templates.*,
|
||||
COALESCE(visible_users.avatar_url, ''::text) AS created_by_avatar_url,
|
||||
COALESCE(visible_users.username, ''::text) AS created_by_username,
|
||||
COALESCE(visible_users.name, ''::text) AS created_by_name,
|
||||
COALESCE(organizations.name, ''::text) AS organization_name,
|
||||
COALESCE(organizations.display_name, ''::text) AS organization_display_name,
|
||||
COALESCE(organizations.icon, ''::text) AS organization_icon
|
||||
FROM ((templates
|
||||
LEFT JOIN visible_users ON ((templates.created_by = visible_users.id)))
|
||||
LEFT JOIN organizations ON ((templates.organization_id = organizations.id)));
|
||||
|
||||
COMMENT ON VIEW template_with_names IS 'Joins in the display name information such as username, avatar, and organization name.';
|
||||
@@ -0,0 +1,19 @@
|
||||
ALTER TABLE templates ADD COLUMN allow_workspace_renames boolean DEFAULT false NOT NULL;
|
||||
|
||||
COMMENT ON COLUMN templates.allow_workspace_renames IS 'Whether workspaces built from this template may be renamed. Renaming can be destructive for templates whose Terraform references the workspace name.';
|
||||
|
||||
DROP VIEW template_with_names;
|
||||
|
||||
CREATE VIEW template_with_names AS
|
||||
SELECT templates.*,
|
||||
COALESCE(visible_users.avatar_url, ''::text) AS created_by_avatar_url,
|
||||
COALESCE(visible_users.username, ''::text) AS created_by_username,
|
||||
COALESCE(visible_users.name, ''::text) AS created_by_name,
|
||||
COALESCE(organizations.name, ''::text) AS organization_name,
|
||||
COALESCE(organizations.display_name, ''::text) AS organization_display_name,
|
||||
COALESCE(organizations.icon, ''::text) AS organization_icon
|
||||
FROM ((templates
|
||||
LEFT JOIN visible_users ON ((templates.created_by = visible_users.id)))
|
||||
LEFT JOIN organizations ON ((templates.organization_id = organizations.id)));
|
||||
|
||||
COMMENT ON VIEW template_with_names IS 'Joins in the display name information such as username, avatar, and organization name.';
|
||||
@@ -192,6 +192,7 @@ func (q *sqlQuerier) GetAuthorizedTemplates(ctx context.Context, arg GetTemplate
|
||||
&i.DisableModuleCache,
|
||||
&i.TimeTilAutostopNotify,
|
||||
&i.AgentsAllowed,
|
||||
&i.AllowWorkspaceRenames,
|
||||
&i.CreatedByAvatarURL,
|
||||
&i.CreatedByUsername,
|
||||
&i.CreatedByName,
|
||||
|
||||
Generated
+3
@@ -6112,6 +6112,7 @@ type Template struct {
|
||||
DisableModuleCache bool `db:"disable_module_cache" json:"disable_module_cache"`
|
||||
TimeTilAutostopNotify int64 `db:"time_til_autostop_notify" json:"time_til_autostop_notify"`
|
||||
AgentsAllowed bool `db:"agents_allowed" json:"agents_allowed"`
|
||||
AllowWorkspaceRenames bool `db:"allow_workspace_renames" json:"allow_workspace_renames"`
|
||||
CreatedByAvatarURL string `db:"created_by_avatar_url" json:"created_by_avatar_url"`
|
||||
CreatedByUsername string `db:"created_by_username" json:"created_by_username"`
|
||||
CreatedByName string `db:"created_by_name" json:"created_by_name"`
|
||||
@@ -6166,6 +6167,8 @@ type TemplateTable struct {
|
||||
TimeTilAutostopNotify int64 `db:"time_til_autostop_notify" json:"time_til_autostop_notify"`
|
||||
// Whether Coder Agents can create workspaces using this template.
|
||||
AgentsAllowed bool `db:"agents_allowed" json:"agents_allowed"`
|
||||
// Whether workspaces built from this template may be renamed. Renaming can be destructive for templates whose Terraform references the workspace name.
|
||||
AllowWorkspaceRenames bool `db:"allow_workspace_renames" json:"allow_workspace_renames"`
|
||||
}
|
||||
|
||||
// Records aggregated usage statistics for templates/users. All usage is rounded up to the nearest minute.
|
||||
|
||||
Generated
+18
-8
@@ -27674,7 +27674,7 @@ func (q *sqlQuerier) GetTemplateAverageBuildTime(ctx context.Context, templateID
|
||||
|
||||
const getTemplateByID = `-- name: GetTemplateByID :one
|
||||
SELECT
|
||||
id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, default_ttl, created_by, icon, user_acl, group_acl, display_name, allow_user_cancel_workspace_jobs, allow_user_autostart, allow_user_autostop, failure_ttl, time_til_dormant, time_til_dormant_autodelete, autostop_requirement_days_of_week, autostop_requirement_weeks, autostart_block_days_of_week, require_active_version, deprecated, activity_bump, max_port_sharing_level, use_classic_parameter_flow, cors_behavior, disable_module_cache, time_til_autostop_notify, agents_allowed, created_by_avatar_url, created_by_username, created_by_name, organization_name, organization_display_name, organization_icon
|
||||
id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, default_ttl, created_by, icon, user_acl, group_acl, display_name, allow_user_cancel_workspace_jobs, allow_user_autostart, allow_user_autostop, failure_ttl, time_til_dormant, time_til_dormant_autodelete, autostop_requirement_days_of_week, autostop_requirement_weeks, autostart_block_days_of_week, require_active_version, deprecated, activity_bump, max_port_sharing_level, use_classic_parameter_flow, cors_behavior, disable_module_cache, time_til_autostop_notify, agents_allowed, allow_workspace_renames, created_by_avatar_url, created_by_username, created_by_name, organization_name, organization_display_name, organization_icon
|
||||
FROM
|
||||
template_with_names
|
||||
WHERE
|
||||
@@ -27720,6 +27720,7 @@ func (q *sqlQuerier) GetTemplateByID(ctx context.Context, id uuid.UUID) (Templat
|
||||
&i.DisableModuleCache,
|
||||
&i.TimeTilAutostopNotify,
|
||||
&i.AgentsAllowed,
|
||||
&i.AllowWorkspaceRenames,
|
||||
&i.CreatedByAvatarURL,
|
||||
&i.CreatedByUsername,
|
||||
&i.CreatedByName,
|
||||
@@ -27732,7 +27733,7 @@ func (q *sqlQuerier) GetTemplateByID(ctx context.Context, id uuid.UUID) (Templat
|
||||
|
||||
const getTemplateByOrganizationAndName = `-- name: GetTemplateByOrganizationAndName :one
|
||||
SELECT
|
||||
id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, default_ttl, created_by, icon, user_acl, group_acl, display_name, allow_user_cancel_workspace_jobs, allow_user_autostart, allow_user_autostop, failure_ttl, time_til_dormant, time_til_dormant_autodelete, autostop_requirement_days_of_week, autostop_requirement_weeks, autostart_block_days_of_week, require_active_version, deprecated, activity_bump, max_port_sharing_level, use_classic_parameter_flow, cors_behavior, disable_module_cache, time_til_autostop_notify, agents_allowed, created_by_avatar_url, created_by_username, created_by_name, organization_name, organization_display_name, organization_icon
|
||||
id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, default_ttl, created_by, icon, user_acl, group_acl, display_name, allow_user_cancel_workspace_jobs, allow_user_autostart, allow_user_autostop, failure_ttl, time_til_dormant, time_til_dormant_autodelete, autostop_requirement_days_of_week, autostop_requirement_weeks, autostart_block_days_of_week, require_active_version, deprecated, activity_bump, max_port_sharing_level, use_classic_parameter_flow, cors_behavior, disable_module_cache, time_til_autostop_notify, agents_allowed, allow_workspace_renames, created_by_avatar_url, created_by_username, created_by_name, organization_name, organization_display_name, organization_icon
|
||||
FROM
|
||||
template_with_names AS templates
|
||||
WHERE
|
||||
@@ -27786,6 +27787,7 @@ func (q *sqlQuerier) GetTemplateByOrganizationAndName(ctx context.Context, arg G
|
||||
&i.DisableModuleCache,
|
||||
&i.TimeTilAutostopNotify,
|
||||
&i.AgentsAllowed,
|
||||
&i.AllowWorkspaceRenames,
|
||||
&i.CreatedByAvatarURL,
|
||||
&i.CreatedByUsername,
|
||||
&i.CreatedByName,
|
||||
@@ -27797,7 +27799,7 @@ func (q *sqlQuerier) GetTemplateByOrganizationAndName(ctx context.Context, arg G
|
||||
}
|
||||
|
||||
const getTemplates = `-- name: GetTemplates :many
|
||||
SELECT id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, default_ttl, created_by, icon, user_acl, group_acl, display_name, allow_user_cancel_workspace_jobs, allow_user_autostart, allow_user_autostop, failure_ttl, time_til_dormant, time_til_dormant_autodelete, autostop_requirement_days_of_week, autostop_requirement_weeks, autostart_block_days_of_week, require_active_version, deprecated, activity_bump, max_port_sharing_level, use_classic_parameter_flow, cors_behavior, disable_module_cache, time_til_autostop_notify, agents_allowed, created_by_avatar_url, created_by_username, created_by_name, organization_name, organization_display_name, organization_icon FROM template_with_names AS templates
|
||||
SELECT id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, default_ttl, created_by, icon, user_acl, group_acl, display_name, allow_user_cancel_workspace_jobs, allow_user_autostart, allow_user_autostop, failure_ttl, time_til_dormant, time_til_dormant_autodelete, autostop_requirement_days_of_week, autostop_requirement_weeks, autostart_block_days_of_week, require_active_version, deprecated, activity_bump, max_port_sharing_level, use_classic_parameter_flow, cors_behavior, disable_module_cache, time_til_autostop_notify, agents_allowed, allow_workspace_renames, created_by_avatar_url, created_by_username, created_by_name, organization_name, organization_display_name, organization_icon FROM template_with_names AS templates
|
||||
ORDER BY (name, id) ASC
|
||||
`
|
||||
|
||||
@@ -27844,6 +27846,7 @@ func (q *sqlQuerier) GetTemplates(ctx context.Context) ([]Template, error) {
|
||||
&i.DisableModuleCache,
|
||||
&i.TimeTilAutostopNotify,
|
||||
&i.AgentsAllowed,
|
||||
&i.AllowWorkspaceRenames,
|
||||
&i.CreatedByAvatarURL,
|
||||
&i.CreatedByUsername,
|
||||
&i.CreatedByName,
|
||||
@@ -27866,7 +27869,7 @@ func (q *sqlQuerier) GetTemplates(ctx context.Context) ([]Template, error) {
|
||||
|
||||
const getTemplatesWithFilter = `-- name: GetTemplatesWithFilter :many
|
||||
SELECT
|
||||
t.id, t.created_at, t.updated_at, t.organization_id, t.deleted, t.name, t.provisioner, t.active_version_id, t.description, t.default_ttl, t.created_by, t.icon, t.user_acl, t.group_acl, t.display_name, t.allow_user_cancel_workspace_jobs, t.allow_user_autostart, t.allow_user_autostop, t.failure_ttl, t.time_til_dormant, t.time_til_dormant_autodelete, t.autostop_requirement_days_of_week, t.autostop_requirement_weeks, t.autostart_block_days_of_week, t.require_active_version, t.deprecated, t.activity_bump, t.max_port_sharing_level, t.use_classic_parameter_flow, t.cors_behavior, t.disable_module_cache, t.time_til_autostop_notify, t.agents_allowed, t.created_by_avatar_url, t.created_by_username, t.created_by_name, t.organization_name, t.organization_display_name, t.organization_icon
|
||||
t.id, t.created_at, t.updated_at, t.organization_id, t.deleted, t.name, t.provisioner, t.active_version_id, t.description, t.default_ttl, t.created_by, t.icon, t.user_acl, t.group_acl, t.display_name, t.allow_user_cancel_workspace_jobs, t.allow_user_autostart, t.allow_user_autostop, t.failure_ttl, t.time_til_dormant, t.time_til_dormant_autodelete, t.autostop_requirement_days_of_week, t.autostop_requirement_weeks, t.autostart_block_days_of_week, t.require_active_version, t.deprecated, t.activity_bump, t.max_port_sharing_level, t.use_classic_parameter_flow, t.cors_behavior, t.disable_module_cache, t.time_til_autostop_notify, t.agents_allowed, t.allow_workspace_renames, t.created_by_avatar_url, t.created_by_username, t.created_by_name, t.organization_name, t.organization_display_name, t.organization_icon
|
||||
FROM
|
||||
template_with_names AS t
|
||||
LEFT JOIN
|
||||
@@ -28036,6 +28039,7 @@ func (q *sqlQuerier) GetTemplatesWithFilter(ctx context.Context, arg GetTemplate
|
||||
&i.DisableModuleCache,
|
||||
&i.TimeTilAutostopNotify,
|
||||
&i.AgentsAllowed,
|
||||
&i.AllowWorkspaceRenames,
|
||||
&i.CreatedByAvatarURL,
|
||||
&i.CreatedByUsername,
|
||||
&i.CreatedByName,
|
||||
@@ -28076,10 +28080,11 @@ INSERT INTO
|
||||
max_port_sharing_level,
|
||||
use_classic_parameter_flow,
|
||||
cors_behavior,
|
||||
agents_allowed
|
||||
agents_allowed,
|
||||
allow_workspace_renames
|
||||
)
|
||||
VALUES
|
||||
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18)
|
||||
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19)
|
||||
`
|
||||
|
||||
type InsertTemplateParams struct {
|
||||
@@ -28101,6 +28106,7 @@ type InsertTemplateParams struct {
|
||||
UseClassicParameterFlow bool `db:"use_classic_parameter_flow" json:"use_classic_parameter_flow"`
|
||||
CorsBehavior CorsBehavior `db:"cors_behavior" json:"cors_behavior"`
|
||||
AgentsAllowed bool `db:"agents_allowed" json:"agents_allowed"`
|
||||
AllowWorkspaceRenames bool `db:"allow_workspace_renames" json:"allow_workspace_renames"`
|
||||
}
|
||||
|
||||
func (q *sqlQuerier) InsertTemplate(ctx context.Context, arg InsertTemplateParams) error {
|
||||
@@ -28123,6 +28129,7 @@ func (q *sqlQuerier) InsertTemplate(ctx context.Context, arg InsertTemplateParam
|
||||
arg.UseClassicParameterFlow,
|
||||
arg.CorsBehavior,
|
||||
arg.AgentsAllowed,
|
||||
arg.AllowWorkspaceRenames,
|
||||
)
|
||||
return err
|
||||
}
|
||||
@@ -28226,7 +28233,8 @@ SET
|
||||
use_classic_parameter_flow = $10,
|
||||
cors_behavior = $11,
|
||||
disable_module_cache = $12,
|
||||
agents_allowed = $13
|
||||
agents_allowed = $13,
|
||||
allow_workspace_renames = $14
|
||||
WHERE
|
||||
id = $1
|
||||
`
|
||||
@@ -28245,6 +28253,7 @@ type UpdateTemplateMetaByIDParams struct {
|
||||
CorsBehavior CorsBehavior `db:"cors_behavior" json:"cors_behavior"`
|
||||
DisableModuleCache bool `db:"disable_module_cache" json:"disable_module_cache"`
|
||||
AgentsAllowed bool `db:"agents_allowed" json:"agents_allowed"`
|
||||
AllowWorkspaceRenames bool `db:"allow_workspace_renames" json:"allow_workspace_renames"`
|
||||
}
|
||||
|
||||
func (q *sqlQuerier) UpdateTemplateMetaByID(ctx context.Context, arg UpdateTemplateMetaByIDParams) error {
|
||||
@@ -28262,6 +28271,7 @@ func (q *sqlQuerier) UpdateTemplateMetaByID(ctx context.Context, arg UpdateTempl
|
||||
arg.CorsBehavior,
|
||||
arg.DisableModuleCache,
|
||||
arg.AgentsAllowed,
|
||||
arg.AllowWorkspaceRenames,
|
||||
)
|
||||
return err
|
||||
}
|
||||
@@ -39515,7 +39525,7 @@ LEFT JOIN LATERAL (
|
||||
) latest_build ON TRUE
|
||||
LEFT JOIN LATERAL (
|
||||
SELECT
|
||||
id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, default_ttl, created_by, icon, user_acl, group_acl, display_name, allow_user_cancel_workspace_jobs, allow_user_autostart, allow_user_autostop, failure_ttl, time_til_dormant, time_til_dormant_autodelete, autostop_requirement_days_of_week, autostop_requirement_weeks, autostart_block_days_of_week, require_active_version, deprecated, activity_bump, max_port_sharing_level, use_classic_parameter_flow, cors_behavior, disable_module_cache, time_til_autostop_notify, agents_allowed
|
||||
id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, default_ttl, created_by, icon, user_acl, group_acl, display_name, allow_user_cancel_workspace_jobs, allow_user_autostart, allow_user_autostop, failure_ttl, time_til_dormant, time_til_dormant_autodelete, autostop_requirement_days_of_week, autostop_requirement_weeks, autostart_block_days_of_week, require_active_version, deprecated, activity_bump, max_port_sharing_level, use_classic_parameter_flow, cors_behavior, disable_module_cache, time_til_autostop_notify, agents_allowed, allow_workspace_renames
|
||||
FROM
|
||||
templates
|
||||
WHERE
|
||||
|
||||
@@ -144,10 +144,11 @@ INSERT INTO
|
||||
max_port_sharing_level,
|
||||
use_classic_parameter_flow,
|
||||
cors_behavior,
|
||||
agents_allowed
|
||||
agents_allowed,
|
||||
allow_workspace_renames
|
||||
)
|
||||
VALUES
|
||||
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18);
|
||||
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19);
|
||||
|
||||
-- name: UpdateTemplateActiveVersionByID :exec
|
||||
UPDATE
|
||||
@@ -182,7 +183,8 @@ SET
|
||||
use_classic_parameter_flow = $10,
|
||||
cors_behavior = $11,
|
||||
disable_module_cache = $12,
|
||||
agents_allowed = $13
|
||||
agents_allowed = $13,
|
||||
allow_workspace_renames = $14
|
||||
WHERE
|
||||
id = $1
|
||||
;
|
||||
|
||||
@@ -556,6 +556,7 @@ func (api *API) templateBuilderCreateTemplate(rw http.ResponseWriter, r *http.Re
|
||||
UseClassicParameterFlow: false,
|
||||
CorsBehavior: database.CorsBehaviorSimple,
|
||||
AgentsAllowed: true,
|
||||
AllowWorkspaceRenames: false,
|
||||
})
|
||||
if err != nil {
|
||||
if database.IsUniqueViolation(err, database.UniqueTemplatesOrganizationIDNameIndex) {
|
||||
|
||||
@@ -420,6 +420,7 @@ func (api *API) postTemplateByOrganization(rw http.ResponseWriter, r *http.Reque
|
||||
allowUserCancelWorkspaceJobs = ptr.NilToDefault(createTemplate.AllowUserCancelWorkspaceJobs, false)
|
||||
allowUserAutostart = ptr.NilToDefault(createTemplate.AllowUserAutostart, true)
|
||||
allowUserAutostop = ptr.NilToDefault(createTemplate.AllowUserAutostop, true)
|
||||
allowWorkspaceRenames = ptr.NilToDefault(createTemplate.AllowWorkspaceRenames, false)
|
||||
)
|
||||
|
||||
defaultsGroups := database.TemplateACL{}
|
||||
@@ -450,6 +451,7 @@ func (api *API) postTemplateByOrganization(rw http.ResponseWriter, r *http.Reque
|
||||
UseClassicParameterFlow: useClassicParameterFlow,
|
||||
CorsBehavior: corsBehavior,
|
||||
AgentsAllowed: agentsAllowed,
|
||||
AllowWorkspaceRenames: allowWorkspaceRenames,
|
||||
})
|
||||
if err != nil {
|
||||
return xerrors.Errorf("insert template: %s", err)
|
||||
@@ -782,6 +784,7 @@ func (api *API) patchTemplateMeta(rw http.ResponseWriter, r *http.Request) {
|
||||
CorsBehavior: resolved.corsBehavior,
|
||||
DisableModuleCache: resolved.disableModuleCache,
|
||||
AgentsAllowed: resolved.agentsAllowed,
|
||||
AllowWorkspaceRenames: resolved.allowWorkspaceRenames,
|
||||
})
|
||||
if err != nil {
|
||||
return xerrors.Errorf("update template metadata: %w", err)
|
||||
@@ -1059,6 +1062,7 @@ func (api *API) convertTemplate(
|
||||
CORSBehavior: codersdk.CORSBehavior(template.CorsBehavior),
|
||||
DisableModuleCache: template.DisableModuleCache,
|
||||
AgentsAllowed: template.AgentsAllowed,
|
||||
AllowWorkspaceRenames: template.AllowWorkspaceRenames,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ type templateMetaUpdate struct {
|
||||
deprecationMessage string
|
||||
useClassicTemplateFlow bool
|
||||
disableModuleCache bool
|
||||
allowWorkspaceRenames bool
|
||||
corsBehavior database.CorsBehavior
|
||||
autostopRequirementDaysOfWeekParsed uint8
|
||||
autostartRequirementDaysOfWeekParsed uint8
|
||||
@@ -87,6 +88,7 @@ func resolveTemplateMetaUpdate(
|
||||
deprecationMessage: ptr.NilToDefault(req.DeprecationMessage, template.Deprecated),
|
||||
useClassicTemplateFlow: ptr.NilToDefault(req.UseClassicParameterFlow, template.UseClassicParameterFlow),
|
||||
disableModuleCache: ptr.NilToDefault(req.DisableModuleCache, template.DisableModuleCache),
|
||||
allowWorkspaceRenames: ptr.NilToDefault(req.AllowWorkspaceRenames, template.AllowWorkspaceRenames),
|
||||
groupACL: template.GroupACL,
|
||||
|
||||
// Default to the original values
|
||||
|
||||
@@ -44,6 +44,7 @@ func baselineTemplate() database.Template {
|
||||
UseClassicParameterFlow: true,
|
||||
CorsBehavior: database.CorsBehaviorPassthru,
|
||||
DisableModuleCache: true,
|
||||
AllowWorkspaceRenames: true,
|
||||
GroupACL: database.TemplateACL{
|
||||
orgID.String(): {"read"},
|
||||
},
|
||||
@@ -87,6 +88,7 @@ func baselineResolved() templateMetaUpdate {
|
||||
deprecationMessage: tpl.Deprecated,
|
||||
useClassicTemplateFlow: tpl.UseClassicParameterFlow,
|
||||
disableModuleCache: tpl.DisableModuleCache,
|
||||
allowWorkspaceRenames: tpl.AllowWorkspaceRenames,
|
||||
corsBehavior: tpl.CorsBehavior,
|
||||
autostopRequirementDaysOfWeekParsed: 0b0000001,
|
||||
autostartRequirementDaysOfWeekParsed: 0b1000000,
|
||||
@@ -290,6 +292,13 @@ func TestResolveTemplateMetaUpdate(t *testing.T) {
|
||||
r.disableModuleCache = false
|
||||
}},
|
||||
},
|
||||
{
|
||||
name: "AllowWorkspaceRenames",
|
||||
req: codersdk.UpdateTemplateMeta{AllowWorkspaceRenames: ptr.Ref(false)},
|
||||
expected: expected{override: func(r *templateMetaUpdate) {
|
||||
r.allowWorkspaceRenames = false
|
||||
}},
|
||||
},
|
||||
|
||||
// CORS behavior.
|
||||
{
|
||||
|
||||
@@ -1844,6 +1844,38 @@ func TestPatchTemplateMeta(t *testing.T) {
|
||||
assert.False(t, updated.DisableModuleCache, "expected false")
|
||||
})
|
||||
|
||||
t.Run("AllowWorkspaceRenames", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
require.False(t, template.AllowWorkspaceRenames, "default is false")
|
||||
|
||||
ctx := testutil.Context(t, testutil.WaitLong)
|
||||
|
||||
req := codersdk.UpdateTemplateMeta{
|
||||
AllowWorkspaceRenames: ptr.Ref(true),
|
||||
}
|
||||
updated, err := client.UpdateTemplateMeta(ctx, template.ID, req)
|
||||
require.NoError(t, err)
|
||||
assert.True(t, updated.AllowWorkspaceRenames, "expected true")
|
||||
|
||||
// Omitting the field preserves the existing value.
|
||||
req.AllowWorkspaceRenames = nil
|
||||
_, err = client.UpdateTemplateMeta(ctx, template.ID, req)
|
||||
require.NoError(t, err)
|
||||
updated, err = client.Template(ctx, template.ID)
|
||||
require.NoError(t, err)
|
||||
assert.True(t, updated.AllowWorkspaceRenames, "expected true")
|
||||
|
||||
req.AllowWorkspaceRenames = ptr.Ref(false)
|
||||
updated, err = client.UpdateTemplateMeta(ctx, template.ID, req)
|
||||
require.NoError(t, err)
|
||||
assert.False(t, updated.AllowWorkspaceRenames, "expected false")
|
||||
})
|
||||
|
||||
t.Run("SupportEmptyOrDefaultFields", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
||||
+22
-13
@@ -1154,9 +1154,17 @@ func (api *API) patchWorkspace(rw http.ResponseWriter, r *http.Request) {
|
||||
// patched in the future, it's enough if one changes.
|
||||
name := workspace.Name
|
||||
if req.Name != "" || req.Name != workspace.Name {
|
||||
if !api.AllowWorkspaceRenames {
|
||||
template, err := api.Database.GetTemplateByID(ctx, workspace.TemplateID)
|
||||
if err != nil {
|
||||
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
|
||||
Message: "Internal error fetching workspace template.",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
if !api.AllowWorkspaceRenames && !template.AllowWorkspaceRenames {
|
||||
httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
|
||||
Message: "Workspace renames are not allowed.",
|
||||
Message: "Workspace renames are not enabled for this template.",
|
||||
})
|
||||
return
|
||||
}
|
||||
@@ -2596,10 +2604,11 @@ func (api *API) patchWorkspaceACL(rw http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
type workspaceData struct {
|
||||
templates []database.Template
|
||||
builds []codersdk.WorkspaceBuild
|
||||
appStatuses []codersdk.WorkspaceAppStatus
|
||||
allowRenames bool
|
||||
templates []database.Template
|
||||
builds []codersdk.WorkspaceBuild
|
||||
appStatuses []codersdk.WorkspaceAppStatus
|
||||
// deploymentAllowsRenames is the deprecated deployment-wide rename flag.
|
||||
deploymentAllowsRenames bool
|
||||
}
|
||||
|
||||
// @Summary Completely clears the workspace's user and group ACLs.
|
||||
@@ -2757,10 +2766,10 @@ func (api *API) workspaceData(ctx context.Context, workspaces []database.Workspa
|
||||
}
|
||||
|
||||
return workspaceData{
|
||||
templates: templates,
|
||||
appStatuses: db2sdk.WorkspaceAppStatuses(appStatuses),
|
||||
builds: apiBuilds,
|
||||
allowRenames: api.AllowWorkspaceRenames,
|
||||
templates: templates,
|
||||
appStatuses: db2sdk.WorkspaceAppStatuses(appStatuses),
|
||||
builds: apiBuilds,
|
||||
deploymentAllowsRenames: api.AllowWorkspaceRenames,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -2846,7 +2855,7 @@ func convertWorkspaces(
|
||||
workspace,
|
||||
build,
|
||||
template,
|
||||
data.allowRenames,
|
||||
data.deploymentAllowsRenames,
|
||||
appStatus,
|
||||
)
|
||||
if err != nil {
|
||||
@@ -2865,7 +2874,7 @@ func convertWorkspace(
|
||||
workspace database.Workspace,
|
||||
workspaceBuild codersdk.WorkspaceBuild,
|
||||
template database.Template,
|
||||
allowRenames bool,
|
||||
deploymentAllowsRenames bool,
|
||||
latestAppStatus codersdk.WorkspaceAppStatus,
|
||||
) (codersdk.Workspace, error) {
|
||||
if requesterID == uuid.Nil {
|
||||
@@ -2953,7 +2962,7 @@ func convertWorkspace(
|
||||
FailingAgents: failingAgents,
|
||||
},
|
||||
AutomaticUpdates: codersdk.AutomaticUpdates(workspace.AutomaticUpdates),
|
||||
AllowRenames: allowRenames,
|
||||
AllowRenames: deploymentAllowsRenames || template.AllowWorkspaceRenames,
|
||||
Favorite: requesterFavorite,
|
||||
NextStartAt: nextStartAt,
|
||||
IsPrebuild: workspace.IsPrebuild(),
|
||||
|
||||
@@ -220,7 +220,44 @@ func TestWorkspace(t *testing.T) {
|
||||
err := client.UpdateWorkspace(ctx, ws1.ID, codersdk.UpdateWorkspaceRequest{
|
||||
Name: want,
|
||||
})
|
||||
require.ErrorContains(t, err, "Workspace renames are not allowed")
|
||||
require.ErrorContains(t, err, "Workspace renames are not enabled for this template")
|
||||
})
|
||||
|
||||
t.Run("RenameAllowedByTemplate", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
// The deployment-wide flag is off. The template setting alone must be
|
||||
// enough to permit renames.
|
||||
client := coderdtest.New(t, &coderdtest.Options{
|
||||
IncludeProvisionerDaemon: true,
|
||||
AllowWorkspaceRenames: false,
|
||||
})
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID, func(req *codersdk.CreateTemplateRequest) {
|
||||
req.AllowWorkspaceRenames = ptr.Ref(true)
|
||||
})
|
||||
ws1 := coderdtest.CreateWorkspace(t, client, template.ID)
|
||||
coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, ws1.LatestBuild.ID)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitMedium)
|
||||
defer cancel()
|
||||
|
||||
require.True(t, template.AllowWorkspaceRenames)
|
||||
|
||||
fetched, err := client.Workspace(ctx, ws1.ID)
|
||||
require.NoError(t, err)
|
||||
require.True(t, fetched.AllowRenames)
|
||||
|
||||
const want = "new-name"
|
||||
err = client.UpdateWorkspace(ctx, ws1.ID, codersdk.UpdateWorkspaceRequest{
|
||||
Name: want,
|
||||
})
|
||||
require.NoError(t, err, "workspace rename failed")
|
||||
|
||||
ws, err := client.Workspace(ctx, ws1.ID)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, want, ws.Name)
|
||||
})
|
||||
|
||||
t.Run("TemplateProperties", func(t *testing.T) {
|
||||
|
||||
+18
-16
@@ -741,19 +741,20 @@ type DeploymentValues struct {
|
||||
EnableTerraformDebugMode serpent.Bool `json:"enable_terraform_debug_mode,omitempty" typescript:",notnull"`
|
||||
UserQuietHoursSchedule UserQuietHoursScheduleConfig `json:"user_quiet_hours_schedule,omitempty" typescript:",notnull"`
|
||||
WebTerminalRenderer serpent.String `json:"web_terminal_renderer,omitempty" typescript:",notnull"`
|
||||
AllowWorkspaceRenames serpent.Bool `json:"allow_workspace_renames,omitempty" typescript:",notnull"`
|
||||
Healthcheck HealthcheckConfig `json:"healthcheck,omitempty" typescript:",notnull"`
|
||||
Retention RetentionConfig `json:"retention,omitempty" typescript:",notnull"`
|
||||
CLIUpgradeMessage serpent.String `json:"cli_upgrade_message,omitempty" typescript:",notnull"`
|
||||
TermsOfServiceURL serpent.String `json:"terms_of_service_url,omitempty" typescript:",notnull"`
|
||||
Notifications NotificationsConfig `json:"notifications,omitempty" typescript:",notnull"`
|
||||
AdditionalCSPPolicy serpent.StringArray `json:"additional_csp_policy,omitempty" typescript:",notnull"`
|
||||
WorkspaceHostnameSuffix serpent.String `json:"workspace_hostname_suffix,omitempty" typescript:",notnull"`
|
||||
Prebuilds PrebuildsConfig `json:"workspace_prebuilds,omitempty" typescript:",notnull"`
|
||||
EnableAITasks serpent.Bool `json:"enable_ai_tasks,omitempty" typescript:",notnull"`
|
||||
AI AIConfig `json:"ai,omitempty"`
|
||||
StatsCollection StatsCollectionConfig `json:"stats_collection,omitempty" typescript:",notnull"`
|
||||
TemplateBuilder TemplateBuilderConfig `json:"template_builder,omitempty"`
|
||||
// Deprecated: Use the per-template allow_workspace_renames setting instead.
|
||||
AllowWorkspaceRenames serpent.Bool `json:"allow_workspace_renames,omitempty" typescript:",notnull"`
|
||||
Healthcheck HealthcheckConfig `json:"healthcheck,omitempty" typescript:",notnull"`
|
||||
Retention RetentionConfig `json:"retention,omitempty" typescript:",notnull"`
|
||||
CLIUpgradeMessage serpent.String `json:"cli_upgrade_message,omitempty" typescript:",notnull"`
|
||||
TermsOfServiceURL serpent.String `json:"terms_of_service_url,omitempty" typescript:",notnull"`
|
||||
Notifications NotificationsConfig `json:"notifications,omitempty" typescript:",notnull"`
|
||||
AdditionalCSPPolicy serpent.StringArray `json:"additional_csp_policy,omitempty" typescript:",notnull"`
|
||||
WorkspaceHostnameSuffix serpent.String `json:"workspace_hostname_suffix,omitempty" typescript:",notnull"`
|
||||
Prebuilds PrebuildsConfig `json:"workspace_prebuilds,omitempty" typescript:",notnull"`
|
||||
EnableAITasks serpent.Bool `json:"enable_ai_tasks,omitempty" typescript:",notnull"`
|
||||
AI AIConfig `json:"ai,omitempty"`
|
||||
StatsCollection StatsCollectionConfig `json:"stats_collection,omitempty" typescript:",notnull"`
|
||||
TemplateBuilder TemplateBuilderConfig `json:"template_builder,omitempty"`
|
||||
|
||||
Config serpent.YAMLConfigPath `json:"config,omitempty" typescript:",notnull"`
|
||||
WriteConfig serpent.Bool `json:"write_config,omitempty" typescript:",notnull"`
|
||||
@@ -3962,13 +3963,14 @@ Write out the current server config as YAML to stdout.`,
|
||||
},
|
||||
{
|
||||
Name: "Allow Workspace Renames",
|
||||
Description: "Allow users to rename their workspaces. " +
|
||||
Description: "Deprecated: use the per-template \"Allow workspace renames\" setting instead. " +
|
||||
"While set, it force-enables renames for every template in the deployment. " +
|
||||
"WARNING: Renaming a workspace can cause Terraform resources that depend on the " +
|
||||
"workspace name to be destroyed and recreated, potentially causing data loss. " +
|
||||
"Only enable this if your templates do not use workspace names in resource identifiers, or if you understand the risks.",
|
||||
"workspace name to be destroyed and recreated, potentially causing data loss.",
|
||||
Flag: "allow-workspace-renames",
|
||||
Env: "CODER_ALLOW_WORKSPACE_RENAMES",
|
||||
Default: "false",
|
||||
Hidden: true,
|
||||
Value: &c.AllowWorkspaceRenames,
|
||||
YAML: "allowWorkspaceRenames",
|
||||
},
|
||||
|
||||
@@ -233,6 +233,11 @@ type CreateTemplateRequest struct {
|
||||
// AgentsAllowed controls whether Coder Agents can create workspaces using
|
||||
// this template. Defaults to true.
|
||||
AgentsAllowed *bool `json:"agents_allowed,omitempty"`
|
||||
|
||||
// AllowWorkspaceRenames permits users to rename workspaces built from this
|
||||
// template. Renaming can be destructive for templates whose Terraform
|
||||
// references the workspace name, so this defaults to false.
|
||||
AllowWorkspaceRenames *bool `json:"allow_workspace_renames,omitempty"`
|
||||
}
|
||||
|
||||
// CreateWorkspaceRequest provides options for creating a new workspace.
|
||||
|
||||
@@ -73,6 +73,11 @@ type Template struct {
|
||||
// DisableModuleCache disables the use of cached Terraform modules during
|
||||
// provisioning.
|
||||
DisableModuleCache bool `json:"disable_module_cache"`
|
||||
|
||||
// AllowWorkspaceRenames permits users to rename workspaces built from this
|
||||
// template. Renaming can be destructive for templates whose Terraform
|
||||
// references the workspace name.
|
||||
AllowWorkspaceRenames bool `json:"allow_workspace_renames"`
|
||||
}
|
||||
|
||||
// WeekdaysToBitmap converts a list of weekdays to a bitmap in accordance with
|
||||
@@ -286,6 +291,10 @@ type UpdateTemplateMeta struct {
|
||||
// AgentsAllowed controls whether Coder Agents can create workspaces using
|
||||
// this template. If omitted, the current value is preserved.
|
||||
AgentsAllowed *bool `json:"agents_allowed,omitempty"`
|
||||
// AllowWorkspaceRenames permits users to rename workspaces built from this
|
||||
// template. Renaming can be destructive for templates whose Terraform
|
||||
// references the workspace name.
|
||||
AllowWorkspaceRenames *bool `json:"allow_workspace_renames,omitempty"`
|
||||
}
|
||||
|
||||
type TemplateExample struct {
|
||||
|
||||
@@ -66,9 +66,12 @@ type Workspace struct {
|
||||
// what is causing an unhealthy status.
|
||||
Health WorkspaceHealth `json:"health"`
|
||||
AutomaticUpdates AutomaticUpdates `json:"automatic_updates" enums:"always,never"`
|
||||
AllowRenames bool `json:"allow_renames"`
|
||||
Favorite bool `json:"favorite"`
|
||||
NextStartAt *time.Time `json:"next_start_at" format:"date-time"`
|
||||
// AllowRenames is the effective rename permission for this workspace,
|
||||
// derived from the template's allow_workspace_renames setting and the
|
||||
// deprecated deployment-wide flag.
|
||||
AllowRenames bool `json:"allow_renames"`
|
||||
Favorite bool `json:"favorite"`
|
||||
NextStartAt *time.Time `json:"next_start_at" format:"date-time"`
|
||||
// IsPrebuild indicates whether the workspace is a prebuilt workspace.
|
||||
// Prebuilt workspaces are owned by the prebuilds system user and have specific behavior,
|
||||
// such as being managed differently from regular workspaces.
|
||||
|
||||
@@ -45,7 +45,7 @@ We track the following resources:
|
||||
| PrebuildsSettings<br><i></i> | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>id</td><td>false</td></tr><tr><td>reconciliation_paused</td><td>true</td></tr></tbody></table> |
|
||||
| RoleSyncSettings<br><i></i> | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>field</td><td>true</td></tr><tr><td>mapping</td><td>true</td></tr></tbody></table> |
|
||||
| TaskTable<br><i></i> | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>created_at</td><td>false</td></tr><tr><td>deleted_at</td><td>false</td></tr><tr><td>display_name</td><td>true</td></tr><tr><td>id</td><td>true</td></tr><tr><td>name</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>prompt</td><td>true</td></tr><tr><td>template_parameters</td><td>true</td></tr><tr><td>template_version_id</td><td>true</td></tr><tr><td>workspace_id</td><td>true</td></tr></tbody></table> |
|
||||
| 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>agents_allowed</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>cors_behavior</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>disable_module_cache</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_autostop_notify</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> |
|
||||
| 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>agents_allowed</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>allow_workspace_renames</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>cors_behavior</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>disable_module_cache</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_autostop_notify</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>has_external_agent</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>chat_spend_limit_micros</td><td>true</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_service_account</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> |
|
||||
| UserSecret<br><i>create, write, delete</i> | <table><thead><tr><th>Field</th><th>Tracked</th></tr></thead><tbody> | <tr><td>created_at</td><td>false</td></tr><tr><td>description</td><td>true</td></tr><tr><td>enabled</td><td>true</td></tr><tr><td>env_name</td><td>true</td></tr><tr><td>file_path</td><td>true</td></tr><tr><td>id</td><td>true</td></tr><tr><td>name</td><td>true</td></tr><tr><td>updated_at</td><td>false</td></tr><tr><td>user_id</td><td>true</td></tr><tr><td>value</td><td>true</td></tr><tr><td>value_key_id</td><td>false</td></tr></tbody></table> |
|
||||
|
||||
@@ -22,15 +22,6 @@ Deprecated options are listed at the end of each section.
|
||||
|
||||
## General
|
||||
|
||||
### Allow workspace renames
|
||||
|
||||
Allow users to rename their workspaces. WARNING: Renaming a workspace can cause Terraform resources that depend on the workspace name to be destroyed and recreated, potentially causing data loss. Only enable this if your templates do not use workspace names in resource identifiers, or if you understand the risks.
|
||||
|
||||
- Environment variable: `CODER_ALLOW_WORKSPACE_RENAMES`
|
||||
- CLI flag: [`--allow-workspace-renames`](../../reference/cli/server.md#--allow-workspace-renames)
|
||||
- YAML key: `allowWorkspaceRenames`
|
||||
- Default value: `false`
|
||||
|
||||
### Cache directory
|
||||
|
||||
The directory to cache temporary files. If unspecified and $CACHE_DIRECTORY is set, it will be used for compatibility with systemd. This directory is NOT safe to be configured as a shared directory across coderd/provisionerd replicas.
|
||||
|
||||
@@ -52,12 +52,19 @@ Because we depend on `coder_workspace.me.owner`, if the owner changes their
|
||||
username, Terraform will recreate the volume (wiping its data!) the next time
|
||||
that Coder starts the workspace.
|
||||
|
||||
To prevent this, use immutable IDs:
|
||||
✅ To prevent this, use immutable IDs:
|
||||
|
||||
- `coder_workspace.me.owner_id`
|
||||
- `coder_workspace.me.id`
|
||||
|
||||
You should also avoid using `coder_workspace.me.name` if your deployment allows workspace renaming via `CODER_ALLOW_WORKSPACE_RENAMES` or `--allow-workspace-renames`.
|
||||
⚠️ Avoid mutable IDs:
|
||||
|
||||
- `coder_workspace.me.name`
|
||||
- `coder_workspace.me.owner`
|
||||
|
||||
Workspace renaming is disabled by default to help prevent this kind of
|
||||
destruction, but a template admin can enable it. Refer to
|
||||
[Workspace renaming](../managing-templates/index.md#workspace-renaming).
|
||||
|
||||
```tf
|
||||
data "coder_workspace" "me" {
|
||||
|
||||
@@ -77,6 +77,49 @@ automatically updated on the next startup.
|
||||
|
||||

|
||||
|
||||
## Workspace renaming
|
||||
|
||||
Workspace renaming is disabled by default on every template.
|
||||
Enable it per template, once you have confirmed that a rename won't destroy anything.
|
||||
|
||||
Terraform exposes the workspace name as `data.coder_workspace.me.name`.
|
||||
If a template uses that value in an attribute Terraform can't change in place, renaming the workspace makes Terraform destroy the resource and create a new one on the next build.
|
||||
When that resource is the home volume, the developer loses their data.
|
||||
|
||||
Other uses of the name are harmless.
|
||||
A Kubernetes label or an environment variable changes without replacing anything.
|
||||
Coder can't tell the two cases apart, so the decision stays with the template admin.
|
||||
|
||||
### Check whether your template is safe to rename
|
||||
|
||||
Search the template for uses of the workspace name:
|
||||
|
||||
```sh
|
||||
grep -rn 'coder_workspace\.[a-z_]*\.name' .
|
||||
```
|
||||
|
||||
For each result, ask whether Terraform would replace the resource if that value changed.
|
||||
Attributes such as a volume name, a disk name, or an instance name usually force replacement.
|
||||
Labels, tags, and environment variables usually don't.
|
||||
|
||||
If a resource would be replaced, reference an immutable identifier instead, such as `data.coder_workspace.me.id`.
|
||||
Refer to [Resource persistence](../extending-templates/resource-persistence.md) for the full set of practices.
|
||||
|
||||
### Enable renaming for a template
|
||||
|
||||
1. Go to the template, then select **Settings**.
|
||||
1. On the **General** page, under **Operations**, select **Allow users to rename their workspaces**.
|
||||
1. Select **Save**.
|
||||
|
||||
Developers can then rename a workspace from the workspace's **Settings** page, or with `coder rename`.
|
||||
|
||||
While the setting is off, the workspace name field is disabled and the API rejects renames.
|
||||
|
||||
> [!WARNING]
|
||||
> The deployment-wide `CODER_ALLOW_WORKSPACE_RENAMES` option is deprecated.
|
||||
> While it is set, renaming is enabled for every template in the deployment, and the per-template setting can't turn it off.
|
||||
> Unset it, then enable renaming on the templates that need it.
|
||||
|
||||
## Delete templates
|
||||
|
||||
You can delete a template using both the coder CLI and UI. Only
|
||||
|
||||
Generated
+86
-79
@@ -6449,6 +6449,7 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in
|
||||
"allow_user_autostart": true,
|
||||
"allow_user_autostop": true,
|
||||
"allow_user_cancel_workspace_jobs": true,
|
||||
"allow_workspace_renames": true,
|
||||
"autostart_requirement": {
|
||||
"days_of_week": [
|
||||
"monday"
|
||||
@@ -6487,6 +6488,7 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in
|
||||
| `allow_user_autostart` | boolean | false | | Allow user autostart allows users to set a schedule for autostarting their workspace. By default this is true. This can only be disabled when using an enterprise license. |
|
||||
| `allow_user_autostop` | boolean | false | | Allow user autostop allows users to set a custom workspace TTL to use in place of the template's DefaultTTL field. By default this is true. If false, the DefaultTTL will always be used. This can only be disabled when using an enterprise license. |
|
||||
| `allow_user_cancel_workspace_jobs` | boolean | false | | Allow users to cancel in-progress workspace jobs. *bool as the default value is "true". |
|
||||
| `allow_workspace_renames` | boolean | false | | Allow workspace renames permits users to rename workspaces built from this template. Renaming can be destructive for templates whose Terraform references the workspace name, so this defaults to false. |
|
||||
| `autostart_requirement` | [codersdk.TemplateAutostartRequirement](#codersdktemplateautostartrequirement) | false | | Autostart requirement allows optionally specifying the autostart allowed days for workspaces created from this template. This is an enterprise feature. |
|
||||
| `autostop_requirement` | [codersdk.TemplateAutostopRequirement](#codersdktemplateautostoprequirement) | false | | Autostop requirement allows optionally specifying the autostop requirement for workspaces created from this template. This is an enterprise feature. |
|
||||
| `cors_behavior` | [codersdk.CORSBehavior](#codersdkcorsbehavior) | false | | Cors behavior allows optionally specifying the CORS behavior for all shared ports. |
|
||||
@@ -8421,84 +8423,84 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o
|
||||
|
||||
### Properties
|
||||
|
||||
| Name | Type | Required | Restrictions | Description |
|
||||
|------------------------------------------------|------------------------------------------------------------------------------------------------------|----------|--------------|--------------------------------------------------------------------|
|
||||
| `access_url` | [serpent.URL](#serpenturl) | false | | |
|
||||
| `additional_csp_policy` | array of string | false | | |
|
||||
| `address` | [serpent.HostPort](#serpenthostport) | false | | Deprecated: Use HTTPAddress or TLS.Address instead. |
|
||||
| `agent_fallback_troubleshooting_url` | [serpent.URL](#serpenturl) | false | | |
|
||||
| `agent_stat_refresh_interval` | integer | false | | |
|
||||
| `ai` | [codersdk.AIConfig](#codersdkaiconfig) | false | | |
|
||||
| `allow_workspace_renames` | boolean | false | | |
|
||||
| `autobuild_poll_interval` | integer | false | | |
|
||||
| `browser_only` | boolean | false | | |
|
||||
| `cache_directory` | string | false | | |
|
||||
| `cli_upgrade_message` | string | false | | |
|
||||
| `cluster` | [codersdk.ClusterConfig](#codersdkclusterconfig) | false | | |
|
||||
| `config` | string | false | | |
|
||||
| `config_ssh` | [codersdk.SSHConfig](#codersdksshconfig) | false | | |
|
||||
| `dangerous` | [codersdk.DangerousConfig](#codersdkdangerousconfig) | false | | |
|
||||
| `derp` | [codersdk.DERP](#codersdkderp) | false | | |
|
||||
| `disable_chat_sharing` | boolean | false | | |
|
||||
| `disable_owner_workspace_exec` | boolean | false | | |
|
||||
| `disable_password_auth` | boolean | false | | |
|
||||
| `disable_path_apps` | boolean | false | | |
|
||||
| `disable_workspace_agent_context_sync` | boolean | false | | |
|
||||
| `disable_workspace_sharing` | boolean | false | | |
|
||||
| `docs_url` | [serpent.URL](#serpenturl) | false | | |
|
||||
| `enable_ai_tasks` | boolean | false | | |
|
||||
| `enable_authz_recording` | boolean | false | | |
|
||||
| `enable_terraform_debug_mode` | boolean | false | | |
|
||||
| `ephemeral_deployment` | boolean | false | | |
|
||||
| `experiments` | array of string | false | | |
|
||||
| `external_auth` | [serpent.Struct-array_codersdk_ExternalAuthConfig](#serpentstruct-array_codersdk_externalauthconfig) | false | | |
|
||||
| `external_auth_github_default_provider_enable` | boolean | false | | |
|
||||
| `external_token_encryption_keys` | array of string | false | | |
|
||||
| `healthcheck` | [codersdk.HealthcheckConfig](#codersdkhealthcheckconfig) | false | | |
|
||||
| `http_address` | string | false | | Http address is a string because it may be set to zero to disable. |
|
||||
| `http_cookies` | [codersdk.HTTPCookieConfig](#codersdkhttpcookieconfig) | false | | |
|
||||
| `job_hang_detector_interval` | integer | false | | |
|
||||
| `logging` | [codersdk.LoggingConfig](#codersdkloggingconfig) | false | | |
|
||||
| `metrics_cache_refresh_interval` | integer | false | | |
|
||||
| `notifications` | [codersdk.NotificationsConfig](#codersdknotificationsconfig) | false | | |
|
||||
| `oauth2` | [codersdk.OAuth2Config](#codersdkoauth2config) | false | | |
|
||||
| `oidc` | [codersdk.OIDCConfig](#codersdkoidcconfig) | false | | |
|
||||
| `pg_auth` | string | false | | |
|
||||
| `pg_conn_max_idle` | string | false | | |
|
||||
| `pg_conn_max_open` | integer | false | | |
|
||||
| `pg_connection_url` | string | false | | |
|
||||
| `pprof` | [codersdk.PprofConfig](#codersdkpprofconfig) | false | | |
|
||||
| `prometheus` | [codersdk.PrometheusConfig](#codersdkprometheusconfig) | false | | |
|
||||
| `provisioner` | [codersdk.ProvisionerConfig](#codersdkprovisionerconfig) | false | | |
|
||||
| `proxy_health_status_interval` | integer | false | | |
|
||||
| `proxy_trusted_headers` | array of string | false | | |
|
||||
| `proxy_trusted_origins` | array of string | false | | |
|
||||
| `rate_limit` | [codersdk.RateLimitConfig](#codersdkratelimitconfig) | false | | |
|
||||
| `redirect_to_access_url` | boolean | false | | |
|
||||
| `retention` | [codersdk.RetentionConfig](#codersdkretentionconfig) | false | | |
|
||||
| `scim_api_key` | string | false | | |
|
||||
| `scim_use_legacy` | boolean | false | | |
|
||||
| `session_lifetime` | [codersdk.SessionLifetime](#codersdksessionlifetime) | false | | |
|
||||
| `ssh_keygen_algorithm` | string | false | | |
|
||||
| `stats_collection` | [codersdk.StatsCollectionConfig](#codersdkstatscollectionconfig) | false | | |
|
||||
| `strict_transport_security` | integer | false | | |
|
||||
| `strict_transport_security_options` | array of string | false | | |
|
||||
| `support` | [codersdk.SupportConfig](#codersdksupportconfig) | false | | |
|
||||
| `swagger` | [codersdk.SwaggerConfig](#codersdkswaggerconfig) | false | | |
|
||||
| `telemetry` | [codersdk.TelemetryConfig](#codersdktelemetryconfig) | false | | |
|
||||
| `template_builder` | [codersdk.TemplateBuilderConfig](#codersdktemplatebuilderconfig) | false | | |
|
||||
| `terms_of_service_url` | string | false | | |
|
||||
| `tls` | [codersdk.TLSConfig](#codersdktlsconfig) | false | | |
|
||||
| `trace` | [codersdk.TraceConfig](#codersdktraceconfig) | false | | |
|
||||
| `update_check` | boolean | false | | |
|
||||
| `user_quiet_hours_schedule` | [codersdk.UserQuietHoursScheduleConfig](#codersdkuserquiethoursscheduleconfig) | false | | |
|
||||
| `verbose` | boolean | false | | |
|
||||
| `web_terminal_renderer` | string | false | | |
|
||||
| `wgtunnel_host` | string | false | | |
|
||||
| `wildcard_access_url` | string | false | | |
|
||||
| `workspace_hostname_suffix` | string | false | | |
|
||||
| `workspace_prebuilds` | [codersdk.PrebuildsConfig](#codersdkprebuildsconfig) | false | | |
|
||||
| `write_config` | boolean | false | | |
|
||||
| Name | Type | Required | Restrictions | Description |
|
||||
|------------------------------------------------|------------------------------------------------------------------------------------------------------|----------|--------------|---------------------------------------------------------------------------|
|
||||
| `access_url` | [serpent.URL](#serpenturl) | false | | |
|
||||
| `additional_csp_policy` | array of string | false | | |
|
||||
| `address` | [serpent.HostPort](#serpenthostport) | false | | Deprecated: Use HTTPAddress or TLS.Address instead. |
|
||||
| `agent_fallback_troubleshooting_url` | [serpent.URL](#serpenturl) | false | | |
|
||||
| `agent_stat_refresh_interval` | integer | false | | |
|
||||
| `ai` | [codersdk.AIConfig](#codersdkaiconfig) | false | | |
|
||||
| `allow_workspace_renames` | boolean | false | | Deprecated: Use the per-template allow_workspace_renames setting instead. |
|
||||
| `autobuild_poll_interval` | integer | false | | |
|
||||
| `browser_only` | boolean | false | | |
|
||||
| `cache_directory` | string | false | | |
|
||||
| `cli_upgrade_message` | string | false | | |
|
||||
| `cluster` | [codersdk.ClusterConfig](#codersdkclusterconfig) | false | | |
|
||||
| `config` | string | false | | |
|
||||
| `config_ssh` | [codersdk.SSHConfig](#codersdksshconfig) | false | | |
|
||||
| `dangerous` | [codersdk.DangerousConfig](#codersdkdangerousconfig) | false | | |
|
||||
| `derp` | [codersdk.DERP](#codersdkderp) | false | | |
|
||||
| `disable_chat_sharing` | boolean | false | | |
|
||||
| `disable_owner_workspace_exec` | boolean | false | | |
|
||||
| `disable_password_auth` | boolean | false | | |
|
||||
| `disable_path_apps` | boolean | false | | |
|
||||
| `disable_workspace_agent_context_sync` | boolean | false | | |
|
||||
| `disable_workspace_sharing` | boolean | false | | |
|
||||
| `docs_url` | [serpent.URL](#serpenturl) | false | | |
|
||||
| `enable_ai_tasks` | boolean | false | | |
|
||||
| `enable_authz_recording` | boolean | false | | |
|
||||
| `enable_terraform_debug_mode` | boolean | false | | |
|
||||
| `ephemeral_deployment` | boolean | false | | |
|
||||
| `experiments` | array of string | false | | |
|
||||
| `external_auth` | [serpent.Struct-array_codersdk_ExternalAuthConfig](#serpentstruct-array_codersdk_externalauthconfig) | false | | |
|
||||
| `external_auth_github_default_provider_enable` | boolean | false | | |
|
||||
| `external_token_encryption_keys` | array of string | false | | |
|
||||
| `healthcheck` | [codersdk.HealthcheckConfig](#codersdkhealthcheckconfig) | false | | |
|
||||
| `http_address` | string | false | | Http address is a string because it may be set to zero to disable. |
|
||||
| `http_cookies` | [codersdk.HTTPCookieConfig](#codersdkhttpcookieconfig) | false | | |
|
||||
| `job_hang_detector_interval` | integer | false | | |
|
||||
| `logging` | [codersdk.LoggingConfig](#codersdkloggingconfig) | false | | |
|
||||
| `metrics_cache_refresh_interval` | integer | false | | |
|
||||
| `notifications` | [codersdk.NotificationsConfig](#codersdknotificationsconfig) | false | | |
|
||||
| `oauth2` | [codersdk.OAuth2Config](#codersdkoauth2config) | false | | |
|
||||
| `oidc` | [codersdk.OIDCConfig](#codersdkoidcconfig) | false | | |
|
||||
| `pg_auth` | string | false | | |
|
||||
| `pg_conn_max_idle` | string | false | | |
|
||||
| `pg_conn_max_open` | integer | false | | |
|
||||
| `pg_connection_url` | string | false | | |
|
||||
| `pprof` | [codersdk.PprofConfig](#codersdkpprofconfig) | false | | |
|
||||
| `prometheus` | [codersdk.PrometheusConfig](#codersdkprometheusconfig) | false | | |
|
||||
| `provisioner` | [codersdk.ProvisionerConfig](#codersdkprovisionerconfig) | false | | |
|
||||
| `proxy_health_status_interval` | integer | false | | |
|
||||
| `proxy_trusted_headers` | array of string | false | | |
|
||||
| `proxy_trusted_origins` | array of string | false | | |
|
||||
| `rate_limit` | [codersdk.RateLimitConfig](#codersdkratelimitconfig) | false | | |
|
||||
| `redirect_to_access_url` | boolean | false | | |
|
||||
| `retention` | [codersdk.RetentionConfig](#codersdkretentionconfig) | false | | |
|
||||
| `scim_api_key` | string | false | | |
|
||||
| `scim_use_legacy` | boolean | false | | |
|
||||
| `session_lifetime` | [codersdk.SessionLifetime](#codersdksessionlifetime) | false | | |
|
||||
| `ssh_keygen_algorithm` | string | false | | |
|
||||
| `stats_collection` | [codersdk.StatsCollectionConfig](#codersdkstatscollectionconfig) | false | | |
|
||||
| `strict_transport_security` | integer | false | | |
|
||||
| `strict_transport_security_options` | array of string | false | | |
|
||||
| `support` | [codersdk.SupportConfig](#codersdksupportconfig) | false | | |
|
||||
| `swagger` | [codersdk.SwaggerConfig](#codersdkswaggerconfig) | false | | |
|
||||
| `telemetry` | [codersdk.TelemetryConfig](#codersdktelemetryconfig) | false | | |
|
||||
| `template_builder` | [codersdk.TemplateBuilderConfig](#codersdktemplatebuilderconfig) | false | | |
|
||||
| `terms_of_service_url` | string | false | | |
|
||||
| `tls` | [codersdk.TLSConfig](#codersdktlsconfig) | false | | |
|
||||
| `trace` | [codersdk.TraceConfig](#codersdktraceconfig) | false | | |
|
||||
| `update_check` | boolean | false | | |
|
||||
| `user_quiet_hours_schedule` | [codersdk.UserQuietHoursScheduleConfig](#codersdkuserquiethoursscheduleconfig) | false | | |
|
||||
| `verbose` | boolean | false | | |
|
||||
| `web_terminal_renderer` | string | false | | |
|
||||
| `wgtunnel_host` | string | false | | |
|
||||
| `wildcard_access_url` | string | false | | |
|
||||
| `workspace_hostname_suffix` | string | false | | |
|
||||
| `workspace_prebuilds` | [codersdk.PrebuildsConfig](#codersdkprebuildsconfig) | false | | |
|
||||
| `write_config` | boolean | false | | |
|
||||
|
||||
## codersdk.DiagnosticExtra
|
||||
|
||||
@@ -13613,6 +13615,7 @@ Git clone makes use of this by parsing the URL from: 'Username for "https://gith
|
||||
"allow_user_autostart": true,
|
||||
"allow_user_autostop": true,
|
||||
"allow_user_cancel_workspace_jobs": true,
|
||||
"allow_workspace_renames": true,
|
||||
"autostart_requirement": {
|
||||
"days_of_week": [
|
||||
"monday"
|
||||
@@ -13675,6 +13678,7 @@ Git clone makes use of this by parsing the URL from: 'Username for "https://gith
|
||||
| `allow_user_autostart` | boolean | false | | Allow user autostart and AllowUserAutostop are enterprise-only. Their values are only used if your license is entitled to use the advanced template scheduling feature. |
|
||||
| `allow_user_autostop` | boolean | false | | |
|
||||
| `allow_user_cancel_workspace_jobs` | boolean | false | | |
|
||||
| `allow_workspace_renames` | boolean | false | | Allow workspace renames permits users to rename workspaces built from this template. Renaming can be destructive for templates whose Terraform references the workspace name. |
|
||||
| `autostart_requirement` | [codersdk.TemplateAutostartRequirement](#codersdktemplateautostartrequirement) | false | | |
|
||||
| `autostop_requirement` | [codersdk.TemplateAutostopRequirement](#codersdktemplateautostoprequirement) | false | | Autostop requirement and AutostartRequirement are enterprise features. Its value is only used if your license is entitled to use the advanced template scheduling feature. |
|
||||
| `build_time_stats` | [codersdk.TemplateBuildTimeStats](#codersdktemplatebuildtimestats) | false | | |
|
||||
@@ -14079,6 +14083,7 @@ Restarts will only happen on weekdays in this list on weeks which line up with W
|
||||
"allow_user_autostart": true,
|
||||
"allow_user_autostop": true,
|
||||
"allow_user_cancel_workspace_jobs": true,
|
||||
"allow_workspace_renames": true,
|
||||
"autostart_requirement": {
|
||||
"days_of_week": [
|
||||
"monday"
|
||||
@@ -15578,6 +15583,7 @@ Restarts will only happen on weekdays in this list on weeks which line up with W
|
||||
"allow_user_autostart": true,
|
||||
"allow_user_autostop": true,
|
||||
"allow_user_cancel_workspace_jobs": true,
|
||||
"allow_workspace_renames": true,
|
||||
"autostart_requirement": {
|
||||
"days_of_week": [
|
||||
"monday"
|
||||
@@ -15619,6 +15625,7 @@ Restarts will only happen on weekdays in this list on weeks which line up with W
|
||||
| `allow_user_autostart` | boolean | false | | |
|
||||
| `allow_user_autostop` | boolean | false | | |
|
||||
| `allow_user_cancel_workspace_jobs` | boolean | false | | |
|
||||
| `allow_workspace_renames` | boolean | false | | Allow workspace renames permits users to rename workspaces built from this template. Renaming can be destructive for templates whose Terraform references the workspace name. |
|
||||
| `autostart_requirement` | [codersdk.TemplateAutostartRequirement](#codersdktemplateautostartrequirement) | false | | |
|
||||
| `autostop_requirement` | [codersdk.TemplateAutostopRequirement](#codersdktemplateautostoprequirement) | false | | Autostop requirement and AutostartRequirement can only be set if your license includes the advanced template scheduling feature. If you attempt to set this value while unlicensed, it will be ignored. |
|
||||
| `cors_behavior` | [codersdk.CORSBehavior](#codersdkcorsbehavior) | false | | |
|
||||
@@ -17049,7 +17056,7 @@ If the schedule is empty, the user will be updated to use the default schedule.|
|
||||
|
||||
| Name | Type | Required | Restrictions | Description |
|
||||
|---------------------------------------------|-------------------------------------------------------------------------|----------|--------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `allow_renames` | boolean | false | | |
|
||||
| `allow_renames` | boolean | false | | Allow renames is the effective rename permission for this workspace, derived from the template's allow_workspace_renames setting and the deprecated deployment-wide flag. |
|
||||
| `automatic_updates` | [codersdk.AutomaticUpdates](#codersdkautomaticupdates) | false | | |
|
||||
| `autostart_schedule` | string | false | | |
|
||||
| `created_at` | string | false | | |
|
||||
|
||||
Generated
+1
@@ -169,6 +169,7 @@ curl -X POST http://coder-server:8080/api/v2/templatebuilder/compose/template \
|
||||
"allow_user_autostart": true,
|
||||
"allow_user_autostop": true,
|
||||
"allow_user_cancel_workspace_jobs": true,
|
||||
"allow_workspace_renames": true,
|
||||
"autostart_requirement": {
|
||||
"days_of_week": [
|
||||
"monday"
|
||||
|
||||
Generated
+36
-26
@@ -42,6 +42,7 @@ To include deprecated templates, specify `deprecated:true` in the search query.
|
||||
"allow_user_autostart": true,
|
||||
"allow_user_autostop": true,
|
||||
"allow_user_cancel_workspace_jobs": true,
|
||||
"allow_workspace_renames": true,
|
||||
"autostart_requirement": {
|
||||
"days_of_week": [
|
||||
"monday"
|
||||
@@ -104,19 +105,20 @@ To include deprecated templates, specify `deprecated:true` in the search query.
|
||||
|
||||
Status Code **200**
|
||||
|
||||
| Name | Type | Required | Restrictions | Description |
|
||||
|--------------------------------------|------------------------------------------------------------------------------------------|----------|--------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `[array item]` | array | false | | |
|
||||
| `» active_user_count` | integer | false | | Active user count is set to -1 when loading. |
|
||||
| `» active_version_id` | string(uuid) | false | | |
|
||||
| `» activity_bump_ms` | integer | false | | |
|
||||
| `» agents_allowed` | boolean | false | | |
|
||||
| `» allow_user_autostart` | boolean | false | | Allow user autostart and AllowUserAutostop are enterprise-only. Their values are only used if your license is entitled to use the advanced template scheduling feature. |
|
||||
| `» allow_user_autostop` | boolean | false | | |
|
||||
| `» allow_user_cancel_workspace_jobs` | boolean | false | | |
|
||||
| `» autostart_requirement` | [codersdk.TemplateAutostartRequirement](schemas.md#codersdktemplateautostartrequirement) | false | | |
|
||||
| `»» days_of_week` | array | false | | Days of week is a list of days of the week in which autostart is allowed to happen. If no days are specified, autostart is not allowed. |
|
||||
| `» autostop_requirement` | [codersdk.TemplateAutostopRequirement](schemas.md#codersdktemplateautostoprequirement) | false | | Autostop requirement and AutostartRequirement are enterprise features. Its value is only used if your license is entitled to use the advanced template scheduling feature. |
|
||||
| Name | Type | Required | Restrictions | Description |
|
||||
|--------------------------------------|------------------------------------------------------------------------------------------|----------|--------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `[array item]` | array | false | | |
|
||||
| `» active_user_count` | integer | false | | Active user count is set to -1 when loading. |
|
||||
| `» active_version_id` | string(uuid) | false | | |
|
||||
| `» activity_bump_ms` | integer | false | | |
|
||||
| `» agents_allowed` | boolean | false | | |
|
||||
| `» allow_user_autostart` | boolean | false | | Allow user autostart and AllowUserAutostop are enterprise-only. Their values are only used if your license is entitled to use the advanced template scheduling feature. |
|
||||
| `» allow_user_autostop` | boolean | false | | |
|
||||
| `» allow_user_cancel_workspace_jobs` | boolean | false | | |
|
||||
| `» allow_workspace_renames` | boolean | false | | Allow workspace renames permits users to rename workspaces built from this template. Renaming can be destructive for templates whose Terraform references the workspace name. |
|
||||
| `» autostart_requirement` | [codersdk.TemplateAutostartRequirement](schemas.md#codersdktemplateautostartrequirement) | false | | |
|
||||
| `»» days_of_week` | array | false | | Days of week is a list of days of the week in which autostart is allowed to happen. If no days are specified, autostart is not allowed. |
|
||||
| `» autostop_requirement` | [codersdk.TemplateAutostopRequirement](schemas.md#codersdktemplateautostoprequirement) | false | | Autostop requirement and AutostartRequirement are enterprise features. Its value is only used if your license is entitled to use the advanced template scheduling feature. |
|
||||
|`»» days_of_week`|array|false||Days of week is a list of days of the week on which restarts are required. Restarts happen within the user's quiet hours (in their configured timezone). If no days are specified, restarts are not required. Weekdays cannot be specified twice.
|
||||
Restarts will only happen on weekdays in this list on weeks which line up with Weeks.|
|
||||
|`»» weeks`|integer|false||Weeks is the number of weeks between required restarts. Weeks are synced across all workspaces (and Coder deployments) using modulo math on a hardcoded epoch week of January 2nd, 2023 (the first Monday of 2023). Values of 0 or 1 indicate weekly restarts. Values of 2 indicate fortnightly restarts, etc.|
|
||||
@@ -185,6 +187,7 @@ curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/templa
|
||||
"allow_user_autostart": true,
|
||||
"allow_user_autostop": true,
|
||||
"allow_user_cancel_workspace_jobs": true,
|
||||
"allow_workspace_renames": true,
|
||||
"autostart_requirement": {
|
||||
"days_of_week": [
|
||||
"monday"
|
||||
@@ -234,6 +237,7 @@ curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/templa
|
||||
"allow_user_autostart": true,
|
||||
"allow_user_autostop": true,
|
||||
"allow_user_cancel_workspace_jobs": true,
|
||||
"allow_workspace_renames": true,
|
||||
"autostart_requirement": {
|
||||
"days_of_week": [
|
||||
"monday"
|
||||
@@ -388,6 +392,7 @@ curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/templat
|
||||
"allow_user_autostart": true,
|
||||
"allow_user_autostop": true,
|
||||
"allow_user_cancel_workspace_jobs": true,
|
||||
"allow_workspace_renames": true,
|
||||
"autostart_requirement": {
|
||||
"days_of_week": [
|
||||
"monday"
|
||||
@@ -812,6 +817,7 @@ To include deprecated templates, specify `deprecated:true` in the search query.
|
||||
"allow_user_autostart": true,
|
||||
"allow_user_autostop": true,
|
||||
"allow_user_cancel_workspace_jobs": true,
|
||||
"allow_workspace_renames": true,
|
||||
"autostart_requirement": {
|
||||
"days_of_week": [
|
||||
"monday"
|
||||
@@ -874,19 +880,20 @@ To include deprecated templates, specify `deprecated:true` in the search query.
|
||||
|
||||
Status Code **200**
|
||||
|
||||
| Name | Type | Required | Restrictions | Description |
|
||||
|--------------------------------------|------------------------------------------------------------------------------------------|----------|--------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `[array item]` | array | false | | |
|
||||
| `» active_user_count` | integer | false | | Active user count is set to -1 when loading. |
|
||||
| `» active_version_id` | string(uuid) | false | | |
|
||||
| `» activity_bump_ms` | integer | false | | |
|
||||
| `» agents_allowed` | boolean | false | | |
|
||||
| `» allow_user_autostart` | boolean | false | | Allow user autostart and AllowUserAutostop are enterprise-only. Their values are only used if your license is entitled to use the advanced template scheduling feature. |
|
||||
| `» allow_user_autostop` | boolean | false | | |
|
||||
| `» allow_user_cancel_workspace_jobs` | boolean | false | | |
|
||||
| `» autostart_requirement` | [codersdk.TemplateAutostartRequirement](schemas.md#codersdktemplateautostartrequirement) | false | | |
|
||||
| `»» days_of_week` | array | false | | Days of week is a list of days of the week in which autostart is allowed to happen. If no days are specified, autostart is not allowed. |
|
||||
| `» autostop_requirement` | [codersdk.TemplateAutostopRequirement](schemas.md#codersdktemplateautostoprequirement) | false | | Autostop requirement and AutostartRequirement are enterprise features. Its value is only used if your license is entitled to use the advanced template scheduling feature. |
|
||||
| Name | Type | Required | Restrictions | Description |
|
||||
|--------------------------------------|------------------------------------------------------------------------------------------|----------|--------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `[array item]` | array | false | | |
|
||||
| `» active_user_count` | integer | false | | Active user count is set to -1 when loading. |
|
||||
| `» active_version_id` | string(uuid) | false | | |
|
||||
| `» activity_bump_ms` | integer | false | | |
|
||||
| `» agents_allowed` | boolean | false | | |
|
||||
| `» allow_user_autostart` | boolean | false | | Allow user autostart and AllowUserAutostop are enterprise-only. Their values are only used if your license is entitled to use the advanced template scheduling feature. |
|
||||
| `» allow_user_autostop` | boolean | false | | |
|
||||
| `» allow_user_cancel_workspace_jobs` | boolean | false | | |
|
||||
| `» allow_workspace_renames` | boolean | false | | Allow workspace renames permits users to rename workspaces built from this template. Renaming can be destructive for templates whose Terraform references the workspace name. |
|
||||
| `» autostart_requirement` | [codersdk.TemplateAutostartRequirement](schemas.md#codersdktemplateautostartrequirement) | false | | |
|
||||
| `»» days_of_week` | array | false | | Days of week is a list of days of the week in which autostart is allowed to happen. If no days are specified, autostart is not allowed. |
|
||||
| `» autostop_requirement` | [codersdk.TemplateAutostopRequirement](schemas.md#codersdktemplateautostoprequirement) | false | | Autostop requirement and AutostartRequirement are enterprise features. Its value is only used if your license is entitled to use the advanced template scheduling feature. |
|
||||
|`»» days_of_week`|array|false||Days of week is a list of days of the week on which restarts are required. Restarts happen within the user's quiet hours (in their configured timezone). If no days are specified, restarts are not required. Weekdays cannot be specified twice.
|
||||
Restarts will only happen on weekdays in this list on weeks which line up with Weeks.|
|
||||
|`»» weeks`|integer|false||Weeks is the number of weeks between required restarts. Weeks are synced across all workspaces (and Coder deployments) using modulo math on a hardcoded epoch week of January 2nd, 2023 (the first Monday of 2023). Values of 0 or 1 indicate weekly restarts. Values of 2 indicate fortnightly restarts, etc.|
|
||||
@@ -1020,6 +1027,7 @@ curl -X GET http://coder-server:8080/api/v2/templates/{template} \
|
||||
"allow_user_autostart": true,
|
||||
"allow_user_autostop": true,
|
||||
"allow_user_cancel_workspace_jobs": true,
|
||||
"allow_workspace_renames": true,
|
||||
"autostart_requirement": {
|
||||
"days_of_week": [
|
||||
"monday"
|
||||
@@ -1146,6 +1154,7 @@ curl -X PATCH http://coder-server:8080/api/v2/templates/{template} \
|
||||
"allow_user_autostart": true,
|
||||
"allow_user_autostop": true,
|
||||
"allow_user_cancel_workspace_jobs": true,
|
||||
"allow_workspace_renames": true,
|
||||
"autostart_requirement": {
|
||||
"days_of_week": [
|
||||
"monday"
|
||||
@@ -1198,6 +1207,7 @@ curl -X PATCH http://coder-server:8080/api/v2/templates/{template} \
|
||||
"allow_user_autostart": true,
|
||||
"allow_user_autostop": true,
|
||||
"allow_user_cancel_workspace_jobs": true,
|
||||
"allow_workspace_renames": true,
|
||||
"autostart_requirement": {
|
||||
"days_of_week": [
|
||||
"monday"
|
||||
|
||||
Generated
-11
@@ -1370,17 +1370,6 @@ Allow users to set their own quiet hours schedule for workspaces to stop in (dep
|
||||
|
||||
The renderer to use when opening a web terminal. Valid values are 'canvas', 'webgl', or 'dom'.
|
||||
|
||||
### --allow-workspace-renames
|
||||
|
||||
| | |
|
||||
|-------------|---------------------------------------------|
|
||||
| Type | <code>bool</code> |
|
||||
| Environment | <code>$CODER_ALLOW_WORKSPACE_RENAMES</code> |
|
||||
| YAML | <code>allowWorkspaceRenames</code> |
|
||||
| Default | <code>false</code> |
|
||||
|
||||
Allow users to rename their workspaces. WARNING: Renaming a workspace can cause Terraform resources that depend on the workspace name to be destroyed and recreated, potentially causing data loss. Only enable this if your templates do not use workspace names in resource identifiers, or if you understand the risks.
|
||||
|
||||
### --health-check-refresh
|
||||
|
||||
| | |
|
||||
|
||||
@@ -45,6 +45,10 @@ coder show <workspace-name>
|
||||
| Reserved names | Cannot use `new` or `create` |
|
||||
| Uniqueness | Must be unique within your workspaces |
|
||||
|
||||
Renaming a workspace after you create it is off by default. A template admin can
|
||||
allow it per template. Refer to
|
||||
[Workspace renaming](../admin/templates/managing-templates/index.md#workspace-renaming).
|
||||
|
||||
## Workspace filtering
|
||||
|
||||
In the Coder UI, you can filter your workspaces using pre-defined filters or
|
||||
|
||||
@@ -136,6 +136,7 @@ var auditableResourcesTypes = map[any]map[string]Action{
|
||||
"disable_module_cache": ActionTrack,
|
||||
"time_til_autostop_notify": ActionTrack,
|
||||
"agents_allowed": ActionTrack,
|
||||
"allow_workspace_renames": ActionTrack,
|
||||
},
|
||||
&database.TemplateVersion{}: {
|
||||
"id": ActionTrack,
|
||||
|
||||
@@ -18,13 +18,6 @@ SUBCOMMANDS:
|
||||
PostgreSQL deployment.
|
||||
|
||||
OPTIONS:
|
||||
--allow-workspace-renames bool, $CODER_ALLOW_WORKSPACE_RENAMES (default: false)
|
||||
Allow users to rename their workspaces. WARNING: Renaming a workspace
|
||||
can cause Terraform resources that depend on the workspace name to be
|
||||
destroyed and recreated, potentially causing data loss. Only enable
|
||||
this if your templates do not use workspace names in resource
|
||||
identifiers, or if you understand the risks.
|
||||
|
||||
--cache-dir string, $CODER_CACHE_DIRECTORY (default: [cache dir])
|
||||
The directory to cache temporary files. If unspecified and
|
||||
$CACHE_DIRECTORY is set, it will be used for compatibility with
|
||||
|
||||
Generated
+26
@@ -4198,6 +4198,12 @@ export interface CreateTemplateRequest {
|
||||
* this template. Defaults to true.
|
||||
*/
|
||||
readonly agents_allowed?: boolean;
|
||||
/**
|
||||
* AllowWorkspaceRenames permits users to rename workspaces built from this
|
||||
* template. Renaming can be destructive for templates whose Terraform
|
||||
* references the workspace name, so this defaults to false.
|
||||
*/
|
||||
readonly allow_workspace_renames?: boolean;
|
||||
}
|
||||
|
||||
// From codersdk/templateversions.go
|
||||
@@ -4835,6 +4841,9 @@ export interface DeploymentValues {
|
||||
readonly enable_terraform_debug_mode?: boolean;
|
||||
readonly user_quiet_hours_schedule?: UserQuietHoursScheduleConfig;
|
||||
readonly web_terminal_renderer?: string;
|
||||
/**
|
||||
* @deprecated Use the per-template allow_workspace_renames setting instead.
|
||||
*/
|
||||
readonly allow_workspace_renames?: boolean;
|
||||
readonly healthcheck?: HealthcheckConfig;
|
||||
readonly retention?: RetentionConfig;
|
||||
@@ -9146,6 +9155,12 @@ export interface Template {
|
||||
* provisioning.
|
||||
*/
|
||||
readonly disable_module_cache: boolean;
|
||||
/**
|
||||
* AllowWorkspaceRenames permits users to rename workspaces built from this
|
||||
* template. Renaming can be destructive for templates whose Terraform
|
||||
* references the workspace name.
|
||||
*/
|
||||
readonly allow_workspace_renames: boolean;
|
||||
}
|
||||
|
||||
// From codersdk/templates.go
|
||||
@@ -10135,6 +10150,12 @@ export interface UpdateTemplateMeta {
|
||||
* this template. If omitted, the current value is preserved.
|
||||
*/
|
||||
readonly agents_allowed?: boolean;
|
||||
/**
|
||||
* AllowWorkspaceRenames permits users to rename workspaces built from this
|
||||
* template. Renaming can be destructive for templates whose Terraform
|
||||
* references the workspace name.
|
||||
*/
|
||||
readonly allow_workspace_renames?: boolean;
|
||||
}
|
||||
|
||||
// From codersdk/users.go
|
||||
@@ -10965,6 +10986,11 @@ export interface Workspace {
|
||||
*/
|
||||
readonly health: WorkspaceHealth;
|
||||
readonly automatic_updates: AutomaticUpdates;
|
||||
/**
|
||||
* AllowRenames is the effective rename permission for this workspace,
|
||||
* derived from the template's allow_workspace_renames setting and the
|
||||
* deprecated deployment-wide flag.
|
||||
*/
|
||||
readonly allow_renames: boolean;
|
||||
readonly favorite: boolean;
|
||||
readonly next_start_at: string | null;
|
||||
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
import { screen, waitFor } from "@testing-library/react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import { MockTemplate } from "#/testHelpers/entities";
|
||||
import { renderComponent } from "#/testHelpers/renderHelpers";
|
||||
import { TemplateSettingsForm } from "./TemplateSettingsForm";
|
||||
|
||||
const renameCheckbox = () =>
|
||||
screen.getByRole("checkbox", {
|
||||
name: /allow users to rename their workspaces/i,
|
||||
});
|
||||
|
||||
const renderForm = (
|
||||
overrides: Partial<Parameters<typeof TemplateSettingsForm>[0]> = {},
|
||||
) => {
|
||||
const onSubmit = vi.fn();
|
||||
renderComponent(
|
||||
<TemplateSettingsForm
|
||||
template={MockTemplate}
|
||||
onSubmit={onSubmit}
|
||||
onCancel={vi.fn()}
|
||||
isSubmitting={false}
|
||||
accessControlEnabled
|
||||
advancedSchedulingEnabled
|
||||
portSharingControlsEnabled
|
||||
{...overrides}
|
||||
/>,
|
||||
);
|
||||
return { onSubmit };
|
||||
};
|
||||
|
||||
describe("TemplateSettingsForm", () => {
|
||||
describe("allow_workspace_renames", () => {
|
||||
it("reflects the template's current value", () => {
|
||||
renderForm({
|
||||
template: { ...MockTemplate, allow_workspace_renames: true },
|
||||
});
|
||||
expect(renameCheckbox()).toBeChecked();
|
||||
});
|
||||
|
||||
it("is unchecked when the template disallows renames", () => {
|
||||
renderForm({
|
||||
template: { ...MockTemplate, allow_workspace_renames: false },
|
||||
});
|
||||
expect(renameCheckbox()).not.toBeChecked();
|
||||
});
|
||||
|
||||
it("submits the new value when toggled on", async () => {
|
||||
const user = userEvent.setup();
|
||||
const { onSubmit } = renderForm({
|
||||
template: { ...MockTemplate, allow_workspace_renames: false },
|
||||
});
|
||||
|
||||
await user.click(renameCheckbox());
|
||||
await user.click(screen.getByRole("button", { name: /save/i }));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(onSubmit).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ allow_workspace_renames: true }),
|
||||
// Formik passes its helpers as a second argument.
|
||||
expect.anything(),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it("submits the new value when toggled off", async () => {
|
||||
const user = userEvent.setup();
|
||||
const { onSubmit } = renderForm({
|
||||
template: { ...MockTemplate, allow_workspace_renames: true },
|
||||
});
|
||||
|
||||
await user.click(renameCheckbox());
|
||||
await user.click(screen.getByRole("button", { name: /save/i }));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(onSubmit).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ allow_workspace_renames: false }),
|
||||
expect.anything(),
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
+36
@@ -19,6 +19,7 @@ import {
|
||||
import { FormField } from "#/components/FormField/FormField";
|
||||
import { IconField } from "#/components/IconField/IconField";
|
||||
import { Label } from "#/components/Label/Label";
|
||||
import { Link } from "#/components/Link/Link";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
@@ -33,6 +34,7 @@ import {
|
||||
} from "#/components/StackLabel/StackLabel";
|
||||
import { Textarea } from "#/components/Textarea/Textarea";
|
||||
import { cn } from "#/utils/cn";
|
||||
import { docs } from "#/utils/docs";
|
||||
import {
|
||||
displayNameValidator,
|
||||
getFormHelpers,
|
||||
@@ -53,6 +55,7 @@ export const validationSchema = Yup.object({
|
||||
),
|
||||
allow_user_cancel_workspace_jobs: Yup.boolean(),
|
||||
agents_allowed: Yup.boolean(),
|
||||
allow_workspace_renames: Yup.boolean(),
|
||||
icon: iconValidator,
|
||||
require_active_version: Yup.boolean(),
|
||||
disable_module_cache: Yup.boolean(),
|
||||
@@ -102,6 +105,7 @@ export const TemplateSettingsForm: FC<TemplateSettingsForm> = ({
|
||||
max_port_share_level: template.max_port_share_level,
|
||||
cors_behavior: template.cors_behavior,
|
||||
disable_module_cache: template.disable_module_cache,
|
||||
allow_workspace_renames: template.allow_workspace_renames,
|
||||
},
|
||||
validationSchema,
|
||||
onSubmit,
|
||||
@@ -307,6 +311,38 @@ export const TemplateSettingsForm: FC<TemplateSettingsForm> = ({
|
||||
</StackLabel>
|
||||
</Label>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start">
|
||||
<Checkbox
|
||||
id="allow_workspace_renames"
|
||||
name="allow_workspace_renames"
|
||||
checked={form.values.allow_workspace_renames}
|
||||
onCheckedChange={(checked) => {
|
||||
form.setFieldValue("allow_workspace_renames", checked === true);
|
||||
}}
|
||||
disabled={isSubmitting}
|
||||
/>
|
||||
<Label htmlFor="allow_workspace_renames">
|
||||
<StackLabel>
|
||||
Allow users to rename their workspaces.
|
||||
<StackLabelHelperText>
|
||||
<div>
|
||||
Only enable this if your template does not use the workspace
|
||||
name in such a way that changing it may destroy/recreate a
|
||||
resource.
|
||||
</div>
|
||||
<Link
|
||||
className="text-xs"
|
||||
href={docs(
|
||||
"/admin/templates/extending-templates/resource-persistence",
|
||||
)}
|
||||
>
|
||||
Learn more
|
||||
</Link>
|
||||
</StackLabelHelperText>
|
||||
</StackLabel>
|
||||
</Label>
|
||||
</div>
|
||||
</FormFields>
|
||||
</FormSection>
|
||||
|
||||
|
||||
+1
@@ -46,6 +46,7 @@ const validFormValues: FormValues = {
|
||||
use_classic_parameter_flow: true,
|
||||
cors_behavior: "simple",
|
||||
disable_module_cache: false,
|
||||
allow_workspace_renames: false,
|
||||
};
|
||||
|
||||
describe("TemplateSettingsPage", () => {
|
||||
|
||||
@@ -963,6 +963,7 @@ export const MockTemplate: TypesGen.Template = {
|
||||
use_classic_parameter_flow: false,
|
||||
cors_behavior: "simple",
|
||||
disable_module_cache: false,
|
||||
allow_workspace_renames: false,
|
||||
};
|
||||
|
||||
const _MockTemplateVersionFiles: TemplateVersionFiles = {
|
||||
|
||||
Reference in New Issue
Block a user