@@ -24,6 +24,7 @@ import (
2424"github.com/hashicorp/terraform-plugin-framework/resource"
2525"github.com/hashicorp/terraform-plugin-framework/resource/schema"
2626"github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault"
27+ "github.com/hashicorp/terraform-plugin-framework/resource/schema/boolplanmodifier"
2728"github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default"
2829"github.com/hashicorp/terraform-plugin-framework/resource/schema/objectdefault"
2930"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
@@ -72,6 +73,7 @@ type TemplateResourceModel struct {
7273RequireActiveVersion types.Bool `tfsdk:"require_active_version"`
7374DeprecationMessage types.String `tfsdk:"deprecation_message"`
7475MaxPortShareLevel types.String `tfsdk:"max_port_share_level"`
76+ UseClassicParameterFlow types.Bool `tfsdk:"use_classic_parameter_flow"`
7577
7678// If null, we are not managing ACL via Terraform (such as for AGPL).
7779ACL types.Object `tfsdk:"acl"`
@@ -97,7 +99,8 @@ func (m *TemplateResourceModel) EqualTemplateMetadata(other *TemplateResourceMod
9799m .TimeTilDormantAutoDeleteMillis .Equal (other .TimeTilDormantAutoDeleteMillis )&&
98100m .RequireActiveVersion .Equal (other .RequireActiveVersion )&&
99101m .DeprecationMessage .Equal (other .DeprecationMessage )&&
100- m .MaxPortShareLevel .Equal (other .MaxPortShareLevel )
102+ m .MaxPortShareLevel .Equal (other .MaxPortShareLevel )&&
103+ m .UseClassicParameterFlow .Equal (other .UseClassicParameterFlow )
101104}
102105
103106func (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
385388Validators : []validator.String {
386389stringvalidator .OneOfCaseInsensitive (string (codersdk .WorkspaceAgentPortShareLevelAuthenticated ),string (codersdk .WorkspaceAgentPortShareLevelOwner ),string (codersdk .WorkspaceAgentPortShareLevelPublic )),
387390},
391+ PlanModifiers : []planmodifier.String {
392+ stringplanmodifier .UseStateForUnknown (),
393+ },
388394},
389395"deprecation_message" : schema.StringAttribute {
390396MarkdownDescription :"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." ,
391397Optional :true ,
392398Computed :true ,
393399Default :stringdefault .StaticString ("" ),
394400},
401+ "use_classic_parameter_flow" : schema.BoolAttribute {
402+ MarkdownDescription :"If true, the classic parameter flow will be used when creating workspaces from this template. Defaults to false." ,
403+ Optional :true ,
404+ Computed :true ,
405+ PlanModifiers : []planmodifier.Bool {
406+ boolplanmodifier .UseStateForUnknown (),
407+ },
408+ },
395409"acl" : schema.SingleNestedAttribute {
396410MarkdownDescription :"(Enterprise) Access control list for the template. If null, ACL policies will not be added, removed, or read by Terraform." ,
397411Optional :true ,
@@ -588,6 +602,25 @@ func (r *TemplateResource) Create(ctx context.Context, req resource.CreateReques
588602data .MaxPortShareLevel = types .StringValue (string (mpslResp .MaxPortShareLevel ))
589603}
590604
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+
591624resp .Diagnostics .Append (data .Versions .setPrivateState (ctx ,resp .Private )... )
592625if resp .Diagnostics .HasError () {
593626return
@@ -627,6 +660,7 @@ func (r *TemplateResource) Read(ctx context.Context, req resource.ReadRequest, r
627660return
628661}
629662data .MaxPortShareLevel = types .StringValue (string (template .MaxPortShareLevel ))
663+ data .UseClassicParameterFlow = types .BoolValue (template .UseClassicParameterFlow )
630664
631665if ! data .ACL .IsNull () {
632666tflog .Info (ctx ,"reading template ACL" )
@@ -701,11 +735,6 @@ func (r *TemplateResource) Update(ctx context.Context, req resource.UpdateReques
701735
702736client := r .data .Client
703737
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- }
709738templateMetadataChanged := ! newState .EqualTemplateMetadata (& curState )
710739// This is required, as the API will reject no-diff updates.
711740if templateMetadataChanged {
@@ -1290,6 +1319,7 @@ func (r *TemplateResourceModel) toUpdateRequest(ctx context.Context, diag *diag.
12901319RequireActiveVersion :r .RequireActiveVersion .ValueBool (),
12911320DeprecationMessage :r .DeprecationMessage .ValueStringPointer (),
12921321MaxPortShareLevel :ptr .Ref (codersdk .WorkspaceAgentPortShareLevel (r .MaxPortShareLevel .ValueString ())),
1322+ UseClassicParameterFlow :ptr .Ref (r .UseClassicParameterFlow .ValueBool ()),
12931323// If we're managing ACL, we want to delete the everyone group
12941324DisableEveryoneGroupAccess :! r .ACL .IsNull (),
12951325}
@@ -1334,6 +1364,7 @@ func (r *TemplateResourceModel) toCreateRequest(ctx context.Context, resp *resou
13341364TimeTilDormantMillis :r .TimeTilDormantMillis .ValueInt64Pointer (),
13351365TimeTilDormantAutoDeleteMillis :r .TimeTilDormantAutoDeleteMillis .ValueInt64Pointer (),
13361366RequireActiveVersion :r .RequireActiveVersion .ValueBool (),
1367+ UseClassicParameterFlow :r .UseClassicParameterFlow .ValueBoolPointer (),
13371368DisableEveryoneGroupAccess :! r .ACL .IsNull (),
13381369}
13391370}