@@ -534,6 +534,7 @@ var (
534534func (r * CLBBindingReconciler [T ]) ensurePortAllocated (ctx context.Context , bd clbbinding.CLBBinding ) error {
535535 status := bd .GetStatus ()
536536 bindings := make (map [portKey ]* networkingv1alpha1.PortBindingStatus )
537+ newBindings := []networkingv1alpha1.PortBindingStatus {}
537538 for i := range status .PortBindings {
538539 binding := & status .PortBindings [i ]
539540 key := portKey {
@@ -545,6 +546,12 @@ func (r *CLBBindingReconciler[T]) ensurePortAllocated(ctx context.Context, bd cl
545546 }
546547
547548 var allocatedPorts portpool.PortAllocations
549+ releasePorts := func () {
550+ if len (allocatedPorts ) > 0 {
551+ allocatedPorts .Release ()
552+ }
553+ allocatedPorts = nil
554+ }
548555 spec := bd .GetSpec ()
549556 allocatedPools := make (map [string ]struct {})
550557LOOP_PORT:
@@ -572,9 +579,9 @@ LOOP_PORT:
572579 }
573580 alreadyAllocated := false
574581 for _ , key := range keys {
575- if _ , exists := bindings [key ]; exists { // 已分配端口,跳过
576- delete (bindings , key )
582+ if binding , exists := bindings [key ]; exists { // 已分配端口,跳过
577583 alreadyAllocated = true
584+ newBindings = append (newBindings , * binding )
578585 }
579586 }
580587 if alreadyAllocated {
@@ -588,7 +595,7 @@ LOOP_PORT:
588595 Name : * secretName ,
589596 })
590597 if err != nil {
591- allocatedPorts . Release ()
598+ releasePorts ()
592599 if apierrors .IsNotFound (errors .Cause (err )) {
593600 r .Recorder .Eventf (bd .GetObject (), corev1 .EventTypeWarning , "CertNotFound" , "cert secret %q not found" , * secretName )
594601 return errors .Wrapf (ErrCertIdNotFound , "cert secret %q not found" , * secretName )
@@ -605,6 +612,7 @@ LOOP_PORT:
605612 if err != nil {
606613 return errors .WithStack (err )
607614 }
615+
608616 // 要么全部分配成功,要么无法分配
609617 if len (allocated ) > 0 { // 分配成功
610618 for _ , allocatedPort := range allocated {
@@ -621,49 +629,31 @@ LOOP_PORT:
621629 if allocatedPort .EndPort > 0 {
622630 binding .LoadbalancerEndPort = & allocatedPort .EndPort
623631 }
624- status . PortBindings = append (status . PortBindings , binding )
632+ newBindings = append (newBindings , binding )
625633 }
626634 allocatedPorts = append (allocatedPorts , allocated ... )
627635 } else { // 只要有一个端口分配失败就认为失败
628- allocatedPorts . Release () // 为保证事务性,释放已分配的端口
636+ releasePorts () // 为保证事务性,释放已分配的端口
629637 return portpool .ErrNoPortAvailable
630638 }
631639 }
632640
633- if len (bindings ) > 0 { // 删除多余的端口绑定
634- for _ , binding := range bindings {
635- _ , err := clb .DeleteListenerByPort (ctx , binding .Region , binding .LoadbalancerId , int64 (binding .LoadbalancerPort ), binding .Protocol )
636- if err != nil {
637- return errors .WithStack (err )
638- }
639- }
640- statuses := []networkingv1alpha1.PortBindingStatus {}
641- for _ , port := range status .PortBindings {
642- key := portKey {
643- Port : port .Port ,
644- Protocol : port .Protocol ,
645- Pool : port .Pool ,
646- }
647- if _ , exists := bindings [key ]; ! exists {
648- statuses = append (statuses , port )
641+ // 将已分配的端口写入 status
642+ clbbinding .SortPortBindings (newBindings )
643+ if ! reflect .DeepEqual (newBindings , status .PortBindings ) {
644+ status .PortBindings = newBindings
645+ if len (allocatedPorts ) > 0 { // 有分配到端口,更新 state 为 Allocated
646+ status .State = networkingv1alpha1 .CLBBindingStateAllocated
647+ }
648+ if err := r .Status ().Update (ctx , bd .GetObject ()); err != nil {
649+ // 更新状态失败,释放已分配端口
650+ releasePorts ()
651+ return errors .WithStack (err )
652+ } else {
653+ for poolName := range allocatedPools {
654+ notifyPortPoolReconcile (poolName )
649655 }
650656 }
651- status .PortBindings = statuses
652- }
653-
654- if len (allocatedPorts ) == 0 && len (bindings ) == 0 { // 没有新端口分配,也没有多余端口需要删除,直接返回
655- return nil
656- }
657- // 将已分配的端口写入 status
658- status .State = networkingv1alpha1 .CLBBindingStateAllocated
659- clbbinding .SortPortBindings (status .PortBindings )
660- if err := r .Status ().Update (ctx , bd .GetObject ()); err != nil {
661- // 更新状态失败,释放已分配端口
662- allocatedPorts .Release ()
663- return errors .WithStack (err )
664- }
665- for poolName := range allocatedPools {
666- notifyPortPoolReconcile (poolName )
667657 }
668658 return nil
669659}
0 commit comments