Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: plan modifier for ordered vlan and add ordered_vlan to state on update calls #145

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ require (
github.com/hashicorp/terraform-plugin-framework-validators v0.12.0
github.com/hashicorp/terraform-plugin-go v0.22.1
github.com/hashicorp/terraform-plugin-log v0.9.0
github.com/megaport/megaportgo v1.2.2
github.com/megaport/megaportgo v1.2.5
)

require (
Expand Down
6 changes: 2 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,8 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/megaport/megaportgo v1.2.0 h1:LLI+3OaK4BzUMazuQm1TAptRaQbGrTp+wDxEjkARCNE=
github.com/megaport/megaportgo v1.2.0/go.mod h1:I+8jJioFFsF+55sxFYCgcKNUENaOpqzwlsIu6NGA7qk=
github.com/megaport/megaportgo v1.2.2 h1:exF0cLFk5Bug9SAThvJDBmwpVf7TCc0XFv7UjRS6x5Y=
github.com/megaport/megaportgo v1.2.2/go.mod h1:I+8jJioFFsF+55sxFYCgcKNUENaOpqzwlsIu6NGA7qk=
github.com/megaport/megaportgo v1.2.5 h1:87IdC1X1zivNv3j0xOtjAJ7oQNAAXhuposfOtom8mis=
github.com/megaport/megaportgo v1.2.5/go.mod h1:I+8jJioFFsF+55sxFYCgcKNUENaOpqzwlsIu6NGA7qk=
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
Expand Down
118 changes: 103 additions & 15 deletions internal/provider/vxc_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -486,8 +486,6 @@ func (orm *vxcResourceModel) fromAPIVXC(ctx context.Context, v *megaport.VXC) di
}
if aEndOrderedVLAN != nil {
aEndModel.OrderedVLAN = types.Int64Value(*aEndOrderedVLAN)
} else {
aEndModel.OrderedVLAN = types.Int64PointerValue(nil)
}
if v.AEndConfiguration.InnerVLAN == 0 {
aEndModel.InnerVLAN = types.Int64PointerValue(nil)
Expand Down Expand Up @@ -522,8 +520,6 @@ func (orm *vxcResourceModel) fromAPIVXC(ctx context.Context, v *megaport.VXC) di
}
if bEndOrderedVLAN != nil {
bEndModel.OrderedVLAN = types.Int64Value(*bEndOrderedVLAN)
} else {
bEndModel.OrderedVLAN = types.Int64PointerValue(nil)
}
if v.BEndConfiguration.InnerVLAN == 0 {
bEndModel.InnerVLAN = types.Int64PointerValue(nil)
Expand Down Expand Up @@ -3229,9 +3225,13 @@ func (r *vxcResource) Read(ctx context.Context, req resource.ReadRequest, resp *
// Set refreshed state
diags = resp.State.Set(ctx, &state)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}

aEndConfig := &vxcEndConfigurationModel{}
bEndConfig := &vxcEndConfigurationModel{}
aEndConfigDiags := state.AEndConfiguration.As(ctx, aEndConfig, basetypes.ObjectAsOptions{})
bEndConfigDiags := state.BEndConfiguration.As(ctx, bEndConfig, basetypes.ObjectAsOptions{})
resp.Diagnostics.Append(aEndConfigDiags...)
resp.Diagnostics.Append(bEndConfigDiags...)
}

