From 3dece51a3af782e49f463088536f60b219c8b539 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=AFla=20MARABESE?= Date: Tue, 17 Jan 2023 17:43:53 +0100 Subject: [PATCH] migrated LB regionalized API to zoned API --- pkg/model/scalewaymodel/api_loadbalancer.go | 14 +- upup/pkg/fi/cloudup/apply_cluster.go | 2 +- upup/pkg/fi/cloudup/scaleway/cloud.go | 54 ++++---- upup/pkg/fi/cloudup/scalewaytasks/instance.go | 18 +-- .../fi/cloudup/scalewaytasks/loadbalancer.go | 126 ++++++------------ 5 files changed, 91 insertions(+), 123 deletions(-) diff --git a/pkg/model/scalewaymodel/api_loadbalancer.go b/pkg/model/scalewaymodel/api_loadbalancer.go index d6fb91099c..e2e8b2072f 100644 --- a/pkg/model/scalewaymodel/api_loadbalancer.go +++ b/pkg/model/scalewaymodel/api_loadbalancer.go @@ -52,6 +52,10 @@ func (b *APILoadBalancerModelBuilder) Build(c *fi.CloudupModelBuilderContext) er return fmt.Errorf("unhandled load-balancer type %q", lbSpec.Type) } + zone, err := scaleway.ParseZoneFromClusterSpec(b.Cluster.Spec) + if err != nil { + return fmt.Errorf("building load-balancer task: %w", err) + } lbTags := []string(nil) for k, v := range b.CloudTags(b.ClusterName(), false) { lbTags = append(lbTags, fmt.Sprintf("%s=%s", k, v)) @@ -60,10 +64,12 @@ func (b *APILoadBalancerModelBuilder) Build(c *fi.CloudupModelBuilderContext) er loadBalancerName := "api." + b.ClusterName() loadBalancer := &scalewaytasks.LoadBalancer{ - Name: fi.PtrTo(loadBalancerName), - Region: fi.PtrTo(b.Region), - Lifecycle: b.Lifecycle, - Tags: lbTags, + Name: fi.PtrTo(loadBalancerName), + Zone: fi.PtrTo(string(zone)), + Lifecycle: b.Lifecycle, + Tags: lbTags, + Description: "Load-balancer for kops cluster " + b.ClusterName(), + SslCompatibilityLevel: string(lb.SSLCompatibilityLevelSslCompatibilityLevelUnknown), } c.AddTask(loadBalancer) diff --git a/upup/pkg/fi/cloudup/apply_cluster.go b/upup/pkg/fi/cloudup/apply_cluster.go index cdb0d12ff0..4753d53b42 100644 --- a/upup/pkg/fi/cloudup/apply_cluster.go +++ b/upup/pkg/fi/cloudup/apply_cluster.go @@ -688,7 +688,7 @@ func (c *ApplyClusterCmd) Run(ctx context.Context) error { KopsModelContext: modelContext, } l.Builders = append(l.Builders, - &scalewaymodel.APILoadBalancerModelBuilder{ScwModelContext: scwModelContext, Lifecycle: clusterLifecycle}, + &scalewaymodel.APILoadBalancerModelBuilder{ScwModelContext: scwModelContext, Lifecycle: networkLifecycle}, &scalewaymodel.InstanceModelBuilder{ScwModelContext: scwModelContext, BootstrapScriptBuilder: bootstrapScriptBuilder, Lifecycle: clusterLifecycle}, &scalewaymodel.SSHKeyModelBuilder{ScwModelContext: scwModelContext, Lifecycle: securityLifecycle}, ) diff --git a/upup/pkg/fi/cloudup/scaleway/cloud.go b/upup/pkg/fi/cloudup/scaleway/cloud.go index 7af2867e98..a348364dbb 100644 --- a/upup/pkg/fi/cloudup/scaleway/cloud.go +++ b/upup/pkg/fi/cloudup/scaleway/cloud.go @@ -57,7 +57,7 @@ type ScwCloud interface { IamService() *iam.API InstanceService() *instance.API - LBService() *lb.API + LBService() *lb.ZonedAPI DeleteGroup(group *cloudinstances.CloudInstanceGroup) error DeleteInstance(i *cloudinstances.CloudInstance) error @@ -91,7 +91,7 @@ type scwCloudImplementation struct { iamAPI *iam.API instanceAPI *instance.API - lbAPI *lb.API + lbAPI *lb.ZonedAPI } // NewScwCloud returns a Cloud with a Scaleway Client using the env vars SCW_ACCESS_KEY, SCW_SECRET_KEY and SCW_DEFAULT_PROJECT_ID @@ -140,7 +140,7 @@ func NewScwCloud(tags map[string]string) (ScwCloud, error) { tags: tags, iamAPI: iam.NewAPI(scwClient), instanceAPI: instance.NewAPI(scwClient), - lbAPI: lb.NewAPI(scwClient), + lbAPI: lb.NewZonedAPI(scwClient), }, nil } @@ -178,7 +178,7 @@ func (s *scwCloudImplementation) InstanceService() *instance.API { return s.instanceAPI } -func (s *scwCloudImplementation) LBService() *lb.API { +func (s *scwCloudImplementation) LBService() *lb.ZonedAPI { return s.lbAPI } @@ -229,9 +229,9 @@ func (s *scwCloudImplementation) DeregisterInstance(i *cloudinstances.CloudInsta return fmt.Errorf("deregistering cloud instance %s of group %q: %w", i.ID, i.CloudInstanceGroup.HumanName, err) } for _, loadBalancer := range lbs { - backEnds, err := s.lbAPI.ListBackends(&lb.ListBackendsRequest{ - Region: s.region, - LBID: loadBalancer.ID, + backEnds, err := s.lbAPI.ListBackends(&lb.ZonedAPIListBackendsRequest{ + Zone: s.zone, + LBID: loadBalancer.ID, }, scw.WithAllPages()) if err != nil { return fmt.Errorf("deregistering cloud instance %s of group %q: listing load-balancer's back-ends for instance creation: %w", i.ID, i.CloudInstanceGroup.HumanName, err) @@ -239,8 +239,8 @@ func (s *scwCloudImplementation) DeregisterInstance(i *cloudinstances.CloudInsta for _, backEnd := range backEnds.Backends { for _, serverIP := range backEnd.Pool { if serverIP == fi.ValueOf(server.Server.PrivateIP) { - _, err := s.lbAPI.RemoveBackendServers(&lb.RemoveBackendServersRequest{ - Region: s.region, + _, err := s.lbAPI.RemoveBackendServers(&lb.ZonedAPIRemoveBackendServersRequest{ + Zone: s.zone, BackendID: backEnd.ID, ServerIP: []string{serverIP}, }) @@ -276,9 +276,9 @@ func (s *scwCloudImplementation) GetApiIngressStatus(cluster *kops.Cluster) ([]f var ingresses []fi.ApiIngressStatus name := "api." + cluster.Name - responseLoadBalancers, err := s.lbAPI.ListLBs(&lb.ListLBsRequest{ - Region: scw.Region(s.Region()), - Name: &name, + responseLoadBalancers, err := s.lbAPI.ListLBs(&lb.ZonedAPIListLBsRequest{ + Zone: s.zone, + Name: &name, }, scw.WithAllPages()) if err != nil { return nil, fmt.Errorf("finding load-balancers: %w", err) @@ -382,9 +382,9 @@ func buildCloudGroup(ig *kops.InstanceGroup, sg []*instance.Server, nodeMap map[ func (s *scwCloudImplementation) GetClusterLoadBalancers(clusterName string) ([]*lb.LB, error) { loadBalancerName := "api." + clusterName - lbs, err := s.lbAPI.ListLBs(&lb.ListLBsRequest{ - Region: s.region, - Name: &loadBalancerName, + lbs, err := s.lbAPI.ListLBs(&lb.ZonedAPIListLBsRequest{ + Zone: s.zone, + Name: &loadBalancerName, }, scw.WithAllPages()) if err != nil { return nil, fmt.Errorf("listing cluster load-balancers: %w", err) @@ -437,33 +437,33 @@ func (s *scwCloudImplementation) DeleteLoadBalancer(loadBalancer *lb.LB) error { ipsToRelease := loadBalancer.IP // We delete the load-balancer once it's in a stable state - _, err := s.lbAPI.WaitForLb(&lb.WaitForLBRequest{ - LBID: loadBalancer.ID, - Region: s.region, + _, err := s.lbAPI.WaitForLb(&lb.ZonedAPIWaitForLBRequest{ + LBID: loadBalancer.ID, + Zone: s.zone, }) if err != nil { return fmt.Errorf("waiting for load-balancer: %w", err) } - err = s.lbAPI.DeleteLB(&lb.DeleteLBRequest{ - Region: s.region, - LBID: loadBalancer.ID, + err = s.lbAPI.DeleteLB(&lb.ZonedAPIDeleteLBRequest{ + Zone: s.zone, + LBID: loadBalancer.ID, }) if err != nil { return fmt.Errorf("deleting load-balancer %s: %w", loadBalancer.ID, err) } // We wait for the load-balancer to be deleted, then we detach its IPs - _, err = s.lbAPI.WaitForLb(&lb.WaitForLBRequest{ - LBID: loadBalancer.ID, - Region: s.region, + _, err = s.lbAPI.WaitForLb(&lb.ZonedAPIWaitForLBRequest{ + LBID: loadBalancer.ID, + Zone: s.zone, }) if !is404Error(err) { return fmt.Errorf("waiting for load-balancer %s after deletion: %w", loadBalancer.ID, err) } for _, ip := range ipsToRelease { - err := s.lbAPI.ReleaseIP(&lb.ReleaseIPRequest{ - Region: s.region, - IPID: ip.ID, + err := s.lbAPI.ReleaseIP(&lb.ZonedAPIReleaseIPRequest{ + Zone: s.zone, + IPID: ip.ID, }) if err != nil { return fmt.Errorf("deleting load-balancer IP: %w", err) diff --git a/upup/pkg/fi/cloudup/scalewaytasks/instance.go b/upup/pkg/fi/cloudup/scalewaytasks/instance.go index fd111d20cd..c84b16da00 100644 --- a/upup/pkg/fi/cloudup/scalewaytasks/instance.go +++ b/upup/pkg/fi/cloudup/scalewaytasks/instance.go @@ -208,7 +208,7 @@ func (_ *Instance) RenderScw(c *fi.CloudupContext, actual, expected, changes *In // If IG is control-plane, we add the new servers' IPs to the load-balancer's back-end if len(controlPlanePrivateIPs) > 0 { lbService := cloud.LBService() - region := scw.Region(cloud.Region()) + zone := scw.Zone(cloud.Zone()) lbs, err := cloud.GetClusterLoadBalancers(cloud.ClusterName(expected.Tags)) if err != nil { @@ -216,9 +216,9 @@ func (_ *Instance) RenderScw(c *fi.CloudupContext, actual, expected, changes *In } for _, loadBalancer := range lbs { - backEnds, err := lbService.ListBackends(&lb.ListBackendsRequest{ - Region: region, - LBID: loadBalancer.ID, + backEnds, err := lbService.ListBackends(&lb.ZonedAPIListBackendsRequest{ + Zone: zone, + LBID: loadBalancer.ID, }) if err != nil { return fmt.Errorf("listing load-balancer's back-ends for instance creation: %w", err) @@ -228,8 +228,8 @@ func (_ *Instance) RenderScw(c *fi.CloudupContext, actual, expected, changes *In } backEnd := backEnds.Backends[0] - _, err = lbService.AddBackendServers(&lb.AddBackendServersRequest{ - Region: region, + _, err = lbService.AddBackendServers(&lb.ZonedAPIAddBackendServersRequest{ + Zone: zone, BackendID: backEnd.ID, ServerIP: controlPlanePrivateIPs, }) @@ -237,9 +237,9 @@ func (_ *Instance) RenderScw(c *fi.CloudupContext, actual, expected, changes *In return fmt.Errorf("adding servers' IPs to load-balancer's back-end: %w", err) } - _, err = lbService.WaitForLb(&lb.WaitForLBRequest{ - LBID: loadBalancer.ID, - Region: region, + _, err = lbService.WaitForLb(&lb.ZonedAPIWaitForLBRequest{ + LBID: loadBalancer.ID, + Zone: zone, }) if err != nil { return fmt.Errorf("waiting for load-balancer %s: %w", loadBalancer.ID, err) diff --git a/upup/pkg/fi/cloudup/scalewaytasks/loadbalancer.go b/upup/pkg/fi/cloudup/scalewaytasks/loadbalancer.go index 574b3254fd..2908645670 100644 --- a/upup/pkg/fi/cloudup/scalewaytasks/loadbalancer.go +++ b/upup/pkg/fi/cloudup/scalewaytasks/loadbalancer.go @@ -32,11 +32,13 @@ type LoadBalancer struct { Name *string Lifecycle fi.Lifecycle - Region *string - LBID *string - LBAddresses []string - Tags []string - ForAPIServer bool + Zone *string + LBID *string + LBAddresses []string + Tags []string + Description string + SslCompatibilityLevel string + ForAPIServer bool } var _ fi.CompareWithID = &LoadBalancer{} @@ -51,20 +53,20 @@ func (l *LoadBalancer) IsForAPIServer() bool { } func (l *LoadBalancer) Find(context *fi.CloudupContext) (*LoadBalancer, error) { - if fi.ValueOf(l.LBID) == "" { - return nil, nil - } - cloud := context.T.Cloud.(scaleway.ScwCloud) lbService := cloud.LBService() - loadBalancer, err := lbService.GetLB(&lb.GetLBRequest{ - Region: scw.Region(cloud.Region()), - LBID: fi.ValueOf(l.LBID), - }) + lbResponse, err := lbService.ListLBs(&lb.ZonedAPIListLBsRequest{ + Zone: scw.Zone(cloud.Zone()), + Name: l.Name, + }, scw.WithAllPages()) if err != nil { - return nil, fmt.Errorf("getting load-balancer %s: %s", fi.ValueOf(l.LBID), err) + return nil, fmt.Errorf("getting load-balancer %s: %w", fi.ValueOf(l.LBID), err) } + if lbResponse.TotalCount != 1 { + return nil, nil + } + loadBalancer := lbResponse.LBs[0] lbIPs := []string(nil) for _, IP := range loadBalancer.IP { @@ -72,8 +74,9 @@ func (l *LoadBalancer) Find(context *fi.CloudupContext) (*LoadBalancer, error) { } return &LoadBalancer{ - Name: &loadBalancer.Name, - LBID: &loadBalancer.ID, + Name: fi.PtrTo(loadBalancer.Name), + LBID: fi.PtrTo(loadBalancer.ID), + Zone: fi.PtrTo(string(loadBalancer.Zone)), LBAddresses: lbIPs, Tags: loadBalancer.Tags, Lifecycle: l.Lifecycle, @@ -89,9 +92,9 @@ func (l *LoadBalancer) FindAddresses(context *fi.CloudupContext) ([]string, erro return nil, nil } - loadBalancer, err := lbService.GetLB(&lb.GetLBRequest{ - Region: scw.Region(cloud.Region()), - LBID: fi.ValueOf(l.LBID), + loadBalancer, err := lbService.GetLB(&lb.ZonedAPIGetLBRequest{ + Zone: scw.Zone(cloud.Zone()), + LBID: fi.ValueOf(l.LBID), }) if err != nil { return nil, err @@ -117,15 +120,15 @@ func (_ *LoadBalancer) CheckChanges(actual, expected, changes *LoadBalancer) err if changes.LBID != nil { return fi.CannotChangeField("ID") } - if changes.Region != nil { - return fi.CannotChangeField("Region") + if changes.Zone != nil { + return fi.CannotChangeField("Zone") } } else { if expected.Name == nil { return fi.RequiredField("Name") } - if expected.Region == nil { - return fi.RequiredField("Region") + if expected.Zone == nil { + return fi.RequiredField("Zone") } } return nil @@ -133,30 +136,20 @@ func (_ *LoadBalancer) CheckChanges(actual, expected, changes *LoadBalancer) err func (l *LoadBalancer) RenderScw(t *scaleway.ScwAPITarget, actual, expected, changes *LoadBalancer) error { lbService := t.Cloud.LBService() - region := scw.Region(fi.ValueOf(expected.Region)) - var loadBalancer *lb.LB - backEndToCreate := true - frontEndToCreate := true + zone := scw.Zone(fi.ValueOf(expected.Zone)) if actual != nil { - klog.Infof("Updating existing load-balancer with name %q", expected.Name) - lbToUpdate, err := lbService.GetLB(&lb.GetLBRequest{ - Region: region, - LBID: fi.ValueOf(actual.LBID), - }) - if err != nil { - return fmt.Errorf("getting load-balancer %q (%s): %w", fi.ValueOf(actual.Name), fi.ValueOf(actual.LBID), err) - } + klog.Infof("Updating existing load-balancer with name %q", expected.Name) // We update the tags if changes != nil || len(actual.Tags) != len(expected.Tags) { - _, err = lbService.UpdateLB(&lb.UpdateLBRequest{ - Region: region, - LBID: lbToUpdate.ID, - Name: lbToUpdate.Name, - Description: lbToUpdate.Description, - SslCompatibilityLevel: lbToUpdate.SslCompatibilityLevel, + _, err := lbService.UpdateLB(&lb.ZonedAPIUpdateLBRequest{ + Zone: zone, + LBID: fi.ValueOf(expected.LBID), + Name: fi.ValueOf(expected.Name), + Description: expected.Description, + SslCompatibilityLevel: lb.SSLCompatibilityLevel(expected.SslCompatibilityLevel), Tags: expected.Tags, }) if err != nil { @@ -164,56 +157,25 @@ func (l *LoadBalancer) RenderScw(t *scaleway.ScwAPITarget, actual, expected, cha } } - // We check that the back-end exists - backEnds, err := lbService.ListBackends(&lb.ListBackendsRequest{ - Region: region, - LBID: lbToUpdate.ID, - Name: scw.StringPtr("lb-backend"), - }) - if err != nil { - return fmt.Errorf("listing back-ends for load-balancer %q: %w", fi.ValueOf(expected.Name), err) - } - if backEnds.TotalCount > 0 { - backEndToCreate = false - } - - // We check that the front-end exists - frontEnds, err := lbService.ListFrontends(&lb.ListFrontendsRequest{ - Region: region, - LBID: lbToUpdate.ID, - Name: scw.StringPtr("lb-frontend"), - }) - if err != nil { - return fmt.Errorf("listing front-ends for load-balancer %q: %w", fi.ValueOf(expected.Name), err) - } - if frontEnds.TotalCount > 0 { - frontEndToCreate = false - } - - lbIPs := []string(nil) - for _, ip := range lbToUpdate.IP { - lbIPs = append(lbIPs, ip.IPAddress) - } - expected.LBID = &lbToUpdate.ID - expected.LBAddresses = lbIPs - - loadBalancer = lbToUpdate + expected.LBID = actual.LBID + expected.LBAddresses = actual.LBAddresses } else { + klog.Infof("Creating new load-balancer with name %q", expected.Name) - lbCreated, err := lbService.CreateLB(&lb.CreateLBRequest{ - Region: region, - Name: fi.ValueOf(expected.Name), - Tags: expected.Tags, + lbCreated, err := lbService.CreateLB(&lb.ZonedAPICreateLBRequest{ + Zone: zone, + Name: fi.ValueOf(expected.Name), + Tags: expected.Tags, }) if err != nil { return fmt.Errorf("creating load-balancer: %w", err) } - _, err = lbService.WaitForLb(&lb.WaitForLBRequest{ - LBID: lbCreated.ID, - Region: region, + _, err = lbService.WaitForLb(&lb.ZonedAPIWaitForLBRequest{ + LBID: lbCreated.ID, + Zone: zone, }) if err != nil { return fmt.Errorf("waiting for load-balancer %s: %w", lbCreated.ID, err)