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

     1  package gcp
     2  
     3  import (
     4  	"context"
     5  	"regexp"
     6  
     7  	"github.com/pkg/errors"
     8  	"google.golang.org/api/googleapi"
     9  	storage "google.golang.org/api/storage/v1"
    10  )
    11  
    12  var (
    13  	// multiDashes is a regexp matching multiple dashes in a sequence.
    14  	multiDashes = regexp.MustCompile(`-{2,}`)
    15  )
    16  
    17  func (o *ClusterUninstaller) listBuckets(ctx context.Context) ([]cloudResource, error) {
    18  	return o.listBucketsWithFilter(ctx, "items(name),nextPageToken", o.ClusterID+"-", nil)
    19  }
    20  
    21  // listBucketsWithFilter lists buckets in the project that satisfy the filter criteria.
    22  // The fields parameter specifies which fields should be returned in the result, the filter string contains
    23  // a prefix string passed to the API to filter results. The filterFunc is a client-side filtering function
    24  // that determines whether a particular result should be returned or not.
    25  func (o *ClusterUninstaller) listBucketsWithFilter(ctx context.Context, fields string, prefix string, filterFunc func(*storage.Bucket) bool) ([]cloudResource, error) {
    26  	o.Logger.Debug("Listing storage buckets")
    27  	ctx, cancel := context.WithTimeout(ctx, defaultTimeout)
    28  	defer cancel()
    29  	result := []cloudResource{}
    30  	req := o.storageSvc.Buckets.List(o.ProjectID).Fields(googleapi.Field(fields))
    31  	if len(prefix) > 0 {
    32  		prefix = multiDashes.ReplaceAllString(prefix, "-")
    33  		req = req.Prefix(prefix)
    34  	}
    35  	err := req.Pages(ctx, func(list *storage.Buckets) error {
    36  		for _, item := range list.Items {
    37  			if filterFunc == nil || filterFunc != nil && filterFunc(item) {
    38  				o.Logger.Debugf("Found bucket: %s", item.Name)
    39  				result = append(result, cloudResource{
    40  					key:      item.Name,
    41  					name:     item.Name,
    42  					typeName: "bucket",
    43  				})
    44  			}
    45  		}
    46  		return nil
    47  	})
    48  	if err != nil {
    49  		return nil, errors.Wrap(err, "failed to fetch object storage buckets")
    50  	}
    51  	return result, nil
    52  }
    53  
    54  func (o *ClusterUninstaller) deleteBucket(ctx context.Context, item cloudResource) error {
    55  	o.Logger.Debugf("Deleting storage bucket %s", item.name)
    56  	ctx, cancel := context.WithTimeout(ctx, defaultTimeout)
    57  	defer cancel()
    58  	err := o.storageSvc.Buckets.Delete(item.name).Context(ctx).Do()
    59  	if err != nil && !isNoOp(err) {
    60  		return errors.Wrapf(err, "failed to delete bucket %s", item.name)
    61  	}
    62  	o.deletePendingItems(item.typeName, []cloudResource{item})
    63  	o.Logger.Infof("Deleted bucket %s", item.name)
    64  	return nil
    65  }
    66  
    67  // destroyBuckets finds all gcs buckets that have a name prefixed
    68  // with the cluster's infra ID. It then removes all the objects in each bucket and deletes it.
    69  func (o *ClusterUninstaller) destroyBuckets(ctx context.Context) error {
    70  	found, err := o.listBuckets(ctx)
    71  	if err != nil {
    72  		return err
    73  	}
    74  	items := o.insertPendingItems("bucket", found)
    75  	for _, item := range items {
    76  		foundObjects, err := o.listBucketObjects(ctx, item)
    77  		if err != nil {
    78  			return err
    79  		}
    80  		objects := o.insertPendingItems("bucketobject", foundObjects)
    81  		for _, object := range objects {
    82  			err = o.deleteBucketObject(ctx, item, object)
    83  			if err != nil {
    84  				o.errorTracker.suppressWarning(object.key, err, o.Logger)
    85  			}
    86  		}
    87  		err = o.deleteBucket(ctx, item)
    88  		if err != nil {
    89  			o.errorTracker.suppressWarning(item.key, err, o.Logger)
    90  		}
    91  	}
    92  	if items = o.getPendingItems("bucket"); len(items) > 0 {
    93  		return errors.Errorf("%d items pending", len(items))
    94  	}
    95  	return nil
    96  }