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 }