99 "time"
1010
1111 stackitconfig "github.com/stackitcloud/cloud-provider-stackit/pkg/stackit/config"
12- //nolint:staticcheck // Temporary workaround: v2api OpenAPI generator currently misses enum constants; fixed in next NVP.
13- lbLegacy "github.com/stackitcloud/stackit-sdk-go/services/loadbalancer"
14- loadbalancer "github.com/stackitcloud/stackit-sdk-go/services/loadbalancer/v2api"
12+ "github.com/stackitcloud/stackit-sdk-go/services/loadbalancer"
1513 corev1 "k8s.io/api/core/v1"
1614
1715 "github.com/stackitcloud/cloud-provider-stackit/pkg/cmp"
@@ -241,38 +239,36 @@ func getPlanID(service *corev1.Service) (planID *string, msgs []string, err erro
241239// lbSpecFromService returns a load balancer specification in the form of a create payload matching the specification of the service, nodes and network.
242240// The property name will be empty and must be set by the caller to produce a valid payload for the API.
243241// An error is returned if the service has invalid options.
244- //
245- //nolint:gocyclo,funlen,staticcheck // Temporary workaround: v2api OpenAPI generator currently misses enum constants; fixed in next NVP.
246- func lbSpecFromService (
242+ func lbSpecFromService ( //nolint:funlen,gocyclo // It is long but not complex.
247243 service * corev1.Service ,
248244 nodes []* corev1.Node ,
249245 opts stackitconfig.LoadBalancerOpts ,
250246 observability * loadbalancer.LoadbalancerOptionObservability ,
251247) (* loadbalancer.CreateLoadBalancerPayload , []Event , error ) {
252248 lb := & loadbalancer.CreateLoadBalancerPayload {
253249 Options : & loadbalancer.LoadBalancerOptions {},
254- Networks : []loadbalancer.Network {
250+ Networks : & []loadbalancer.Network {
255251 {
256- Role : new (string (lbLegacy .NETWORKROLE_LISTENERS_AND_TARGETS ) ),
252+ Role : new (loadbalancer .NETWORKROLE_LISTENERS_AND_TARGETS ),
257253 NetworkId : & opts .NetworkID ,
258254 },
259255 },
260256 }
261257
262258 if listenerNetwork := service .Annotations [listenerNetworkAnnotation ]; listenerNetwork != "" {
263- lb .Networks = []loadbalancer.Network {
259+ lb .Networks = & []loadbalancer.Network {
264260 {
265- Role : new (string (lbLegacy .NETWORKROLE_TARGETS ) ),
261+ Role : new (loadbalancer .NETWORKROLE_TARGETS ),
266262 NetworkId : & opts .NetworkID ,
267263 }, {
268- Role : new (string (lbLegacy .NETWORKROLE_LISTENERS ) ),
264+ Role : new (loadbalancer .NETWORKROLE_LISTENERS ),
269265 NetworkId : & listenerNetwork ,
270266 },
271267 }
272268 } else {
273- lb .Networks = []loadbalancer.Network {
269+ lb .Networks = & []loadbalancer.Network {
274270 {
275- Role : new (string (lbLegacy .NETWORKROLE_LISTENERS_AND_TARGETS ) ),
271+ Role : new (loadbalancer .NETWORKROLE_LISTENERS_AND_TARGETS ),
276272 NetworkId : & opts .NetworkID ,
277273 },
278274 }
@@ -497,22 +493,22 @@ func lbSpecFromService(
497493 name = fmt .Sprintf ("port-%s-%d" , strings .ToLower (string (port .Protocol )), port .Port )
498494 }
499495
500- var protocol lbLegacy .ListenerProtocol
496+ var protocol loadbalancer .ListenerProtocol
501497 var tcpOptions * loadbalancer.OptionsTCP
502498 var udpOptions * loadbalancer.OptionsUDP
503499
504500 switch port .Protocol {
505501 case corev1 .ProtocolTCP :
506502 if proxyProtocolEnableForPort (tcpProxyProtocolEnabled , tcpProxyProtocolPortFilter , port .Port ) {
507- protocol = lbLegacy .LISTENERPROTOCOL_TCP_PROXY
503+ protocol = loadbalancer .LISTENERPROTOCOL_TCP_PROXY
508504 } else {
509- protocol = lbLegacy .LISTENERPROTOCOL_TCP
505+ protocol = loadbalancer .LISTENERPROTOCOL_TCP
510506 }
511507 tcpOptions = & loadbalancer.OptionsTCP {
512508 IdleTimeout : new (fmt.Sprintf ("%.0fs" , tcpIdleTimeout .Seconds ())),
513509 }
514510 case corev1 .ProtocolUDP :
515- protocol = lbLegacy .LISTENERPROTOCOL_UDP
511+ protocol = loadbalancer .LISTENERPROTOCOL_UDP
516512 udpOptions = & loadbalancer.OptionsUDP {
517513 IdleTimeout : new (fmt.Sprintf ("%.0fs" , udpIdleTimeout .Seconds ())),
518514 }
@@ -522,33 +518,33 @@ func lbSpecFromService(
522518
523519 listeners = append (listeners , loadbalancer.Listener {
524520 DisplayName : & name ,
525- Port : new (port.Port ),
521+ Port : new (int64 ( port.Port ) ),
526522 TargetPool : & name ,
527- Protocol : new (string ( protocol ) ),
523+ Protocol : new (protocol ),
528524 Tcp : tcpOptions ,
529525 Udp : udpOptions ,
530526 })
531527
532528 targetPools = append (targetPools , loadbalancer.TargetPool {
533529 Name : & name ,
534- TargetPort : new (port.NodePort ),
535- Targets : targets ,
530+ TargetPort : new (int64 ( port.NodePort ) ),
531+ Targets : & targets ,
536532 SessionPersistence : & loadbalancer.SessionPersistence {
537533 UseSourceIpAddress : new (useSourceIP ),
538534 },
539535 })
540536 }
541- lb .Listeners = listeners
542- lb .TargetPools = targetPools
537+ lb .Listeners = & listeners
538+ lb .TargetPools = & targetPools
543539
544540 lb .Options .AccessControl = & loadbalancer.LoadbalancerOptionAccessControl {}
545541 // For backwards-compatibility, the spec takes precedence over the annotation.
546542 if sourceRanges , found := service .Annotations [yawolLoadBalancerSourceRangesAnnotation ]; found {
547543 r := strings .Split (sourceRanges , "," )
548- lb .Options .AccessControl .AllowedSourceRanges = r
544+ lb .Options .AccessControl .AllowedSourceRanges = & r
549545 }
550546 if len (service .Spec .LoadBalancerSourceRanges ) > 0 {
551- lb .Options .AccessControl .AllowedSourceRanges = service .Spec .LoadBalancerSourceRanges
547+ lb .Options .AccessControl .AllowedSourceRanges = & service .Spec .LoadBalancerSourceRanges
552548 }
553549
554550 if event := checkUnsupportedAnnotations (service ); event != nil {
@@ -591,8 +587,6 @@ type resultImmutableChanged struct {
591587// compareLBwithSpec checks whether the load balancer fulfills the specification.
592588// If immutableChanged is not nil then spec differs from lb such that an update will fail.
593589// Otherwise, fulfills will indicate whether an update is necessary.
594- //
595- //nolint:staticcheck // Temporary workaround: v2api OpenAPI generator currently misses enum constants; fixed in next NVP.
596590func compareLBwithSpec (lb * loadbalancer.LoadBalancer , spec * loadbalancer.CreateLoadBalancerPayload ) (fulfills bool , immutableChanged * resultImmutableChanged ) { //nolint:gocyclo,funlen,lll // It is long but not complex.
597591 // If a mutable property has changed we must still check the rest of the object because if there is an immutable change it must always be returned.
598592 fulfills = true
@@ -643,11 +637,11 @@ func compareLBwithSpec(lb *loadbalancer.LoadBalancer, spec *loadbalancer.CreateL
643637 return false , & resultImmutableChanged {field : ".options.ephemeralAddress" , annotation : externalIPAnnotation }
644638 }
645639
646- if len (lb .Listeners ) != len (spec .Listeners ) {
640+ if cmp . LenSlicePtr (lb .Listeners ) != cmp . LenSlicePtr (spec .Listeners ) {
647641 fulfills = false
648- } else {
649- for i , x := range lb .Listeners {
650- y := spec .Listeners [i ]
642+ } else if lb . Listeners != nil && spec . Listeners != nil {
643+ for i , x := range * lb .Listeners {
644+ y := ( * spec .Listeners ) [i ]
651645 if ! cmp .PtrValEqual (x .DisplayName , y .DisplayName ) {
652646 fulfills = false
653647 }
@@ -660,38 +654,40 @@ func compareLBwithSpec(lb *loadbalancer.LoadBalancer, spec *loadbalancer.CreateL
660654 if ! cmp .PtrValEqual (x .TargetPool , y .TargetPool ) {
661655 fulfills = false
662656 }
663- if (cmp .UnpackPtr (x .Protocol ) == string ( lbLegacy .LISTENERPROTOCOL_TCP ) || cmp .UnpackPtr (x .Protocol ) == string ( lbLegacy .LISTENERPROTOCOL_TCP_PROXY ) ) &&
657+ if (cmp .UnpackPtr (x .Protocol ) == loadbalancer .LISTENERPROTOCOL_TCP || cmp .UnpackPtr (x .Protocol ) == loadbalancer .LISTENERPROTOCOL_TCP_PROXY ) &&
664658 ! cmp .PtrValEqualFn (x .Tcp , y .Tcp , func (a , b loadbalancer.OptionsTCP ) bool {
665659 return cmp .PtrValEqual (a .IdleTimeout , b .IdleTimeout )
666660 }) {
667661 fulfills = false
668662 }
669- if cmp .UnpackPtr (x .Protocol ) == string ( lbLegacy .LISTENERPROTOCOL_UDP ) && ! cmp .PtrValEqualFn (x .Udp , y .Udp , func (a , b loadbalancer.OptionsUDP ) bool {
663+ if cmp .UnpackPtr (x .Protocol ) == loadbalancer .LISTENERPROTOCOL_UDP && ! cmp .PtrValEqualFn (x .Udp , y .Udp , func (a , b loadbalancer.OptionsUDP ) bool {
670664 return cmp .PtrValEqual (a .IdleTimeout , b .IdleTimeout )
671665 }) {
672666 fulfills = false
673667 }
674668 }
675669 }
676670
677- if len (lb .Networks ) != len (spec .Networks ) {
671+ if cmp . LenSlicePtr (lb .Networks ) != cmp . LenSlicePtr (spec .Networks ) {
678672 return false , & resultImmutableChanged {field : "len(.networks)" , annotation : listenerNetworkAnnotation }
679673 }
680- for i , x := range lb .Networks {
681- y := spec .Networks [i ]
682- if ! cmp .PtrValEqual (x .NetworkId , y .NetworkId ) {
683- return false , & resultImmutableChanged {field : fmt .Sprintf (".networks[%d].networkId" , i ), annotation : listenerNetworkAnnotation }
684- }
685- if ! cmp .PtrValEqual (x .Role , y .Role ) {
686- return false , & resultImmutableChanged {field : fmt .Sprintf (".networks[%d].role" , i ), annotation : listenerNetworkAnnotation }
674+ if cmp .LenSlicePtr (lb .Networks ) > 0 {
675+ for i , x := range * lb .Networks {
676+ y := (* spec .Networks )[i ]
677+ if ! cmp .PtrValEqual (x .NetworkId , y .NetworkId ) {
678+ return false , & resultImmutableChanged {field : fmt .Sprintf (".networks[%d].networkId" , i ), annotation : listenerNetworkAnnotation }
679+ }
680+ if ! cmp .PtrValEqual (x .Role , y .Role ) {
681+ return false , & resultImmutableChanged {field : fmt .Sprintf (".networks[%d].role" , i ), annotation : listenerNetworkAnnotation }
682+ }
687683 }
688684 }
689685
690- if len (lb .TargetPools ) != len (spec .TargetPools ) {
686+ if cmp . LenSlicePtr (lb .TargetPools ) != cmp . LenSlicePtr (spec .TargetPools ) {
691687 fulfills = false
692- } else {
693- for i , x := range lb .TargetPools {
694- y := spec .TargetPools [i ]
688+ } else if lb . TargetPools != nil && spec . TargetPools != nil {
689+ for i , x := range * lb .TargetPools {
690+ y := ( * spec .TargetPools ) [i ]
695691 if ! cmp .PtrValEqual (x .Name , y .Name ) {
696692 fulfills = false
697693 }
@@ -721,7 +717,13 @@ func compareLBwithSpec(lb *loadbalancer.LoadBalancer, spec *loadbalancer.CreateL
721717 }) {
722718 fulfills = false
723719 }
724- if ! cmp .SliceEqualUnordered (x .Targets , y .Targets , func (a , b loadbalancer.Target ) bool {
720+ if x .Targets == nil || y .Targets == nil {
721+ // At this point one pointer is nil.
722+ // We consider nil pointer to be equal to a nil slice and an empty slice.
723+ if cmp .LenSlicePtr (x .Targets ) != cmp .LenSlicePtr (y .Targets ) {
724+ fulfills = false
725+ }
726+ } else if ! cmp .SliceEqualUnordered (* x .Targets , * y .Targets , func (a , b loadbalancer.Target ) bool {
725727 if ! cmp .PtrValEqual (a .DisplayName , b .DisplayName ) {
726728 return false
727729 }
@@ -743,8 +745,8 @@ func compareLBwithSpec(lb *loadbalancer.LoadBalancer, spec *loadbalancer.CreateL
743745 }
744746
745747 if ! cmp .SliceEqual (
746- cmp .UnpackPtr (cmp .UnpackPtr (lb .Options ).AccessControl ).AllowedSourceRanges ,
747- cmp .UnpackPtr (cmp .UnpackPtr (spec .Options ).AccessControl ).AllowedSourceRanges ,
748+ cmp .UnpackPtr (cmp .UnpackPtr (cmp . UnpackPtr ( lb .Options ).AccessControl ).AllowedSourceRanges ) ,
749+ cmp .UnpackPtr (cmp .UnpackPtr (cmp . UnpackPtr ( spec .Options ).AccessControl ).AllowedSourceRanges ) ,
748750 ) {
749751 fulfills = false
750752 }
0 commit comments