@@ -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
834858func (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+ }
0 commit comments