Skip to content

Commit 71ed067

Browse files
Terraform Team AutomationMaxrovr
authored andcommitted
Bug Fix - update the load balancer ports
1 parent b9603ea commit 71ed067

File tree

5 files changed

+90
-59
lines changed

5 files changed

+90
-59
lines changed

internal/integrationtest/core_instance_pool_instance_test.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,19 @@ var (
5454
"image": acctest.Representation{RepType: acctest.Required, Create: `${var.InstanceImageOCID[var.region]}`},
5555
"ipxe_script": acctest.Representation{RepType: acctest.Optional, Create: `ipxeScript`},
5656
"is_pv_encryption_in_transit_enabled": acctest.Representation{RepType: acctest.Optional, Create: `false`},
57-
"launch_options": acctest.RepresentationGroup{RepType: acctest.Optional, Group: CoreInstanceLaunchOptionsRepresentation},
57+
"launch_options": acctest.RepresentationGroup{RepType: acctest.Optional, Group: CoreInstanceLaunchOptionsRepresentationOnlyNetworkType},
5858
"metadata": acctest.Representation{RepType: acctest.Optional, Create: map[string]string{"user_data": "abcd"}},
5959
"shape_config": acctest.RepresentationGroup{RepType: acctest.Optional, Group: CoreInstanceShapeConfigRepresentation},
6060
"source_details": acctest.RepresentationGroup{RepType: acctest.Optional, Group: CoreInstanceSourceDetailsRepresentation},
6161
"subnet_id": acctest.Representation{RepType: acctest.Required, Create: `${oci_core_subnet.test_subnet.id}`},
6262
"state": acctest.Representation{RepType: acctest.Required, Create: `RUNNING`},
6363
}
6464

