@@ -2,77 +2,113 @@ package gcp
22
33import (
44 "context"
5+ "fmt"
56
6- "github.com/pkg/errors "
7+ "github.com/sirupsen/logrus "
78 "google.golang.org/api/compute/v1"
89 "google.golang.org/api/googleapi"
910
1011 "github.com/openshift/installer/pkg/types/gcp"
1112)
1213
13- func (o * ClusterUninstaller ) listForwardingRules (ctx context.Context ) ([]cloudResource , error ) {
14- return o .listForwardingRulesWithFilter (ctx , "items(name,region,loadBalancingScheme),nextPageToken" , o .clusterIDFilter (), nil )
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
1547}
1648
1749// listForwardingRulesWithFilter lists forwarding rules in the project that satisfy the filter criteria.
1850// The fields parameter specifies which fields should be returned in the result, the filter string contains
1951// a filter string passed to the API to filter results. The filterFunc is a client-side filtering function
2052// that determines whether a particular result should be returned or not.
21- func (o * ClusterUninstaller ) listForwardingRulesWithFilter (ctx context.Context , fields string , filter string , filterFunc func (* compute.ForwardingRule ) bool ) ([]cloudResource , error ) {
22- o .Logger .Debugf ("Listing forwarding rules" )
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 )
2355 ctx , cancel := context .WithTimeout (ctx , defaultTimeout )
2456 defer cancel ()
57+
2558 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
2677 req := o .computeSvc .ForwardingRules .List (o .ProjectID , o .Region ).Fields (googleapi .Field (fields ))
2778 if len (filter ) > 0 {
2879 req = req .Filter (filter )
2980 }
3081 err := req .Pages (ctx , func (list * compute.ForwardingRuleList ) error {
31- for _ , item := range list .Items {
32- if filterFunc == nil || filterFunc != nil && filterFunc (item ) {
33- o .Logger .Debugf ("Found forwarding rule: %s" , item .Name )
34- var quota []gcp.QuotaUsage
35- switch item .LoadBalancingScheme {
36- case "EXTERNAL" :
37- quota = []gcp.QuotaUsage {{
38- Metric : & gcp.Metric {
39- Service : gcp .ServiceComputeEngineAPI ,
40- Limit : "external_network_lb_forwarding_rules" ,
41- Dimensions : map [string ]string {
42- "region" : getNameFromURL ("regions" , item .Region ),
43- },
44- },
45- Amount : 1 ,
46- }}
47- }
48- result = append (result , cloudResource {
49- key : item .Name ,
50- name : item .Name ,
51- typeName : "forwardingrule" ,
52- quota : quota ,
53- })
54- }
55- }
82+ result = append (result , createForwardingRuleResources (filterFunc , list )... )
5683 return nil
5784 })
85+
5886 if err != nil {
59- return nil , errors . Wrapf ( err , "failed to list forwarding rules" )
87+ return nil , fmt . Errorf ( "failed to list regional forwarding rules: %w" , err )
6088 }
6189 return result , nil
6290}
6391
64- func (o * ClusterUninstaller ) deleteForwardingRule (ctx context.Context , item cloudResource ) error {
92+ func (o * ClusterUninstaller ) deleteForwardingRule (ctx context.Context , item cloudResource , scope resourceScope ) error {
6593 o .Logger .Debugf ("Deleting forwarding rule %s" , item .name )
6694 ctx , cancel := context .WithTimeout (ctx , defaultTimeout )
6795 defer cancel ()
68- op , err := o .computeSvc .ForwardingRules .Delete (o .ProjectID , o .Region , item .name ).RequestId (o .requestID (item .typeName , item .name )).Context (ctx ).Do ()
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+
69105 if err != nil && ! isNoOp (err ) {
70106 o .resetRequestID (item .typeName , item .name )
71- return errors . Wrapf ( err , "failed to delete forwarding rule %s" , item .name )
107+ return fmt . Errorf ( "failed to delete forwarding rule %s: %w " , item .name , err )
72108 }
73109 if op != nil && op .Status == "DONE" && isErrorStatus (op .HttpErrorStatusCode ) {
74110 o .resetRequestID (item .typeName , item .name )
75- return errors .Errorf ("failed to delete forwarding rule %s with error: %s" , item .name , operationErrorMessage (op ))
111+ return fmt .Errorf ("failed to delete forwarding rule %s with error: %s: %w " , item .name , operationErrorMessage (op ), err )
76112 }
77113 if (err != nil && isNoOp (err )) || (op != nil && op .Status == "DONE" ) {
78114 o .resetRequestID (item .typeName , item .name )
@@ -85,19 +121,21 @@ func (o *ClusterUninstaller) deleteForwardingRule(ctx context.Context, item clou
85121// destroyForwardingRules removes all forwarding rules with a name prefixed
86122// with the cluster's infra ID.
87123func (o * ClusterUninstaller ) destroyForwardingRules (ctx context.Context ) error {
88- found , err := o .listForwardingRules (ctx )
89- if err != nil {
90- return err
91- }
92- items := o .insertPendingItems ("forwardingrule" , found )
93- for _ , item := range items {
94- err := o .deleteForwardingRule (ctx , item )
124+ for _ , scope := range []resourceScope {gcpGlobalResource , gcpRegionalResource } {
125+ found , err := o .listForwardingRules (ctx , scope )
95126 if err != nil {
96- o .errorTracker .suppressWarning (item .key , err , o .Logger )
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+ return fmt .Errorf ("%d items pending" , len (items ))
97138 }
98- }
99- if items = o .getPendingItems ("forwardingrule" ); len (items ) > 0 {
100- return errors .Errorf ("%d items pending" , len (items ))
101139 }
102140 return nil
103141}
0 commit comments