github.com/openshift/installer@v1.4.17/pkg/destroy/gcp/healthcheck.go (about)

     1  package gcp
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  
     7  	"github.com/pkg/errors"
     8  	"google.golang.org/api/compute/v1"
     9  	"google.golang.org/api/googleapi"
    10  
    11  	"github.com/openshift/installer/pkg/types/gcp"
    12  )
    13  
    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)
    16  }
    17  
    18  // listHealthChecksWithFilter lists health checks in the project that satisfy the filter criteria.
    19  // The fields parameter specifies which fields should be returned in the result, the filter string contains
    20  // a filter string passed to the API to filter results. The filterFunc is a client-side filtering function
    21  // that determines whether a particular result should be returned or not.
    22  func (o *ClusterUninstaller) listHealthChecksWithFilter(ctx context.Context, typeName, fields, filter string, listFunc healthCheckListFunc) ([]cloudResource, error) {
    23  	o.Logger.Debugf("Listing health checks")
    24  	ctx, cancel := context.WithTimeout(ctx, defaultTimeout)
    25  	defer cancel()
    26  	result := []cloudResource{}
    27  	list, err := listFunc(ctx, filter, fields)
    28  	if err != nil {
    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  		})
    46  	}
    47  	return result, nil
    48  }
    49  
    50  func (o *ClusterUninstaller) deleteHealthCheck(ctx context.Context, item cloudResource, deleteFunc healthCheckDestroyFunc) error {
    51  	o.Logger.Debugf("Deleting health check %s", item.name)
    52  	ctx, cancel := context.WithTimeout(ctx, defaultTimeout)
    53  	defer cancel()
    54  	op, err := deleteFunc(ctx, item)
    55  	if err != nil && !isNoOp(err) {
    56  		o.resetRequestID(item.typeName, item.name)
    57  		return errors.Wrapf(err, "failed to delete health check %s", item.name)
    58  	}
    59  	if op != nil && op.Status == "DONE" && isErrorStatus(op.HttpErrorStatusCode) {
    60  		o.resetRequestID(item.typeName, item.name)
    61  		return errors.Errorf("failed to delete health check %s with error: %s", item.name, operationErrorMessage(op))
    62  	}
    63  	if (err != nil && isNoOp(err)) || (op != nil && op.Status == "DONE") {
    64  		o.resetRequestID(item.typeName, item.name)
    65  		o.deletePendingItems(item.typeName, []cloudResource{item})
    66  		o.Logger.Infof("Deleted health check %s", item.name)
    67  	}
    68  	return nil
    69  }
    70  
    71  // destroyHealthChecks removes all health check resources that have a name prefixed
    72  // with the cluster's infra ID.
    73  func (o *ClusterUninstaller) destroyHealthChecks(ctx context.Context) error {
    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)
    87  		if err != nil {
    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))
    99  		}
   100  	}
   101  	return nil
   102  }
   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  }