@@ -24,6 +24,7 @@ import (
24
24
"github.com/hashicorp/terraform-plugin-framework/resource"
25
25
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
26
26
"github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault"
27
+ "github.com/hashicorp/terraform-plugin-framework/resource/schema/boolplanmodifier"
27
28
"github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default"
28
29
"github.com/hashicorp/terraform-plugin-framework/resource/schema/objectdefault"
29
30
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
@@ -72,6 +73,7 @@ type TemplateResourceModel struct {
72
73
RequireActiveVersion types.Bool `tfsdk:"require_active_version"`
73
74
DeprecationMessage types.String `tfsdk:"deprecation_message"`
74
75
MaxPortShareLevel types.String `tfsdk:"max_port_share_level"`
76
+ UseClassicParameterFlow types.Bool `tfsdk:"use_classic_parameter_flow"`
75
77
76
78
// If null, we are not managing ACL via Terraform (such as for AGPL).
77
79
ACL types.Object `tfsdk:"acl"`
@@ -97,7 +99,8 @@ func (m *TemplateResourceModel) EqualTemplateMetadata(other *TemplateResourceMod
97
99
m .TimeTilDormantAutoDeleteMillis .Equal (other .TimeTilDormantAutoDeleteMillis ) &&
98
100
m .RequireActiveVersion .Equal (other .RequireActiveVersion ) &&
99
101
m .DeprecationMessage .Equal (other .DeprecationMessage ) &&
100
- m .MaxPortShareLevel .Equal (other .MaxPortShareLevel )
102
+ m .MaxPortShareLevel .Equal (other .MaxPortShareLevel ) &&
103
+ m .UseClassicParameterFlow .Equal (other .UseClassicParameterFlow )
101
104
}
102
105
103
106
func (m * TemplateResourceModel ) CheckEntitlements (ctx context.Context , features map [codersdk.FeatureName ]codersdk.Feature ) (diags diag.Diagnostics ) {
@@ -385,13 +388,24 @@ func (r *TemplateResource) Schema(ctx context.Context, req resource.SchemaReques
385
388
Validators : []validator.String {
386
389
stringvalidator .OneOfCaseInsensitive (string (codersdk .WorkspaceAgentPortShareLevelAuthenticated ), string (codersdk .WorkspaceAgentPortShareLevelOwner ), string (codersdk .WorkspaceAgentPortShareLevelPublic )),
387
390
},
391
+ PlanModifiers : []planmodifier.String {
392
+ stringplanmodifier .UseStateForUnknown (),
393
+ },
388
394
},
389
395
"deprecation_message" : schema.StringAttribute {
390
396
MarkdownDescription : "If set, the template will be marked as deprecated with the provided message and users will be blocked from creating new workspaces from it. Does nothing if set when the resource is created." ,
391
397
Optional : true ,
392
398
Computed : true ,
393
399
Default : stringdefault .StaticString ("" ),
394
400
},
401
+ "use_classic_parameter_flow" : schema.BoolAttribute {
402
+ MarkdownDescription : "If true, the classic parameter flow will be used when creating workspaces from this template. This only affects deployments with the experiment \" dynamic-parameters\" enabled. Defaults to false." ,
403
+ Optional : true ,
404
+ Computed : true ,
405
+ PlanModifiers : []planmodifier.Bool {
406
+ boolplanmodifier .UseStateForUnknown (),
407
+ },
408
+ },
395
409
"acl" : schema.SingleNestedAttribute {
396
410
MarkdownDescription : "(Enterprise) Access control list for the template. If null, ACL policies will not be added, removed, or read by Terraform." ,
397
411
Optional : true ,
@@ -588,6 +602,25 @@ func (r *TemplateResource) Create(ctx context.Context, req resource.CreateReques
588
602
data .MaxPortShareLevel = types .StringValue (string (mpslResp .MaxPortShareLevel ))
589
603
}
590
604
605
+ // TODO: Remove this update call (and the attribute) once the provider
606
+ // requires a Coder version where this flag has been removed.
607
+ if data .UseClassicParameterFlow .IsUnknown () {
608
+ data .UseClassicParameterFlow = types .BoolValue (templateResp .UseClassicParameterFlow )
609
+ } else if data .UseClassicParameterFlow .ValueBool () == templateResp .UseClassicParameterFlow {
610
+ tflog .Info (ctx , "use classic parameter flow set to default, not updating" )
611
+ } else {
612
+ ucpfReq := data .toUpdateRequest (ctx , & resp .Diagnostics )
613
+ if resp .Diagnostics .HasError () {
614
+ return
615
+ }
616
+ ucpfResp , err := client .UpdateTemplateMeta (ctx , data .ID .ValueUUID (), * ucpfReq )
617
+ if err != nil {
618
+ resp .Diagnostics .AddError ("Client Error" , fmt .Sprintf ("Failed to set use classic parameter flow via update: %s" , err ))
619
+ return
620
+ }
621
+ data .UseClassicParameterFlow = types .BoolValue (ucpfResp .UseClassicParameterFlow )
622
+ }
623
+
591
624
resp .Diagnostics .Append (data .Versions .setPrivateState (ctx , resp .Private )... )
592
625
if resp .Diagnostics .HasError () {
593
626
return
@@ -627,6 +660,7 @@ func (r *TemplateResource) Read(ctx context.Context, req resource.ReadRequest, r
627
660
return
628
661
}
629
662
data .MaxPortShareLevel = types .StringValue (string (template .MaxPortShareLevel ))
663
+ data .UseClassicParameterFlow = types .BoolValue (template .UseClassicParameterFlow )
630
664
631
665
if ! data .ACL .IsNull () {
632
666
tflog .Info (ctx , "reading template ACL" )
@@ -701,11 +735,6 @@ func (r *TemplateResource) Update(ctx context.Context, req resource.UpdateReques
701
735
702
736
client := r .data .Client
703
737
704
- // TODO(ethanndickson): Remove this once the provider requires a Coder
705
- // deployment running `v2.15.0` or later.
706
- if newState .MaxPortShareLevel .IsUnknown () {
707
- newState .MaxPortShareLevel = curState .MaxPortShareLevel
708
- }
709
738
templateMetadataChanged := ! newState .EqualTemplateMetadata (& curState )
710
739
// This is required, as the API will reject no-diff updates.
711
740
if templateMetadataChanged {
@@ -1290,6 +1319,7 @@ func (r *TemplateResourceModel) toUpdateRequest(ctx context.Context, diag *diag.
1290
1319
RequireActiveVersion : r .RequireActiveVersion .ValueBool (),
1291
1320
DeprecationMessage : r .DeprecationMessage .ValueStringPointer (),
1292
1321
MaxPortShareLevel : ptr .Ref (codersdk .WorkspaceAgentPortShareLevel (r .MaxPortShareLevel .ValueString ())),
1322
+ UseClassicParameterFlow : ptr .Ref (r .UseClassicParameterFlow .ValueBool ()),
1293
1323
// If we're managing ACL, we want to delete the everyone group
1294
1324
DisableEveryoneGroupAccess : ! r .ACL .IsNull (),
1295
1325
}
@@ -1334,6 +1364,7 @@ func (r *TemplateResourceModel) toCreateRequest(ctx context.Context, resp *resou
1334
1364
TimeTilDormantMillis : r .TimeTilDormantMillis .ValueInt64Pointer (),
1335
1365
TimeTilDormantAutoDeleteMillis : r .TimeTilDormantAutoDeleteMillis .ValueInt64Pointer (),
1336
1366
RequireActiveVersion : r .RequireActiveVersion .ValueBool (),
1367
+ UseClassicParameterFlow : r .UseClassicParameterFlow .ValueBoolPointer (),
1337
1368
DisableEveryoneGroupAccess : ! r .ACL .IsNull (),
1338
1369
}
1339
1370
}
0 commit comments