diff --git a/cloud-controller-manager/alicloud.go b/cloud-controller-manager/alicloud.go index 2f6a79157..7c0c4ecff 100644 --- a/cloud-controller-manager/alicloud.go +++ b/cloud-controller-manager/alicloud.go @@ -416,7 +416,7 @@ func (c *Cloud) UpdateLoadBalancer( Nodes: ns, BackendTypeENI: utils.IsENIBackendType(service), } - return c.climgr.LoadBalancers().UpdateLoadBalancer(ctx, service, backends, true) + return c.climgr.LoadBalancers().UpdateLoadBalancer(ctx, service, backends, true, nil) } // EnsureLoadBalancerDeleted deletes the specified load balancer if it diff --git a/cloud-controller-manager/loadbalancer.go b/cloud-controller-manager/loadbalancer.go index b5e8047f2..5a2b1bf75 100644 --- a/cloud-controller-manager/loadbalancer.go +++ b/cloud-controller-manager/loadbalancer.go @@ -147,54 +147,15 @@ type LoadBalancerClient struct { func (s *LoadBalancerClient) FindLoadBalancer(ctx context.Context, service *v1.Service) (bool, *slb.LoadBalancerType, error) { def, _ := ExtractAnnotationRequest(service) - //loadbalancer := service.Status.LoadBalancer - //klog.V(4).Infof("alicloud: find loadbalancer [%v] with user defined annotations [%v]\n",loadbalancer,def) - //if len(loadbalancer.Ingress) > 0 { - // if lbid := fromLoadBalancerStatus(service); lbid != "" { - // if def.Loadbalancerid != "" && def.Loadbalancerid != lbid { - // klog.Errorf("alicloud: changing loadbalancer id was not allowed after loadbalancer"+ - // " was already created ! please remove service annotation: [%s]\n", ServiceAnnotationLoadBalancerId) - // return false, nil, fmt.Errorf("alicloud: change loadbalancer id after service " + - // "has been created is not supported. remove service annotation[%s] and retry!", ServiceAnnotationLoadBalancerId) - // } - // // found loadbalancer id in service ingress status. - // // this id was set previously when loadbalancer was created. - // return s.FindLoadBalancerByID(lbid) - // } - //} - - // User assigned lobadbalancer id go first. + // User assigned loadbalancer id go first. if def.Loadbalancerid != "" { - return s.FindLoadBalancerByID(ctx, def.Loadbalancerid) + lb, err := s.c.DescribeLoadBalancerAttribute(ctx, def.Loadbalancerid) + return err == nil, lb, err } // if not, find by slb tags return s.FindLoadBalancerByTags(ctx, service) } -func (s *LoadBalancerClient) FindLoadBalancerByID(ctx context.Context, lbid string) (bool, *slb.LoadBalancerType, error) { - - lbs, err := s.c.DescribeLoadBalancers( - ctx, - &slb.DescribeLoadBalancersArgs{ - RegionId: DEFAULT_REGION, - LoadBalancerId: lbid, - }, - ) - klog.Infof("find loadbalancer with id [%s], %d found.", lbid, len(lbs)) - if err != nil { - return false, nil, err - } - - if lbs == nil || len(lbs) == 0 { - return false, nil, nil - } - if len(lbs) > 1 { - klog.Warningf("multiple loadbalancer returned with id [%s], using the first one with IP=%s", lbid, lbs[0].Address) - } - lb, err := s.c.DescribeLoadBalancerAttribute(ctx, lbs[0].LoadBalancerId) - return err == nil, lb, err -} - func (s *LoadBalancerClient) FindLoadBalancerByTags(ctx context.Context, service *v1.Service) (bool, *slb.LoadBalancerType, error) { if service.UID == "" { return false, nil, fmt.Errorf("unexpected empty service uid") @@ -455,10 +416,16 @@ func (s *LoadBalancerClient) EnsureLoadBalancer(ctx context.Context, service *v1 utils.Logf(service, "alicloud: can not get loadbalancer attribute. ") return nil, err } - vgs := BuildVirturalGroupFromService(s, service, origined) + + localVgs := BuildVirturalGroupFromService(s, service, origined) + remoteVgs, err := BuildVirtualGroupFromRemoteAPI(ctx, origined, s) + if err != nil { + return origined, fmt.Errorf("build virtual group from remote api: error %s", err.Error()) + } + updateLocalVGroupsByRemoteVGroups(localVgs, remoteVgs) // Make sure virtual server backend group has been updated. - if err := EnsureVirtualGroups(ctx, vgs, nodes); err != nil { + if err := EnsureVirtualGroups(ctx, localVgs, nodes); err != nil { return origined, fmt.Errorf("update backend servers: error %s", err.Error()) } // Apply listener when @@ -469,12 +436,12 @@ func (s *LoadBalancerClient) EnsureLoadBalancer(ctx context.Context, service *v1 utils.Logf(service, "not user defined loadbalancer[%s], start to apply listener.", origined.LoadBalancerId) // If listener update is needed. Switch to vserver group immediately. // No longer update default backend servers. - if err := EnsureListeners(ctx, s, service, origined, vgs); err != nil { + if err := EnsureListeners(ctx, s, service, origined, localVgs); err != nil { return origined, fmt.Errorf("ensure listener error: %s", err.Error()) } } - return origined, s.UpdateLoadBalancer(ctx, service, nodes, false) + return origined, s.UpdateLoadBalancer(ctx, service, nodes, false, origined) } func isLoadBalancerNonReusable(tags []slb.TagItemType, service *v1.Service) (bool, string) { @@ -490,14 +457,19 @@ func isLoadBalancerNonReusable(tags []slb.TagItemType, service *v1.Service) (boo } //UpdateLoadBalancer make sure slb backend is reconciled -func (s *LoadBalancerClient) UpdateLoadBalancer(ctx context.Context, service *v1.Service, nodes *EndpointWithENI, withVgroup bool) error { - - exists, lb, err := s.FindLoadBalancer(ctx, service) - if err != nil { - return err - } - if !exists { - return fmt.Errorf("the loadbalance you specified by name [%s] does not exist", service.Name) +func (s *LoadBalancerClient) UpdateLoadBalancer(ctx context.Context, service *v1.Service, nodes *EndpointWithENI, withVgroup bool, lb *slb.LoadBalancerType) error { + if lb == nil { + var ( + exists bool + err error + ) + exists, lb, err = s.FindLoadBalancer(ctx, service) + if err != nil { + return err + } + if !exists { + return fmt.Errorf("the loadbalance you specified by name [%s] does not exist", service.Name) + } } if withVgroup { vgs := BuildVirturalGroupFromService(s, service, lb) @@ -559,7 +531,14 @@ func (s *LoadBalancerClient) EnsureLoadBalanceDeleted(ctx context.Context, servi // skip delete user defined loadbalancer if isUserDefinedLoadBalancer(service) { utils.Logf(service, "user managed loadbalancer will not be deleted by cloudprovider.") - return EnsureListenersDeleted(ctx, s.c, service, lb, BuildVirturalGroupFromService(s, service, lb)) + localVgs := BuildVirturalGroupFromService(s, service, lb) + remoteVgs, err := BuildVirtualGroupFromRemoteAPI(ctx, lb, s) + if err != nil { + return fmt.Errorf("build virtual group from remote api: error %s", err.Error()) + } + updateLocalVGroupsByRemoteVGroups(localVgs, remoteVgs) + + return EnsureListenersDeleted(ctx, s.c, service, lb, localVgs) } return s.c.DeleteLoadBalancer(ctx, lb.LoadBalancerId) @@ -752,3 +731,14 @@ func keepResourceVersion(service *v1.Service) error { // keeper.set(serviceUIDNoneExist, currentVersion) return nil } + +func updateLocalVGroupsByRemoteVGroups(localVgs *vgroups, remoteVgs vgroups) { + for _, vg := range *localVgs { + for _, remote := range remoteVgs { + if remote.NamedKey.Key() == vg.NamedKey.Key() { + vg.VGroupId = remote.VGroupId + break + } + } + } +} diff --git a/cloud-controller-manager/vgroups.go b/cloud-controller-manager/vgroups.go index 9bca11cba..8b23809d5 100644 --- a/cloud-controller-manager/vgroups.go +++ b/cloud-controller-manager/vgroups.go @@ -11,7 +11,6 @@ import ( "k8s.io/cloud-provider-alibaba-cloud/cloud-controller-manager/utils" "k8s.io/klog" "reflect" - "strings" ) type vgroup struct { @@ -99,14 +98,8 @@ func (v *vgroup) Remove(ctx context.Context) error { } func (v *vgroup) Update(ctx context.Context) error { if v.VGroupId == "" { - err := v.Describe(ctx) - if err != nil { - if !strings.Contains(err.Error(), "not found") { - return fmt.Errorf("update: vserver group error, %s", err.Error()) - } - if err := v.Add(ctx); err != nil { - return err - } + if err := v.Add(ctx); err != nil { + return err } } @@ -371,15 +364,7 @@ func CleanUPVGroupMerged( func CleanUPVGroupDirect(ctx context.Context, local *vgroups) error { for _, vg := range *local { if vg.VGroupId == "" { - err := vg.Describe(ctx) - if err != nil { - if strings.Contains(err.Error(), "not found") { - // skip none exist vgroup - vg.Logf("skip none exist vgroup. %s", vg.LoadBalancerId) - continue - } - return err - } + continue } err := vg.Remove(ctx) if err != nil {