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

     1  package gcp
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  
     7  	"github.com/sirupsen/logrus"
     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) listBackendServices(ctx context.Context, scope resourceScope) ([]cloudResource, error) {
    15  	return o.listBackendServicesWithFilter(ctx, "items(name),nextPageToken", o.clusterIDFilter(), nil, scope)
    16  }
    17  
    18  func createBackendServiceCloudResources(filterFunc func(*compute.BackendService) bool, list *compute.BackendServiceList) []cloudResource {
    19  	result := []cloudResource{}
    20  
    21  	for _, item := range list.Items {
    22  		if filterFunc == nil || filterFunc(item) {
    23  			logrus.Debugf("Found backend service: %s", item.Name)
    24  			result = append(result, cloudResource{
    25  				key:      item.Name,
    26  				name:     item.Name,
    27  				typeName: "backendservice",
    28  				quota: []gcp.QuotaUsage{{
    29  					Metric: &gcp.Metric{
    30  						Service: gcp.ServiceComputeEngineAPI,
    31  						Limit:   "backend_services",
    32  					},
    33  					Amount: 1,
    34  				}},
    35  			})
    36  		}
    37  	}
    38  
    39  	return result
    40  }
    41  
    42  // listBackendServicesWithFilter lists backend services in the project that satisfy the filter criteria.
    43  // The fields parameter specifies which fields should be returned in the result, the filter string contains
    44  // a filter string passed to the API to filter results. The filterFunc is a client-side filtering function
    45  // that determines whether a particular result should be returned or not.
    46  func (o *ClusterUninstaller) listBackendServicesWithFilter(ctx context.Context, fields string, filter string, filterFunc func(*compute.BackendService) bool, scope resourceScope) ([]cloudResource, error) {
    47  	o.Logger.Debugf("Listing %s backend services", scope)
    48  	ctx, cancel := context.WithTimeout(ctx, defaultTimeout)
    49  	defer cancel()
    50  	result := []cloudResource{}
    51  
    52  	if scope == gcpGlobalResource {
    53  		req := o.computeSvc.BackendServices.List(o.ProjectID).Fields(googleapi.Field(fields))
    54  		if len(filter) > 0 {
    55  			req = req.Filter(filter)
    56  		}
    57  		err := req.Pages(ctx, func(list *compute.BackendServiceList) error {
    58  			result = append(result, createBackendServiceCloudResources(filterFunc, list)...)
    59  			return nil
    60  		})
    61  		if err != nil {
    62  			return nil, fmt.Errorf("failed to list global backend services: %w", err)
    63  		}
    64  		return result, nil
    65  	}
    66  
    67  	// Regional backend services
    68  	req := o.computeSvc.RegionBackendServices.List(o.ProjectID, o.Region).Fields(googleapi.Field(fields))
    69  	if len(filter) > 0 {
    70  		req = req.Filter(filter)
    71  	}
    72  	err := req.Pages(ctx, func(list *compute.BackendServiceList) error {
    73  		result = append(result, createBackendServiceCloudResources(filterFunc, list)...)
    74  		return nil
    75  	})
    76  	if err != nil {
    77  		return nil, fmt.Errorf("failed to list regional backend services: %w", err)
    78  	}
    79  
    80  	return result, nil
    81  }
    82  
    83  func (o *ClusterUninstaller) deleteBackendService(ctx context.Context, item cloudResource, scope resourceScope) error {
    84  	o.Logger.Debugf("Deleting backend service %s", item.name)
    85  	ctx, cancel := context.WithTimeout(ctx, defaultTimeout)
    86  	defer cancel()
    87  
    88  	var op *compute.Operation
    89  	var err error
    90  	if scope == gcpGlobalResource {
    91  		op, err = o.computeSvc.BackendServices.Delete(o.ProjectID, item.name).RequestId(o.requestID(item.typeName, item.name)).Context(ctx).Do()
    92  	} else {
    93  		op, err = o.computeSvc.RegionBackendServices.Delete(o.ProjectID, o.Region, item.name).RequestId(o.requestID(item.typeName, item.name)).Context(ctx).Do()
    94  	}
    95  
    96  	if op != nil && op.Status == "DONE" && isErrorStatus(op.HttpErrorStatusCode) {
    97  		o.resetRequestID(item.typeName, item.name)
    98  		return fmt.Errorf("failed to delete backend service %s with error: %s: %w", item.name, operationErrorMessage(op), err)
    99  	}
   100  	if (err != nil && isNoOp(err)) || (op != nil && op.Status == "DONE") {
   101  		o.resetRequestID(item.typeName, item.name)
   102  		o.deletePendingItems(item.typeName, []cloudResource{item})
   103  		o.Logger.Infof("Deleted backend service %s", item.name)
   104  	}
   105  	return nil
   106  }
   107  
   108  // destroyBackendServices removes backend services with a name prefixed
   109  // with the cluster's infra ID.
   110  func (o *ClusterUninstaller) destroyBackendServices(ctx context.Context) error {
   111  	for _, scope := range []resourceScope{gcpGlobalResource, gcpRegionalResource} {
   112  		found, err := o.listBackendServices(ctx, scope)
   113  		if err != nil {
   114  			return fmt.Errorf("failed to list backend services: %w", err)
   115  		}
   116  		items := o.insertPendingItems("backendservice", found)
   117  		for _, item := range items {
   118  			err := o.deleteBackendService(ctx, item, scope)
   119  			if err != nil {
   120  				o.errorTracker.suppressWarning(item.key, err, o.Logger)
   121  			}
   122  		}
   123  		if items = o.getPendingItems("backendservice"); len(items) > 0 {
   124  			for _, item := range items {
   125  				if err := o.deleteBackendService(ctx, item, scope); err != nil {
   126  					return fmt.Errorf("error deleting pending backend service %s: %w", item.name, err)
   127  				}
   128  			}
   129  		}
   130  	}
   131  	return nil
   132  }