github.com/openshift/installer@v1.4.17/pkg/destroy/gcp/firewall.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) listFirewalls(ctx context.Context) ([]cloudResource, error) {
    15  	// The firewall rules that the destroyer is searching for here include a
    16  	// pattern before and after the cluster ID. Use a regular expression that allows
    17  	// wildcard values before and after the cluster ID.
    18  	filter := fmt.Sprintf("name eq .*%s.*", o.ClusterID)
    19  	return o.listFirewallsWithFilter(ctx, "items(name),nextPageToken", filter, nil)
    20  }
    21  
    22  // listFirewallsWithFilter lists firewall rules in the project that satisfy the filter criteria.
    23  // The fields parameter specifies which fields should be returned in the result, the filter string contains
    24  // a filter string passed to the API to filter results. The filterFunc is a client-side filtering function
    25  // that determines whether a particular result should be returned or not.
    26  func (o *ClusterUninstaller) listFirewallsWithFilter(ctx context.Context, fields string, filter string, filterFunc func(*compute.Firewall) bool) ([]cloudResource, error) {
    27  	o.Logger.Debugf("Listing firewall rules")
    28  	results := []cloudResource{}
    29  
    30  	findFirewallRules := func(projectID string) ([]cloudResource, error) {
    31  		ctx, cancel := context.WithTimeout(ctx, defaultTimeout)
    32  		defer cancel()
    33  		result := []cloudResource{}
    34  		req := o.computeSvc.Firewalls.List(projectID).Fields(googleapi.Field(fields))
    35  		if len(filter) > 0 {
    36  			req = req.Filter(filter)
    37  		}
    38  		err := req.Pages(ctx, func(list *compute.FirewallList) error {
    39  			for _, item := range list.Items {
    40  				if filterFunc == nil || filterFunc != nil && filterFunc(item) {
    41  					o.Logger.Debugf("Found firewall rule: %s", item.Name)
    42  					result = append(result, cloudResource{
    43  						key:      item.Name,
    44  						name:     item.Name,
    45  						project:  projectID,
    46  						typeName: "firewall",
    47  						quota: []gcp.QuotaUsage{{
    48  							Metric: &gcp.Metric{
    49  								Service: gcp.ServiceComputeEngineAPI,
    50  								Limit:   "firewalls",
    51  							},
    52  							Amount: 1,
    53  						}},
    54  					})
    55  				}
    56  			}
    57  			return nil
    58  		})
    59  
    60  		if err != nil {
    61  			return nil, errors.Wrapf(err, "failed to list firewall rules for project %s", projectID)
    62  		}
    63  		return result, nil
    64  	}
    65  
    66  	findResults, err := findFirewallRules(o.ProjectID)
    67  	if err != nil {
    68  		return results, err
    69  	}
    70  	results = append(results, findResults...)
    71  
    72  	if o.NetworkProjectID != "" {
    73  		o.Logger.Debugf("Listing firewall rules for network project %s", o.NetworkProjectID)
    74  		findResults, err := findFirewallRules(o.NetworkProjectID)
    75  		if err != nil {
    76  			return results, err
    77  		}
    78  		results = append(results, findResults...)
    79  	}
    80  
    81  	return results, nil
    82  }
    83  
    84  func (o *ClusterUninstaller) deleteFirewall(ctx context.Context, item cloudResource) error {
    85  	o.Logger.Debugf("Deleting firewall rule %s", item.name)
    86  	ctx, cancel := context.WithTimeout(ctx, defaultTimeout)
    87  	defer cancel()
    88  	op, err := o.computeSvc.Firewalls.Delete(item.project, item.name).RequestId(o.requestID(item.typeName, item.name)).Context(ctx).Do()
    89  	if err != nil && !isNoOp(err) {
    90  		o.resetRequestID(item.typeName, item.name)
    91  		return errors.Wrapf(err, "failed to delete firewall %s", item.name)
    92  	}
    93  	if op != nil && op.Status == "DONE" && isErrorStatus(op.HttpErrorStatusCode) {
    94  		o.resetRequestID(item.typeName, item.name)
    95  		return errors.Errorf("failed to delete firewall %s with error: %s", item.name, operationErrorMessage(op))
    96  	}
    97  	if (err != nil && isNoOp(err)) || (op != nil && op.Status == "DONE") {
    98  		o.resetRequestID(item.typeName, item.name)
    99  		o.deletePendingItems(item.typeName, []cloudResource{item})
   100  		o.Logger.Infof("Deleted firewall rule %s", item.name)
   101  	}
   102  	return nil
   103  }
   104  
   105  // destroyFirewalls removes all firewall resources that have a name prefixed
   106  // with the cluster's infra ID.
   107  func (o *ClusterUninstaller) destroyFirewalls(ctx context.Context) error {
   108  	found, err := o.listFirewalls(ctx)
   109  	if err != nil {
   110  		return err
   111  	}
   112  	items := o.insertPendingItems("firewall", found)
   113  	for _, item := range items {
   114  		err := o.deleteFirewall(ctx, item)
   115  		if err != nil {
   116  			o.errorTracker.suppressWarning(item.key, err, o.Logger)
   117  		}
   118  	}
   119  	if items = o.getPendingItems("firewall"); len(items) > 0 {
   120  		return errors.Errorf("%d items pending", len(items))
   121  	}
   122  	return nil
   123  }