From 0fca23addd6e10b3b4cd301695d3ec206f17db5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=AFla=20MARABESE?= Date: Tue, 20 Dec 2022 13:48:24 +0100 Subject: [PATCH] list and delete load-balancers --- pkg/resources/scaleway/resources.go | 40 ++++++++++++-- upup/pkg/fi/cloudup/scaleway/cloud.go | 53 +++++++++++++++++++ .../fi/cloudup/scalewaytasks/loadbalancer.go | 1 - 3 files changed, 90 insertions(+), 4 deletions(-) diff --git a/pkg/resources/scaleway/resources.go b/pkg/resources/scaleway/resources.go index 04c866191c..ab2dfd3e5e 100644 --- a/pkg/resources/scaleway/resources.go +++ b/pkg/resources/scaleway/resources.go @@ -23,12 +23,14 @@ import ( iam "github.com/scaleway/scaleway-sdk-go/api/iam/v1alpha1" "github.com/scaleway/scaleway-sdk-go/api/instance/v1" + "github.com/scaleway/scaleway-sdk-go/api/lb/v1" ) const ( - resourceTypeServer = "server" - resourceTypeSSHKey = "ssh-key" - resourceTypeVolume = "volume" + resourceTypeLoadBalancer = "load-balancer" + resourceTypeServer = "server" + resourceTypeSSHKey = "ssh-key" + resourceTypeVolume = "volume" ) type listFn func(fi.Cloud, string) ([]*resources.Resource, error) @@ -38,6 +40,7 @@ func ListResources(cloud scaleway.ScwCloud, clusterInfo resources.ClusterInfo) ( clusterName := clusterInfo.Name listFunctions := []listFn{ + listLoadBalancers, listServers, listSSHKeys, listVolumes, @@ -56,6 +59,30 @@ func ListResources(cloud scaleway.ScwCloud, clusterInfo resources.ClusterInfo) ( return resourceTrackers, nil } +func listLoadBalancers(cloud fi.Cloud, clusterName string) ([]*resources.Resource, error) { + c := cloud.(scaleway.ScwCloud) + lbs, err := c.GetClusterLoadBalancers(clusterName) + if err != nil { + return nil, err + } + + resourceTrackers := []*resources.Resource(nil) + for _, loadBalancer := range lbs { + resourceTracker := &resources.Resource{ + Name: loadBalancer.Name, + ID: loadBalancer.ID, + Type: resourceTypeLoadBalancer, + Deleter: func(cloud fi.Cloud, tracker *resources.Resource) error { + return deleteLoadBalancer(cloud, tracker) + }, + Obj: loadBalancer, + } + resourceTrackers = append(resourceTrackers, resourceTracker) + } + + return resourceTrackers, nil +} + func listServers(cloud fi.Cloud, clusterName string) ([]*resources.Resource, error) { c := cloud.(scaleway.ScwCloud) servers, err := c.GetClusterServers(clusterName, nil) @@ -131,6 +158,13 @@ func listVolumes(cloud fi.Cloud, clusterName string) ([]*resources.Resource, err return resourceTrackers, nil } +func deleteLoadBalancer(cloud fi.Cloud, tracker *resources.Resource) error { + c := cloud.(scaleway.ScwCloud) + loadBalancer := tracker.Obj.(*lb.LB) + + return c.DeleteLoadBalancer(loadBalancer) +} + func deleteServer(cloud fi.Cloud, tracker *resources.Resource) error { c := cloud.(scaleway.ScwCloud) server := tracker.Obj.(*instance.Server) diff --git a/upup/pkg/fi/cloudup/scaleway/cloud.go b/upup/pkg/fi/cloudup/scaleway/cloud.go index a1ec55521e..430190b8ea 100644 --- a/upup/pkg/fi/cloudup/scaleway/cloud.go +++ b/upup/pkg/fi/cloudup/scaleway/cloud.go @@ -68,10 +68,12 @@ type ScwCloud interface { GetApiIngressStatus(cluster *kops.Cluster) ([]fi.ApiIngressStatus, error) GetCloudGroups(cluster *kops.Cluster, instancegroups []*kops.InstanceGroup, warnUnmatched bool, nodes []v1.Node) (map[string]*cloudinstances.CloudInstanceGroup, error) + GetClusterLoadBalancers(clusterName string) ([]*lb.LB, error) GetClusterServers(clusterName string, serverName *string) ([]*instance.Server, error) GetClusterSSHKeys(clusterName string) ([]*iam.SSHKey, error) GetClusterVolumes(clusterName string) ([]*instance.Volume, error) + DeleteLoadBalancer(loadBalancer *lb.LB) error DeleteServer(server *instance.Server) error DeleteSSHKey(sshkey *iam.SSHKey) error DeleteVolume(volume *instance.Volume) error @@ -378,6 +380,18 @@ func buildCloudGroup(ig *kops.InstanceGroup, sg []*instance.Server, nodeMap map[ return cloudInstanceGroup, nil } +func (s *scwCloudImplementation) GetClusterLoadBalancers(clusterName string) ([]*lb.LB, error) { + loadBalancerName := "api." + clusterName + lbs, err := s.lbAPI.ListLBs(&lb.ListLBsRequest{ + Region: s.region, + Name: &loadBalancerName, + }, scw.WithAllPages()) + if err != nil { + return nil, fmt.Errorf("failed to list cluster load-balancers: %w", err) + } + return lbs.LBs, nil +} + func (s *scwCloudImplementation) GetClusterServers(clusterName string, serverName *string) ([]*instance.Server, error) { request := &instance.ListServersRequest{ Zone: s.zone, @@ -419,6 +433,45 @@ func (s *scwCloudImplementation) GetClusterVolumes(clusterName string) ([]*insta return volumes.Volumes, nil } +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, + }) + if err != nil { + return fmt.Errorf("error waiting for load-balancer: %w", err) + } + err = s.lbAPI.DeleteLB(&lb.DeleteLBRequest{ + Region: s.region, + LBID: loadBalancer.ID, + }) + if err != nil { + return fmt.Errorf("failed to delete 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, + }) + if !is404Error(err) { + return fmt.Errorf("error 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, + }) + if err != nil { + return fmt.Errorf("failed to delete load-balancer IP: %w", err) + } + } + return nil +} + func (s *scwCloudImplementation) DeleteServer(server *instance.Server) error { srv, err := s.instanceAPI.GetServer(&instance.GetServerRequest{ Zone: s.zone, diff --git a/upup/pkg/fi/cloudup/scalewaytasks/loadbalancer.go b/upup/pkg/fi/cloudup/scalewaytasks/loadbalancer.go index b412154dfe..212ebef6d4 100644 --- a/upup/pkg/fi/cloudup/scalewaytasks/loadbalancer.go +++ b/upup/pkg/fi/cloudup/scalewaytasks/loadbalancer.go @@ -159,7 +159,6 @@ func (l *LoadBalancer) RenderScw(t *scaleway.ScwAPITarget, actual, expected, cha Name: fi.ValueOf(expected.Name), IPID: nil, Tags: expected.Tags, - //Type: expected.Type, }) if err != nil { return err