github.com/openshift/installer@v1.4.17/pkg/destroy/gcp/forwardingrule.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) listForwardingRules(ctx context.Context, scope resourceScope) ([]cloudResource, error) { 15 return o.listForwardingRulesWithFilter(ctx, "items(name,region,loadBalancingScheme),nextPageToken", o.clusterIDFilter(), nil, scope) 16 } 17 18 func createForwardingRuleResources(filterFunc func(*compute.ForwardingRule) bool, list *compute.ForwardingRuleList) []cloudResource { 19 result := []cloudResource{} 20 21 for _, item := range list.Items { 22 if filterFunc == nil || filterFunc(item) { 23 logrus.Debugf("Found forwarding rule: %s", item.Name) 24 var quota []gcp.QuotaUsage 25 if item.LoadBalancingScheme == "EXTERNAL" { 26 quota = []gcp.QuotaUsage{{ 27 Metric: &gcp.Metric{ 28 Service: gcp.ServiceComputeEngineAPI, 29 Limit: "external_network_lb_forwarding_rules", 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: "forwardingrule", 41 quota: quota, 42 }) 43 } 44 } 45 46 return result 47 } 48 49 // listForwardingRulesWithFilter lists forwarding rules in the project that satisfy the filter criteria. 50 // The fields parameter specifies which fields should be returned in the result, the filter string contains 51 // a filter string passed to the API to filter results. The filterFunc is a client-side filtering function 52 // that determines whether a particular result should be returned or not. 53 func (o *ClusterUninstaller) listForwardingRulesWithFilter(ctx context.Context, fields string, filter string, filterFunc func(*compute.ForwardingRule) bool, scope resourceScope) ([]cloudResource, error) { 54 o.Logger.Debugf("Listing %s forwarding rules", scope) 55 ctx, cancel := context.WithTimeout(ctx, defaultTimeout) 56 defer cancel() 57 58 result := []cloudResource{} 59 60 if scope == gcpGlobalResource { 61 req := o.computeSvc.GlobalForwardingRules.List(o.ProjectID).Fields(googleapi.Field(fields)) 62 if len(filter) > 0 { 63 req = req.Filter(filter) 64 } 65 err := req.Pages(ctx, func(list *compute.ForwardingRuleList) error { 66 result = append(result, createForwardingRuleResources(filterFunc, list)...) 67 return nil 68 }) 69 if err != nil { 70 return nil, fmt.Errorf("failed to list global forwarding rules: %w", err) 71 } 72 73 return result, nil 74 } 75 76 // Regional forwarding rules 77 req := o.computeSvc.ForwardingRules.List(o.ProjectID, o.Region).Fields(googleapi.Field(fields)) 78 if len(filter) > 0 { 79 req = req.Filter(filter) 80 } 81 err := req.Pages(ctx, func(list *compute.ForwardingRuleList) error { 82 result = append(result, createForwardingRuleResources(filterFunc, list)...) 83 return nil 84 }) 85 86 if err != nil { 87 return nil, fmt.Errorf("failed to list regional forwarding rules: %w", err) 88 } 89 return result, nil 90 } 91 92 func (o *ClusterUninstaller) deleteForwardingRule(ctx context.Context, item cloudResource, scope resourceScope) error { 93 o.Logger.Debugf("Deleting %s forwarding rule %s", scope, item.name) 94 ctx, cancel := context.WithTimeout(ctx, defaultTimeout) 95 defer cancel() 96 97 var op *compute.Operation 98 var err error 99 if scope == gcpGlobalResource { 100 op, err = o.computeSvc.GlobalForwardingRules.Delete(o.ProjectID, item.name).RequestId(o.requestID(item.typeName, item.name)).Context(ctx).Do() 101 } else { 102 op, err = o.computeSvc.ForwardingRules.Delete(o.ProjectID, o.Region, item.name).RequestId(o.requestID(item.typeName, item.name)).Context(ctx).Do() 103 } 104 105 if err != nil && !isNoOp(err) { 106 o.resetRequestID(item.typeName, item.name) 107 return fmt.Errorf("failed to delete forwarding rule %s: %w", item.name, err) 108 } 109 if op != nil && op.Status == "DONE" && isErrorStatus(op.HttpErrorStatusCode) { 110 o.resetRequestID(item.typeName, item.name) 111 return fmt.Errorf("failed to delete forwarding rule %s with error: %s: %w", item.name, operationErrorMessage(op), err) 112 } 113 if op != nil && op.Status == "DONE" { 114 o.resetRequestID(item.typeName, item.name) 115 o.deletePendingItems(item.typeName, []cloudResource{item}) 116 o.Logger.Infof("Deleted forwarding rule %s", item.name) 117 } 118 return nil 119 } 120 121 // destroyForwardingRules removes all forwarding rules with a name prefixed 122 // with the cluster's infra ID. 123 func (o *ClusterUninstaller) destroyForwardingRules(ctx context.Context) error { 124 for _, scope := range []resourceScope{gcpRegionalResource, gcpGlobalResource} { 125 found, err := o.listForwardingRules(ctx, scope) 126 if err != nil { 127 return fmt.Errorf("failed to list forwarding rules: %w", err) 128 } 129 items := o.insertPendingItems("forwardingrule", found) 130 for _, item := range items { 131 if err := o.deleteForwardingRule(ctx, item, scope); err != nil { 132 o.Logger.Errorf("error deleting forwarding rule %s: %w", item.name, err) 133 o.errorTracker.suppressWarning(item.key, err, o.Logger) 134 } 135 } 136 if items = o.getPendingItems("forwardingrule"); len(items) > 0 { 137 for _, item := range items { 138 if err := o.deleteForwardingRule(ctx, item, scope); err != nil { 139 return fmt.Errorf("error deleting pending forwarding rule %s: %w", item.name, err) 140 } 141 } 142 } 143 } 144 return nil 145 }