Skip to content

Commit 601892a

Browse files
authored
⭐ ELB load balancer tags query and discovery for classic load balancers (#6672)
* elb tag and classic discovery * describe tags in batches of 20 * only get tags if filtered
1 parent 51341f3 commit 601892a

File tree

5 files changed

+133
-4
lines changed

5 files changed

+133
-4
lines changed

providers/aws/resources/aws.lr

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1659,6 +1659,8 @@ private aws.elb.loadbalancer @defaults("name region elbType scheme vpcId dnsName
16591659
elbType string
16601660
// VPC where the load balancer is located
16611661
vpc aws.vpc
1662+
// Tags on the load balancer
1663+
tags() map[string]string
16621664
// List of target groups for the load balancer
16631665
targetGroups() []aws.elb.targetgroup
16641666
}

providers/aws/resources/aws.lr.go

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

providers/aws/resources/aws.lr.versions

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,6 +1030,7 @@ aws.elb.loadbalancer.name 9.0.0
10301030
aws.elb.loadbalancer.region 11.0.4
10311031
aws.elb.loadbalancer.scheme 9.0.0
10321032
aws.elb.loadbalancer.securityGroups 11.0.3
1033+
aws.elb.loadbalancer.tags 11.12.3
10331034
aws.elb.loadbalancer.targetGroups 11.1.0
10341035
aws.elb.loadbalancer.vpc 11.0.4
10351036
aws.elb.loadbalancer.vpcId 9.0.8

providers/aws/resources/aws_elb.go

Lines changed: 97 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"github.com/aws/aws-sdk-go-v2/aws"
1313
"github.com/aws/aws-sdk-go-v2/aws/arn"
1414
"github.com/aws/aws-sdk-go-v2/service/elasticloadbalancing"
15+
elbv1types "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancing/types"
1516
"github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2"
1617
elbtypes "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2/types"
1718
"github.com/rs/zerolog/log"
@@ -69,14 +70,16 @@ func (a *mqlAwsElb) getClassicLoadBalancers(conn *connection.AwsConnection) []*j
6970
}
7071
return nil, err
7172
}
73+
7274
for _, lb := range lbs.LoadBalancerDescriptions {
7375
jsonListeners, err := convert.JsonToDictSlice(lb.ListenerDescriptions)
7476
if err != nil {
7577
return nil, err
7678
}
79+
lbName := convert.ToValue(lb.LoadBalancerName)
7780
mqlLb, err := CreateResource(a.MqlRuntime, ResourceAwsElbLoadbalancer,
7881
map[string]*llx.RawData{
79-
"arn": llx.StringData(fmt.Sprintf(elbv1LbArnPattern, region, conn.AccountId(), convert.ToValue(lb.LoadBalancerName))),
82+
"arn": llx.StringData(fmt.Sprintf(elbv1LbArnPattern, region, conn.AccountId(), lbName)),
8083
"createdTime": llx.TimeDataPtr(lb.CreatedTime),
8184
"createdAt": llx.TimeDataPtr(lb.CreatedTime),
8285
"dnsName": llx.StringDataPtr(lb.DNSName),
@@ -91,6 +94,18 @@ func (a *mqlAwsElb) getClassicLoadBalancers(conn *connection.AwsConnection) []*j
9194
return nil, err
9295
}
9396
res = append(res, mqlLb)
97+
// keeps the tags lazy unless the filters need to be evaluated
98+
if conn.Filters.General.HasTags() {
99+
tags, err := mqlLb.(*mqlAwsElbLoadbalancer).tags()
100+
if err != nil {
101+
return nil, err
102+
}
103+
if conn.Filters.General.IsFilteredOutByTags(mapStringInterfaceToStringString(tags)) {
104+
continue
105+
}
106+
}
107+
108+
res = append(res, mqlLb)
94109
}
95110
}
96111
return jobpool.JobResult(res), nil
@@ -147,6 +162,7 @@ func (a *mqlAwsElb) getLoadBalancers(conn *connection.AwsConnection) []*jobpool.
147162
}
148163
return nil, err
149164
}
165+
150166
for _, lb := range lbs.LoadBalancers {
151167
availabilityZones := []any{}
152168
for _, zone := range lb.AvailabilityZones {
@@ -198,6 +214,18 @@ func (a *mqlAwsElb) getLoadBalancers(conn *connection.AwsConnection) []*jobpool.
198214
return nil, err
199215
}
200216
res = append(res, mqlLb)
217+
// keeps the tags lazy unless the filters need to be evaluated
218+
if conn.Filters.General.HasTags() {
219+
tags, err := mqlLb.(*mqlAwsElbLoadbalancer).tags()
220+
if err != nil {
221+
return nil, err
222+
}
223+
if conn.Filters.General.IsFilteredOutByTags(mapStringInterfaceToStringString(tags)) {
224+
continue
225+
}
226+
}
227+
228+
res = append(res, mqlLb)
201229
}
202230
}
203231
return jobpool.JobResult(res), nil
@@ -229,18 +257,30 @@ func initAwsElbLoadbalancer(runtime *plugin.Runtime, args map[string]*llx.RawDat
229257
}
230258
elb := obj.(*mqlAwsElb)
231259

