diff --git a/apstra/blueprint/connectivity_templates/primitives/bgp_peering_generic_sytem.go b/apstra/blueprint/connectivity_templates/primitives/bgp_peering_generic_sytem.go index 1229fb59..8a333a2c 100644 --- a/apstra/blueprint/connectivity_templates/primitives/bgp_peering_generic_sytem.go +++ b/apstra/blueprint/connectivity_templates/primitives/bgp_peering_generic_sytem.go @@ -361,15 +361,28 @@ func (o bgpPeeringGenericSystemBatchIdPlanModifier) MarkdownDescription(ctx cont } func (o bgpPeeringGenericSystemBatchIdPlanModifier) PlanModifyString(ctx context.Context, req planmodifier.StringRequest, resp *planmodifier.StringResponse) { - var plan BgpPeeringGenericSystem + var plan, state BgpPeeringGenericSystem + + // unpacking the parent object's plan should always work resp.Diagnostics.Append(req.Plan.GetAttribute(ctx, req.Path.ParentPath(), &plan)...) if resp.Diagnostics.HasError() { return } - // do we have any children? + // attempting to unpack the parent object's state indicates whether state *exists* + d := req.State.GetAttribute(ctx, req.Path.ParentPath(), &state) + stateDoesNotExist := d.HasError() + + // do we have zero children? if len(plan.RoutingPolicies.Elements()) == 0 { + resp.PlanValue = types.StringNull() // with no children the batch id should be null + return + } + + // are we a new object? + if stateDoesNotExist { resp.PlanValue = types.StringUnknown() // we are a new object. the batch id is not knowable + return } // we're not new, and we have children. use the old value diff --git a/apstra/blueprint/connectivity_templates/primitives/bgp_peering_ip_endpoint.go b/apstra/blueprint/connectivity_templates/primitives/bgp_peering_ip_endpoint.go index 6003b264..9eb2f93d 100644 --- a/apstra/blueprint/connectivity_templates/primitives/bgp_peering_ip_endpoint.go +++ b/apstra/blueprint/connectivity_templates/primitives/bgp_peering_ip_endpoint.go @@ -326,21 +326,28 @@ func (o bgpPeeringIpEndpointBatchIdPlanModifier) MarkdownDescription(ctx context } func (o bgpPeeringIpEndpointBatchIdPlanModifier) PlanModifyString(ctx context.Context, req planmodifier.StringRequest, resp *planmodifier.StringResponse) { - var plan BgpPeeringIpEndpoint + var plan, state BgpPeeringIpEndpoint + + // unpacking the parent object's plan should always work resp.Diagnostics.Append(req.Plan.GetAttribute(ctx, req.Path.ParentPath(), &plan)...) if resp.Diagnostics.HasError() { return } - // do we have any children? + // attempting to unpack the parent object's state indicates whether state *exists* + d := req.State.GetAttribute(ctx, req.Path.ParentPath(), &state) + stateDoesNotExist := d.HasError() + + // do we have zero children? if len(plan.RoutingPolicies.Elements()) == 0 { resp.PlanValue = types.StringNull() // with no children the batch id should be null return } // are we a new object? - if plan.Id.IsUnknown() { + if stateDoesNotExist { resp.PlanValue = types.StringUnknown() // we are a new object. the batch id is not knowable + return } // we're not new, and we have children. use the old value diff --git a/apstra/blueprint/connectivity_templates/primitives/dynamic_bgp_peering.go b/apstra/blueprint/connectivity_templates/primitives/dynamic_bgp_peering.go index 8cda93a3..6001e865 100644 --- a/apstra/blueprint/connectivity_templates/primitives/dynamic_bgp_peering.go +++ b/apstra/blueprint/connectivity_templates/primitives/dynamic_bgp_peering.go @@ -337,21 +337,28 @@ func (o dynamicBgpPeeringBatchIdPlanModifier) MarkdownDescription(ctx context.Co } func (o dynamicBgpPeeringBatchIdPlanModifier) PlanModifyString(ctx context.Context, req planmodifier.StringRequest, resp *planmodifier.StringResponse) { - var plan DynamicBgpPeering + var plan, state DynamicBgpPeering + + // unpacking the parent object's plan should always work resp.Diagnostics.Append(req.Plan.GetAttribute(ctx, req.Path.ParentPath(), &plan)...) if resp.Diagnostics.HasError() { return } - // do we have any children? + // attempting to unpack the parent object's state indicates whether state *exists* + d := req.State.GetAttribute(ctx, req.Path.ParentPath(), &state) + stateDoesNotExist := d.HasError() + + // do we have zero children? if len(plan.RoutingPolicies.Elements()) == 0 { resp.PlanValue = types.StringNull() // with no children the batch id should be null return } // are we a new object? - if plan.Id.IsUnknown() { + if stateDoesNotExist { resp.PlanValue = types.StringUnknown() // we are a new object. the batch id is not knowable + return } // we're not new, and we have children. use the old value diff --git a/apstra/blueprint/connectivity_templates/primitives/ip_link.go b/apstra/blueprint/connectivity_templates/primitives/ip_link.go index c9ffd202..18696d42 100644 --- a/apstra/blueprint/connectivity_templates/primitives/ip_link.go +++ b/apstra/blueprint/connectivity_templates/primitives/ip_link.go @@ -335,13 +335,19 @@ func (o ipLinkBatchIdPlanModifier) MarkdownDescription(ctx context.Context) stri } func (o ipLinkBatchIdPlanModifier) PlanModifyString(ctx context.Context, req planmodifier.StringRequest, resp *planmodifier.StringResponse) { - var plan IpLink + var plan, state IpLink + + // unpacking the parent object's plan should always work resp.Diagnostics.Append(req.Plan.GetAttribute(ctx, req.Path.ParentPath(), &plan)...) if resp.Diagnostics.HasError() { return } - // do we have any children? + // attempting to unpack the parent object's state indicates whether state *exists* + d := req.State.GetAttribute(ctx, req.Path.ParentPath(), &state) + stateDoesNotExist := d.HasError() + + // do we have zero children? if len(plan.BgpPeeringGenericSystems.Elements())+ len(plan.BgpPeeringIpEndpoints.Elements())+ len(plan.DynamicBgpPeerings.Elements())+ @@ -351,8 +357,9 @@ func (o ipLinkBatchIdPlanModifier) PlanModifyString(ctx context.Context, req pla } // are we a new object? - if plan.Id.IsUnknown() { + if stateDoesNotExist { resp.PlanValue = types.StringUnknown() // we are a new object. the batch id is not knowable + return } // we're not new, and we have children. use the old value diff --git a/apstra/blueprint/connectivity_templates/primitives/virtual_network_single.go b/apstra/blueprint/connectivity_templates/primitives/virtual_network_single.go index db7af973..6bf93d8a 100644 --- a/apstra/blueprint/connectivity_templates/primitives/virtual_network_single.go +++ b/apstra/blueprint/connectivity_templates/primitives/virtual_network_single.go @@ -208,13 +208,19 @@ func (o virtualNetworkSingleBatchIdPlanModifier) MarkdownDescription(ctx context } func (o virtualNetworkSingleBatchIdPlanModifier) PlanModifyString(ctx context.Context, req planmodifier.StringRequest, resp *planmodifier.StringResponse) { - var plan VirtualNetworkSingle + var plan, state VirtualNetworkSingle + + // unpacking the parent object's plan should always work resp.Diagnostics.Append(req.Plan.GetAttribute(ctx, req.Path.ParentPath(), &plan)...) if resp.Diagnostics.HasError() { return } - // do we have any children? + // attempting to unpack the parent object's state indicates whether state *exists* + d := req.State.GetAttribute(ctx, req.Path.ParentPath(), &state) + stateDoesNotExist := d.HasError() + + // do we have zero children? if len(plan.BgpPeeringGenericSystems.Elements())+ len(plan.StaticRoutes.Elements()) == 0 { resp.PlanValue = types.StringNull() // with no children the batch id should be null @@ -222,8 +228,9 @@ func (o virtualNetworkSingleBatchIdPlanModifier) PlanModifyString(ctx context.Co } // are we a new object? - if plan.Id.IsUnknown() { + if stateDoesNotExist { resp.PlanValue = types.StringUnknown() // we are a new object. the batch id is not knowable + return } // we're not new, and we have children. use the old value