Skip to content

Commit c94bdb3

Browse files
Merge pull request #8275 from barbacbd/OCPBUGS-32306
OCPBUGS-32306: GCP Destroy find regional and global addresses
2 parents a70f3aa + ffb231c commit c94bdb3

File tree

2 files changed

+83
-48
lines changed

2 files changed

+83
-48
lines changed

pkg/destroy/gcp/address.go

Lines changed: 82 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -2,76 +2,107 @@ package gcp
22

33
import (
44
"context"
5+
"fmt"
56

6-
"github.com/pkg/errors"
7+
"github.com/sirupsen/logrus"
78
"google.golang.org/api/compute/v1"
89
"google.golang.org/api/googleapi"
910

1011
"github.com/openshift/installer/pkg/types/gcp"
1112
)
1213

13-
func (o *ClusterUninstaller) listAddresses(ctx context.Context) ([]cloudResource, error) {
14-
return o.listAddressesWithFilter(ctx, "items(name,region,addressType),nextPageToken", o.clusterIDFilter(), nil)
14+
func (o *ClusterUninstaller) listAddresses(ctx context.Context, scope resourceScope) ([]cloudResource, error) {
15+
return o.listAddressesWithFilter(ctx, "items(name,region,addressType),nextPageToken", o.clusterIDFilter(), nil, scope)
16+
}
17+
18+
func createAddressCloudResources(filterFunc func(address *compute.Address) bool, list *compute.AddressList) []cloudResource {
19+
result := []cloudResource{}
20+
21+
for _, item := range list.Items {
22+
if filterFunc == nil || filterFunc(item) {
23+
logrus.Debugf("Found address: %s", item.Name)
24+
var quota []gcp.QuotaUsage
25+
if item.AddressType == "INTERNAL" {
26+
quota = []gcp.QuotaUsage{{
27+
Metric: &gcp.Metric{
28+
Service: gcp.ServiceComputeEngineAPI,
29+
Limit: "internal_addresses",
30+
Dimensions: map[string]string{
31+
"region": getNameFromURL("regions", item.Region),
32+
},
33+
},
34+
Amount: 1,
35+
}}
36+
}
37+
result = append(result, cloudResource{
38+
key: item.Name,
39+
name: item.Name,
40+
typeName: "address",
41+
quota: quota,
42+
})
43+
}
44+
}
45+
46+
return result
1547
}
1648

1749
// listAddressesWithFilter lists addresses in the project that satisfy the filter criteria.
1850
// The fields parameter specifies which fields should be returned in the result, the filter string contains
1951
// a filter string passed to the API to filter results. The filterFunc is a client-side filtering function
2052
// that determines whether a particular result should be returned or not.
21-
func (o *ClusterUninstaller) listAddressesWithFilter(ctx context.Context, fields string, filter string, filterFunc func(*compute.Address) bool) ([]cloudResource, error) {
22-
o.Logger.Debugf("Listing addresses")
53+
func (o *ClusterUninstaller) listAddressesWithFilter(ctx context.Context, fields string, filter string, filterFunc func(*compute.Address) bool, scope resourceScope) ([]cloudResource, error) {
54+
o.Logger.Debugf("Listing %s addresses", scope)
2355
ctx, cancel := context.WithTimeout(ctx, defaultTimeout)
2456
defer cancel()
2557
result := []cloudResource{}
58+
59+
if scope == gcpGlobalResource {
60+
req := o.computeSvc.GlobalAddresses.List(o.ProjectID).Fields(googleapi.Field(fields))
61+
if len(filter) > 0 {
62+
req = req.Filter(filter)
63+
}
64+
err := req.Pages(ctx, func(list *compute.AddressList) error {
65+
result = append(result, createAddressCloudResources(filterFunc, list)...)
66+
return nil
67+
})
68+
if err != nil {
69+
return nil, fmt.Errorf("failed to list global addresses: %w", err)
70+
}
71+
return result, nil
72+
}
73+
74+
// Regional addresses
2675
req := o.computeSvc.Addresses.List(o.ProjectID, o.Region).Fields(googleapi.Field(fields))
2776
if len(filter) > 0 {
2877
req = req.Filter(filter)
2978
}
3079
err := req.Pages(ctx, func(list *compute.AddressList) error {
31-
for _, item := range list.Items {
32-
if filterFunc == nil || filterFunc != nil && filterFunc(item) {
33-
o.Logger.Debugf("Found address: %s", item.Name)
34-
var quota []gcp.QuotaUsage
35-
if item.AddressType == "INTERNAL" {
36-
quota = []gcp.QuotaUsage{{
37-
Metric: &gcp.Metric{
38-
Service: gcp.ServiceComputeEngineAPI,
39-
Limit: "internal_addresses",
40-
Dimensions: map[string]string{
41-
"region": getNameFromURL("regions", item.Region),
42-
},
43-
},
44-
Amount: 1,
45-
}}
46-
}
47-
result = append(result, cloudResource{
48-
key: item.Name,
49-
name: item.Name,
50-
typeName: "address",
51-
quota: quota,
52-
})
53-
}
54-
}
80+
result = append(result, createAddressCloudResources(filterFunc, list)...)
5581
return nil
5682
})
5783
if err != nil {
58-
return nil, errors.Wrapf(err, "failed to list addresses")
84+
return nil, fmt.Errorf("failed to list regional addresses: %w", err)
5985
}
86+
6087
return result, nil
6188
}
6289

63-
func (o *ClusterUninstaller) deleteAddress(ctx context.Context, item cloudResource) error {
90+
func (o *ClusterUninstaller) deleteAddress(ctx context.Context, item cloudResource, scope resourceScope) error {
6491
o.Logger.Debugf("Deleting address %s", item.name)
6592
ctx, cancel := context.WithTimeout(ctx, defaultTimeout)
6693
defer cancel()
67-
op, err := o.computeSvc.Addresses.Delete(o.ProjectID, o.Region, item.name).RequestId(o.requestID(item.typeName, item.name)).Context(ctx).Do()
68-
if err != nil && !isNoOp(err) {
69-
o.resetRequestID(item.typeName, item.name)
70-
return errors.Wrapf(err, "failed to delete address %s", item.name)
94+
95+
var op *compute.Operation
96+
var err error
97+
if scope == gcpGlobalResource {
98+
op, err = o.computeSvc.GlobalAddresses.Delete(o.ProjectID, item.name).RequestId(o.requestID(item.typeName, item.name)).Context(ctx).Do()
99+
} else {
100+
op, err = o.computeSvc.Addresses.Delete(o.ProjectID, o.Region, item.name).RequestId(o.requestID(item.typeName, item.name)).Context(ctx).Do()
71101
}
102+
72103
if op != nil && op.Status == "DONE" && isErrorStatus(op.HttpErrorStatusCode) {
73104
o.resetRequestID(item.typeName, item.name)
74-
return errors.Errorf("failed to delete address %s with error: %s", item.name, operationErrorMessage(op))
105+
return fmt.Errorf("failed to delete address %s with error: %s: %w", item.name, operationErrorMessage(op), err)
75106
}
76107
if (err != nil && isNoOp(err)) || (op != nil && op.Status == "DONE") {
77108
o.resetRequestID(item.typeName, item.name)
@@ -84,19 +115,23 @@ func (o *ClusterUninstaller) deleteAddress(ctx context.Context, item cloudResour
84115
// destroyAddresses removes all address resources that have a name prefixed
85116
// with the cluster's infra ID.
86117
func (o *ClusterUninstaller) destroyAddresses(ctx context.Context) error {
87-
found, err := o.listAddresses(ctx)
88-
if err != nil {
89-
return err
90-
}
91-
items := o.insertPendingItems("address", found)
92-
for _, item := range items {
93-
err := o.deleteAddress(ctx, item)
118+
for _, scope := range []resourceScope{gcpGlobalResource, gcpRegionalResource} {
119+
found, err := o.listAddresses(ctx, scope)
94120
if err != nil {
95-
o.errorTracker.suppressWarning(item.key, err, o.Logger)
121+
return fmt.Errorf("failed to list %s addresses: %w", scope, err)
122+
}
123+
items := o.insertPendingItems("address", found)
124+
for _, item := range items {
125+
err := o.deleteAddress(ctx, item, scope)
126+
if err != nil {
127+
o.errorTracker.suppressWarning(item.key, err, o.Logger)
128+
}
129+
}
130+
for _, item := range o.getPendingItems("address") {
131+
if err := o.deleteAddress(ctx, item, scope); err != nil {
132+
return fmt.Errorf("error deleting pending address %s: %w", item.name, err)
133+
}
96134
}
97-
}
98-
if items = o.getPendingItems("address"); len(items) > 0 {
99-
return errors.Errorf("%d items pending", len(items))
100135
}
101136
return nil
102137
}

pkg/destroy/gcp/cloudcontroller.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ func (o *ClusterUninstaller) discoverCloudControllerLoadBalancerResources(ctx co
7676
loadBalancerNameFilter := fmt.Sprintf("name eq \"%s\"", loadBalancerName)
7777

7878
// Discover associated addresses: loadBalancerName
79-
found, err := o.listAddressesWithFilter(ctx, "items(name),nextPageToken", loadBalancerNameFilter, nil)
79+
found, err := o.listAddressesWithFilter(ctx, "items(name),nextPageToken", loadBalancerNameFilter, nil, gcpRegionalResource)
8080
if err != nil {
8181
return err
8282
}

0 commit comments

Comments
 (0)