github.com/openshift/installer@v1.4.17/pkg/destroy/gcp/instancegroup.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) listInstanceGroups(ctx context.Context) ([]cloudResource, error) { 15 return o.listInstanceGroupsWithFilter(ctx, "items/*/instanceGroups(name,selfLink,zone),nextPageToken", o.clusterIDFilter(), nil) 16 } 17 18 // listInstanceGroupsWithFilter lists addresses in the project that satisfy the filter criteria. 19 // The fields parameter specifies which fields should be returned in the result, the filter string contains 20 // a filter string passed to the API to filter results. The filterFunc is a client-side filtering function 21 // that determines whether a particular result should be returned or not. 22 func (o *ClusterUninstaller) listInstanceGroupsWithFilter(ctx context.Context, fields string, filter string, filterFunc func(*compute.InstanceGroup) bool) ([]cloudResource, error) { 23 o.Logger.Debugf("Listing instance groups") 24 ctx, cancel := context.WithTimeout(ctx, defaultTimeout) 25 defer cancel() 26 result := []cloudResource{} 27 req := o.computeSvc.InstanceGroups.AggregatedList(o.ProjectID).Fields(googleapi.Field(fields)) 28 if len(filter) > 0 { 29 req = req.Filter(filter) 30 } 31 err := req.Pages(ctx, func(list *compute.InstanceGroupAggregatedList) error { 32 for _, scopedList := range list.Items { 33 for _, item := range scopedList.InstanceGroups { 34 if filterFunc == nil || filterFunc != nil && filterFunc(item) { 35 zoneName := o.getZoneName(item.Zone) 36 o.Logger.Debugf("Found instance group: %s in zone %s", item.Name, zoneName) 37 result = append(result, cloudResource{ 38 key: fmt.Sprintf("%s/%s", zoneName, item.Name), 39 name: item.Name, 40 typeName: "instancegroup", 41 zone: zoneName, 42 url: item.SelfLink, 43 quota: []gcp.QuotaUsage{{ 44 Metric: &gcp.Metric{ 45 Service: gcp.ServiceComputeEngineAPI, 46 Limit: "instance_groups", 47 Dimensions: map[string]string{ 48 "region": getRegionFromZone(zoneName), 49 }, 50 }, 51 Amount: 1, 52 }}, 53 }) 54 } 55 } 56 } 57 return nil 58 }) 59 if err != nil { 60 return nil, errors.Wrapf(err, "failed to fetch compute instance groups") 61 } 62 return result, nil 63 } 64 65 func (o *ClusterUninstaller) deleteInstanceGroup(ctx context.Context, item cloudResource) error { 66 o.Logger.Debugf("Deleting instance group %s in zone %s", item.name, item.zone) 67 ctx, cancel := context.WithTimeout(ctx, defaultTimeout) 68 defer cancel() 69 op, err := o.computeSvc.InstanceGroups.Delete(o.ProjectID, item.zone, item.name).RequestId(o.requestID(item.typeName, item.zone, item.name)).Context(ctx).Do() 70 if err != nil && !isNoOp(err) { 71 o.resetRequestID(item.typeName, item.zone, item.name) 72 return errors.Wrapf(err, "failed to delete instance group %s in zone %s", item.name, item.zone) 73 } 74 if op != nil && op.Status == "DONE" && isErrorStatus(op.HttpErrorStatusCode) { 75 o.resetRequestID("instancegroup", item.zone, item.name) 76 return errors.Errorf("failed to delete instance group %s in zone %s with error: %s", item.name, item.zone, operationErrorMessage(op)) 77 } 78 if (err != nil && isNoOp(err)) || (op != nil && op.Status == "DONE") { 79 o.resetRequestID(item.typeName, item.name) 80 o.deletePendingItems(item.typeName, []cloudResource{item}) 81 o.Logger.Infof("Deleted instance group %s", item.name) 82 } 83 return nil 84 } 85 86 // destroyInstanceGroups searches for instance groups that have a name prefixed 87 // with the cluster's infra ID, and then deletes each instance found. 88 func (o *ClusterUninstaller) destroyInstanceGroups(ctx context.Context) error { 89 found, err := o.listInstanceGroups(ctx) 90 if err != nil { 91 return err 92 } 93 items := o.insertPendingItems("instancegroup", found) 94 for _, item := range items { 95 err := o.deleteInstanceGroup(ctx, item) 96 if err != nil { 97 o.errorTracker.suppressWarning(item.key, err, o.Logger) 98 } 99 } 100 if items = o.getPendingItems("instancegroup"); len(items) > 0 { 101 return errors.Errorf("%d items pending", len(items)) 102 } 103 return nil 104 }