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 }