1
1
package cli
2
2
3
3
import (
4
+ "context"
4
5
"fmt"
5
6
"net/http"
6
7
"strings"
@@ -46,6 +47,7 @@ func (r *RootCmd) templateEdit() *clibase.Cmd {
46
47
),
47
48
Short : "Edit the metadata of a template by name." ,
48
49
Handler : func (inv * clibase.Invocation ) error {
50
+ << << << < HEAD
49
51
// This clause can be removed when workspace_actions is no longer experimental
50
52
if failureTTL != 0 || dormancyThreshold != 0 || dormancyAutoDeletion != 0 {
51
53
experiments , exErr := client .Experiments (inv .Context ())
@@ -89,6 +91,8 @@ func (r *RootCmd) templateEdit() *clibase.Cmd {
89
91
}
90
92
}
91
93
94
+ == == == =
95
+ >> >> >> > 3 c377e5d3 (combine edit flags )
92
96
organization , err := CurrentOrganization (inv , client )
93
97
if err != nil {
94
98
return xerrors .Errorf ("get current organization: %w" , err )
@@ -98,71 +102,55 @@ func (r *RootCmd) templateEdit() *clibase.Cmd {
98
102
return xerrors .Errorf ("get workspace template: %w" , err )
99
103
}
100
104
101
- // Copy the default value if the list is empty, or if the user
102
- // specified the "none" value clear the list.
103
- if len (autostopRequirementDaysOfWeek ) == 0 {
104
- autostopRequirementDaysOfWeek = template .AutostopRequirement .DaysOfWeek
105
- }
106
- if len (autostartRequirementDaysOfWeek ) == 1 && autostartRequirementDaysOfWeek [0 ] == "all" {
107
- // Set it to every day of the week
108
- autostartRequirementDaysOfWeek = []string {"monday" , "tuesday" , "wednesday" , "thursday" , "friday" , "saturday" , "sunday" }
109
- } else if len (autostartRequirementDaysOfWeek ) == 0 {
110
- autostartRequirementDaysOfWeek = template .AutostartRequirement .DaysOfWeek
111
- }
112
- if unsetAutostopRequirementDaysOfWeek {
113
- autostopRequirementDaysOfWeek = []string {}
114
- }
115
- if failureTTL == 0 {
116
- failureTTL = time .Duration (template .FailureTTLMillis ) * time .Millisecond
117
- }
118
- if dormancyThreshold == 0 {
119
- dormancyThreshold = time .Duration (template .TimeTilDormantMillis ) * time .Millisecond
120
- }
121
- if dormancyAutoDeletion == 0 {
122
- dormancyAutoDeletion = time .Duration (template .TimeTilDormantAutoDeleteMillis ) * time .Millisecond
123
- }
124
-
125
- // Default values
126
- if ! userSetOption (inv , "description" ) {
127
- description = template .Description
128
- }
105
+ unsetAutostopRequirementDaysOfWeek , err := editTemplateEntitlementsCheck (inv .Context (), editTemplateEntitlementsArgs {
106
+ client : client ,
107
+ inv : inv ,
108
+ template : template ,
129
109
130
- if ! userSetOption (inv , "icon" ) {
131
- icon = template .Icon
132
- }
110
+ name : name ,
111
+ displayName : displayName ,
112
+ description : description ,
113
+ icon : icon ,
114
+ defaultTTL : defaultTTL ,
115
+ maxTTL : maxTTL ,
116
+ autostopRequirementDaysOfWeek : autostopRequirementDaysOfWeek ,
117
+ autostopRequirementWeeks : autostopRequirementWeeks ,
118
+ autostartRequirementDaysOfWeek : autostartRequirementDaysOfWeek ,
119
+ failureTTL : failureTTL ,
120
+ dormancyThreshold : dormancyThreshold ,
121
+ dormancyAutoDeletion : dormancyAutoDeletion ,
122
+ allowUserCancelWorkspaceJobs : allowUserCancelWorkspaceJobs ,
123
+ allowUserAutostart : allowUserAutostart ,
124
+ allowUserAutostop : allowUserAutostop ,
125
+ requireActiveVersion : requireActiveVersion ,
126
+ deprecationMessage : deprecationMessage ,
127
+ disableEveryone : false , // TODO: Add new flag
128
+ })
133
129
134
- if ! userSetOption (inv , "display-name" ) {
135
- displayName = template .DisplayName
136
- }
130
+ req := updateTemplateMetaRequest (updateTemplateMetaArgs {
131
+ client : client ,
132
+ inv : inv ,
133
+ template : template ,
134
+ unsetAutostopRequirementDaysOfWeek : unsetAutostopRequirementDaysOfWeek ,
137
135
138
- var deprecated * string
139
- if ! userSetOption (inv , "deprecated" ) {
140
- deprecated = & deprecationMessage
141
- }
142
-
143
- req := codersdk.UpdateTemplateMeta {
144
- Name : name ,
145
- DisplayName : displayName ,
146
- Description : description ,
147
- Icon : icon ,
148
- DefaultTTLMillis : defaultTTL .Milliseconds (),
149
- MaxTTLMillis : maxTTL .Milliseconds (),
150
- AutostopRequirement : & codersdk.TemplateAutostopRequirement {
151
- DaysOfWeek : autostopRequirementDaysOfWeek ,
152
- Weeks : autostopRequirementWeeks ,
153
- },
154
- AutostartRequirement : & codersdk.TemplateAutostartRequirement {
155
- DaysOfWeek : autostartRequirementDaysOfWeek ,
156
- },
157
- FailureTTLMillis : failureTTL .Milliseconds (),
158
- TimeTilDormantMillis : dormancyThreshold .Milliseconds (),
159
- TimeTilDormantAutoDeleteMillis : dormancyAutoDeletion .Milliseconds (),
160
- AllowUserCancelWorkspaceJobs : allowUserCancelWorkspaceJobs ,
161
- AllowUserAutostart : allowUserAutostart ,
162
- AllowUserAutostop : allowUserAutostop ,
163
- RequireActiveVersion : requireActiveVersion ,
164
- DeprecationMessage : deprecated ,
165
- }
136
+ name : name ,
137
+ displayName : displayName ,
138
+ description : description ,
139
+ icon : icon ,
140
+ defaultTTL : defaultTTL ,
141
+ maxTTL : maxTTL ,
142
+ autostopRequirementDaysOfWeek : autostopRequirementDaysOfWeek ,
143
+ autostopRequirementWeeks : autostopRequirementWeeks ,
144
+ autostartRequirementDaysOfWeek : autostartRequirementDaysOfWeek ,
145
+ failureTTL : failureTTL ,
146
+ dormancyThreshold : dormancyThreshold ,
147
+ dormancyAutoDeletion : dormancyAutoDeletion ,
148
+ allowUserCancelWorkspaceJobs : allowUserCancelWorkspaceJobs ,
149
+ allowUserAutostart : allowUserAutostart ,
150
+ allowUserAutostop : allowUserAutostop ,
151
+ requireActiveVersion : requireActiveVersion ,
152
+ deprecationMessage : deprecationMessage ,
153
+ })
166
154
167
155
_ , err = client .UpdateTemplateMeta (inv .Context (), template .ID , req )
168
156
if err != nil {
@@ -297,3 +285,171 @@ func (r *RootCmd) templateEdit() *clibase.Cmd {
297
285
298
286
return cmd
299
287
}
288
+
289
+ type editTemplateEntitlementsArgs struct {
290
+ client * codersdk.Client
291
+ inv * clibase.Invocation
292
+
293
+ defaultTTL time.Duration
294
+ maxTTL time.Duration
295
+ autostopRequirementDaysOfWeek []string
296
+ autostopRequirementWeeks int64
297
+ autostartRequirementDaysOfWeek []string
298
+ failureTTL time.Duration
299
+ dormancyThreshold time.Duration
300
+ dormancyAutoDeletion time.Duration
301
+ allowUserCancelWorkspaceJobs bool
302
+ allowUserAutostart bool
303
+ allowUserAutostop bool
304
+ requireActiveVersion bool
305
+ }
306
+
307
+ func editTemplateEntitlementsCheck (ctx context.Context , args editTemplateEntitlementsArgs ) (bool , error ) {
308
+ // This clause can be removed when workspace_actions is no longer experimental
309
+ if args .failureTTL != 0 || args .dormancyThreshold != 0 || args .dormancyAutoDeletion != 0 {
310
+ experiments , exErr := args .client .Experiments (ctx )
311
+ if exErr != nil {
312
+ return false , xerrors .Errorf ("get experiments: %w" , exErr )
313
+ }
314
+
315
+ if ! experiments .Enabled (codersdk .ExperimentWorkspaceActions ) {
316
+ 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." )
317
+ }
318
+ }
319
+
320
+ unsetAutostopRequirementDaysOfWeek := len (args .autostopRequirementDaysOfWeek ) == 1 && args .autostopRequirementDaysOfWeek [0 ] == "none"
321
+ requiresScheduling := (len (args .autostopRequirementDaysOfWeek ) > 0 && ! unsetAutostopRequirementDaysOfWeek ) ||
322
+ args .autostopRequirementWeeks > 0 ||
323
+ ! args .allowUserAutostart ||
324
+ ! args .allowUserAutostop ||
325
+ args .maxTTL != 0 ||
326
+ args .failureTTL != 0 ||
327
+ args .dormancyThreshold != 0 ||
328
+ args .dormancyAutoDeletion != 0 ||
329
+ len (args .autostartRequirementDaysOfWeek ) > 0
330
+
331
+ requiresEntitlement := requiresScheduling || args .requireActiveVersion
332
+ if requiresEntitlement {
333
+ entitlements , err := args .client .Entitlements (ctx )
334
+ if cerr , ok := codersdk .AsError (err ); ok && cerr .StatusCode () == http .StatusNotFound {
335
+ return false , xerrors .Errorf ("your deployment appears to be an AGPL deployment, so you cannot set enterprise-only flags" )
336
+ } else if err != nil {
337
+ return false , xerrors .Errorf ("get entitlements: %w" , err )
338
+ }
339
+
340
+ if requiresScheduling && ! entitlements .Features [codersdk .FeatureAdvancedTemplateScheduling ].Enabled {
341
+ 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" )
342
+ }
343
+
344
+ if args .requireActiveVersion {
345
+ if ! entitlements .Features [codersdk .FeatureAccessControl ].Enabled {
346
+ return false , xerrors .Errorf ("your license is not entitled to use enterprise access control, so you cannot set --require-active-version" )
347
+ }
348
+
349
+ experiments , exErr := args .client .Experiments (ctx )
350
+ if exErr != nil {
351
+ return false , xerrors .Errorf ("get experiments: %w" , exErr )
352
+ }
353
+
354
+ if ! experiments .Enabled (codersdk .ExperimentTemplateUpdatePolicies ) {
355
+ return false , xerrors .Errorf ("--require-active-version is an experimental feature, contact an administrator to enable the 'template_update_policies' experiment on your Coder server" )
356
+ }
357
+ }
358
+ }
359
+
360
+ return unsetAutostopRequirementDaysOfWeek , nil
361
+ }
362
+
363
+ type updateTemplateMetaArgs struct {
364
+ client * codersdk.Client
365
+ inv * clibase.Invocation
366
+ template codersdk.Template
367
+ unsetAutostopRequirementDaysOfWeek bool
368
+
369
+ name string
370
+ displayName string
371
+ description string
372
+ icon string
373
+ defaultTTL time.Duration
374
+ maxTTL time.Duration
375
+ autostopRequirementDaysOfWeek []string
376
+ autostopRequirementWeeks int64
377
+ autostartRequirementDaysOfWeek []string
378
+ failureTTL time.Duration
379
+ dormancyThreshold time.Duration
380
+ dormancyAutoDeletion time.Duration
381
+ allowUserCancelWorkspaceJobs bool
382
+ allowUserAutostart bool
383
+ allowUserAutostop bool
384
+ requireActiveVersion bool
385
+ deprecationMessage string
386
+ disableEveryone bool
387
+ }
388
+
389
+ func updateTemplateMetaRequest (args updateTemplateMetaArgs ) codersdk.UpdateTemplateMeta {
390
+ // Copy the default value if the list is empty, or if the user
391
+ // specified the "none" value clear the list.
392
+ if len (args .autostopRequirementDaysOfWeek ) == 0 {
393
+ args .autostopRequirementDaysOfWeek = args .template .AutostopRequirement .DaysOfWeek
394
+ }
395
+ if len (args .autostartRequirementDaysOfWeek ) == 1 && args .autostartRequirementDaysOfWeek [0 ] == "all" {
396
+ // Set it to every day of the week
397
+ args .autostartRequirementDaysOfWeek = []string {"monday" , "tuesday" , "wednesday" , "thursday" , "friday" , "saturday" , "sunday" }
398
+ } else if len (args .autostartRequirementDaysOfWeek ) == 0 {
399
+ args .autostartRequirementDaysOfWeek = args .template .AutostartRequirement .DaysOfWeek
400
+ }
401
+ if args .unsetAutostopRequirementDaysOfWeek {
402
+ args .autostopRequirementDaysOfWeek = []string {}
403
+ }
404
+ if args .failureTTL == 0 {
405
+ args .failureTTL = time .Duration (args .template .FailureTTLMillis ) * time .Millisecond
406
+ }
407
+ if args .dormancyThreshold == 0 {
408
+ args .dormancyThreshold = time .Duration (args .template .TimeTilDormantMillis ) * time .Millisecond
409
+ }
410
+ if args .dormancyAutoDeletion == 0 {
411
+ args .dormancyAutoDeletion = time .Duration (args .template .TimeTilDormantAutoDeleteMillis ) * time .Millisecond
412
+ }
413
+
414
+ // Default values
415
+ if ! userSetOption (args .inv , "description" ) {
416
+ args .description = args .template .Description
417
+ }
418
+
419
+ if ! userSetOption (args .inv , "icon" ) {
420
+ args .icon = args .template .Icon
421
+ }
422
+
423
+ if ! userSetOption (args .inv , "display-name" ) {
424
+ args .displayName = args .template .DisplayName
425
+ }
426
+
427
+ var deprecated * string
428
+ if ! userSetOption (args .inv , "deprecated" ) {
429
+ deprecated = & args .deprecationMessage
430
+ }
431
+
432
+ return codersdk.UpdateTemplateMeta {
433
+ Name : args .name ,
434
+ DisplayName : args .displayName ,
435
+ Description : args .description ,
436
+ Icon : args .icon ,
437
+ DefaultTTLMillis : args .defaultTTL .Milliseconds (),
438
+ MaxTTLMillis : args .maxTTL .Milliseconds (),
439
+ AutostopRequirement : & codersdk.TemplateAutostopRequirement {
440
+ DaysOfWeek : args .autostopRequirementDaysOfWeek ,
441
+ Weeks : args .autostopRequirementWeeks ,
442
+ },
443
+ AutostartRequirement : & codersdk.TemplateAutostartRequirement {
444
+ DaysOfWeek : args .autostartRequirementDaysOfWeek ,
445
+ },
446
+ FailureTTLMillis : args .failureTTL .Milliseconds (),
447
+ TimeTilDormantMillis : args .dormancyThreshold .Milliseconds (),
448
+ TimeTilDormantAutoDeleteMillis : args .dormancyAutoDeletion .Milliseconds (),
449
+ AllowUserCancelWorkspaceJobs : args .allowUserCancelWorkspaceJobs ,
450
+ AllowUserAutostart : args .allowUserAutostart ,
451
+ AllowUserAutostop : args .allowUserAutostop ,
452
+ RequireActiveVersion : args .requireActiveVersion ,
453
+ DeprecationMessage : deprecated ,
454
+ }
455
+ }
0 commit comments