diff --git a/apstra/apstra_plan_modifier/use_null_state_for_unknown.go b/apstra/apstra_plan_modifier/use_null_state_for_unknown.go new file mode 100644 index 00000000..ee716eb6 --- /dev/null +++ b/apstra/apstra_plan_modifier/use_null_state_for_unknown.go @@ -0,0 +1,185 @@ +package apstraplanmodifier + +// the contents of this file are based on: +// https://github.com/hashicorp/terraform-plugin-framework/blob/v1.9.0/resource/schema/stringplanmodifier/use_state_for_unknown.go +// +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" +) + +// UseNullStateForUnknown returns a plan modifier that copies a known prior state +// value into the planned value. Use this when it is known that an unconfigured +// value will remain the same after a resource update. +// +// To prevent Terraform errors, the framework automatically sets unconfigured +// and Computed attributes to an unknown value "(known after apply)" on update. +// Using this plan modifier will instead display the prior state value in the +// plan, unless a prior plan modifier adjusts the value. +func UseNullStateForUnknown() useNullStateForUnknownModifier { + return useNullStateForUnknownModifier{} +} + +var ( + _ planmodifier.Bool = (*useNullStateForUnknownModifier)(nil) + _ planmodifier.Float64 = (*useNullStateForUnknownModifier)(nil) + _ planmodifier.Int64 = (*useNullStateForUnknownModifier)(nil) + _ planmodifier.List = (*useNullStateForUnknownModifier)(nil) + _ planmodifier.Map = (*useNullStateForUnknownModifier)(nil) + _ planmodifier.Number = (*useNullStateForUnknownModifier)(nil) + _ planmodifier.Object = (*useNullStateForUnknownModifier)(nil) + _ planmodifier.Set = (*useNullStateForUnknownModifier)(nil) + _ planmodifier.String = (*useNullStateForUnknownModifier)(nil) +) + +// useNullStateForUnknownModifier implements the plan modifier. +type useNullStateForUnknownModifier struct{} + +// Description returns a human-readable description of the plan modifier. +func (m useNullStateForUnknownModifier) Description(_ context.Context) string { + return "Once set, the value of this attribute in state will not change, even if it's null." +} + +// MarkdownDescription returns a markdown description of the plan modifier. +func (m useNullStateForUnknownModifier) MarkdownDescription(_ context.Context) string { + return "Once set, the value of this attribute in state will not change, even if it's null." +} + +// PlanModifyBool implements the plan modification logic. +func (m useNullStateForUnknownModifier) PlanModifyBool(_ context.Context, req planmodifier.BoolRequest, resp *planmodifier.BoolResponse) { + // Do nothing if there is a known planned value. + if !req.PlanValue.IsUnknown() { + return + } + + // Do nothing if there is an unknown configuration value, otherwise interpolation gets messed up. + if req.ConfigValue.IsUnknown() { + return + } + + resp.PlanValue = req.StateValue +} + +// PlanModifyInt64 implements the plan modification logic. +func (m useNullStateForUnknownModifier) PlanModifyInt64(_ context.Context, req planmodifier.Int64Request, resp *planmodifier.Int64Response) { + // Do nothing if there is a known planned value. + if !req.PlanValue.IsUnknown() { + return + } + + // Do nothing if there is an unknown configuration value, otherwise interpolation gets messed up. + if req.ConfigValue.IsUnknown() { + return + } + + resp.PlanValue = req.StateValue +} + +// PlanModifyFloat64 implements the plan modification logic. +func (m useNullStateForUnknownModifier) PlanModifyFloat64(_ context.Context, req planmodifier.Float64Request, resp *planmodifier.Float64Response) { + // Do nothing if there is a known planned value. + if !req.PlanValue.IsUnknown() { + return + } + + // Do nothing if there is an unknown configuration value, otherwise interpolation gets messed up. + if req.ConfigValue.IsUnknown() { + return + } + + resp.PlanValue = req.StateValue +} + +// PlanModifyList implements the plan modification logic. +func (m useNullStateForUnknownModifier) PlanModifyList(_ context.Context, req planmodifier.ListRequest, resp *planmodifier.ListResponse) { + // Do nothing if there is a known planned value. + if !req.PlanValue.IsUnknown() { + return + } + + // Do nothing if there is an unknown configuration value, otherwise interpolation gets messed up. + if req.ConfigValue.IsUnknown() { + return + } + + resp.PlanValue = req.StateValue +} + +// PlanModifyMap implements the plan modification logic. +func (m useNullStateForUnknownModifier) PlanModifyMap(_ context.Context, req planmodifier.MapRequest, resp *planmodifier.MapResponse) { + // Do nothing if there is a known planned value. + if !req.PlanValue.IsUnknown() { + return + } + + // Do nothing if there is an unknown configuration value, otherwise interpolation gets messed up. + if req.ConfigValue.IsUnknown() { + return + } + + resp.PlanValue = req.StateValue +} + +// PlanModifyNumber implements the plan modification logic. +func (m useNullStateForUnknownModifier) PlanModifyNumber(_ context.Context, req planmodifier.NumberRequest, resp *planmodifier.NumberResponse) { + // Do nothing if there is a known planned value. + if !req.PlanValue.IsUnknown() { + return + } + + // Do nothing if there is an unknown configuration value, otherwise interpolation gets messed up. + if req.ConfigValue.IsUnknown() { + return + } + + resp.PlanValue = req.StateValue +} + +// PlanModifyObject implements the plan modification logic. +func (m useNullStateForUnknownModifier) PlanModifyObject(_ context.Context, req planmodifier.ObjectRequest, resp *planmodifier.ObjectResponse) { + // Do nothing if there is a known planned value. + if !req.PlanValue.IsUnknown() { + return + } + + // Do nothing if there is an unknown configuration value, otherwise interpolation gets messed up. + if req.ConfigValue.IsUnknown() { + return + } + + resp.PlanValue = req.StateValue +} + +// PlanModifySet implements the plan modification logic. +func (m useNullStateForUnknownModifier) PlanModifySet(_ context.Context, req planmodifier.SetRequest, resp *planmodifier.SetResponse) { + // Do nothing if there is a known planned value. + if !req.PlanValue.IsUnknown() { + return + } + + // Do nothing if there is an unknown configuration value, otherwise interpolation gets messed up. + if req.ConfigValue.IsUnknown() { + return + } + + resp.PlanValue = req.StateValue +} + +// PlanModifyString implements the plan modification logic. +func (m useNullStateForUnknownModifier) PlanModifyString(_ context.Context, req planmodifier.StringRequest, resp *planmodifier.StringResponse) { + // Do nothing if there is a known planned value. + if !req.PlanValue.IsUnknown() { + return + } + + // Do nothing if there is an unknown configuration value, otherwise interpolation gets messed up. + if req.ConfigValue.IsUnknown() { + return + } + + resp.PlanValue = req.StateValue +} diff --git a/apstra/resources/asn_pool.go b/apstra/resources/asn_pool.go index 0423ac78..7866986e 100644 --- a/apstra/resources/asn_pool.go +++ b/apstra/resources/asn_pool.go @@ -4,6 +4,7 @@ import ( "context" "github.com/Juniper/apstra-go-sdk/apstra" + apstraplanmodifier "github.com/Juniper/terraform-provider-apstra/apstra/apstra_plan_modifier" "github.com/Juniper/terraform-provider-apstra/apstra/utils" "github.com/hashicorp/terraform-plugin-framework-validators/setvalidator" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" @@ -95,20 +96,24 @@ func (o AsnPool) ResourceAttributes() map[string]resourceSchema.Attribute { }, }, "total": resourceSchema.Int64Attribute{ - MarkdownDescription: "Mutable read-only is always null in a Resource. Use the matching Data Source for this information.", + MarkdownDescription: "Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information.", Computed: true, + PlanModifiers: []planmodifier.Int64{apstraplanmodifier.UseNullStateForUnknown()}, }, "status": resourceSchema.StringAttribute{ - MarkdownDescription: "Mutable read-only is always null in a Resource. Use the matching Data Source for this information.", + MarkdownDescription: "Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information.", Computed: true, + PlanModifiers: []planmodifier.String{apstraplanmodifier.UseNullStateForUnknown()}, }, "used": resourceSchema.Int64Attribute{ - MarkdownDescription: "Mutable read-only is always null in a Resource. Use the matching Data Source for this information.", + MarkdownDescription: "Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information.", Computed: true, + PlanModifiers: []planmodifier.Int64{apstraplanmodifier.UseNullStateForUnknown()}, }, "used_percentage": resourceSchema.Float64Attribute{ - MarkdownDescription: "Mutable read-only is always null in a Resource. Use the matching Data Source for this information.", + MarkdownDescription: "Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information.", Computed: true, + PlanModifiers: []planmodifier.Float64{apstraplanmodifier.UseNullStateForUnknown()}, }, } } diff --git a/apstra/resources/asn_pool_range.go b/apstra/resources/asn_pool_range.go index 24dad48f..2e66650a 100644 --- a/apstra/resources/asn_pool_range.go +++ b/apstra/resources/asn_pool_range.go @@ -5,12 +5,14 @@ import ( "math" "github.com/Juniper/apstra-go-sdk/apstra" + apstraplanmodifier "github.com/Juniper/terraform-provider-apstra/apstra/apstra_plan_modifier" "github.com/hashicorp/terraform-plugin-framework-validators/int64validator" "github.com/hashicorp/terraform-plugin-framework/attr" dataSourceSchema "github.com/hashicorp/terraform-plugin-framework/datasource/schema" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" resourceSchema "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" ) @@ -83,20 +85,24 @@ func (o AsnPoolRange) ResourceAttributes() map[string]resourceSchema.Attribute { }, }, "total": resourceSchema.Int64Attribute{ - MarkdownDescription: "Mutable read-only is always null in a Resource. Use the matching Data Source for this information.", + MarkdownDescription: "Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information.", Computed: true, + PlanModifiers: []planmodifier.Int64{apstraplanmodifier.UseNullStateForUnknown()}, }, "status": resourceSchema.StringAttribute{ - MarkdownDescription: "Mutable read-only is always null in a Resource. Use the matching Data Source for this information.", + MarkdownDescription: "Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information.", Computed: true, + PlanModifiers: []planmodifier.String{apstraplanmodifier.UseNullStateForUnknown()}, }, "used": resourceSchema.Int64Attribute{ - MarkdownDescription: "Mutable read-only is always null in a Resource. Use the matching Data Source for this information.", + MarkdownDescription: "Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information.", Computed: true, + PlanModifiers: []planmodifier.Int64{apstraplanmodifier.UseNullStateForUnknown()}, }, "used_percentage": resourceSchema.Float64Attribute{ - MarkdownDescription: "Mutable read-only is always null in a Resource. Use the matching Data Source for this information.", + MarkdownDescription: "Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information.", Computed: true, + PlanModifiers: []planmodifier.Float64{apstraplanmodifier.UseNullStateForUnknown()}, }, } } diff --git a/apstra/resources/integer_pool.go b/apstra/resources/integer_pool.go index 7178688c..19524fe0 100644 --- a/apstra/resources/integer_pool.go +++ b/apstra/resources/integer_pool.go @@ -4,6 +4,7 @@ import ( "context" "github.com/Juniper/apstra-go-sdk/apstra" + apstraplanmodifier "github.com/Juniper/terraform-provider-apstra/apstra/apstra_plan_modifier" "github.com/Juniper/terraform-provider-apstra/apstra/utils" "github.com/hashicorp/terraform-plugin-framework-validators/setvalidator" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" @@ -95,23 +96,24 @@ func (o IntegerPool) ResourceAttributes() map[string]resourceSchema.Attribute { }, }, "total": resourceSchema.Int64Attribute{ - MarkdownDescription: "Total number of Integers in the Integer Pool.", + MarkdownDescription: "Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information.", Computed: true, + PlanModifiers: []planmodifier.Int64{apstraplanmodifier.UseNullStateForUnknown()}, }, "status": resourceSchema.StringAttribute{ - MarkdownDescription: "Status of the Integer Pool. " + - "Note that this element is probably better read from a `data` source because it will be more up-to-date.", - Computed: true, + MarkdownDescription: "Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information.", + Computed: true, + PlanModifiers: []planmodifier.String{apstraplanmodifier.UseNullStateForUnknown()}, }, "used": resourceSchema.Int64Attribute{ - MarkdownDescription: "Count of used Integers in the Integer Pool. " + - "Note that this element is probably better read from a `data` source because it will be more up-to-date.", - Computed: true, + MarkdownDescription: "Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information.", + Computed: true, + PlanModifiers: []planmodifier.Int64{apstraplanmodifier.UseNullStateForUnknown()}, }, "used_percentage": resourceSchema.Float64Attribute{ - MarkdownDescription: "Percent of used Integers in the Integer Pool. " + - "Note that this element is probably better read from a `data` source because it will be more up-to-date.", - Computed: true, + MarkdownDescription: "Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information.", + Computed: true, + PlanModifiers: []planmodifier.Float64{apstraplanmodifier.UseNullStateForUnknown()}, }, } } diff --git a/apstra/resources/integer_pool_range.go b/apstra/resources/integer_pool_range.go index e7d94ad9..32a28f40 100644 --- a/apstra/resources/integer_pool_range.go +++ b/apstra/resources/integer_pool_range.go @@ -5,12 +5,14 @@ import ( "math" "github.com/Juniper/apstra-go-sdk/apstra" + apstraplanmodifier "github.com/Juniper/terraform-provider-apstra/apstra/apstra_plan_modifier" "github.com/hashicorp/terraform-plugin-framework-validators/int64validator" "github.com/hashicorp/terraform-plugin-framework/attr" dataSourceSchema "github.com/hashicorp/terraform-plugin-framework/datasource/schema" "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" resourceSchema "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" ) @@ -83,20 +85,24 @@ func (o IntegerPoolRange) ResourceAttributes() map[string]resourceSchema.Attribu }, }, "total": resourceSchema.Int64Attribute{ - MarkdownDescription: "Mutable read-only is always null in a Resource. Use the matching Data Source for this information.", + MarkdownDescription: "Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information.", Computed: true, + PlanModifiers: []planmodifier.Int64{apstraplanmodifier.UseNullStateForUnknown()}, }, "status": resourceSchema.StringAttribute{ - MarkdownDescription: "Mutable read-only is always null in a Resource. Use the matching Data Source for this information.", + MarkdownDescription: "Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information.", Computed: true, + PlanModifiers: []planmodifier.String{apstraplanmodifier.UseNullStateForUnknown()}, }, "used": resourceSchema.Int64Attribute{ - MarkdownDescription: "Mutable read-only is always null in a Resource. Use the matching Data Source for this information.", + MarkdownDescription: "Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information.", Computed: true, + PlanModifiers: []planmodifier.Int64{apstraplanmodifier.UseNullStateForUnknown()}, }, "used_percentage": resourceSchema.Float64Attribute{ - MarkdownDescription: "Mutable read-only is always null in a Resource. Use the matching Data Source for this information.", + MarkdownDescription: "Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information.", Computed: true, + PlanModifiers: []planmodifier.Float64{apstraplanmodifier.UseNullStateForUnknown()}, }, } } diff --git a/apstra/resources/ipv4_pool.go b/apstra/resources/ipv4_pool.go index 15b1ce9c..ba886f8b 100644 --- a/apstra/resources/ipv4_pool.go +++ b/apstra/resources/ipv4_pool.go @@ -4,6 +4,7 @@ import ( "context" "github.com/Juniper/apstra-go-sdk/apstra" + apstraplanmodifier "github.com/Juniper/terraform-provider-apstra/apstra/apstra_plan_modifier" "github.com/Juniper/terraform-provider-apstra/apstra/utils" "github.com/hashicorp/terraform-plugin-framework-validators/setvalidator" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" @@ -95,23 +96,24 @@ func (o Ipv4Pool) ResourceAttributes() map[string]resourceSchema.Attribute { }, }, "total": resourceSchema.NumberAttribute{ - MarkdownDescription: "Total number of addresses in the IPv4 pool.", + MarkdownDescription: "Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information.", Computed: true, + PlanModifiers: []planmodifier.Number{apstraplanmodifier.UseNullStateForUnknown()}, }, "status": resourceSchema.StringAttribute{ - MarkdownDescription: "Status of the IPv4 pool. " + - "Note that this element is probably better read from a `data` source because it will be more up-to-date.", - Computed: true, + MarkdownDescription: "Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information.", + Computed: true, + PlanModifiers: []planmodifier.String{apstraplanmodifier.UseNullStateForUnknown()}, }, "used": resourceSchema.NumberAttribute{ - MarkdownDescription: "Count of used addresses in the IPv4 pool. " + - "Note that this element is probably better read from a `data` source because it will be more up-to-date.", - Computed: true, + MarkdownDescription: "Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information.", + Computed: true, + PlanModifiers: []planmodifier.Number{apstraplanmodifier.UseNullStateForUnknown()}, }, "used_percentage": resourceSchema.Float64Attribute{ - MarkdownDescription: "Percent of used addresses in the IPv4 pool. " + - "Note that this element is probably better read from a `data` source because it will be more up-to-date.", - Computed: true, + MarkdownDescription: "Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information.", + Computed: true, + PlanModifiers: []planmodifier.Float64{apstraplanmodifier.UseNullStateForUnknown()}, }, } } diff --git a/apstra/resources/ipv4_pool_subnet.go b/apstra/resources/ipv4_pool_subnet.go index eaa380ab..80473f04 100644 --- a/apstra/resources/ipv4_pool_subnet.go +++ b/apstra/resources/ipv4_pool_subnet.go @@ -4,6 +4,7 @@ import ( "context" "github.com/Juniper/apstra-go-sdk/apstra" + apstraplanmodifier "github.com/Juniper/terraform-provider-apstra/apstra/apstra_plan_modifier" apstravalidator "github.com/Juniper/terraform-provider-apstra/apstra/apstra_validator" "github.com/Juniper/terraform-provider-apstra/apstra/utils" "github.com/hashicorp/terraform-plugin-framework-nettypes/cidrtypes" @@ -11,6 +12,7 @@ import ( dataSourceSchema "github.com/hashicorp/terraform-plugin-framework/datasource/schema" "github.com/hashicorp/terraform-plugin-framework/diag" resourceSchema "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" ) @@ -52,8 +54,9 @@ func (o Ipv4PoolSubnet) DataSourceAttributes() map[string]dataSourceSchema.Attri func (o Ipv4PoolSubnet) ResourceAttributes() map[string]resourceSchema.Attribute { return map[string]resourceSchema.Attribute{ "status": resourceSchema.StringAttribute{ - MarkdownDescription: "Mutable read-only is always null in a Resource. Use the matching Data Source for this information.", + MarkdownDescription: "Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information.", Computed: true, + PlanModifiers: []planmodifier.String{apstraplanmodifier.UseNullStateForUnknown()}, }, "network": resourceSchema.StringAttribute{ MarkdownDescription: "Network specification in CIDR syntax (\"192.0.2.0/24\").", @@ -63,16 +66,19 @@ func (o Ipv4PoolSubnet) ResourceAttributes() map[string]resourceSchema.Attribute // ParseCidr is still required because the IPv4PrefixType doesn't enforce the zero address. }, "total": resourceSchema.NumberAttribute{ - MarkdownDescription: "Mutable read-only is always null in a Resource. Use the matching Data Source for this information.", + MarkdownDescription: "Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information.", Computed: true, + PlanModifiers: []planmodifier.Number{apstraplanmodifier.UseNullStateForUnknown()}, }, "used": resourceSchema.NumberAttribute{ - MarkdownDescription: "Mutable read-only is always null in a Resource. Use the matching Data Source for this information.", + MarkdownDescription: "Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information.", Computed: true, + PlanModifiers: []planmodifier.Number{apstraplanmodifier.UseNullStateForUnknown()}, }, "used_percentage": resourceSchema.Float64Attribute{ - MarkdownDescription: "Mutable read-only is always null in a Resource. Use the matching Data Source for this information.", + MarkdownDescription: "Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information.", Computed: true, + PlanModifiers: []planmodifier.Float64{apstraplanmodifier.UseNullStateForUnknown()}, }, } } diff --git a/apstra/resources/ipv6_pool.go b/apstra/resources/ipv6_pool.go index f8efcf84..7d89b10c 100644 --- a/apstra/resources/ipv6_pool.go +++ b/apstra/resources/ipv6_pool.go @@ -4,6 +4,7 @@ import ( "context" "github.com/Juniper/apstra-go-sdk/apstra" + apstraplanmodifier "github.com/Juniper/terraform-provider-apstra/apstra/apstra_plan_modifier" "github.com/Juniper/terraform-provider-apstra/apstra/utils" "github.com/hashicorp/terraform-plugin-framework-validators/setvalidator" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" @@ -95,23 +96,24 @@ func (o Ipv6Pool) ResourceAttributes() map[string]resourceSchema.Attribute { }, }, "total": resourceSchema.NumberAttribute{ - MarkdownDescription: "Total number of addresses in the IPv6 pool.", + MarkdownDescription: "Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information.", Computed: true, + PlanModifiers: []planmodifier.Number{apstraplanmodifier.UseNullStateForUnknown()}, }, "status": resourceSchema.StringAttribute{ - MarkdownDescription: "Status of the IPv6 pool. " + - "Note that this element is probably better read from a `data` source because it will be more up-to-date.", - Computed: true, + MarkdownDescription: "Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information.", + Computed: true, + PlanModifiers: []planmodifier.String{apstraplanmodifier.UseNullStateForUnknown()}, }, "used": resourceSchema.NumberAttribute{ - MarkdownDescription: "Count of used addresses in the IPv6 pool. " + - "Note that this element is probably better read from a `data` source because it will be more up-to-date.", - Computed: true, + MarkdownDescription: "Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information.", + Computed: true, + PlanModifiers: []planmodifier.Number{apstraplanmodifier.UseNullStateForUnknown()}, }, "used_percentage": resourceSchema.Float64Attribute{ - MarkdownDescription: "Percent of used addresses in the IPv6 pool. " + - "Note that this element is probably better read from a `data` source because it will be more up-to-date.", - Computed: true, + MarkdownDescription: "Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information.", + Computed: true, + PlanModifiers: []planmodifier.Float64{apstraplanmodifier.UseNullStateForUnknown()}, }, } } diff --git a/apstra/resources/ipv6_pool_subnet.go b/apstra/resources/ipv6_pool_subnet.go index 8fae0404..6f765860 100644 --- a/apstra/resources/ipv6_pool_subnet.go +++ b/apstra/resources/ipv6_pool_subnet.go @@ -4,6 +4,7 @@ import ( "context" "github.com/Juniper/apstra-go-sdk/apstra" + apstraplanmodifier "github.com/Juniper/terraform-provider-apstra/apstra/apstra_plan_modifier" apstravalidator "github.com/Juniper/terraform-provider-apstra/apstra/apstra_validator" "github.com/Juniper/terraform-provider-apstra/apstra/utils" "github.com/hashicorp/terraform-plugin-framework-nettypes/cidrtypes" @@ -11,6 +12,7 @@ import ( dataSourceSchema "github.com/hashicorp/terraform-plugin-framework/datasource/schema" "github.com/hashicorp/terraform-plugin-framework/diag" resourceSchema "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" ) @@ -52,8 +54,9 @@ func (o Ipv6PoolSubnet) DataSourceAttributes() map[string]dataSourceSchema.Attri func (o Ipv6PoolSubnet) ResourceAttributes() map[string]resourceSchema.Attribute { return map[string]resourceSchema.Attribute{ "status": resourceSchema.StringAttribute{ - MarkdownDescription: "Mutable read-only is always null in a Resource. Use the matching Data Source for this information.", + MarkdownDescription: "Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information.", Computed: true, + PlanModifiers: []planmodifier.String{apstraplanmodifier.UseNullStateForUnknown()}, }, "network": resourceSchema.StringAttribute{ MarkdownDescription: "Network specification in CIDR syntax (\"2001:db8::/64\").", @@ -63,16 +66,19 @@ func (o Ipv6PoolSubnet) ResourceAttributes() map[string]resourceSchema.Attribute // ParseCidr is still required because the IPv6PrefixType doesn't enforce the zero address. }, "total": resourceSchema.NumberAttribute{ - MarkdownDescription: "Mutable read-only is always null in a Resource. Use the matching Data Source for this information.", + MarkdownDescription: "Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information.", Computed: true, + PlanModifiers: []planmodifier.Number{apstraplanmodifier.UseNullStateForUnknown()}, }, "used": resourceSchema.NumberAttribute{ - MarkdownDescription: "Mutable read-only is always null in a Resource. Use the matching Data Source for this information.", + MarkdownDescription: "Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information.", Computed: true, + PlanModifiers: []planmodifier.Number{apstraplanmodifier.UseNullStateForUnknown()}, }, "used_percentage": resourceSchema.Float64Attribute{ - MarkdownDescription: "Mutable read-only is always null in a Resource. Use the matching Data Source for this information.", + MarkdownDescription: "Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information.", Computed: true, + PlanModifiers: []planmodifier.Float64{apstraplanmodifier.UseNullStateForUnknown()}, }, } } diff --git a/apstra/resources/vni_pool.go b/apstra/resources/vni_pool.go index e1f0f35f..8546645e 100644 --- a/apstra/resources/vni_pool.go +++ b/apstra/resources/vni_pool.go @@ -4,6 +4,7 @@ import ( "context" "github.com/Juniper/apstra-go-sdk/apstra" + apstraplanmodifier "github.com/Juniper/terraform-provider-apstra/apstra/apstra_plan_modifier" "github.com/Juniper/terraform-provider-apstra/apstra/utils" "github.com/hashicorp/terraform-plugin-framework-validators/setvalidator" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" @@ -95,23 +96,24 @@ func (o VniPool) ResourceAttributes() map[string]resourceSchema.Attribute { }, }, "total": resourceSchema.Int64Attribute{ - MarkdownDescription: "Total number of VNIs in the VNI Pool.", + MarkdownDescription: "Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information.", Computed: true, + PlanModifiers: []planmodifier.Int64{apstraplanmodifier.UseNullStateForUnknown()}, }, "status": resourceSchema.StringAttribute{ - MarkdownDescription: "Status of the VNI Pool. " + - "Note that this element is probably better read from a `data` source because it will be more up-to-date.", - Computed: true, + MarkdownDescription: "Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information.", + Computed: true, + PlanModifiers: []planmodifier.String{apstraplanmodifier.UseNullStateForUnknown()}, }, "used": resourceSchema.Int64Attribute{ - MarkdownDescription: "Count of used VNIs in the VNI Pool. " + - "Note that this element is probably better read from a `data` source because it will be more up-to-date.", - Computed: true, + MarkdownDescription: "Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information.", + Computed: true, + PlanModifiers: []planmodifier.Int64{apstraplanmodifier.UseNullStateForUnknown()}, }, "used_percentage": resourceSchema.Float64Attribute{ - MarkdownDescription: "Percent of used VNIs in the VNI Pool. " + - "Note that this element is probably better read from a `data` source because it will be more up-to-date.", - Computed: true, + MarkdownDescription: "Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information.", + Computed: true, + PlanModifiers: []planmodifier.Float64{apstraplanmodifier.UseNullStateForUnknown()}, }, } } diff --git a/apstra/resources/vni_pool_range.go b/apstra/resources/vni_pool_range.go index e0e4b98d..81de6fe5 100644 --- a/apstra/resources/vni_pool_range.go +++ b/apstra/resources/vni_pool_range.go @@ -4,6 +4,7 @@ import ( "context" "github.com/Juniper/apstra-go-sdk/apstra" + apstraplanmodifier "github.com/Juniper/terraform-provider-apstra/apstra/apstra_plan_modifier" "github.com/Juniper/terraform-provider-apstra/apstra/constants" "github.com/hashicorp/terraform-plugin-framework-validators/int64validator" "github.com/hashicorp/terraform-plugin-framework/attr" @@ -11,6 +12,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/path" resourceSchema "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" ) @@ -78,20 +80,24 @@ func (o VniPoolRange) ResourceAttributes() map[string]resourceSchema.Attribute { }, }, "total": resourceSchema.Int64Attribute{ - MarkdownDescription: "Mutable read-only is always null in a Resource. Use the matching Data Source for this information.", + MarkdownDescription: "Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information.", Computed: true, + PlanModifiers: []planmodifier.Int64{apstraplanmodifier.UseNullStateForUnknown()}, }, "status": resourceSchema.StringAttribute{ - MarkdownDescription: "Mutable read-only is always null in a Resource. Use the matching Data Source for this information.", + MarkdownDescription: "Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information.", Computed: true, + PlanModifiers: []planmodifier.String{apstraplanmodifier.UseNullStateForUnknown()}, }, "used": resourceSchema.Int64Attribute{ - MarkdownDescription: "Mutable read-only is always null in a Resource. Use the matching Data Source for this information.", + MarkdownDescription: "Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information.", Computed: true, + PlanModifiers: []planmodifier.Int64{apstraplanmodifier.UseNullStateForUnknown()}, }, "used_percentage": resourceSchema.Float64Attribute{ - MarkdownDescription: "Mutable read-only is always null in a Resource. Use the matching Data Source for this information.", + MarkdownDescription: "Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information.", Computed: true, + PlanModifiers: []planmodifier.Float64{apstraplanmodifier.UseNullStateForUnknown()}, }, } } diff --git a/docs/resources/asn_pool.md b/docs/resources/asn_pool.md index 6f7e73bc..9ae3b92c 100644 --- a/docs/resources/asn_pool.md +++ b/docs/resources/asn_pool.md @@ -40,10 +40,10 @@ resource "apstra_asn_pool" "rfc5398" { ### Read-Only - `id` (String) Apstra ID number of the pool -- `status` (String) Mutable read-only is always null in a Resource. Use the matching Data Source for this information. -- `total` (Number) Mutable read-only is always null in a Resource. Use the matching Data Source for this information. -- `used` (Number) Mutable read-only is always null in a Resource. Use the matching Data Source for this information. -- `used_percentage` (Number) Mutable read-only is always null in a Resource. Use the matching Data Source for this information. +- `status` (String) Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information. +- `total` (Number) Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information. +- `used` (Number) Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information. +- `used_percentage` (Number) Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information. ### Nested Schema for `ranges` @@ -55,10 +55,10 @@ Required: Read-Only: -- `status` (String) Mutable read-only is always null in a Resource. Use the matching Data Source for this information. -- `total` (Number) Mutable read-only is always null in a Resource. Use the matching Data Source for this information. -- `used` (Number) Mutable read-only is always null in a Resource. Use the matching Data Source for this information. -- `used_percentage` (Number) Mutable read-only is always null in a Resource. Use the matching Data Source for this information. +- `status` (String) Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information. +- `total` (Number) Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information. +- `used` (Number) Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information. +- `used_percentage` (Number) Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information. diff --git a/docs/resources/integer_pool.md b/docs/resources/integer_pool.md index 69519244..8109ff4a 100644 --- a/docs/resources/integer_pool.md +++ b/docs/resources/integer_pool.md @@ -77,10 +77,10 @@ resource "apstra_integer_pool" "five_random_ranges" { ### Read-Only - `id` (String) Apstra ID number of the pool -- `status` (String) Status of the Integer Pool. Note that this element is probably better read from a `data` source because it will be more up-to-date. -- `total` (Number) Total number of Integers in the Integer Pool. -- `used` (Number) Count of used Integers in the Integer Pool. Note that this element is probably better read from a `data` source because it will be more up-to-date. -- `used_percentage` (Number) Percent of used Integers in the Integer Pool. Note that this element is probably better read from a `data` source because it will be more up-to-date. +- `status` (String) Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information. +- `total` (Number) Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information. +- `used` (Number) Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information. +- `used_percentage` (Number) Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information. ### Nested Schema for `ranges` @@ -92,10 +92,10 @@ Required: Read-Only: -- `status` (String) Mutable read-only is always null in a Resource. Use the matching Data Source for this information. -- `total` (Number) Mutable read-only is always null in a Resource. Use the matching Data Source for this information. -- `used` (Number) Mutable read-only is always null in a Resource. Use the matching Data Source for this information. -- `used_percentage` (Number) Mutable read-only is always null in a Resource. Use the matching Data Source for this information. +- `status` (String) Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information. +- `total` (Number) Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information. +- `used` (Number) Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information. +- `used_percentage` (Number) Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information. diff --git a/docs/resources/ipv4_pool.md b/docs/resources/ipv4_pool.md index 8496a1e1..a14be4f7 100644 --- a/docs/resources/ipv4_pool.md +++ b/docs/resources/ipv4_pool.md @@ -73,10 +73,10 @@ output "example_pool_size" { ### Read-Only - `id` (String) Apstra ID number of the pool -- `status` (String) Status of the IPv4 pool. Note that this element is probably better read from a `data` source because it will be more up-to-date. -- `total` (Number) Total number of addresses in the IPv4 pool. -- `used` (Number) Count of used addresses in the IPv4 pool. Note that this element is probably better read from a `data` source because it will be more up-to-date. -- `used_percentage` (Number) Percent of used addresses in the IPv4 pool. Note that this element is probably better read from a `data` source because it will be more up-to-date. +- `status` (String) Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information. +- `total` (Number) Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information. +- `used` (Number) Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information. +- `used_percentage` (Number) Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information. ### Nested Schema for `subnets` @@ -87,10 +87,10 @@ Required: Read-Only: -- `status` (String) Mutable read-only is always null in a Resource. Use the matching Data Source for this information. -- `total` (Number) Mutable read-only is always null in a Resource. Use the matching Data Source for this information. -- `used` (Number) Mutable read-only is always null in a Resource. Use the matching Data Source for this information. -- `used_percentage` (Number) Mutable read-only is always null in a Resource. Use the matching Data Source for this information. +- `status` (String) Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information. +- `total` (Number) Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information. +- `used` (Number) Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information. +- `used_percentage` (Number) Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information. diff --git a/docs/resources/ipv6_pool.md b/docs/resources/ipv6_pool.md index e146e498..66539c24 100644 --- a/docs/resources/ipv6_pool.md +++ b/docs/resources/ipv6_pool.md @@ -73,10 +73,10 @@ locals { ### Read-Only - `id` (String) Apstra ID number of the pool -- `status` (String) Status of the IPv6 pool. Note that this element is probably better read from a `data` source because it will be more up-to-date. -- `total` (Number) Total number of addresses in the IPv6 pool. -- `used` (Number) Count of used addresses in the IPv6 pool. Note that this element is probably better read from a `data` source because it will be more up-to-date. -- `used_percentage` (Number) Percent of used addresses in the IPv6 pool. Note that this element is probably better read from a `data` source because it will be more up-to-date. +- `status` (String) Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information. +- `total` (Number) Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information. +- `used` (Number) Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information. +- `used_percentage` (Number) Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information. ### Nested Schema for `subnets` @@ -87,10 +87,10 @@ Required: Read-Only: -- `status` (String) Mutable read-only is always null in a Resource. Use the matching Data Source for this information. -- `total` (Number) Mutable read-only is always null in a Resource. Use the matching Data Source for this information. -- `used` (Number) Mutable read-only is always null in a Resource. Use the matching Data Source for this information. -- `used_percentage` (Number) Mutable read-only is always null in a Resource. Use the matching Data Source for this information. +- `status` (String) Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information. +- `total` (Number) Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information. +- `used` (Number) Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information. +- `used_percentage` (Number) Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information. diff --git a/docs/resources/vni_pool.md b/docs/resources/vni_pool.md index 064e8e92..96321759 100644 --- a/docs/resources/vni_pool.md +++ b/docs/resources/vni_pool.md @@ -62,10 +62,10 @@ resource "apstra_vni_pool" "five_random_ranges" { ### Read-Only - `id` (String) Apstra ID number of the pool -- `status` (String) Status of the VNI Pool. Note that this element is probably better read from a `data` source because it will be more up-to-date. -- `total` (Number) Total number of VNIs in the VNI Pool. -- `used` (Number) Count of used VNIs in the VNI Pool. Note that this element is probably better read from a `data` source because it will be more up-to-date. -- `used_percentage` (Number) Percent of used VNIs in the VNI Pool. Note that this element is probably better read from a `data` source because it will be more up-to-date. +- `status` (String) Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information. +- `total` (Number) Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information. +- `used` (Number) Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information. +- `used_percentage` (Number) Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information. ### Nested Schema for `ranges` @@ -77,10 +77,10 @@ Required: Read-Only: -- `status` (String) Mutable read-only is always null in a Resource. Use the matching Data Source for this information. -- `total` (Number) Mutable read-only is always null in a Resource. Use the matching Data Source for this information. -- `used` (Number) Mutable read-only is always null in a Resource. Use the matching Data Source for this information. -- `used_percentage` (Number) Mutable read-only is always null in a Resource. Use the matching Data Source for this information. +- `status` (String) Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information. +- `total` (Number) Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information. +- `used` (Number) Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information. +- `used_percentage` (Number) Mutable read-only attribute is always null in a Resource. Use the matching Data Source for this information.