260+
arnVal := args["arn"].Value.(string)
261+
232262
rawResources := elb.GetLoadBalancers()
233263
if rawResources.Error != nil {
234264
return nil, nil, rawResources.Error
235265
}
236-
237-
arnVal := args["arn"].Value.(string)
238266
for _, rawResource := range rawResources.Data {
239267
lb := rawResource.(*mqlAwsElbLoadbalancer)
240268
if lb.Arn.Data == arnVal {
241269
return args, lb, nil
242270
}
243271
}
272+
273+
classicResources := elb.GetClassicLoadBalancers()
274+
if classicResources.Error != nil {
275+
return nil, nil, classicResources.Error
276+
}
277+
for _, rawResource := range classicResources.Data {
278+
lb := rawResource.(*mqlAwsElbLoadbalancer)
279+
if lb.Arn.Data == arnVal {
280+
return args, lb, nil
281+
}
282+
}
283+
244284
return nil, nil, errors.New("elb load balancer does not exist")
245285
}
246286

@@ -307,6 +347,60 @@ func isV1LoadBalancerArn(a string) bool {
307347
return false
308348
}
309349

350+
func elbv2TagsToMap(tags []elbtypes.Tag) map[string]any {
351+
tagsMap := make(map[string]any)
352+
for _, tag := range tags {
353+
tagsMap[convert.ToValue(tag.Key)] = convert.ToValue(tag.Value)
354+
}
355+
return tagsMap
356+
}
357+
358+
func elbv1TagsToMap(tags []elbv1types.Tag) map[string]any {
359+
tagsMap := make(map[string]any)
360+
for _, tag := range tags {
361+
tagsMap[convert.ToValue(tag.Key)] = convert.ToValue(tag.Value)
362+
}
363+
return tagsMap
364+
}
365+
366+
func (a *mqlAwsElbLoadbalancer) tags() (map[string]any, error) {
367+
conn := a.MqlRuntime.Connection.(*connection.AwsConnection)
368+
lbArn := a.Arn.Data
369+
name := a.Name.Data
370+
371+
region, err := GetRegionFromArn(lbArn)
372+
if err != nil {
373+
return nil, err
374+
}
375+
ctx := context.Background()
376+
377+
if isV1LoadBalancerArn(lbArn) {
378+
svc := conn.Elb(region)
379+
resp, err := svc.DescribeTags(ctx, &elasticloadbalancing.DescribeTagsInput{LoadBalancerNames: []string{name}})
380+
if err != nil {
381+
return nil, err
382+
}
383+
for _, desc := range resp.TagDescriptions {
384+
if convert.ToValue(desc.LoadBalancerName) == name {
385+
return elbv1TagsToMap(desc.Tags), nil
386+
}
387+
}
388+
return map[string]any{}, nil
389+
}
390+
391+
svc := conn.Elbv2(region)
392+
resp, err := svc.DescribeTags(ctx, &elasticloadbalancingv2.DescribeTagsInput{ResourceArns: []string{lbArn}})
393+
if err != nil {
394+
return nil, err
395+
}
396+
for _, desc := range resp.TagDescriptions {
397+
if convert.ToValue(desc.ResourceArn) == lbArn {
398+
return elbv2TagsToMap(desc.Tags), nil
399+
}
400+
}
401+
return map[string]any{}, nil
402+
}
403+
310404
func (a *mqlAwsElbTargetgroup) id() (string, error) {
311405
return a.Arn.Data, nil
312406
}

providers/aws/resources/discovery.go

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -883,15 +883,33 @@ func discover(runtime *plugin.Runtime, awsAccount *mqlAwsAccount, target string,
883883
region = p.Region
884884
}
885885
}
886+
tags := mapStringInterfaceToStringString(f.Tags.Data)
886887
m := mqlObject{
887-
name: f.Name.Data, labels: map[string]string{},
888+
name: f.Name.Data, labels: tags,
888889
awsObject: awsObject{
889890
account: accountId, region: region, arn: f.Arn.Data,
890891
id: f.Name.Data, service: "elb", objectType: "loadbalancer",
891892
},
892893
}
893894
assetList = append(assetList, MqlObjectToAsset(accountId, m, conn))
894895
}
896+
897+
classicLbs := e.GetClassicLoadBalancers()
898+
if classicLbs == nil {
899+
return assetList, nil
900+
}
901+
for i := range classicLbs.Data {
902+
f := classicLbs.Data[i].(*mqlAwsElbLoadbalancer)
903+
tags := mapStringInterfaceToStringString(f.Tags.Data)
904+
m := mqlObject{
905+
name: f.Name.Data, labels: tags,
906+
awsObject: awsObject{
907+
account: accountId, region: f.Region.Data, arn: f.Arn.Data,
908+
id: f.Name.Data, service: "elb", objectType: "loadbalancer",
909+
},
910+
}
911+
assetList = append(assetList, MqlObjectToAsset(accountId, m, conn))
912+
}
895913
case DiscoveryESDomains:
896914
res, err := NewResource(runtime, "aws.es", map[string]*llx.RawData{})
897915
if err != nil {

0 commit comments

Comments
 (0)