Skip to content

Commit 4765e43

Browse files
committed
destroy/gcp: Delete regional health check
This commit adds the capability to delete regional health checks along with the global health checks. To do this, it refactors the health-check code so that the logic essentially remains the same, but different services (health check or regoinal health check) can be injected.
1 parent 7142cf9 commit 4765e43

File tree

2 files changed

+74
-43
lines changed

2 files changed

+74
-43
lines changed

pkg/destroy/gcp/cloudcontroller.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ func (o *ClusterUninstaller) discoverCloudControllerLoadBalancerResources(ctx co
121121
o.insertPendingItems("forwardingrule", found)
122122

123123
// Discover associated health checks: loadBalancerName
124-
found, err = o.listHealthChecksWithFilter(ctx, "items(name),nextPageToken", loadBalancerNameFilter, nil)
124+
found, err = o.listHealthChecksWithFilter(ctx, "healthcheck", "items(name),nextPageToken", loadBalancerNameFilter, o.healthCheckList)
125125
if err != nil {
126126
return err
127127
}
@@ -196,7 +196,7 @@ func (o *ClusterUninstaller) discoverCloudControllerResources(ctx context.Contex
196196
if len(o.cloudControllerUID) > 0 {
197197
// Discover Cloud Controller health checks: k8s-cloudControllerUID-node
198198
filter := fmt.Sprintf("name eq \"k8s-%s-node\"", o.cloudControllerUID)
199-
found, err := o.listHealthChecksWithFilter(ctx, "items(name),nextPageToken", filter, nil)
199+
found, err := o.listHealthChecksWithFilter(ctx, "healthcheck", "items(name),nextPageToken", filter, o.healthCheckList)
200200
if err != nil {
201201
return err
202202
}

pkg/destroy/gcp/healthcheck.go

Lines changed: 72 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package gcp
22

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

67
"github.com/pkg/errors"
78
"google.golang.org/api/compute/v1"
@@ -10,54 +11,47 @@ import (
1011
"github.com/openshift/installer/pkg/types/gcp"
1112
)
1213

13-
func (o *ClusterUninstaller) listHealthChecks(ctx context.Context) ([]cloudResource, error) {
14-
return o.listHealthChecksWithFilter(ctx, "items(name),nextPageToken", o.clusterIDFilter(), nil)
14+
func (o *ClusterUninstaller) listHealthChecks(ctx context.Context, typeName string, listFunc healthCheckListFunc) ([]cloudResource, error) {
15+
return o.listHealthChecksWithFilter(ctx, typeName, "items(name),nextPageToken", o.clusterIDFilter(), listFunc)
1516
}
1617

1718
// listHealthChecksWithFilter lists health checks in the project that satisfy the filter criteria.
1819
// The fields parameter specifies which fields should be returned in the result, the filter string contains
1920
// a filter string passed to the API to filter results. The filterFunc is a client-side filtering function
2021
// that determines whether a particular result should be returned or not.
21-
func (o *ClusterUninstaller) listHealthChecksWithFilter(ctx context.Context, fields string, filter string, filterFunc func(*compute.HealthCheck) bool) ([]cloudResource, error) {
22+
func (o *ClusterUninstaller) listHealthChecksWithFilter(ctx context.Context, typeName, fields, filter string, listFunc healthCheckListFunc) ([]cloudResource, error) {
2223
o.Logger.Debugf("Listing health checks")
2324
ctx, cancel := context.WithTimeout(ctx, defaultTimeout)
2425
defer cancel()
2526
result := []cloudResource{}
26-
req := o.computeSvc.HealthChecks.List(o.ProjectID).Fields(googleapi.Field(fields))
27-
if len(filter) > 0 {
28-
req = req.Filter(filter)
29-
}
30-
err := req.Pages(ctx, func(list *compute.HealthCheckList) error {
31-
for _, item := range list.Items {
32-
if filterFunc == nil || filterFunc != nil && filterFunc(item) {
33-
o.Logger.Debugf("Found health check: %s", item.Name)
34-
result = append(result, cloudResource{
35-
key: item.Name,
36-
name: item.Name,
37-
typeName: "healthcheck",
38-
quota: []gcp.QuotaUsage{{
39-
Metric: &gcp.Metric{
40-
Service: gcp.ServiceComputeEngineAPI,
41-
Limit: "health_checks",
42-
},
43-
Amount: 1,
44-
}},
45-
})
46-
}
47-
}
48-
return nil
49-
})
27+
list, err := listFunc(ctx, filter, fields)
5028
if err != nil {
51-
return nil, errors.Wrapf(err, "failed to list health checks")
29+
return nil, fmt.Errorf("failed to list health checks: %w", err)
30+
}
31+
32+
for _, item := range list.Items {
33+
o.Logger.Debugf("Found health check: %s", item.Name)
34+
result = append(result, cloudResource{
35+
key: item.Name,
36+
name: item.Name,
37+
typeName: typeName,
38+
quota: []gcp.QuotaUsage{{
39+
Metric: &gcp.Metric{
40+
Service: gcp.ServiceComputeEngineAPI,
41+
Limit: "health_checks",
42+
},
43+
Amount: 1,
44+
}},
45+
})
5246
}
5347
return result, nil
5448
}
5549

56-
func (o *ClusterUninstaller) deleteHealthCheck(ctx context.Context, item cloudResource) error {
50+
func (o *ClusterUninstaller) deleteHealthCheck(ctx context.Context, item cloudResource, deleteFunc healthCheckDestroyFunc) error {
5751
o.Logger.Debugf("Deleting health check %s", item.name)
5852
ctx, cancel := context.WithTimeout(ctx, defaultTimeout)
5953
defer cancel()
60-
op, err := o.computeSvc.HealthChecks.Delete(o.ProjectID, item.name).RequestId(o.requestID(item.typeName, item.name)).Context(ctx).Do()
54+
op, err := deleteFunc(ctx, item)
6155
if err != nil && !isNoOp(err) {
6256
o.resetRequestID(item.typeName, item.name)
6357
return errors.Wrapf(err, "failed to delete health check %s", item.name)
@@ -77,19 +71,56 @@ func (o *ClusterUninstaller) deleteHealthCheck(ctx context.Context, item cloudRe
7771
// destroyHealthChecks removes all health check resources that have a name prefixed
7872
// with the cluster's infra ID.
7973
func (o *ClusterUninstaller) destroyHealthChecks(ctx context.Context) error {
80-
found, err := o.listHealthChecks(ctx)
81-
if err != nil {
82-
return err
83-
}
84-
items := o.insertPendingItems("healthcheck", found)
85-
for _, item := range items {
86-
err := o.deleteHealthCheck(ctx, item)
74+
for _, hcd := range []healthCheckDestroyer{
75+
{
76+
itemTypeName: "healthcheck",
77+
destroyFunc: o.healthCheckDelete,
78+
listFunc: o.healthCheckList,
79+
},
80+
{
81+
itemTypeName: "regionHealthCheck",
82+
destroyFunc: o.regionHealthCheckDelete,
83+
listFunc: o.regionHealthCheckList,
84+
},
85+
} {
86+
found, err := o.listHealthChecks(ctx, hcd.itemTypeName, hcd.listFunc)
8787
if err != nil {
88-
o.errorTracker.suppressWarning(item.key, err, o.Logger)
88+
return err
89+
}
90+
items := o.insertPendingItems(hcd.itemTypeName, found)
91+
for _, item := range items {
92+
err := o.deleteHealthCheck(ctx, item, hcd.destroyFunc)
93+
if err != nil {
94+
o.errorTracker.suppressWarning(item.key, err, o.Logger)
95+
}
96+
}
97+
if items = o.getPendingItems(hcd.itemTypeName); len(items) > 0 {
98+
return errors.Errorf("%d items pending", len(items))
8999
}
90-
}
91-
if items = o.getPendingItems("healthcheck"); len(items) > 0 {
92-
return errors.Errorf("%d items pending", len(items))
93100
}
94101
return nil
95102
}
103+
104+
type healthCheckListFunc func(ctx context.Context, filter, fields string) (*compute.HealthCheckList, error)
105+
type healthCheckDestroyFunc func(ctx context.Context, item cloudResource) (*compute.Operation, error)
106+
type healthCheckDestroyer struct {
107+
itemTypeName string
108+
destroyFunc healthCheckDestroyFunc
109+
listFunc healthCheckListFunc
110+
}
111+
112+
func (o *ClusterUninstaller) healthCheckDelete(ctx context.Context, item cloudResource) (*compute.Operation, error) {
113+
return o.computeSvc.HealthChecks.Delete(o.ProjectID, item.name).RequestId(o.requestID(item.typeName, item.name)).Context(ctx).Do()
114+
}
115+
116+
func (o *ClusterUninstaller) healthCheckList(ctx context.Context, filter, fields string) (*compute.HealthCheckList, error) {
117+
return o.computeSvc.HealthChecks.List(o.ProjectID).Filter(filter).Fields(googleapi.Field(fields)).Context(ctx).Do()
118+
}
119+
120+
func (o *ClusterUninstaller) regionHealthCheckDelete(ctx context.Context, item cloudResource) (*compute.Operation, error) {
121+
return o.computeSvc.RegionHealthChecks.Delete(o.ProjectID, o.Region, item.name).RequestId(o.requestID(item.typeName, item.name)).Context(ctx).Do()
122+
}
123+
124+
func (o *ClusterUninstaller) regionHealthCheckList(ctx context.Context, filter, fields string) (*compute.HealthCheckList, error) {
125+
return o.computeSvc.RegionHealthChecks.List(o.ProjectID, o.Region).Filter(filter).Fields(googleapi.Field(fields)).Context(ctx).Do()
126+
}

0 commit comments

Comments
 (0)