65+
// Because NetworkType is the only supported launchOption
66+
CoreInstanceLaunchOptionsRepresentationOnlyNetworkType = map[string]interface{}{
67+
"network_type": acctest.Representation{RepType: acctest.Optional, Create: `PARAVIRTUALIZED`},
68+
}
69+
6570
CoreInstancePoolForAttachInstanceRepresentation = map[string]interface{}{
6671
"compartment_id": acctest.Representation{RepType: acctest.Required, Create: `${var.compartment_id}`},
6772
"instance_configuration_id": acctest.Representation{RepType: acctest.Required, Create: `${oci_core_instance_configuration.test_instance_configuration.id}`},

internal/integrationtest/core_instance_pool_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ var (
126126
"shape": acctest.Representation{RepType: acctest.Optional, Create: InstanceConfigurationVmShape},
127127
"source_details": acctest.RepresentationGroup{RepType: acctest.Optional, Group: CoreInstanceConfigurationInstanceDetailsLaunchDetailsSourceDetailsRepresentation},
128128
"agent_config": acctest.RepresentationGroup{RepType: acctest.Optional, Group: CoreInstanceAgentConfigRepresentation},
129-
"launch_options": acctest.RepresentationGroup{RepType: acctest.Optional, Group: CoreInstanceLaunchOptionsRepresentation},
129+
"launch_options": acctest.RepresentationGroup{RepType: acctest.Optional, Group: CoreInstanceLaunchOptionsRepresentationOnlyNetworkType},
130130
"is_pv_encryption_in_transit_enabled": acctest.Representation{RepType: acctest.Optional, Create: `false`},
131131
"launch_mode": acctest.Representation{RepType: acctest.Optional, Create: `NATIVE`},
132132
"preferred_maintenance_action": acctest.Representation{RepType: acctest.Optional, Create: `LIVE_MIGRATE`},

internal/service/core/core_instance_pool_resource.go

Lines changed: 79 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -806,29 +806,53 @@ func (s *CoreInstancePoolResourceCrud) updateCompartment(compartment interface{}
806806
return nil
807807
}
808808

809-
func (s *CoreInstancePoolResourceCrud) oneEditAway(oldLoadBalancers []oci_core.AttachLoadBalancerDetails, newLoadBalancers []oci_core.AttachLoadBalancerDetails) (bool, string, oci_core.AttachLoadBalancerDetails, oci_core.AttachLoadBalancerDetails) {
810-
if Abs(len(newLoadBalancers)-len(oldLoadBalancers)) != 1 {
811-
return false, "", oci_core.AttachLoadBalancerDetails{}, oci_core.AttachLoadBalancerDetails{}
812-
}
813-
if len(newLoadBalancers) > len(oldLoadBalancers) {
814-
for i := 0; i < len(oldLoadBalancers); i++ {
815-
if *oldLoadBalancers[i].LoadBalancerId != *newLoadBalancers[i].LoadBalancerId {
816-
return false, "", oci_core.AttachLoadBalancerDetails{}, oci_core.AttachLoadBalancerDetails{}
817-
}
809+
/**
810+
This method decides if load_balancers update/attach/detach should go through.
811+
Only one operation can happen in single request
812+
1. update/attach should happen from the end of the lb list
813+
2. detach can happen from anywhere in the list.
814+
*/
815+
func (s *CoreInstancePoolResourceCrud) oneEditAway(oldLoadBalancers []oci_core.AttachLoadBalancerDetails, newLoadBalancers []oci_core.AttachLoadBalancerDetails) (bool, string, oci_core.AttachLoadBalancerDetails, oci_core.AttachLoadBalancerDetails, string) {
816+
newLbsLength := len(newLoadBalancers)
817+
oldLbsLength := len(oldLoadBalancers)
818+
819+
// if old and new lb size is > 1 throw error
820+
if Abs(newLbsLength-oldLbsLength) > 1 {
821+
return false, "", oci_core.AttachLoadBalancerDetails{}, oci_core.AttachLoadBalancerDetails{}, "Error: Failed to update load balancers, only one load balancer can be modified but found more than one"
822+
}
823+
824+
// if old and new lb size is same that means this is an update to lb
825+
if Abs(newLbsLength-oldLbsLength) == 0 {
826+
deltas, positionToUpdate := s.getLoadBalancerDeltas(oldLoadBalancers, newLoadBalancers)
827+
if deltas > 1 {
828+
return false, "", oci_core.AttachLoadBalancerDetails{}, oci_core.AttachLoadBalancerDetails{}, "Error: Failed to update load balancers details, only one load balancer can be modified but found more than one"
829+
} else if deltas == 1 && positionToUpdate == newLbsLength-1 {
830+
return true, "update", oldLoadBalancers[positionToUpdate], newLoadBalancers[positionToUpdate], ""
818831
}
819-
return true, "attach", oci_core.AttachLoadBalancerDetails{}, newLoadBalancers[len(newLoadBalancers)-1]
832+
return false, "", oci_core.AttachLoadBalancerDetails{}, oci_core.AttachLoadBalancerDetails{}, "Error: Failed to update load balancers, only the load balancer which is at the end of the config can be modified"
820833
}
821-
for i := 0; i < len(newLoadBalancers); i++ {
822-
if *oldLoadBalancers[i].LoadBalancerId != *newLoadBalancers[i].LoadBalancerId {
823-
for j := i + 1; j < len(newLoadBalancers); j++ {
824-
if *oldLoadBalancers[j].LoadBalancerId != *newLoadBalancers[j-1].LoadBalancerId {
825-
return false, "", oci_core.AttachLoadBalancerDetails{}, oci_core.AttachLoadBalancerDetails{}
834+
835+
// If the new lbs length is > old one that means an attach of an lb
836+
if newLbsLength > oldLbsLength {
837+
deltas, _ := s.getLoadBalancerDeltas(oldLoadBalancers, newLoadBalancers)
838+
if deltas != 0 {
839+
return false, "", oci_core.AttachLoadBalancerDetails{}, oci_core.AttachLoadBalancerDetails{}, "Error: Failed to attach load balancer, only the load balancer which is at the end of the config can be attached"
840+
}
841+
return true, "attach", oci_core.AttachLoadBalancerDetails{}, newLoadBalancers[newLbsLength-1], ""
842+
}
843+
844+
// Remaining case does detach
845+
for i := 0; i < newLbsLength; i++ {
846+
if lbHasChanges(oldLoadBalancers[i], newLoadBalancers[i]) /**oldLoadBalancers[i].LoadBalancerId != *newLoadBalancers[i].LoadBalancerId*/ {
847+
for j := i + 1; j < newLbsLength; j++ {
848+
if lbHasChanges(oldLoadBalancers[j], newLoadBalancers[j-1]) /**oldLoadBalancers[j].LoadBalancerId != *newLoadBalancers[j-1].LoadBalancerId*/ {
849+
return false, "", oci_core.AttachLoadBalancerDetails{}, oci_core.AttachLoadBalancerDetails{}, "Error: Failed to detach load balancer, only one load balancer can be detached but found more than one"
826850
}
827851
}
828-
return true, "detach", oldLoadBalancers[i], oci_core.AttachLoadBalancerDetails{}
852+
return true, "detach", oldLoadBalancers[i], oci_core.AttachLoadBalancerDetails{}, ""
829853
}
830854
}
831-
return true, "detach", oldLoadBalancers[len(oldLoadBalancers)-1], oci_core.AttachLoadBalancerDetails{}
855+
return true, "detach", oldLoadBalancers[oldLbsLength-1], oci_core.AttachLoadBalancerDetails{}, ""
832856
}
833857

834858
func (s *CoreInstancePoolResourceCrud) updateLoadBalancers(oldRaw interface{}, newRaw interface{}) error {
@@ -845,48 +869,49 @@ func (s *CoreInstancePoolResourceCrud) updateLoadBalancers(oldRaw interface{}, n
845869
converted := mapToAttachLoadBalancerDetails(item.(map[string]interface{}))
846870
newBalancers[i] = converted
847871
}
848-
canEdit, operation, oldLoadbalancer, newLoadBalancer := s.oneEditAway(oldBalancers, newBalancers)
872+
canEdit, operation, oldLoadbalancer, newLoadBalancer, errorMsg := s.oneEditAway(oldBalancers, newBalancers)
849873
if !canEdit {
850-
return fmt.Errorf("only one add/remove is allowed at once, new LoadBalancer must be added at the end of list")
874+
return fmt.Errorf(errorMsg)
851875
}
852876
id := s.D.Id()
853877

854-
if operation == "attach" {
855-
attachLoadBalancerRequest := oci_core.AttachLoadBalancerRequest{}
856-
attachLoadBalancerRequest.InstancePoolId = &id
857-
attachLoadBalancerRequest.RequestMetadata.RetryPolicy = tfresource.GetRetryPolicy(s.DisableNotFoundRetries, "core")
858-
attachLoadBalancerRequest.AttachLoadBalancerDetails = newLoadBalancer
859-
_, err := s.Client.AttachLoadBalancer(context.Background(), attachLoadBalancerRequest)
878+
if operation == "detach" || operation == "update" {
879+
detachLoadBalancerRequest := oci_core.DetachLoadBalancerRequest{}
880+
detachLoadBalancerRequest.LoadBalancerId = oldLoadbalancer.LoadBalancerId
881+
detachLoadBalancerRequest.RequestMetadata.RetryPolicy = tfresource.GetRetryPolicy(s.DisableNotFoundRetries, "core")
882+
detachLoadBalancerRequest.InstancePoolId = &id
883+
detachLoadBalancerRequest.BackendSetName = oldLoadbalancer.BackendSetName
884+
_, err := s.Client.DetachLoadBalancer(context.Background(), detachLoadBalancerRequest)
860885

861886
if err != nil {
862887
return err
863888
}
864889

865-
_, err = s.pollForLbOperationCompletion(&id, &attachLoadBalancerRequest.AttachLoadBalancerDetails)
890+
_, err = s.pollForLbOperationCompletion(&id, &oldLoadbalancer)
866891

867892
if err != nil {
868893
return err
869894
}
870895
}
871896

872-
if operation == "detach" {
873-
detachLoadBalancerRequest := oci_core.DetachLoadBalancerRequest{}
874-
detachLoadBalancerRequest.LoadBalancerId = oldLoadbalancer.LoadBalancerId
875-
detachLoadBalancerRequest.RequestMetadata.RetryPolicy = tfresource.GetRetryPolicy(s.DisableNotFoundRetries, "core")
876-
detachLoadBalancerRequest.InstancePoolId = &id
877-
detachLoadBalancerRequest.BackendSetName = oldLoadbalancer.BackendSetName
878-
_, err := s.Client.DetachLoadBalancer(context.Background(), detachLoadBalancerRequest)
897+
if operation == "attach" || operation == "update" {
898+
attachLoadBalancerRequest := oci_core.AttachLoadBalancerRequest{}
899+
attachLoadBalancerRequest.InstancePoolId = &id
900+
attachLoadBalancerRequest.RequestMetadata.RetryPolicy = tfresource.GetRetryPolicy(s.DisableNotFoundRetries, "core")
901+
attachLoadBalancerRequest.AttachLoadBalancerDetails = newLoadBalancer
902+
_, err := s.Client.AttachLoadBalancer(context.Background(), attachLoadBalancerRequest)
879903

880904
if err != nil {
881905
return err
882906
}
883907

884-
_, err = s.pollForLbOperationCompletion(&id, &oldLoadbalancer)
908+
_, err = s.pollForLbOperationCompletion(&id, &attachLoadBalancerRequest.AttachLoadBalancerDetails)
885909

886910
if err != nil {
887911
return err
888912
}
889913
}
914+
890915
return nil
891916
}
892917

@@ -946,3 +971,23 @@ func (s *CoreInstancePoolResourceCrud) pollForLbOperationCompletion(poolId *stri
946971

947972
return &response.InstancePool, nil
948973
}
974+
975+
func (s *CoreInstancePoolResourceCrud) getLoadBalancerDeltas(balancers []oci_core.AttachLoadBalancerDetails, balancers2 []oci_core.AttachLoadBalancerDetails) (int, int) {
976+
lbLength := len(balancers)
977+
deltas := 0
978+
positionToUpdate := -1
979+
for i := 0; i < lbLength; i++ {
980+
if lbHasChanges(balancers[i], balancers2[i]) {
981+
deltas++
982+
positionToUpdate = i
983+
}
984+
}
985+
return deltas, positionToUpdate
986+
}
987+
988+
func lbHasChanges(details oci_core.AttachLoadBalancerDetails, details2 oci_core.AttachLoadBalancerDetails) bool {
989+
return !(*details.BackendSetName == *details2.BackendSetName &&
990+
*details.LoadBalancerId == *details2.LoadBalancerId &&
991+
*details.Port == *details2.Port &&
992+
*details.VnicSelection == *details2.VnicSelection)
993+
}

internal/tfresource/crud_helpers.go

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -518,29 +518,10 @@ func MySqlVersionDiffSuppress(key string, old string, new string, d *schema.Reso
518518
func LoadBalancersSuppressDiff(key string, old string, new string, d *schema.ResourceData) bool {
519519
return loadBalancersSuppressDiff(d)
520520
}
521-
func loadBalancersSuppressDiff(d schemaResourceData) bool {
522-
if !d.HasChange("load_balancers") {
523-
return true
524-
}
525-
oldRaw, newRaw := d.GetChange("load_balancers")
526-
interfaces := oldRaw.([]interface{})
527-
oldBalancers := make(map[string]bool, len(interfaces))
528-
for _, item := range interfaces {
529-
oldBalancers[item.(map[string]interface{})["load_balancer_id"].(string)] = true
530-
}
531521

532-
interfaces = newRaw.([]interface{})
533-
if len(interfaces) != len(oldBalancers) {
534-
return false
535-
}
536-
537-
for _, item := range interfaces {
538-
converted := item.(map[string]interface{})["load_balancer_id"].(string)
539-
if _, ok := oldBalancers[converted]; !ok {
540-
return false
541-
}
542-
}
543-
return true
522+
// Removed custom logic for diffs because we should update the lb details for nay change on the existing lb.
523+
func loadBalancersSuppressDiff(d schemaResourceData) bool {
524+
return !d.HasChange("load_balancers")
544525
}
545526

546527
func EqualIgnoreCaseSuppressDiff(key string, old string, new string, d *schema.ResourceData) bool {

internal/tfresource/crud_helpers_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -894,7 +894,7 @@ func TestUnitloadBalancersSuppressDiff(t *testing.T) {
894894
{
895895
name: "Test HasChange() is true and output is true",
896896
args: args{d: changeReqResourceData("4")},
897-
output: true,
897+
output: false,
898898
},
899899
}
900900
for _, test := range tests {

0 commit comments

Comments
 (0)