@@ -2,9 +2,12 @@ package elbv2
2
2
3
3
import (
4
4
"context"
5
+ "github.com/aws/aws-sdk-go-v2/aws"
5
6
awssdk "github.com/aws/aws-sdk-go/aws"
6
7
elbv2sdk "github.com/aws/aws-sdk-go/service/elbv2"
8
+ "github.com/aws/aws-sdk-go/service/resourcegroupstaggingapi"
7
9
"github.com/go-logr/logr"
10
+ "github.com/pkg/errors"
8
11
"k8s.io/apimachinery/pkg/util/sets"
9
12
"sigs.k8s.io/aws-load-balancer-controller/pkg/algorithm"
10
13
"sigs.k8s.io/aws-load-balancer-controller/pkg/aws/services"
@@ -93,26 +96,28 @@ type TaggingManager interface {
93
96
}
94
97
95
98
// NewDefaultTaggingManager constructs default TaggingManager.
96
- func NewDefaultTaggingManager (elbv2Client services.ELBV2 , vpcID string , featureGates config.FeatureGates , logger logr.Logger ) * defaultTaggingManager {
99
+ func NewDefaultTaggingManager (elbv2Client services.ELBV2 , vpcID string , featureGates config.FeatureGates , rgt services. RGT , logger logr.Logger ) * defaultTaggingManager {
97
100
return & defaultTaggingManager {
98
101
elbv2Client : elbv2Client ,
99
102
vpcID : vpcID ,
100
103
featureGates : featureGates ,
101
104
logger : logger ,
102
105
describeTagsChunkSize : defaultDescribeTagsChunkSize ,
106
+ rgt : rgt ,
103
107
}
104
108
}
105
109
106
110
var _ TaggingManager = & defaultTaggingManager {}
107
111
108
112
// default implementation for TaggingManager
109
- // @TODO: use AWS Resource Groups Tagging API to optimize this implementation once it have PrivateLink support.
113
+ // @TODO: deprecate ELB API and only use AWS Resource Groups Tagging API to optimize this implementation once RGT has PrivateLink support.
110
114
type defaultTaggingManager struct {
111
115
elbv2Client services.ELBV2
112
116
vpcID string
113
117
featureGates config.FeatureGates
114
118
logger logr.Logger
115
119
describeTagsChunkSize int
120
+ rgt services.RGT
116
121
}
117
122
118
123
func (m * defaultTaggingManager ) ReconcileTags (ctx context.Context , arn string , desiredTags map [string ]string , opts ... ReconcileTagsOption ) error {
@@ -123,7 +128,7 @@ func (m *defaultTaggingManager) ReconcileTags(ctx context.Context, arn string, d
123
128
reconcileOpts .ApplyOptions (opts )
124
129
currentTags := reconcileOpts .CurrentTags
125
130
if currentTags == nil {
126
- tagsByARN , err := m .describeResourceTags (ctx , []string {arn })
131
+ tagsByARN , err := m .describeResourceTagsNative (ctx , []string {arn })
127
132
if err != nil {
128
133
return err
129
134
}
@@ -188,7 +193,7 @@ func (m *defaultTaggingManager) ListListeners(ctx context.Context, lbARN string)
188
193
}
189
194
var tagsByARN map [string ]map [string ]string
190
195
if m .featureGates .Enabled (config .ListenerRulesTagging ) {
191
- tagsByARN , err = m .describeResourceTags (ctx , lsARNs )
196
+ tagsByARN , err = m .describeResourceTagsNative (ctx , lsARNs )
192
197
if err != nil {
193
198
return nil , err
194
199
}
@@ -221,7 +226,7 @@ func (m *defaultTaggingManager) ListListenerRules(ctx context.Context, lsARN str
221
226
}
222
227
var tagsByARN map [string ]map [string ]string
223
228
if m .featureGates .Enabled (config .ListenerRulesTagging ) {
224
- tagsByARN , err = m .describeResourceTags (ctx , lrARNs )
229
+ tagsByARN , err = m .describeResourceTagsNative (ctx , lrARNs )
225
230
if err != nil {
226
231
return nil , err
227
232
}
@@ -238,12 +243,64 @@ func (m *defaultTaggingManager) ListListenerRules(ctx context.Context, lsARN str
238
243
}
239
244
240
245
func (m * defaultTaggingManager ) ListLoadBalancers (ctx context.Context , tagFilters ... tracking.TagFilter ) ([]LoadBalancerWithTags , error ) {
246
+ if m .featureGates .Enabled (config .EnableRGTAPI ) {
247
+ return m .listLoadBalancersRGT (ctx , tagFilters )
248
+ }
249
+ return m .listLoadBalancersNative (ctx , tagFilters )
250
+ }
251
+
252
+ func (m * defaultTaggingManager ) ListTargetGroups (ctx context.Context , tagFilters ... tracking.TagFilter ) ([]TargetGroupWithTags , error ) {
253
+ if m .featureGates .Enabled (config .EnableRGTAPI ) {
254
+ return m .listTargetGroupsRGT (ctx , tagFilters )
255
+ }
256
+ return m .listTargetGroupsNative (ctx , tagFilters )
257
+
258
+ }
259
+
260
+ func (m * defaultTaggingManager ) listLoadBalancersRGT (ctx context.Context , tagFilters []tracking.TagFilter ) ([]LoadBalancerWithTags , error ) {
261
+ // use a map to avoid potential duplication in returned resources
262
+ resourceTagsByARN := make (map [string ][]* resourcegroupstaggingapi.Tag )
263
+ for _ , tagFilter := range tagFilters {
264
+ req := & resourcegroupstaggingapi.GetResourcesInput {
265
+ TagFilters : convertTagFiltersToRGTTagFilters (tagFilter ),
266
+ ResourceTypeFilters : aws .StringSlice ([]string {services .ResourceTypeELBLoadBalancer }),
267
+ }
268
+ resources , err := m .rgt .GetResourcesAsList (ctx , req )
269
+ if err != nil {
270
+ return nil , err
271
+ }
272
+ for _ , resource := range resources {
273
+ if _ , exists := resourceTagsByARN [aws .StringValue (resource .ResourceARN )]; ! exists {
274
+ resourceTagsByARN [aws .StringValue (resource .ResourceARN )] = resource .Tags
275
+ }
276
+ }
277
+ }
278
+ var matchedLBs []LoadBalancerWithTags
279
+ for resourceARN , resourceTags := range resourceTagsByARN {
280
+ elbv2Req := & elbv2sdk.DescribeLoadBalancersInput {
281
+ LoadBalancerArns : []* string {& resourceARN },
282
+ }
283
+ elbv2Resp , err := m .elbv2Client .DescribeLoadBalancersAsList (ctx , elbv2Req )
284
+ if err != nil {
285
+ return nil , err
286
+ }
287
+ if len (elbv2Resp ) == 0 {
288
+ return nil , errors .Errorf ("no load balancer found for the arn: %v" , resourceARN )
289
+ }
290
+ matchedLBs = append (matchedLBs , LoadBalancerWithTags {
291
+ LoadBalancer : elbv2Resp [0 ],
292
+ Tags : services .ParseRGTTags (resourceTags ),
293
+ })
294
+ }
295
+ return matchedLBs , nil
296
+ }
297
+
298
+ func (m * defaultTaggingManager ) listLoadBalancersNative (ctx context.Context , tagFilters []tracking.TagFilter ) ([]LoadBalancerWithTags , error ) {
241
299
req := & elbv2sdk.DescribeLoadBalancersInput {}
242
300
lbs , err := m .elbv2Client .DescribeLoadBalancersAsList (ctx , req )
243
301
if err != nil {
244
302
return nil , err
245
303
}
246
-
247
304
lbARNsWithinVPC := make ([]string , 0 , len (lbs ))
248
305
lbByARNWithinVPC := make (map [string ]* elbv2sdk.LoadBalancer , len (lbs ))
249
306
for _ , lb := range lbs {
@@ -254,7 +311,7 @@ func (m *defaultTaggingManager) ListLoadBalancers(ctx context.Context, tagFilter
254
311
lbARNsWithinVPC = append (lbARNsWithinVPC , lbARN )
255
312
lbByARNWithinVPC [lbARN ] = lb
256
313
}
257
- tagsByARN , err := m .describeResourceTags (ctx , lbARNsWithinVPC )
314
+ tagsByARN , err := m .describeResourceTagsNative (ctx , lbARNsWithinVPC )
258
315
if err != nil {
259
316
return nil , err
260
317
}
@@ -279,7 +336,45 @@ func (m *defaultTaggingManager) ListLoadBalancers(ctx context.Context, tagFilter
279
336
return matchedLBs , nil
280
337
}
281
338
282
- func (m * defaultTaggingManager ) ListTargetGroups (ctx context.Context , tagFilters ... tracking.TagFilter ) ([]TargetGroupWithTags , error ) {
339
+ func (m * defaultTaggingManager ) listTargetGroupsRGT (ctx context.Context , tagFilters []tracking.TagFilter ) ([]TargetGroupWithTags , error ) {
340
+ // use a map to avoid potential duplication in returned resources
341
+ resourceTagsByARN := make (map [string ][]* resourcegroupstaggingapi.Tag )
342
+ for _ , tagFilter := range tagFilters {
343
+ req := & resourcegroupstaggingapi.GetResourcesInput {
344
+ TagFilters : convertTagFiltersToRGTTagFilters (tagFilter ),
345
+ ResourceTypeFilters : aws .StringSlice ([]string {services .ResourceTypeELBTargetGroup }),
346
+ }
347
+ resources , err := m .rgt .GetResourcesAsList (ctx , req )
348
+ if err != nil {
349
+ return nil , err
350
+ }
351
+ for _ , resource := range resources {
352
+ if _ , exists := resourceTagsByARN [aws .StringValue (resource .ResourceARN )]; ! exists {
353
+ resourceTagsByARN [aws .StringValue (resource .ResourceARN )] = resource .Tags
354
+ }
355
+ }
356
+ }
357
+ var matchedTGs []TargetGroupWithTags
358
+ for resourceARN , resourceTags := range resourceTagsByARN {
359
+ elbv2Req := & elbv2sdk.DescribeTargetGroupsInput {
360
+ TargetGroupArns : []* string {& resourceARN },
361
+ }
362
+ elbv2Resp , err := m .elbv2Client .DescribeTargetGroupsAsList (ctx , elbv2Req )
363
+ if err != nil {
364
+ return nil , err
365
+ }
366
+ if len (elbv2Resp ) == 0 {
367
+ return nil , errors .Errorf ("no target group found for the arn: %v" , resourceARN )
368
+ }
369
+ matchedTGs = append (matchedTGs , TargetGroupWithTags {
370
+ TargetGroup : elbv2Resp [0 ],
371
+ Tags : services .ParseRGTTags (resourceTags ),
372
+ })
373
+ }
374
+ return matchedTGs , nil
375
+ }
376
+
377
+ func (m * defaultTaggingManager ) listTargetGroupsNative (ctx context.Context , tagFilters []tracking.TagFilter ) ([]TargetGroupWithTags , error ) {
283
378
req := & elbv2sdk.DescribeTargetGroupsInput {}
284
379
tgs , err := m .elbv2Client .DescribeTargetGroupsAsList (ctx , req )
285
380
if err != nil {
@@ -296,7 +391,7 @@ func (m *defaultTaggingManager) ListTargetGroups(ctx context.Context, tagFilters
296
391
tgARNsWithinVPC = append (tgARNsWithinVPC , tgARN )
297
392
tgByARNWithinVPC [tgARN ] = tg
298
393
}
299
- tagsByARN , err := m .describeResourceTags (ctx , tgARNsWithinVPC )
394
+ tagsByARN , err := m .describeResourceTagsNative (ctx , tgARNsWithinVPC )
300
395
if err != nil {
301
396
return nil , err
302
397
}
@@ -321,9 +416,9 @@ func (m *defaultTaggingManager) ListTargetGroups(ctx context.Context, tagFilters
321
416
return matchedTGs , nil
322
417
}
323
418
324
- // describeResourceTags describes tags for elbv2 resources.
419
+ // describeResourceTagsNative describes tags for elbv2 resources.
325
420
// returns tags indexed by resource ARN.
326
- func (m * defaultTaggingManager ) describeResourceTags (ctx context.Context , arns []string ) (map [string ]map [string ]string , error ) {
421
+ func (m * defaultTaggingManager ) describeResourceTagsNative (ctx context.Context , arns []string ) (map [string ]map [string ]string , error ) {
327
422
tagsByARN := make (map [string ]map [string ]string , len (arns ))
328
423
arnsChunks := algorithm .ChunkStrings (arns , m .describeTagsChunkSize )
329
424
for _ , arnsChunk := range arnsChunks {
@@ -365,3 +460,15 @@ func convertSDKTagsToTags(sdkTags []*elbv2sdk.Tag) map[string]string {
365
460
}
366
461
return tags
367
462
}
463
+
464
+ // convert tagFilters to RGTTagFilters
465
+ func convertTagFiltersToRGTTagFilters (tagFilter tracking.TagFilter ) []* resourcegroupstaggingapi.TagFilter {
466
+ var RGTTagFilters []* resourcegroupstaggingapi.TagFilter
467
+ for k , v := range tagFilter {
468
+ RGTTagFilters = append (RGTTagFilters , & resourcegroupstaggingapi.TagFilter {
469
+ Key : aws .String (k ),
470
+ Values : aws .StringSlice (v ),
471
+ })
472
+ }
473
+ return RGTTagFilters
474
+ }
0 commit comments