diff --git a/cmd/ci-clean/main.go b/cmd/ci-clean/main.go index 6f97929b..26049cc5 100644 --- a/cmd/ci-clean/main.go +++ b/cmd/ci-clean/main.go @@ -29,6 +29,8 @@ import ( "github.com/spf13/cobra" kerrors "k8s.io/apimachinery/pkg/util/errors" + "sigs.k8s.io/cluster-api-provider-packet/internal/emlb" + lbaas "sigs.k8s.io/cluster-api-provider-packet/internal/lbaas/v1" "sigs.k8s.io/cluster-api-provider-packet/pkg/cloud/packet" ) @@ -94,6 +96,26 @@ func cleanup(ctx context.Context, metalAuthToken, metalProjectID string) error { errs = append(errs, err) } + emlbClient := emlb.NewEMLB(metalAuthToken, metalProjectID, "da") + + loadBalancerPools, _, err := emlbClient.GetLoadBalancerPools(ctx) + if err != nil { + return fmt.Errorf("failed to list load balancer pools: %w", err) + } + + if err := deleteEMLBPools(ctx, emlbClient, loadBalancerPools); err != nil { + errs = append(errs, err) + } + + loadBalancers, _, err := emlbClient.GetLoadBalancers(ctx) + if err != nil { + return fmt.Errorf("failed to list load balancers: %w", err) + } + + if err := deleteEMLBs(ctx, emlbClient, loadBalancers); err != nil { + errs = append(errs, err) + } + return kerrors.NewAggregate(errs) } @@ -155,3 +177,35 @@ func deleteKeys(ctx context.Context, metalClient *packet.Client, keys metal.SSHK return kerrors.NewAggregate(errs) } + +func deleteEMLBPools(ctx context.Context, emlbClient *emlb.EMLB, pools *lbaas.LoadBalancerPoolCollection) error { + var errs []error + + for _, pool := range pools.Pools { + if time.Since(pool.GetCreatedAt()) > 4*time.Hour { + fmt.Printf("Deleting Load Balancer: %s\n", pool.GetName()) + _, err := emlbClient.DeleteLoadBalancerPool(ctx, pool.GetId()) + if err != nil { + errs = append(errs, fmt.Errorf("failed to delete Load Balancer %q: %w", pool.GetName(), err)) + } + } + } + + return kerrors.NewAggregate(errs) +} + +func deleteEMLBs(ctx context.Context, emlbClient *emlb.EMLB, lbs *lbaas.LoadBalancerCollection) error { + var errs []error + + for _, lb := range lbs.Loadbalancers { + if time.Since(lb.GetCreatedAt()) > 4*time.Hour { + fmt.Printf("Deleting Load Balancer: %s\n", lb.GetName()) + _, err := emlbClient.DeleteLoadBalancer(ctx, lb.GetId()) + if err != nil { + errs = append(errs, fmt.Errorf("failed to delete Load Balancer %q: %w", lb.GetName(), err)) + } + } + } + + return kerrors.NewAggregate(errs) +} diff --git a/controllers/packetcluster_controller.go b/controllers/packetcluster_controller.go index 1f85c9b7..fb7ca5c0 100644 --- a/controllers/packetcluster_controller.go +++ b/controllers/packetcluster_controller.go @@ -196,7 +196,7 @@ func (r *PacketClusterReconciler) reconcileDelete(ctx context.Context, clusterSc // Create new EMLB object lb := emlb.NewEMLB(r.PacketClient.GetConfig().DefaultHeader["X-Auth-Token"], packetCluster.Spec.ProjectID, packetCluster.Spec.Metro) - if err := lb.DeleteLoadBalancer(ctx, clusterScope); err != nil { + if err := lb.DeleteClusterLoadBalancer(ctx, clusterScope); err != nil { return fmt.Errorf("failed to delete load balancer: %w", err) } } diff --git a/internal/emlb/emlb.go b/internal/emlb/emlb.go index 47414402..83ce11ff 100644 --- a/internal/emlb/emlb.go +++ b/internal/emlb/emlb.go @@ -231,8 +231,8 @@ func (e *EMLB) ReconcileVIPOrigin(ctx context.Context, machineScope *scope.Machi return nil } -// DeleteLoadBalancer deletes the Equinix Metal Load Balancer associated with a given ClusterScope. -func (e *EMLB) DeleteLoadBalancer(ctx context.Context, clusterScope *scope.ClusterScope) error { +// DeleteClusterLoadBalancer deletes the Equinix Metal Load Balancer associated with a given ClusterScope. +func (e *EMLB) DeleteClusterLoadBalancer(ctx context.Context, clusterScope *scope.ClusterScope) error { log := ctrl.LoggerFrom(ctx) packetCluster := clusterScope.PacketCluster @@ -247,7 +247,7 @@ func (e *EMLB) DeleteLoadBalancer(ctx context.Context, clusterScope *scope.Clust log.Info("Deleting EMLB", "Cluster Metro", e.metro, "Cluster Name", clusterName, "Project ID", e.projectID, "Load Balancer ID", lbID) - resp, err := e.deleteLoadBalancer(ctx, lbID) + resp, err := e.DeleteLoadBalancer(ctx, lbID) if err != nil { if resp.StatusCode == http.StatusNotFound { return nil @@ -273,7 +273,7 @@ func (e *EMLB) DeleteLoadBalancerOrigin(ctx context.Context, machineScope *scope log.Info("Deleting EMLB Pool", "Cluster Metro", e.metro, "Cluster Name", clusterName, "Project ID", e.projectID, "Pool ID", lbPoolID) - resp, err := e.deletePool(ctx, lbPoolID) + resp, err := e.DeleteLoadBalancerPool(ctx, lbPoolID) if err != nil { if resp.StatusCode != http.StatusNotFound { return nil @@ -284,6 +284,22 @@ func (e *EMLB) DeleteLoadBalancerOrigin(ctx context.Context, machineScope *scope return err } +// GetLoadBalancers returns a Load Balancer Collection of all the Equinix Metal Load Balancers in a project. +func (e *EMLB) GetLoadBalancers(ctx context.Context) (*lbaas.LoadBalancerCollection, *http.Response, error) { + ctx = context.WithValue(ctx, lbaas.ContextOAuth2, e.tokenExchanger) + + LoadBalancerCollection, resp, err := e.client.ProjectsApi.ListLoadBalancers(ctx, e.projectID).Execute() + return LoadBalancerCollection, resp, err +} + +// GetLoadBalancerPools returns a Load Balancer Collection of all the Equinix Metal Load Balancers in a project. +func (e *EMLB) GetLoadBalancerPools(ctx context.Context) (*lbaas.LoadBalancerPoolCollection, *http.Response, error) { + ctx = context.WithValue(ctx, lbaas.ContextOAuth2, e.tokenExchanger) + + LoadBalancerPoolCollection, resp, err := e.client.ProjectsApi.ListPools(ctx, e.projectID).Execute() + return LoadBalancerPoolCollection, resp, err +} + // getLoadBalancer Returns a Load Balancer object given an id. func (e *EMLB) getLoadBalancer(ctx context.Context, id string) (*lbaas.LoadBalancer, *http.Response, error) { ctx = context.WithValue(ctx, lbaas.ContextOAuth2, e.tokenExchanger) @@ -452,12 +468,14 @@ func (e *EMLB) createOrigin(ctx context.Context, poolID, originName string, targ return e.client.PoolsApi.CreateLoadBalancerPoolOrigin(ctx, poolID).LoadBalancerPoolOriginCreate(createOriginRequest).Execute() } -func (e *EMLB) deleteLoadBalancer(ctx context.Context, lbID string) (*http.Response, error) { +// DeleteLoadBalancer deletes an Equinix Metal Load Balancer given an ID. +func (e *EMLB) DeleteLoadBalancer(ctx context.Context, lbID string) (*http.Response, error) { ctx = context.WithValue(ctx, lbaas.ContextOAuth2, e.tokenExchanger) return e.client.LoadBalancersApi.DeleteLoadBalancer(ctx, lbID).Execute() } -func (e *EMLB) deletePool(ctx context.Context, poolID string) (*http.Response, error) { +// DeleteLoadBalancerPool deletes an Equinix Metal Load Balancer Origin Pool given an ID. +func (e *EMLB) DeleteLoadBalancerPool(ctx context.Context, poolID string) (*http.Response, error) { ctx = context.WithValue(ctx, lbaas.ContextOAuth2, e.tokenExchanger) return e.client.PoolsApi.DeleteLoadBalancerPool(ctx, poolID).Execute() }