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  }