in cleanerupper/cleanerupper.go [715:1036]
func CleanNetworks(clients Clients, project string, delete PolicyFunc, dryRun bool) ([]string, []error) {
networks, err := clients.Daisy.ListNetworks(project)
if err != nil {
return nil, []error{fmt.Errorf("error listing networks in project %q: %v", project, err)}
}
firewalls, err := clients.Daisy.ListFirewallRules(project)
if err != nil {
return nil, []error{fmt.Errorf("error listing firewalls in project %q: %v", project, err)}
}
subnetworks, err := clients.Daisy.AggregatedListSubnetworks(project)
if err != nil {
return nil, []error{fmt.Errorf("error listing subnetworks in project %q: %v", project, err)}
}
regionalForwardingRules := make(map[string][]*compute.ForwardingRule)
regionalBackendServices := make(map[string][]*compute.BackendService)
regionalNetworkEndpointGroups := make(map[string][]*compute.NetworkEndpointGroup)
regionalURLMaps := make(map[string][]*compute.UrlMap)
regionalHTTPProxies := make(map[string][]*compute.TargetHttpProxy)
var deletedMu sync.Mutex
var deleted []string
var errsMu sync.Mutex
var errs []error
var wg sync.WaitGroup
for _, n := range networks {
if !delete(n) {
continue
}
name := path.Base(n.SelfLink)
netpartial := fmt.Sprintf("projects/%s/global/networks/%s", project, name)
// Delete firewall rules associated with network.
for _, f := range firewalls {
if f.Network != n.SelfLink {
continue
}
name := path.Base(f.SelfLink)
fwallpartial := fmt.Sprintf("projects/%s/global/firewalls/%s", project, name)
wg.Add(1)
go func() {
defer wg.Done()
if !dryRun {
if err := clients.Daisy.DeleteFirewallRule(project, name); err != nil {
errsMu.Lock()
defer errsMu.Unlock()
errs = append(errs, err)
return
}
}
deletedMu.Lock()
defer deletedMu.Unlock()
deleted = append(deleted, fwallpartial)
}()
}
for _, sn := range subnetworks {
if sn.Network != n.SelfLink {
continue
}
// If this network is setup with auto subnetworks we need to ignore any subnetworks that are in 10.128.0.0/9.
// https://cloud.google.com/vpc/docs/vpc#ip-ranges
if n.AutoCreateSubnetworks == true {
i, err := strconv.Atoi(strings.Split(sn.IpCidrRange, ".")[1])
if err != nil {
fmt.Printf("Error parsing network range %q: %v\n", sn.IpCidrRange, err)
}
if i >= 128 {
continue
}
}
// Don't delete network yet - wait until resources associated with it are
// deleted to avoid resource in use issues.
region := path.Base(sn.Region)
regionFRs, ok := regionalForwardingRules[region]
if !ok {
var err error
regionFRs, err = clients.Daisy.ListForwardingRules(project, region)
if err != nil {
errsMu.Lock()
errs = append(errs, err)
errsMu.Unlock()
} else {
regionalForwardingRules[region] = regionFRs
}
}
// Delete all forwarding rules in the same region as the subnetwork.
for _, fr := range regionFRs {
if fr.Network != n.SelfLink {
continue
}
frpartial := fmt.Sprintf("projects/%s/regions/%s/forwardingRules/%s", project, region, fr.Name)
wg.Add(1)
go func(frName string) {
defer wg.Done()
if !dryRun {
if err := clients.Daisy.DeleteForwardingRule(project, region, frName); err != nil {
errsMu.Lock()
defer errsMu.Unlock()
errs = append(errs, err)
return
}
}
deletedMu.Lock()
defer deletedMu.Unlock()
deleted = append(deleted, frpartial)
}(fr.Name)
}
regionBSs, ok := regionalBackendServices[region]
if !ok {
var err error
regionBSs, err = clients.Daisy.ListRegionBackendServices(project, region)
if err != nil {
errsMu.Lock()
errs = append(errs, err)
errsMu.Unlock()
} else {
regionalBackendServices[region] = regionBSs
}
}
// Delete all backend services in the same region as the subnetwork.
for _, bs := range regionBSs {
if bs.Network != n.SelfLink {
continue
}
bspartial := fmt.Sprintf("projects/%s/regions/%s/backendServices/%s", project, region, bs.Name)
regionUMs, ok := regionalURLMaps[region]
if !ok {
var err error
regionUMs, err = clients.Daisy.ListRegionURLMaps(project, region)
if err != nil {
errsMu.Lock()
errs = append(errs, err)
errsMu.Unlock()
} else {
regionalURLMaps[region] = regionUMs
}
}
// Delete all url maps in the same region as the subnetwork.
for _, um := range regionUMs {
if um.DefaultService != bs.SelfLink {
continue
}
umpartial := fmt.Sprintf("projects/%s/regions/%s/urlMaps/%s", project, region, um.Name)
regionHPs, ok := regionalHTTPProxies[region]
if !ok {
var err error
regionHPs, err = clients.Daisy.ListRegionTargetHTTPProxies(project, region)
if err != nil {
errsMu.Lock()
errs = append(errs, err)
errsMu.Unlock()
} else {
regionalHTTPProxies[region] = regionHPs
}
}
// Delete all target http proxies in the same region as the subnetwork.
for _, hp := range regionHPs {
if hp.UrlMap != um.SelfLink {
continue
}
hppartial := fmt.Sprintf("projects/%s/regions/%s/targetHttpProxies/%s", project, region, hp.Name)
wg.Add(1)
go func(hpName string) {
defer wg.Done()
if !dryRun {
if err := clients.Daisy.DeleteRegionTargetHTTPProxy(project, region, hpName); err != nil {
errsMu.Lock()
defer errsMu.Unlock()
errs = append(errs, err)
return
}
}
deletedMu.Lock()
defer deletedMu.Unlock()
deleted = append(deleted, hppartial)
}(path.Base(hp.Name))
}
wg.Wait()
// Wait for target http proxy deletion before URL map deletion to avoid resource
// in use issues.
wg.Add(1)
go func(unName string) {
defer wg.Done()
if !dryRun {
if err := clients.Daisy.DeleteRegionURLMap(project, region, unName); err != nil {
errsMu.Lock()
defer errsMu.Unlock()
errs = append(errs, err)
return
}
}
deletedMu.Lock()
defer deletedMu.Unlock()
deleted = append(deleted, umpartial)
}(path.Base(um.Name))
}
// Wait for URL Map deletion before backend service deletion to avoid resource
// in use issues.
wg.Wait()
wg.Add(1)
go func(bsName string) {
defer wg.Done()
if !dryRun {
if err := clients.Daisy.DeleteRegionBackendService(project, region, bsName); err != nil {
errsMu.Lock()
defer errsMu.Unlock()
errs = append(errs, err)
return
}
}
deletedMu.Lock()
defer deletedMu.Unlock()
deleted = append(deleted, bspartial)
}(bs.Name)
wg.Wait()
// Delete all health checks in the same region as the subnetwork.
for _, hc := range bs.HealthChecks {
hcpartial := fmt.Sprintf("projects/%s/regions/%s/healthChecks/%s", project, region, path.Base(hc))
wg.Add(1)
go func(hcName string) {
defer wg.Done()
if !dryRun {
if err := clients.Daisy.DeleteRegionHealthCheck(project, region, hcName); err != nil {
errsMu.Lock()
defer errsMu.Unlock()
errs = append(errs, err)
return
}
}
deletedMu.Lock()
defer deletedMu.Unlock()
deleted = append(deleted, hcpartial)
}(path.Base(hc))
}
}
wg.Wait()
regionalNEGs, ok := regionalNetworkEndpointGroups[region]
if !ok {
var err error
regionalNEGs, err = clients.Daisy.ListRegionNetworkEndpointGroups(project, region)
if err != nil {
errsMu.Lock()
errs = append(errs, err)
errsMu.Unlock()
} else {
regionalNetworkEndpointGroups[region] = regionalNEGs
}
}
for _, neg := range regionalNEGs {
// Delete all NEGs in the same region as the subnetwork.
if neg.Network != n.SelfLink {
continue
}
negpartial := fmt.Sprintf("projects/%s/regions/%s/networkEndpointGroups/%s", project, region, neg.Name)
wg.Add(1)
go func(negName string) {
defer wg.Done()
if !dryRun {
if err := clients.Daisy.DeleteRegionNetworkEndpointGroup(project, region, negName); err != nil {
errsMu.Lock()
defer errsMu.Unlock()
errs = append(errs, err)
return
}
}
deletedMu.Lock()
defer deletedMu.Unlock()
deleted = append(deleted, negpartial)
}(neg.Name)
}
// Wait for NEG deletion before subnetwork deletion to avoid resource in use
// issues.
wg.Wait()
subnetpartial := fmt.Sprintf("projects/%s/regions/%s/subnetworks/%s", project, region, sn.Name)
wg.Wait()
wg.Add(1)
go func(snName string) {
defer wg.Done()
if !dryRun {
if err := clients.Daisy.DeleteSubnetwork(project, region, snName); err != nil {
errsMu.Lock()
defer errsMu.Unlock()
errs = append(errs, err)
return
}
}
deletedMu.Lock()
defer deletedMu.Unlock()
deleted = append(deleted, subnetpartial)
}(sn.Name)
}
// Wait for subnetwork deletion before network deletion to avoid resource
// in use issues.
wg.Wait()
wg.Add(1)
go func() {
defer wg.Done()
if !dryRun {
if err := clients.Daisy.DeleteNetwork(project, name); err != nil {
errsMu.Lock()
defer errsMu.Unlock()
errs = append(errs, err)
return
}
}
deletedMu.Lock()
defer deletedMu.Unlock()
deleted = append(deleted, netpartial)
}()
}
wg.Wait()
return deleted, errs
}