diff --git a/cli/templatecreate.go b/cli/templatecreate.go index 51a4c33cfa226..62de354fc4c1c 100644 --- a/cli/templatecreate.go +++ b/cli/templatecreate.go @@ -1,6 +1,7 @@ package cli import ( + "context" "errors" "fmt" "io" @@ -46,39 +47,22 @@ func (r *RootCmd) templateCreate() *clibase.Cmd { r.InitClient(client), ), Handler: func(inv *clibase.Invocation) error { - isTemplateSchedulingOptionsSet := failureTTL != 0 || dormancyThreshold != 0 || dormancyAutoDeletion != 0 || maxTTL != 0 - - if isTemplateSchedulingOptionsSet || requireActiveVersion { - if failureTTL != 0 || dormancyThreshold != 0 || dormancyAutoDeletion != 0 { - // This call can be removed when workspace_actions is no longer experimental - experiments, exErr := client.Experiments(inv.Context()) - if exErr != nil { - return xerrors.Errorf("get experiments: %w", exErr) - } - - if !experiments.Enabled(codersdk.ExperimentWorkspaceActions) { - return xerrors.Errorf("--failure-ttl, --dormancy-threshold, and --dormancy-auto-deletion are experimental features. Use the workspace_actions CODER_EXPERIMENTS flag to set these configuration values.") - } - } - - entitlements, err := client.Entitlements(inv.Context()) - if cerr, ok := codersdk.AsError(err); ok && cerr.StatusCode() == http.StatusNotFound { - return xerrors.Errorf("your deployment appears to be an AGPL deployment, so you cannot set enterprise-only flags") - } else if err != nil { - return xerrors.Errorf("get entitlements: %w", err) - } - - if isTemplateSchedulingOptionsSet { - if !entitlements.Features[codersdk.FeatureAdvancedTemplateScheduling].Enabled { - return xerrors.Errorf("your license is not entitled to use advanced template scheduling, so you cannot set --failure-ttl, --inactivity-ttl, or --max-ttl") - } - } - - if requireActiveVersion { - if !entitlements.Features[codersdk.FeatureAccessControl].Enabled { - return xerrors.Errorf("your license is not entitled to use enterprise access control, so you cannot set --require-active-version") - } - } + _, _ = fmt.Fprintln(inv.Stdout, "\n"+pretty.Sprint(cliui.DefaultStyles.Wrap, + pretty.Sprint( + cliui.DefaultStyles.Warn, "DEPRECATION WARNING: The `coder templates push` command should be used instead. This command will be removed in a future release. ")+"\n")) + time.Sleep(1 * time.Second) + + err := checkTemplateCreateEntitlements(inv.Context(), checkTemplateCreateEntitlementsArgs{ + client: client, + requireActiveVersion: requireActiveVersion, + defaultTTL: defaultTTL, + failureTTL: failureTTL, + dormancyThreshold: dormancyThreshold, + dormancyAutoDeletion: dormancyAutoDeletion, + maxTTL: maxTTL, + }) + if err != nil { + return err } organization, err := CurrentOrganization(inv, client) @@ -357,3 +341,52 @@ func ParseProvisionerTags(rawTags []string) (map[string]string, error) { } return tags, nil } + +type checkTemplateCreateEntitlementsArgs struct { + client *codersdk.Client + requireActiveVersion bool + defaultTTL time.Duration + failureTTL time.Duration + dormancyThreshold time.Duration + dormancyAutoDeletion time.Duration + maxTTL time.Duration +} + +func checkTemplateCreateEntitlements(ctx context.Context, args checkTemplateCreateEntitlementsArgs) error { + isTemplateSchedulingOptionsSet := args.failureTTL != 0 || args.dormancyThreshold != 0 || args.dormancyAutoDeletion != 0 || args.maxTTL != 0 + + if isTemplateSchedulingOptionsSet || args.requireActiveVersion { + if args.failureTTL != 0 || args.dormancyThreshold != 0 || args.dormancyAutoDeletion != 0 { + // This call can be removed when workspace_actions is no longer experimental + experiments, exErr := args.client.Experiments(ctx) + if exErr != nil { + return xerrors.Errorf("get experiments: %w", exErr) + } + + if !experiments.Enabled(codersdk.ExperimentWorkspaceActions) { + return xerrors.Errorf("--failure-ttl, --dormancy-threshold, and --dormancy-auto-deletion are experimental features. Use the workspace_actions CODER_EXPERIMENTS flag to set these configuration values.") + } + } + + entitlements, err := args.client.Entitlements(ctx) + if cerr, ok := codersdk.AsError(err); ok && cerr.StatusCode() == http.StatusNotFound { + return xerrors.Errorf("your deployment appears to be an AGPL deployment, so you cannot set enterprise-only flags") + } else if err != nil { + return xerrors.Errorf("get entitlements: %w", err) + } + + if isTemplateSchedulingOptionsSet { + if !entitlements.Features[codersdk.FeatureAdvancedTemplateScheduling].Enabled { + return xerrors.Errorf("your license is not entitled to use advanced template scheduling, so you cannot set --failure-ttl, --inactivity-ttl, or --max-ttl") + } + } + + if args.requireActiveVersion { + if !entitlements.Features[codersdk.FeatureAccessControl].Enabled { + return xerrors.Errorf("your license is not entitled to use enterprise access control, so you cannot set --require-active-version") + } + } + } + + return nil +} diff --git a/cli/templateedit.go b/cli/templateedit.go index 9cbcefc88730f..39f7c34537fb4 100644 --- a/cli/templateedit.go +++ b/cli/templateedit.go @@ -1,6 +1,7 @@ package cli import ( + "context" "fmt" "net/http" "strings" @@ -46,49 +47,6 @@ func (r *RootCmd) templateEdit() *clibase.Cmd { ), Short: "Edit the metadata of a template by name.", Handler: func(inv *clibase.Invocation) error { - // This clause can be removed when workspace_actions is no longer experimental - if failureTTL != 0 || dormancyThreshold != 0 || dormancyAutoDeletion != 0 { - experiments, exErr := client.Experiments(inv.Context()) - if exErr != nil { - return xerrors.Errorf("get experiments: %w", exErr) - } - - if !experiments.Enabled(codersdk.ExperimentWorkspaceActions) { - return xerrors.Errorf("--failure-ttl, --dormancy-threshold, and --dormancy-auto-deletion are experimental features. Use the workspace_actions CODER_EXPERIMENTS flag to set these configuration values.") - } - } - - unsetAutostopRequirementDaysOfWeek := len(autostopRequirementDaysOfWeek) == 1 && autostopRequirementDaysOfWeek[0] == "none" - requiresScheduling := (len(autostopRequirementDaysOfWeek) > 0 && !unsetAutostopRequirementDaysOfWeek) || - autostopRequirementWeeks > 0 || - !allowUserAutostart || - !allowUserAutostop || - maxTTL != 0 || - failureTTL != 0 || - dormancyThreshold != 0 || - dormancyAutoDeletion != 0 || - len(autostartRequirementDaysOfWeek) > 0 - - requiresEntitlement := requiresScheduling || requireActiveVersion - if requiresEntitlement { - entitlements, err := client.Entitlements(inv.Context()) - if cerr, ok := codersdk.AsError(err); ok && cerr.StatusCode() == http.StatusNotFound { - return xerrors.Errorf("your deployment appears to be an AGPL deployment, so you cannot set enterprise-only flags") - } else if err != nil { - return xerrors.Errorf("get entitlements: %w", err) - } - - if requiresScheduling && !entitlements.Features[codersdk.FeatureAdvancedTemplateScheduling].Enabled { - return xerrors.Errorf("your license is not entitled to use advanced template scheduling, so you cannot set --max-ttl, --failure-ttl, --inactivityTTL, --allow-user-autostart=false or --allow-user-autostop=false") - } - - if requireActiveVersion { - if !entitlements.Features[codersdk.FeatureAccessControl].Enabled { - return xerrors.Errorf("your license is not entitled to use enterprise access control, so you cannot set --require-active-version") - } - } - } - organization, err := CurrentOrganization(inv, client) if err != nil { return xerrors.Errorf("get current organization: %w", err) @@ -98,71 +56,51 @@ func (r *RootCmd) templateEdit() *clibase.Cmd { return xerrors.Errorf("get workspace template: %w", err) } - // Copy the default value if the list is empty, or if the user - // specified the "none" value clear the list. - if len(autostopRequirementDaysOfWeek) == 0 { - autostopRequirementDaysOfWeek = template.AutostopRequirement.DaysOfWeek - } - if len(autostartRequirementDaysOfWeek) == 1 && autostartRequirementDaysOfWeek[0] == "all" { - // Set it to every day of the week - autostartRequirementDaysOfWeek = []string{"monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"} - } else if len(autostartRequirementDaysOfWeek) == 0 { - autostartRequirementDaysOfWeek = template.AutostartRequirement.DaysOfWeek - } - if unsetAutostopRequirementDaysOfWeek { - autostopRequirementDaysOfWeek = []string{} - } - if failureTTL == 0 { - failureTTL = time.Duration(template.FailureTTLMillis) * time.Millisecond - } - if dormancyThreshold == 0 { - dormancyThreshold = time.Duration(template.TimeTilDormantMillis) * time.Millisecond - } - if dormancyAutoDeletion == 0 { - dormancyAutoDeletion = time.Duration(template.TimeTilDormantAutoDeleteMillis) * time.Millisecond - } - - // Default values - if !userSetOption(inv, "description") { - description = template.Description - } + unsetAutostopRequirementDaysOfWeek, err := checkEditTemplateEntitlements(inv.Context(), checkEditTemplateEntitlementsArgs{ + client: client, + inv: inv, - if !userSetOption(inv, "icon") { - icon = template.Icon - } - - if !userSetOption(inv, "display-name") { - displayName = template.DisplayName + defaultTTL: defaultTTL, + maxTTL: maxTTL, + autostopRequirementDaysOfWeek: autostopRequirementDaysOfWeek, + autostopRequirementWeeks: autostopRequirementWeeks, + autostartRequirementDaysOfWeek: autostartRequirementDaysOfWeek, + failureTTL: failureTTL, + dormancyThreshold: dormancyThreshold, + dormancyAutoDeletion: dormancyAutoDeletion, + allowUserCancelWorkspaceJobs: allowUserCancelWorkspaceJobs, + allowUserAutostart: allowUserAutostart, + allowUserAutostop: allowUserAutostop, + requireActiveVersion: requireActiveVersion, + }) + if err != nil { + return err } - var deprecated *string - if !userSetOption(inv, "deprecated") { - deprecated = &deprecationMessage - } + req := updateTemplateMetaRequest(updateTemplateMetaArgs{ + client: client, + inv: inv, + template: template, + unsetAutostopRequirementDaysOfWeek: unsetAutostopRequirementDaysOfWeek, - req := codersdk.UpdateTemplateMeta{ - Name: name, - DisplayName: displayName, - Description: description, - Icon: icon, - DefaultTTLMillis: defaultTTL.Milliseconds(), - MaxTTLMillis: maxTTL.Milliseconds(), - AutostopRequirement: &codersdk.TemplateAutostopRequirement{ - DaysOfWeek: autostopRequirementDaysOfWeek, - Weeks: autostopRequirementWeeks, - }, - AutostartRequirement: &codersdk.TemplateAutostartRequirement{ - DaysOfWeek: autostartRequirementDaysOfWeek, - }, - FailureTTLMillis: failureTTL.Milliseconds(), - TimeTilDormantMillis: dormancyThreshold.Milliseconds(), - TimeTilDormantAutoDeleteMillis: dormancyAutoDeletion.Milliseconds(), - AllowUserCancelWorkspaceJobs: allowUserCancelWorkspaceJobs, - AllowUserAutostart: allowUserAutostart, - AllowUserAutostop: allowUserAutostop, - RequireActiveVersion: requireActiveVersion, - DeprecationMessage: deprecated, - } + name: name, + displayName: displayName, + description: description, + icon: icon, + defaultTTL: defaultTTL, + maxTTL: maxTTL, + autostopRequirementDaysOfWeek: autostopRequirementDaysOfWeek, + autostopRequirementWeeks: autostopRequirementWeeks, + autostartRequirementDaysOfWeek: autostartRequirementDaysOfWeek, + failureTTL: failureTTL, + dormancyThreshold: dormancyThreshold, + dormancyAutoDeletion: dormancyAutoDeletion, + allowUserCancelWorkspaceJobs: allowUserCancelWorkspaceJobs, + allowUserAutostart: allowUserAutostart, + allowUserAutostop: allowUserAutostop, + requireActiveVersion: requireActiveVersion, + deprecationMessage: deprecationMessage, + }) _, err = client.UpdateTemplateMeta(inv.Context(), template.ID, req) if err != nil { @@ -297,3 +235,170 @@ func (r *RootCmd) templateEdit() *clibase.Cmd { return cmd } + +type checkEditTemplateEntitlementsArgs struct { + client *codersdk.Client + inv *clibase.Invocation + + defaultTTL time.Duration + maxTTL time.Duration + autostopRequirementDaysOfWeek []string + autostopRequirementWeeks int64 + autostartRequirementDaysOfWeek []string + failureTTL time.Duration + dormancyThreshold time.Duration + dormancyAutoDeletion time.Duration + allowUserCancelWorkspaceJobs bool + allowUserAutostart bool + allowUserAutostop bool + requireActiveVersion bool +} + +func checkEditTemplateEntitlements(ctx context.Context, args checkEditTemplateEntitlementsArgs) (bool, error) { + // This clause can be removed when workspace_actions is no longer experimental + if args.failureTTL != 0 || args.dormancyThreshold != 0 || args.dormancyAutoDeletion != 0 { + experiments, exErr := args.client.Experiments(ctx) + if exErr != nil { + return false, xerrors.Errorf("get experiments: %w", exErr) + } + + if !experiments.Enabled(codersdk.ExperimentWorkspaceActions) { + return false, xerrors.Errorf("--failure-ttl, --dormancy-threshold, and --dormancy-auto-deletion are experimental features. Use the workspace_actions CODER_EXPERIMENTS flag to set these configuration values.") + } + } + + unsetAutostopRequirementDaysOfWeek := len(args.autostopRequirementDaysOfWeek) == 1 && args.autostopRequirementDaysOfWeek[0] == "none" + requiresScheduling := (len(args.autostopRequirementDaysOfWeek) > 0 && !unsetAutostopRequirementDaysOfWeek) || + args.autostopRequirementWeeks > 0 || + !args.allowUserAutostart || + !args.allowUserAutostop || + args.maxTTL != 0 || + args.failureTTL != 0 || + args.dormancyThreshold != 0 || + args.dormancyAutoDeletion != 0 || + len(args.autostartRequirementDaysOfWeek) > 0 + + requiresEntitlement := requiresScheduling || args.requireActiveVersion + if requiresEntitlement { + entitlements, err := args.client.Entitlements(ctx) + if cerr, ok := codersdk.AsError(err); ok && cerr.StatusCode() == http.StatusNotFound { + return false, xerrors.Errorf("your deployment appears to be an AGPL deployment, so you cannot set enterprise-only flags") + } else if err != nil { + return false, xerrors.Errorf("get entitlements: %w", err) + } + + if requiresScheduling && !entitlements.Features[codersdk.FeatureAdvancedTemplateScheduling].Enabled { + return false, xerrors.Errorf("your license is not entitled to use advanced template scheduling, so you cannot set --max-ttl, --failure-ttl, --inactivityTTL, --allow-user-autostart=false or --allow-user-autostop=false") + } + + if args.requireActiveVersion { + if !entitlements.Features[codersdk.FeatureAccessControl].Enabled { + return false, xerrors.Errorf("your license is not entitled to use enterprise access control, so you cannot set --require-active-version") + } + } + } + + return unsetAutostopRequirementDaysOfWeek, nil +} + +type updateTemplateMetaArgs struct { + client *codersdk.Client + inv *clibase.Invocation + template codersdk.Template + unsetAutostopRequirementDaysOfWeek bool + + name string + displayName string + description string + icon string + defaultTTL time.Duration + maxTTL time.Duration + autostopRequirementDaysOfWeek []string + autostopRequirementWeeks int64 + autostartRequirementDaysOfWeek []string + failureTTL time.Duration + dormancyThreshold time.Duration + dormancyAutoDeletion time.Duration + allowUserCancelWorkspaceJobs bool + allowUserAutostart bool + allowUserAutostop bool + requireActiveVersion bool + deprecationMessage string + disableEveryone bool +} + +func updateTemplateMetaRequest(args updateTemplateMetaArgs) codersdk.UpdateTemplateMeta { + // Copy the default value if the list is empty, or if the user + // specified the "none" value clear the list. + if len(args.autostopRequirementDaysOfWeek) == 0 { + args.autostopRequirementDaysOfWeek = args.template.AutostopRequirement.DaysOfWeek + } + if len(args.autostartRequirementDaysOfWeek) == 1 && args.autostartRequirementDaysOfWeek[0] == "all" { + // Set it to every day of the week + args.autostartRequirementDaysOfWeek = []string{"monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"} + } else if len(args.autostartRequirementDaysOfWeek) == 0 { + args.autostartRequirementDaysOfWeek = args.template.AutostartRequirement.DaysOfWeek + } + if args.unsetAutostopRequirementDaysOfWeek { + args.autostopRequirementDaysOfWeek = []string{} + } + unsetDefaultTTL, err := time.ParseDuration("24h") + if err != nil { + panic(err) + } + + if args.defaultTTL == unsetDefaultTTL { + args.defaultTTL = time.Duration(args.template.DefaultTTLMillis) * time.Millisecond + } + if args.failureTTL == 0 { + args.failureTTL = time.Duration(args.template.FailureTTLMillis) * time.Millisecond + } + if args.dormancyThreshold == 0 { + args.dormancyThreshold = time.Duration(args.template.TimeTilDormantMillis) * time.Millisecond + } + if args.dormancyAutoDeletion == 0 { + args.dormancyAutoDeletion = time.Duration(args.template.TimeTilDormantAutoDeleteMillis) * time.Millisecond + } + + // Default values + if !userSetOption(args.inv, "description") { + args.description = args.template.Description + } + + if !userSetOption(args.inv, "icon") { + args.icon = args.template.Icon + } + + if !userSetOption(args.inv, "display-name") { + args.displayName = args.template.DisplayName + } + + var deprecated *string + if !userSetOption(args.inv, "deprecated") { + deprecated = &args.deprecationMessage + } + + return codersdk.UpdateTemplateMeta{ + Name: args.name, + DisplayName: args.displayName, + Description: args.description, + Icon: args.icon, + DefaultTTLMillis: args.defaultTTL.Milliseconds(), + MaxTTLMillis: args.maxTTL.Milliseconds(), + AutostopRequirement: &codersdk.TemplateAutostopRequirement{ + DaysOfWeek: args.autostopRequirementDaysOfWeek, + Weeks: args.autostopRequirementWeeks, + }, + AutostartRequirement: &codersdk.TemplateAutostartRequirement{ + DaysOfWeek: args.autostartRequirementDaysOfWeek, + }, + FailureTTLMillis: args.failureTTL.Milliseconds(), + TimeTilDormantMillis: args.dormancyThreshold.Milliseconds(), + TimeTilDormantAutoDeleteMillis: args.dormancyAutoDeletion.Milliseconds(), + AllowUserCancelWorkspaceJobs: args.allowUserCancelWorkspaceJobs, + AllowUserAutostart: args.allowUserAutostart, + AllowUserAutostop: args.allowUserAutostop, + RequireActiveVersion: args.requireActiveVersion, + DeprecationMessage: deprecated, + } +} diff --git a/cli/templatepush.go b/cli/templatepush.go index 4c903ef7ca4d9..0b1d765d0b4f1 100644 --- a/cli/templatepush.go +++ b/cli/templatepush.go @@ -2,12 +2,15 @@ package cli import ( "bufio" + "errors" "fmt" "io" + "net/http" "os" "path/filepath" "strings" "time" + "unicode/utf8" "github.com/briandowns/spinner" "golang.org/x/xerrors" @@ -165,7 +168,24 @@ func (r *RootCmd) templatePush() *clibase.Cmd { provisionerTags []string uploadFlags templateUploadFlags activate bool - create bool + + displayName string + description string + icon string + requireActiveVersion bool + disableEveryone bool + defaultTTL time.Duration + failureTTL time.Duration + dormancyThreshold time.Duration + dormancyAutoDeletion time.Duration + maxTTL time.Duration + autostopRequirementDaysOfWeek []string + autostopRequirementWeeks int64 + autostartRequirementDaysOfWeek []string + allowUserAutostart bool + allowUserAutostop bool + allowUserCancelWorkspaceJobs bool + deprecationMessage string ) client := new(codersdk.Client) cmd := &clibase.Cmd{ @@ -178,6 +198,39 @@ func (r *RootCmd) templatePush() *clibase.Cmd { Handler: func(inv *clibase.Invocation) error { uploadFlags.setWorkdir(workdir) + err := checkTemplateCreateEntitlements(inv.Context(), checkTemplateCreateEntitlementsArgs{ + client: client, + requireActiveVersion: requireActiveVersion, + defaultTTL: defaultTTL, + failureTTL: failureTTL, + dormancyThreshold: dormancyThreshold, + dormancyAutoDeletion: dormancyAutoDeletion, + maxTTL: maxTTL, + }) + if err != nil { + return err + } + + unsetAutostopRequirementDaysOfWeek, err := checkEditTemplateEntitlements(inv.Context(), checkEditTemplateEntitlementsArgs{ + client: client, + inv: inv, + defaultTTL: defaultTTL, + maxTTL: maxTTL, + autostopRequirementDaysOfWeek: autostopRequirementDaysOfWeek, + autostopRequirementWeeks: autostopRequirementWeeks, + autostartRequirementDaysOfWeek: autostartRequirementDaysOfWeek, + failureTTL: failureTTL, + dormancyThreshold: dormancyThreshold, + dormancyAutoDeletion: dormancyAutoDeletion, + allowUserCancelWorkspaceJobs: allowUserCancelWorkspaceJobs, + allowUserAutostart: allowUserAutostart, + allowUserAutostop: allowUserAutostop, + requireActiveVersion: requireActiveVersion, + }) + if err != nil { + return err + } + organization, err := CurrentOrganization(inv, client) if err != nil { return err @@ -188,10 +241,15 @@ func (r *RootCmd) templatePush() *clibase.Cmd { return err } + if utf8.RuneCountInString(name) > 31 { + return xerrors.Errorf("Template name must be less than 32 characters") + } + var createTemplate bool template, err := client.TemplateByName(inv.Context(), organization.ID, name) if err != nil { - if !create { + var apiError *codersdk.Error + if errors.As(err, &apiError) && apiError.StatusCode() != http.StatusNotFound { return err } createTemplate = true @@ -269,6 +327,46 @@ func (r *RootCmd) templatePush() *clibase.Cmd { } _, _ = fmt.Fprintf(inv.Stdout, "Updated version at %s!\n", pretty.Sprint(cliui.DefaultStyles.DateTimeStamp, time.Now().Format(time.Stamp))) + + // refresh template data for edit api call + template, err = client.TemplateByName(inv.Context(), organization.ID, name) + if err != nil { + return err + } + req := updateTemplateMetaRequest(updateTemplateMetaArgs{ + client: client, + inv: inv, + template: template, + unsetAutostopRequirementDaysOfWeek: unsetAutostopRequirementDaysOfWeek, + + displayName: displayName, + description: description, + icon: icon, + requireActiveVersion: requireActiveVersion, + disableEveryone: disableEveryone, + defaultTTL: defaultTTL, + failureTTL: failureTTL, + dormancyThreshold: dormancyThreshold, + dormancyAutoDeletion: dormancyAutoDeletion, + maxTTL: maxTTL, + autostopRequirementDaysOfWeek: autostopRequirementDaysOfWeek, + autostopRequirementWeeks: autostopRequirementWeeks, + autostartRequirementDaysOfWeek: autostartRequirementDaysOfWeek, + allowUserAutostart: allowUserAutostart, + allowUserAutostop: allowUserAutostop, + allowUserCancelWorkspaceJobs: allowUserCancelWorkspaceJobs, + deprecationMessage: deprecationMessage, + }) + + _, err = client.UpdateTemplateMeta(inv.Context(), template.ID, req) + if err != nil { + return xerrors.Errorf("update template metadata: %w", err) + } + if err != nil { + return err + } + _, _ = fmt.Fprintf(inv.Stdout, "Updated template metadata at %s!\n", pretty.Sprint(cliui.DefaultStyles.DateTimeStamp, time.Now().Format(time.Stamp))) + return nil }, } @@ -315,6 +413,27 @@ func (r *RootCmd) templatePush() *clibase.Cmd { Description: "Specify a name for the new template version. It will be automatically generated if not provided.", Value: clibase.StringOf(&versionName), }, + { + Flag: "display-name", + Description: "Edit the template display name.", + Value: clibase.StringOf(&displayName), + }, + { + Flag: "description", + Description: "Edit the template description.", + Value: clibase.StringOf(&description), + }, + { + Name: "Deprecated", + Flag: "deprecated", + Description: "Sets the template as deprecated. Must be a message explaining why the template is deprecated.", + Value: clibase.StringOf(&deprecationMessage), + }, + { + Flag: "icon", + Description: "Edit the template icon path.", + Value: clibase.StringOf(&icon), + }, { Flag: "always-prompt", Description: "Always prompt all parameters. Does not pull parameter values from active template version.", @@ -327,10 +446,103 @@ func (r *RootCmd) templatePush() *clibase.Cmd { Value: clibase.BoolOf(&activate), }, { - Flag: "create", - Description: "Create the template if it does not exist.", + Flag: "require-active-version", + Description: "Requires workspace builds to use the active template version. This setting does not apply to template admins. This is an enterprise-only feature.", + Value: clibase.BoolOf(&requireActiveVersion), Default: "false", - Value: clibase.BoolOf(&create), + }, + { + Flag: "default-ttl", + Description: "Specify a default TTL for workspaces created from this template. It is the default time before shutdown - workspaces created from this template default to this value. Maps to \"Default autostop\" in the UI.", + Default: "24h", + Value: clibase.DurationOf(&defaultTTL), + }, + { + Flag: "failure-ttl", + Description: "Specify a failure TTL for workspaces created from this template. It is the amount of time after a failed \"start\" build before coder automatically schedules a \"stop\" build to cleanup.This licensed feature's default is 0h (off). Maps to \"Failure cleanup\"in the UI.", + Default: "0h", + Value: clibase.DurationOf(&failureTTL), + }, + { + Flag: "dormancy-threshold", + Description: "Specify a duration workspaces may be inactive prior to being moved to the dormant state. This licensed feature's default is 0h (off). Maps to \"Dormancy threshold\" in the UI.", + Default: "0h", + Value: clibase.DurationOf(&dormancyThreshold), + }, + { + Flag: "dormancy-auto-deletion", + Description: "Specify a duration workspaces may be in the dormant state prior to being deleted. This licensed feature's default is 0h (off). Maps to \"Dormancy Auto-Deletion\" in the UI.", + Default: "0h", + Value: clibase.DurationOf(&dormancyAutoDeletion), + }, + { + Flag: "max-ttl", + Description: "Edit the template maximum time before shutdown - workspaces created from this template must shutdown within the given duration after starting. This is an enterprise-only feature.", + Value: clibase.DurationOf(&maxTTL), + }, + { + Flag: "private", + Description: "Disable the default behavior of granting template access to the 'everyone' group. " + + "The template permissions must be updated to allow non-admin users to use this template.", + Value: clibase.BoolOf(&disableEveryone), + }, + { + Flag: "autostart-requirement-weekdays", + // workspaces created from this template must be restarted on the given weekdays. To unset this value for the template (and disable the autostop requirement for the template), pass 'none'. + Description: "Edit the template autostart requirement weekdays - workspaces created from this template can only autostart on the given weekdays. To unset this value for the template (and allow autostart on all days), pass 'all'.", + Value: clibase.Validate(clibase.StringArrayOf(&autostartRequirementDaysOfWeek), func(value *clibase.StringArray) error { + v := value.GetSlice() + if len(v) == 1 && v[0] == "all" { + return nil + } + _, err := codersdk.WeekdaysToBitmap(v) + if err != nil { + return xerrors.Errorf("invalid autostart requirement days of week %q: %w", strings.Join(v, ","), err) + } + return nil + }), + }, + { + Flag: "autostop-requirement-weekdays", + Description: "Edit the template autostop requirement weekdays - workspaces created from this template must be restarted on the given weekdays. To unset this value for the template (and disable the autostop requirement for the template), pass 'none'.", + // TODO(@dean): unhide when we delete max_ttl + Hidden: true, + Value: clibase.Validate(clibase.StringArrayOf(&autostopRequirementDaysOfWeek), func(value *clibase.StringArray) error { + v := value.GetSlice() + if len(v) == 1 && v[0] == "none" { + return nil + } + _, err := codersdk.WeekdaysToBitmap(v) + if err != nil { + return xerrors.Errorf("invalid autostop requirement days of week %q: %w", strings.Join(v, ","), err) + } + return nil + }), + }, + { + Flag: "autostop-requirement-weeks", + Description: "Edit the template autostop requirement weeks - workspaces created from this template must be restarted on an n-weekly basis.", + // TODO(@dean): unhide when we delete max_ttl + Hidden: true, + Value: clibase.Int64Of(&autostopRequirementWeeks), + }, + { + Flag: "allow-user-cancel-workspace-jobs", + Description: "Allow users to cancel in-progress workspace jobs.", + Default: "true", + Value: clibase.BoolOf(&allowUserCancelWorkspaceJobs), + }, + { + Flag: "allow-user-autostart", + Description: "Allow users to configure autostart for workspaces on this template. This can only be disabled in enterprise.", + Default: "true", + Value: clibase.BoolOf(&allowUserAutostart), + }, + { + Flag: "allow-user-autostop", + Description: "Allow users to customize the autostop TTL for workspaces on this template. This can only be disabled in enterprise.", + Default: "true", + Value: clibase.BoolOf(&allowUserAutostop), }, cliui.SkipPromptOption(), } diff --git a/cli/templatepush_test.go b/cli/templatepush_test.go index 5736df8cc2edf..0c129f9ad07f4 100644 --- a/cli/templatepush_test.go +++ b/cli/templatepush_test.go @@ -6,8 +6,10 @@ import ( "os" "path/filepath" "runtime" + "strconv" "strings" "testing" + "time" "github.com/google/uuid" "github.com/stretchr/testify/assert" @@ -676,10 +678,9 @@ func TestTemplatePush(t *testing.T) { args := []string{ "templates", "push", - templateName, + "my-template", "--directory", source, "--test.provisioner", string(database.ProvisionerTypeEcho), - "--create", } inv, root := clitest.New(t, args...) clitest.SetupConfig(t, templateAdmin, root) @@ -709,6 +710,153 @@ func TestTemplatePush(t *testing.T) { require.NotEqual(t, uuid.Nil, template.ActiveVersionID) }) }) + + t.Run("EditMetadata", func(t *testing.T) { + t.Parallel() + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true}) + owner := coderdtest.CreateFirstUser(t, client) + templateAdmin, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID, rbac.RoleTemplateAdmin()) + version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, nil) + _ = coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID) + + template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID) + + // Test the cli command. + source := clitest.CreateTemplateVersionSource(t, &echo.Responses{ + Parse: echo.ParseComplete, + ProvisionApply: echo.ApplyComplete, + }) + + name := "new-template-name" + displayName := "New Display Name 789" + desc := "lorem ipsum dolor sit amet et cetera" + icon := "/icon/new-icon.png" + defaultTTL := 12 * time.Hour + allowUserCancelWorkspaceJobs := false + + inv, root := clitest.New(t, + "templates", + "push", + template.Name, + "--directory", source, + "--test.provisioner", string(database.ProvisionerTypeEcho), + "--name", name, + "--display-name", displayName, + "--description", desc, + "--icon", icon, + "--default-ttl", defaultTTL.String(), + "--allow-user-cancel-workspace-jobs="+strconv.FormatBool(allowUserCancelWorkspaceJobs), + ) + clitest.SetupConfig(t, templateAdmin, root) + pty := ptytest.New(t).Attach(inv) + + execDone := make(chan error) + go func() { + execDone <- inv.Run() + }() + + matches := []struct { + match string + write string + }{ + {match: "Upload", write: "yes"}, + } + for _, m := range matches { + pty.ExpectMatch(m.match) + pty.WriteLine(m.write) + } + + require.NoError(t, <-execDone) + + // Assert that the template version changed. + templateVersions, err := client.TemplateVersionsByTemplate(context.Background(), codersdk.TemplateVersionsByTemplateRequest{ + TemplateID: template.ID, + }) + require.NoError(t, err) + assert.Len(t, templateVersions, 2) + assert.NotEqual(t, template.ActiveVersionID, templateVersions[1].ID) + require.Equal(t, name, templateVersions[1].Name) + + // Assert that the template metadata changed. + updated, err := client.Template(context.Background(), template.ID) + require.NoError(t, err) + assert.Equal(t, template.Name, updated.Name) + assert.Equal(t, displayName, updated.DisplayName) + assert.Equal(t, desc, updated.Description) + assert.Equal(t, icon, updated.Icon) + assert.Equal(t, defaultTTL.Milliseconds(), updated.DefaultTTLMillis) + assert.Equal(t, allowUserCancelWorkspaceJobs, updated.AllowUserCancelWorkspaceJobs) + }) + + t.Run("EditMetadataKeepUnsetUnchanged", func(t *testing.T) { + t.Parallel() + client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true}) + owner := coderdtest.CreateFirstUser(t, client) + templateAdmin, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID, rbac.RoleTemplateAdmin()) + version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, nil) + _ = coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID) + + template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID) + + // Test the cli command. + source := clitest.CreateTemplateVersionSource(t, &echo.Responses{ + Parse: echo.ParseComplete, + ProvisionApply: echo.ApplyComplete, + }) + + desc := "lorem ipsum dolor sit amet et cetera" + + inv, root := clitest.New(t, + "templates", + "push", + template.Name, + "--directory", source, + "--test.provisioner", string(database.ProvisionerTypeEcho), + "--description", desc, + ) + clitest.SetupConfig(t, templateAdmin, root) + pty := ptytest.New(t).Attach(inv) + + execDone := make(chan error) + go func() { + execDone <- inv.Run() + }() + + matches := []struct { + match string + write string + }{ + {match: "Upload", write: "yes"}, + } + for _, m := range matches { + pty.ExpectMatch(m.match) + pty.WriteLine(m.write) + } + + require.NoError(t, <-execDone) + + // Assert that the template version changed. + templateVersions, err := client.TemplateVersionsByTemplate(context.Background(), codersdk.TemplateVersionsByTemplateRequest{ + TemplateID: template.ID, + }) + require.NoError(t, err) + assert.Len(t, templateVersions, 2) + assert.NotEqual(t, template.ActiveVersionID, templateVersions[1].ID) + + // Assert that the template metadata changed. + updated, err := client.Template(context.Background(), template.ID) + require.NoError(t, err) + assert.Equal(t, template.Name, updated.Name) + assert.Equal(t, template.DisplayName, updated.DisplayName) + assert.Equal(t, desc, updated.Description) + assert.Equal(t, template.Icon, updated.Icon) + assert.Equal(t, template.DefaultTTLMillis, updated.DefaultTTLMillis) + assert.Equal(t, template.FailureTTLMillis, updated.FailureTTLMillis) + assert.Equal(t, template.TimeTilDormantAutoDeleteMillis, updated.TimeTilDormantAutoDeleteMillis) + assert.Equal(t, template.AutostartRequirement.DaysOfWeek, updated.AutostartRequirement.DaysOfWeek) + assert.Equal(t, template.AutostopRequirement.DaysOfWeek, updated.AutostopRequirement.DaysOfWeek) + assert.Equal(t, template.RequireActiveVersion, updated.RequireActiveVersion) + }) } func createEchoResponsesWithTemplateVariables(templateVariables []*proto.TemplateVariable) *echo.Responses { diff --git a/cli/testdata/coder_templates_push_--help.golden b/cli/testdata/coder_templates_push_--help.golden index 9d255c1f8bc23..e484c143e9971 100644 --- a/cli/testdata/coder_templates_push_--help.golden +++ b/cli/testdata/coder_templates_push_--help.golden @@ -6,23 +6,76 @@ USAGE: Push a new template version from the current directory or as specified by flag OPTIONS: + --deprecated string + Sets the template as deprecated. Must be a message explaining why the + template is deprecated. + --activate bool (default: true) Whether the new template will be marked active. + --allow-user-autostart bool (default: true) + Allow users to configure autostart for workspaces on this template. + This can only be disabled in enterprise. + + --allow-user-autostop bool (default: true) + Allow users to customize the autostop TTL for workspaces on this + template. This can only be disabled in enterprise. + + --allow-user-cancel-workspace-jobs bool (default: true) + Allow users to cancel in-progress workspace jobs. + --always-prompt bool Always prompt all parameters. Does not pull parameter values from active template version. - --create bool (default: false) - Create the template if it does not exist. + --autostart-requirement-weekdays string-array + Edit the template autostart requirement weekdays - workspaces created + from this template can only autostart on the given weekdays. To unset + this value for the template (and allow autostart on all days), pass + 'all'. + + --default-ttl duration (default: 24h) + Specify a default TTL for workspaces created from this template. It is + the default time before shutdown - workspaces created from this + template default to this value. Maps to "Default autostop" in the UI. + + --description string + Edit the template description. -d, --directory string (default: .) Specify the directory to create from, use '-' to read tar from stdin. + --display-name string + Edit the template display name. + + --dormancy-auto-deletion duration (default: 0h) + Specify a duration workspaces may be in the dormant state prior to + being deleted. This licensed feature's default is 0h (off). Maps to + "Dormancy Auto-Deletion" in the UI. + + --dormancy-threshold duration (default: 0h) + Specify a duration workspaces may be inactive prior to being moved to + the dormant state. This licensed feature's default is 0h (off). Maps + to "Dormancy threshold" in the UI. + + --failure-ttl duration (default: 0h) + Specify a failure TTL for workspaces created from this template. It is + the amount of time after a failed "start" build before coder + automatically schedules a "stop" build to cleanup.This licensed + feature's default is 0h (off). Maps to "Failure cleanup"in the UI. + + --icon string + Edit the template icon path. + --ignore-lockfile bool (default: false) Ignore warnings about not having a .terraform.lock.hcl file present in the template. + --max-ttl duration + Edit the template maximum time before shutdown - workspaces created + from this template must shutdown within the given duration after + starting. This is an enterprise-only feature. + -m, --message string Specify a message describing the changes in this version of the template. Messages longer than 72 characters will be displayed as @@ -32,9 +85,19 @@ OPTIONS: Specify a name for the new template version. It will be automatically generated if not provided. + --private bool + Disable the default behavior of granting template access to the + 'everyone' group. The template permissions must be updated to allow + non-admin users to use this template. + --provisioner-tag string-array Specify a set of tags to target provisioner daemons. + --require-active-version bool (default: false) + Requires workspace builds to use the active template version. This + setting does not apply to template admins. This is an enterprise-only + feature. + --var string-array Alias of --variable. diff --git a/coderd/database/queries.sql.go b/coderd/database/queries.sql.go index 2a1f3b316c650..81bbe52386cf9 100644 --- a/coderd/database/queries.sql.go +++ b/coderd/database/queries.sql.go @@ -6075,19 +6075,21 @@ SET name = $4, icon = $5, display_name = $6, - allow_user_cancel_workspace_jobs = $7 + allow_user_cancel_workspace_jobs = $7, + group_acl = $8 WHERE id = $1 ` type UpdateTemplateMetaByIDParams struct { - ID uuid.UUID `db:"id" json:"id"` - UpdatedAt time.Time `db:"updated_at" json:"updated_at"` - Description string `db:"description" json:"description"` - Name string `db:"name" json:"name"` - Icon string `db:"icon" json:"icon"` - DisplayName string `db:"display_name" json:"display_name"` - AllowUserCancelWorkspaceJobs bool `db:"allow_user_cancel_workspace_jobs" json:"allow_user_cancel_workspace_jobs"` + ID uuid.UUID `db:"id" json:"id"` + UpdatedAt time.Time `db:"updated_at" json:"updated_at"` + Description string `db:"description" json:"description"` + Name string `db:"name" json:"name"` + Icon string `db:"icon" json:"icon"` + DisplayName string `db:"display_name" json:"display_name"` + AllowUserCancelWorkspaceJobs bool `db:"allow_user_cancel_workspace_jobs" json:"allow_user_cancel_workspace_jobs"` + GroupACL TemplateACL `db:"group_acl" json:"group_acl"` } func (q *sqlQuerier) UpdateTemplateMetaByID(ctx context.Context, arg UpdateTemplateMetaByIDParams) error { @@ -6099,6 +6101,7 @@ func (q *sqlQuerier) UpdateTemplateMetaByID(ctx context.Context, arg UpdateTempl arg.Icon, arg.DisplayName, arg.AllowUserCancelWorkspaceJobs, + arg.GroupACL, ) return err } diff --git a/coderd/database/queries/templates.sql b/coderd/database/queries/templates.sql index af8c3fe80f420..ca031bb0bd839 100644 --- a/coderd/database/queries/templates.sql +++ b/coderd/database/queries/templates.sql @@ -115,7 +115,8 @@ SET name = $4, icon = $5, display_name = $6, - allow_user_cancel_workspace_jobs = $7 + allow_user_cancel_workspace_jobs = $7, + group_acl = $8 WHERE id = $1 ; diff --git a/coderd/templates.go b/coderd/templates.go index 5e6d9644a782f..d4c33a454ce16 100644 --- a/coderd/templates.go +++ b/coderd/templates.go @@ -667,6 +667,11 @@ func (api *API) patchTemplateMeta(rw http.ResponseWriter, r *http.Request) { name = template.Name } + groupACL := template.GroupACL + if req.DisableEveryoneGroupAccess { + groupACL = database.TemplateACL{} + } + var err error err = tx.UpdateTemplateMetaByID(ctx, database.UpdateTemplateMetaByIDParams{ ID: template.ID, @@ -676,6 +681,7 @@ func (api *API) patchTemplateMeta(rw http.ResponseWriter, r *http.Request) { Description: req.Description, Icon: req.Icon, AllowUserCancelWorkspaceJobs: req.AllowUserCancelWorkspaceJobs, + GroupACL: groupACL, }) if err != nil { return xerrors.Errorf("update template metadata: %w", err) diff --git a/codersdk/templates.go b/codersdk/templates.go index 8164843ad0c66..1be4d931ad7a2 100644 --- a/codersdk/templates.go +++ b/codersdk/templates.go @@ -241,6 +241,12 @@ type UpdateTemplateMeta struct { // If passed an empty string, will remove the deprecated message, making // the template usable for new workspaces again. DeprecationMessage *string `json:"deprecation_message"` + // DisableEveryoneGroupAccess allows optionally disabling the default + // behavior of granting the 'everyone' group access to use the template. + // If this is set to true, the template will not be available to all users, + // and must be explicitly granted to users or groups in the permissions settings + // of the template. + DisableEveryoneGroupAccess bool `json:"disable_everyone_group_access"` } type TemplateExample struct { diff --git a/docs/cli/templates_push.md b/docs/cli/templates_push.md index bfa73fdad1151..9df46fdf69e9c 100644 --- a/docs/cli/templates_push.md +++ b/docs/cli/templates_push.md @@ -12,6 +12,14 @@ coder templates push [flags] [template] ## Options +### --deprecated + +| | | +| ---- | ------------------- | +| Type | string | + +Sets the template as deprecated. Must be a message explaining why the template is deprecated. + ### --activate | | | @@ -21,6 +29,33 @@ coder templates push [flags] [template] Whether the new template will be marked active. +### --allow-user-autostart + +| | | +| ------- | ----------------- | +| Type | bool | +| Default | true | + +Allow users to configure autostart for workspaces on this template. This can only be disabled in enterprise. + +### --allow-user-autostop + +| | | +| ------- | ----------------- | +| Type | bool | +| Default | true | + +Allow users to customize the autostop TTL for workspaces on this template. This can only be disabled in enterprise. + +### --allow-user-cancel-workspace-jobs + +| | | +| ------- | ----------------- | +| Type | bool | +| Default | true | + +Allow users to cancel in-progress workspace jobs. + ### --always-prompt | | | @@ -29,14 +64,30 @@ Whether the new template will be marked active. Always prompt all parameters. Does not pull parameter values from active template version. -### --create +### --autostart-requirement-weekdays -| | | -| ------- | ------------------ | -| Type | bool | -| Default | false | +| | | +| ---- | ------------------------- | +| Type | string-array | + +Edit the template autostart requirement weekdays - workspaces created from this template can only autostart on the given weekdays. To unset this value for the template (and allow autostart on all days), pass 'all'. + +### --default-ttl + +| | | +| ------- | --------------------- | +| Type | duration | +| Default | 24h | + +Specify a default TTL for workspaces created from this template. It is the default time before shutdown - workspaces created from this template default to this value. Maps to "Default autostop" in the UI. + +### --description + +| | | +| ---- | ------------------- | +| Type | string | -Create the template if it does not exist. +Edit the template description. ### -d, --directory @@ -47,6 +98,49 @@ Create the template if it does not exist. Specify the directory to create from, use '-' to read tar from stdin. +### --display-name + +| | | +| ---- | ------------------- | +| Type | string | + +Edit the template display name. + +### --dormancy-auto-deletion + +| | | +| ------- | --------------------- | +| Type | duration | +| Default | 0h | + +Specify a duration workspaces may be in the dormant state prior to being deleted. This licensed feature's default is 0h (off). Maps to "Dormancy Auto-Deletion" in the UI. + +### --dormancy-threshold + +| | | +| ------- | --------------------- | +| Type | duration | +| Default | 0h | + +Specify a duration workspaces may be inactive prior to being moved to the dormant state. This licensed feature's default is 0h (off). Maps to "Dormancy threshold" in the UI. + +### --failure-ttl + +| | | +| ------- | --------------------- | +| Type | duration | +| Default | 0h | + +Specify a failure TTL for workspaces created from this template. It is the amount of time after a failed "start" build before coder automatically schedules a "stop" build to cleanup.This licensed feature's default is 0h (off). Maps to "Failure cleanup"in the UI. + +### --icon + +| | | +| ---- | ------------------- | +| Type | string | + +Edit the template icon path. + ### --ignore-lockfile | | | @@ -56,6 +150,14 @@ Specify the directory to create from, use '-' to read tar from stdin. Ignore warnings about not having a .terraform.lock.hcl file present in the template. +### --max-ttl + +| | | +| ---- | --------------------- | +| Type | duration | + +Edit the template maximum time before shutdown - workspaces created from this template must shutdown within the given duration after starting. This is an enterprise-only feature. + ### -m, --message | | | @@ -72,6 +174,14 @@ Specify a message describing the changes in this version of the template. Messag Specify a name for the new template version. It will be automatically generated if not provided. +### --private + +| | | +| ---- | ----------------- | +| Type | bool | + +Disable the default behavior of granting template access to the 'everyone' group. The template permissions must be updated to allow non-admin users to use this template. + ### --provisioner-tag | | | @@ -80,6 +190,15 @@ Specify a name for the new template version. It will be automatically generated Specify a set of tags to target provisioner daemons. +### --require-active-version + +| | | +| ------- | ------------------ | +| Type | bool | +| Default | false | + +Requires workspace builds to use the active template version. This setting does not apply to template admins. This is an enterprise-only feature. + ### --var | | | diff --git a/site/src/api/typesGenerated.ts b/site/src/api/typesGenerated.ts index 98def777d9a91..bd5b35ecd5aab 100644 --- a/site/src/api/typesGenerated.ts +++ b/site/src/api/typesGenerated.ts @@ -1264,6 +1264,7 @@ export interface UpdateTemplateMeta { readonly update_workspace_dormant_at: boolean; readonly require_active_version: boolean; readonly deprecation_message?: string; + readonly disable_everyone_group_access: boolean; } // From codersdk/users.go diff --git a/site/src/pages/TemplateSettingsPage/TemplateGeneralSettingsPage/TemplateSettingsForm.tsx b/site/src/pages/TemplateSettingsPage/TemplateGeneralSettingsPage/TemplateSettingsForm.tsx index 2c37ca5729ba6..77de9c36bb583 100644 --- a/site/src/pages/TemplateSettingsPage/TemplateGeneralSettingsPage/TemplateSettingsForm.tsx +++ b/site/src/pages/TemplateSettingsPage/TemplateGeneralSettingsPage/TemplateSettingsForm.tsx @@ -77,6 +77,7 @@ export const TemplateSettingsForm: FC = ({ update_workspace_dormant_at: false, require_active_version: template.require_active_version, deprecation_message: template.deprecation_message, + disable_everyone_group_access: false, }, validationSchema, onSubmit, diff --git a/site/src/pages/TemplateSettingsPage/TemplateGeneralSettingsPage/TemplateSettingsPage.test.tsx b/site/src/pages/TemplateSettingsPage/TemplateGeneralSettingsPage/TemplateSettingsPage.test.tsx index be0d593c9e13e..ee6153646584a 100644 --- a/site/src/pages/TemplateSettingsPage/TemplateGeneralSettingsPage/TemplateSettingsPage.test.tsx +++ b/site/src/pages/TemplateSettingsPage/TemplateGeneralSettingsPage/TemplateSettingsPage.test.tsx @@ -47,6 +47,7 @@ const validFormValues: FormValues = { update_workspace_last_used_at: false, update_workspace_dormant_at: false, require_active_version: false, + disable_everyone_group_access: false, }; const renderTemplateSettingsPage = async () => { diff --git a/site/src/pages/TemplateSettingsPage/TemplateSchedulePage/TemplateScheduleForm.tsx b/site/src/pages/TemplateSettingsPage/TemplateSchedulePage/TemplateScheduleForm.tsx index f1f0af511ec9b..89f26cc5d451e 100644 --- a/site/src/pages/TemplateSettingsPage/TemplateSchedulePage/TemplateScheduleForm.tsx +++ b/site/src/pages/TemplateSettingsPage/TemplateSchedulePage/TemplateScheduleForm.tsx @@ -118,6 +118,7 @@ export const TemplateScheduleForm: FC = ({ update_workspace_last_used_at: false, update_workspace_dormant_at: false, require_active_version: false, + disable_everyone_group_access: false, }, validationSchema, onSubmit: () => { @@ -238,6 +239,7 @@ export const TemplateScheduleForm: FC = ({ update_workspace_last_used_at: form.values.update_workspace_last_used_at, update_workspace_dormant_at: form.values.update_workspace_dormant_at, require_active_version: false, + disable_everyone_group_access: false, }); }; diff --git a/site/src/pages/TemplateSettingsPage/TemplateSchedulePage/TemplateSchedulePage.test.tsx b/site/src/pages/TemplateSettingsPage/TemplateSchedulePage/TemplateSchedulePage.test.tsx index 77e50d73f0657..1a5618cf3263a 100644 --- a/site/src/pages/TemplateSettingsPage/TemplateSchedulePage/TemplateSchedulePage.test.tsx +++ b/site/src/pages/TemplateSettingsPage/TemplateSchedulePage/TemplateSchedulePage.test.tsx @@ -28,6 +28,7 @@ const validFormValues: TemplateScheduleFormValues = { inactivity_cleanup_enabled: false, dormant_autodeletion_cleanup_enabled: false, require_active_version: false, + disable_everyone_group_access: false, autostart_requirement_days_of_week: [ "monday", "tuesday",