diff --git a/tools/clean/atlas/atlas.go b/tools/clean/atlas/atlas.go index 825ca09c51..eb3e7c33ff 100644 --- a/tools/clean/atlas/atlas.go +++ b/tools/clean/atlas/atlas.go @@ -52,7 +52,7 @@ func (c *Cleaner) Clean(ctx context.Context, lifetime int) error { for _, proj := range projects { p := proj - fmt.Println(text.FgHiWhite.Sprintf("\tStarting deletion of project %s(%s) ...", p.GetName(), p.GetId())) + fmt.Println(text.FgHiWhite.Sprintf("\tStarting deletion of project %s(%s) (created at %v)...", p.GetName(), p.GetId(), p.Created)) if time.Since(p.Created) < time.Duration(lifetime)*time.Hour { fmt.Println(text.FgYellow.Sprintf("\tProject %s(%s) skipped once created less than %d hour ago", p.GetName(), p.GetId(), lifetime)) diff --git a/tools/clean/atlas/network_peering.go b/tools/clean/atlas/network_peering.go index e8c3a60756..87beea61d3 100644 --- a/tools/clean/atlas/network_peering.go +++ b/tools/clean/atlas/network_peering.go @@ -8,16 +8,28 @@ import ( "go.mongodb.org/atlas-sdk/v20231001002/admin" ) -func (c *Cleaner) listNetworkPeering(ctx context.Context, projectID string) []admin.BaseNetworkPeeringConnectionSettings { - peers, _, err := c.client.NetworkPeeringApi. - ListPeeringConnections(ctx, projectID). - Execute() - if err != nil { - fmt.Println(text.FgRed.Sprintf("\tFailed to list networking peering for project %s: %s", projectID, err)) +var ( + SupportedProviders = []string{"AWS", "AZURE", "GCP"} +) +func (c *Cleaner) listNetworkPeering(ctx context.Context, projectID string) []admin.BaseNetworkPeeringConnectionSettings { + peers := []admin.BaseNetworkPeeringConnectionSettings{} + for _, providerName := range SupportedProviders { + peers = append(peers, c.listNetworkPeeringForProvider(ctx, projectID, providerName)...) + } + if len(peers) == 0 { return nil } + return peers +} +func (c *Cleaner) listNetworkPeeringForProvider(ctx context.Context, projectID, providerName string) []admin.BaseNetworkPeeringConnectionSettings { + queryArgs := admin.ListPeeringConnectionsApiParams{GroupId: projectID, ProviderName: &providerName} + peers, _, err := c.client.NetworkPeeringApi.ListPeeringConnectionsWithParams(ctx, &queryArgs).Execute() + if err != nil { + fmt.Println(text.FgRed.Sprintf("\tFailed to list %s networking peering for project %s: %s", providerName, projectID, err)) + return []admin.BaseNetworkPeeringConnectionSettings{} + } return peers.Results } diff --git a/tools/clean/provider/gcp.go b/tools/clean/provider/gcp.go index ecd8e1e301..d48aec1191 100644 --- a/tools/clean/provider/gcp.go +++ b/tools/clean/provider/gcp.go @@ -19,18 +19,60 @@ type GCP struct { projectID string networkClient *compute.NetworksClient + subnetworksClient *compute.SubnetworksClient forwardRuleClient *compute.ForwardingRulesClient addressClient *compute.AddressesClient keyManagementClient *kms.KeyManagementClient } func (gcp *GCP) DeleteVpc(ctx context.Context, vpcName string) error { + vpcGetRequest := &computepb.GetNetworkRequest{ + Project: gcp.projectID, + Network: vpcName, + } + net, err := gcp.networkClient.Get(ctx, vpcGetRequest) + if err != nil { + return fmt.Errorf("failed to get VPC %q: %v", vpcName, err) + } + for _, subnetURL := range net.Subnetworks { + subnet, region := decodeSubnetURL(subnetURL) + if subnet == "" { + return fmt.Errorf("failed to decode subnet URL %q", subnetURL) + } + subnetDeleteRequest := &computepb.DeleteSubnetworkRequest{ + Project: gcp.projectID, + Subnetwork: subnet, + Region: region, + } + op, err := gcp.subnetworksClient.Delete(ctx, subnetDeleteRequest) + if err := waitOrFailOp(ctx, op, err); err != nil { + return fmt.Errorf("failed to delete subnet %q: %v", subnet, err) + } + } vpcRequest := &computepb.DeleteNetworkRequest{ Project: gcp.projectID, Network: vpcName, } op, err := gcp.networkClient.Delete(ctx, vpcRequest) + if err := waitOrFailOp(ctx, op, err); err != nil { + return fmt.Errorf("failed to delete VPC %q: %v", vpcName, err) + } + + return nil +} + +func decodeSubnetURL(subnetURL string) (string, string) { + parts := strings.Split(subnetURL, "/") + if len(parts) < 11 { + return "", "" + } + region := parts[8] + subnet := parts[10] + return subnet, region +} + +func waitOrFailOp(ctx context.Context, op *compute.Operation, err error) error { if err != nil { return err } @@ -39,7 +81,6 @@ func (gcp *GCP) DeleteVpc(ctx context.Context, vpcName string) error { if err != nil { return err } - return nil } @@ -177,6 +218,11 @@ func NewGCPCleaner(ctx context.Context) (*GCP, error) { return nil, err } + subnetworksClient, err := compute.NewSubnetworksRESTClient(ctx) + if err != nil { + return nil, err + } + forwardRuleClient, err := compute.NewForwardingRulesRESTClient(ctx) if err != nil { return nil, err @@ -195,6 +241,7 @@ func NewGCPCleaner(ctx context.Context) (*GCP, error) { return &GCP{ projectID: projectID, networkClient: networkClient, + subnetworksClient: subnetworksClient, forwardRuleClient: forwardRuleClient, addressClient: addressClient, keyManagementClient: keyManagementClient,