func (r *vxcResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
Expand All @@ -3244,6 +3244,14 @@ func (r *vxcResource) Update(ctx context.Context, req resource.UpdateRequest, re
return
}

// If Imported, AEndPartnerConfig will be null. Set the partner config to the existing one in the plan.
if state.AEndPartnerConfig.IsNull() {
state.AEndPartnerConfig = plan.AEndPartnerConfig
}
if state.BEndPartnerConfig.IsNull() {
state.BEndPartnerConfig = plan.BEndPartnerConfig
}

var aEndPlan, bEndPlan, aEndState, bEndState *vxcEndConfigurationModel

aEndPlanDiags := plan.AEndConfiguration.As(ctx, &aEndPlan, basetypes.ObjectAsOptions{})
Expand Down Expand Up @@ -3278,24 +3286,32 @@ func (r *vxcResource) Update(ctx context.Context, req resource.UpdateRequest, re
}

// If Ordered VLAN is different from actual VLAN, attempt to change it to the ordered VLAN value.
if !aEndPlan.OrderedVLAN.IsUnknown() && !aEndPlan.OrderedVLAN.IsNull() && !aEndPlan.OrderedVLAN.Equal(aEndState.VLAN) {
updateReq.AEndVLAN = megaport.PtrTo(int(aEndPlan.OrderedVLAN.ValueInt64()))
if !aEndPlan.OrderedVLAN.IsUnknown() && !aEndPlan.OrderedVLAN.IsNull() {
if !aEndPlan.OrderedVLAN.Equal(aEndState.VLAN) {
updateReq.AEndVLAN = megaport.PtrTo(int(aEndPlan.OrderedVLAN.ValueInt64()))
}
aEndState.OrderedVLAN = aEndPlan.OrderedVLAN
}

if !aEndPlan.InnerVLAN.IsUnknown() && !aEndPlan.InnerVLAN.IsNull() && !aEndPlan.InnerVLAN.Equal(aEndState.InnerVLAN) {
updateReq.AEndInnerVLAN = megaport.PtrTo(int(aEndPlan.InnerVLAN.ValueInt64()))
if !aEndPlan.InnerVLAN.IsUnknown() && !aEndPlan.InnerVLAN.IsNull() {
if !aEndPlan.InnerVLAN.Equal(aEndState.InnerVLAN) {
updateReq.AEndInnerVLAN = megaport.PtrTo(int(aEndPlan.InnerVLAN.ValueInt64()))
}
aEndState.InnerVLAN = aEndPlan.InnerVLAN
}

// If Ordered VLAN is different from actual VLAN, attempt to change it to the ordered VLAN value.
if !bEndPlan.OrderedVLAN.IsUnknown() && !bEndPlan.OrderedVLAN.IsNull() && !bEndPlan.OrderedVLAN.Equal(bEndState.VLAN) {
updateReq.BEndVLAN = megaport.PtrTo(int(bEndPlan.OrderedVLAN.ValueInt64()))
if !bEndPlan.OrderedVLAN.IsUnknown() && !bEndPlan.OrderedVLAN.IsNull() {
if !bEndPlan.OrderedVLAN.Equal(bEndState.VLAN) {
updateReq.BEndVLAN = megaport.PtrTo(int(bEndPlan.OrderedVLAN.ValueInt64()))
}
bEndState.OrderedVLAN = bEndPlan.OrderedVLAN
}

if !bEndPlan.InnerVLAN.IsUnknown() && !bEndPlan.InnerVLAN.IsNull() && !bEndPlan.InnerVLAN.Equal(bEndState.InnerVLAN) {
updateReq.BEndInnerVLAN = megaport.PtrTo(int(bEndPlan.InnerVLAN.ValueInt64()))
if !bEndPlan.InnerVLAN.IsUnknown() && !bEndPlan.InnerVLAN.IsNull() {
if !bEndPlan.InnerVLAN.Equal(bEndState.InnerVLAN) {
updateReq.BEndInnerVLAN = megaport.PtrTo(int(bEndPlan.InnerVLAN.ValueInt64()))
}
bEndState.InnerVLAN = bEndPlan.InnerVLAN
}

Expand Down Expand Up @@ -3409,6 +3425,7 @@ func (r *vxcResource) Configure(_ context.Context, req resource.ConfigureRequest
func (r *vxcResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
// Retrieve import ID and save to id attribute
resource.ImportStatePassthroughID(ctx, path.Root("product_uid"), req, resp)

}

func fromAPICSPConnection(ctx context.Context, c megaport.CSPConnectionConfig) (types.Object, diag.Diagnostics) {
Expand Down Expand Up @@ -3531,3 +3548,74 @@ func fromAPICSPConnection(ctx context.Context, c megaport.CSPConnectionConfig) (
apiDiags.AddError("Error creating CSP Connection", "Could not create CSP Connection, unknown type")
return types.ObjectNull(cspConnectionFullAttrs), apiDiags
}

func (r *vxcResource) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
// Get current state
var plan, state vxcResourceModel
diags := diag.Diagnostics{}

planDiags := req.Plan.Get(ctx, &plan)
resp.Diagnostics.Append(planDiags...)
if !req.State.Raw.IsNull() {
stateDiags := req.State.Get(ctx, &state)
resp.Diagnostics.Append(stateDiags...)
}
if resp.Diagnostics.HasError() {
return
}

// If VXC is not yet created, return
if !state.UID.IsNull() {
aEndStateObj := state.AEndConfiguration
bEndStateObj := state.BEndConfiguration
aEndStateConfig := &vxcEndConfigurationModel{}
bEndStateConfig := &vxcEndConfigurationModel{}
aEndDiags := aEndStateObj.As(ctx, aEndStateConfig, basetypes.ObjectAsOptions{})
bEndDiags := bEndStateObj.As(ctx, bEndStateConfig, basetypes.ObjectAsOptions{})
diags = append(diags, aEndDiags...)
diags = append(diags, bEndDiags...)
aEndPlanObj := plan.AEndConfiguration
bEndPlanObj := plan.BEndConfiguration
aEndPlanConfig := &vxcEndConfigurationModel{}
bEndPlanConfig := &vxcEndConfigurationModel{}
aEndDiags = aEndPlanObj.As(ctx, aEndPlanConfig, basetypes.ObjectAsOptions{})
bEndDiags = bEndPlanObj.As(ctx, bEndPlanConfig, basetypes.ObjectAsOptions{})
diags = append(diags, aEndDiags...)
diags = append(diags, bEndDiags...)
if aEndStateConfig.OrderedVLAN.IsUnknown() {
aEndPlanConfig.OrderedVLAN = aEndStateConfig.VLAN
}
if bEndStateConfig.OrderedVLAN.IsUnknown() {
bEndPlanConfig.OrderedVLAN = bEndStateConfig.VLAN
}
if state.AEndPartnerConfig.IsNull() {
state.AEndPartnerConfig = plan.AEndPartnerConfig
} else {
if !plan.AEndPartnerConfig.Equal(state.AEndPartnerConfig) {
resp.RequiresReplace = append(resp.RequiresReplace, path.Root("a_end_partner_config"))
}
}
if state.BEndPartnerConfig.IsNull() {
state.BEndPartnerConfig = plan.BEndPartnerConfig
} else {
if !plan.BEndPartnerConfig.Equal(state.BEndPartnerConfig) {
resp.RequiresReplace = append(resp.RequiresReplace, path.Root("b_end_partner_config"))
}
}
newPlanAEndObj, aEndDiags := types.ObjectValueFrom(ctx, vxcEndConfigurationAttrs, aEndPlanConfig)
newPlanBEndObj, bEndDiags := types.ObjectValueFrom(ctx, vxcEndConfigurationAttrs, bEndPlanConfig)
diags = append(diags, aEndDiags...)
diags = append(diags, bEndDiags...)
plan.AEndConfiguration = newPlanAEndObj
plan.BEndConfiguration = newPlanBEndObj
req.Plan.Set(ctx, &plan)
resp.Plan.Set(ctx, &plan)
stateDiags := req.State.Set(ctx, &state)
diags = append(diags, stateDiags...)
}

resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}
}