Skip to content

Commit 1f8723e

Browse files
🐛 Fix ELB classic load balancer field alignment and filtering (#6679)
* align fields and fix errors * add tag filter example
1 parent 30737c3 commit 1f8723e

File tree

3 files changed

+77
-29
lines changed

3 files changed

+77
-29
lines changed

providers/aws/config/config.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ Notes:
132132
Long: "filters",
133133
Type: plugin.FlagType_KeyValue,
134134
Default: "",
135-
Desc: "Filter options, e.g., --filters regions=us-east-2,us-east-1 , --filters ec2:instance-ids=i-093439483935",
135+
Desc: "Filter options, e.g., --filters regions=us-east-2,us-east-1 --filters ec2:instance-ids=i-093439483935 --filters tag:Environment=production --filters tag:Team=platform --filters exclude:tag:Environment=dev",
136136
},
137137
},
138138
},

providers/aws/resources/aws_elb.go

Lines changed: 75 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -77,23 +77,61 @@ func (a *mqlAwsElb) getClassicLoadBalancers(conn *connection.AwsConnection) []*j
7777
return nil, err
7878
}
7979
lbName := convert.ToValue(lb.LoadBalancerName)
80-
mqlLb, err := CreateResource(a.MqlRuntime, ResourceAwsElbLoadbalancer,
81-
map[string]*llx.RawData{
82-
"arn": llx.StringData(fmt.Sprintf(elbv1LbArnPattern, region, conn.AccountId(), lbName)),
83-
"createdTime": llx.TimeDataPtr(lb.CreatedTime),
84-
"createdAt": llx.TimeDataPtr(lb.CreatedTime),
85-
"dnsName": llx.StringDataPtr(lb.DNSName),
86-
"elbType": llx.StringData("classic"),
87-
"listenerDescriptions": llx.AnyData(jsonListeners),
88-
"name": llx.StringDataPtr(lb.LoadBalancerName),
89-
"region": llx.StringData(region),
90-
"scheme": llx.StringDataPtr(lb.Scheme),
91-
"vpcId": llx.StringDataPtr(lb.VPCId),
92-
})
80+
81+
availabilityZones := []any{}
82+
for _, zone := range lb.AvailabilityZones {
83+
availabilityZones = append(availabilityZones, zone)
84+
}
85+
86+
sgs := []any{}
87+
for _, sg := range lb.SecurityGroups {
88+
mqlSg, err := NewResource(a.MqlRuntime, ResourceAwsEc2Securitygroup,
89+
map[string]*llx.RawData{
90+
"arn": llx.StringData(fmt.Sprintf(securityGroupArnPattern, region, conn.AccountId(), sg)),
91+
})
92+
if err != nil {
93+
// When tag filters are active, the security group may not be in the
94+
// filtered list. Log and continue rather than failing the entire LB.
95+
log.Debug().Str("sg", sg).Err(err).Msg("could not resolve security group for classic ELB")
96+
continue
97+
}
98+
sgs = append(sgs, mqlSg)
99+
}
100+
101+
args := map[string]*llx.RawData{
102+
"arn": llx.StringData(fmt.Sprintf(elbv1LbArnPattern, region, conn.AccountId(), lbName)),
103+
"availabilityZones": llx.ArrayData(availabilityZones, types.String),
104+
"createdTime": llx.TimeDataPtr(lb.CreatedTime),
105+
"createdAt": llx.TimeDataPtr(lb.CreatedTime),
106+
"dnsName": llx.StringDataPtr(lb.DNSName),
107+
"elbType": llx.StringData("classic"),
108+
"hostedZoneId": llx.StringDataPtr(lb.CanonicalHostedZoneNameID),
109+
"listenerDescriptions": llx.AnyData(jsonListeners),
110+
"name": llx.StringDataPtr(lb.LoadBalancerName),
111+
"region": llx.StringData(region),
112+
"scheme": llx.StringDataPtr(lb.Scheme),
113+
"securityGroups": llx.ArrayData(sgs, types.Resource(ResourceAwsEc2Securitygroup)),
114+
"vpcId": llx.StringDataPtr(lb.VPCId),
115+
"vpc": llx.NilData,
116+
}
117+
118+
if lb.VPCId != nil {
119+
mqlVpc, err := NewResource(a.MqlRuntime, ResourceAwsVpc,
120+
map[string]*llx.RawData{
121+
"arn": llx.StringData(fmt.Sprintf(vpcArnPattern, region, conn.AccountId(), convert.ToValue(lb.VPCId))),
122+
})
123+
if err != nil {
124+
// When tag filters are active, the VPC may not be in the filtered list.
125+
log.Debug().Str("vpcId", convert.ToValue(lb.VPCId)).Err(err).Msg("could not resolve VPC for classic ELB")
126+
} else {
127+
args["vpc"] = llx.ResourceData(mqlVpc, mqlVpc.MqlName())
128+
}
129+
}
130+
131+
mqlLb, err := CreateResource(a.MqlRuntime, ResourceAwsElbLoadbalancer, args)
93132
if err != nil {
94133
return nil, err
95134
}
96-
res = append(res, mqlLb)
97135
// keeps the tags lazy unless the filters need to be evaluated
98136
if conn.Filters.General.HasTags() {
99137
tags, err := mqlLb.(*mqlAwsElbLoadbalancer).tags()
@@ -176,7 +214,10 @@ func (a *mqlAwsElb) getLoadBalancers(conn *connection.AwsConnection) []*jobpool.
176214
"arn": llx.StringData(fmt.Sprintf(securityGroupArnPattern, region, conn.AccountId(), sg)),
177215
})
178216
if err != nil {
179-
return nil, err
217+
// When tag filters are active, the security group may not be in the
218+
// filtered list. Log and continue rather than failing the entire LB.
219+
log.Debug().Str("sg", sg).Err(err).Msg("could not resolve security group for ELB")
220+
continue
180221
}
181222
sgs = append(sgs, mqlSg)
182223
}
@@ -203,17 +244,18 @@ func (a *mqlAwsElb) getLoadBalancers(conn *connection.AwsConnection) []*jobpool.
203244
"arn": llx.StringData(fmt.Sprintf(vpcArnPattern, region, conn.AccountId(), convert.ToValue(lb.VpcId))),
204245
})
205246
if err != nil {
206-
return nil, err
247+
// When tag filters are active, the VPC may not be in the filtered list.
248+
log.Debug().Str("vpcId", convert.ToValue(lb.VpcId)).Err(err).Msg("could not resolve VPC for ELB")
249+
} else {
250+
// update the vpc setting
251+
args["vpc"] = llx.ResourceData(mqlVpc, mqlVpc.MqlName())
207252
}
208-
// update the vpc setting
209-
args["vpc"] = llx.ResourceData(mqlVpc, mqlVpc.MqlName())
210253
}
211254

212255
mqlLb, err := CreateResource(a.MqlRuntime, ResourceAwsElbLoadbalancer, args)
213256
if err != nil {
214257
return nil, err
215258
}
216-
res = append(res, mqlLb)
217259
// keeps the tags lazy unless the filters need to be evaluated
218260
if conn.Filters.General.HasTags() {
219261
tags, err := mqlLb.(*mqlAwsElbLoadbalancer).tags()
@@ -251,14 +293,21 @@ func initAwsElbLoadbalancer(runtime *plugin.Runtime, args map[string]*llx.RawDat
251293
return nil, nil, errors.New("arn required to fetch elb loadbalancer")
252294
}
253295

296+
arnVal := args["arn"].Value.(string)
297+
298+
// Quick check: if the ARN doesn't belong to elasticloadbalancing, this asset
299+
// is not an ELB. This happens when the query runs against non-ELB discovered
300+
// assets (e.g., DynamoDB tables, IAM users, S3 buckets).
301+
if arnVal == "" || !strings.Contains(arnVal, ":elasticloadbalancing:") {
302+
return nil, nil, errors.New("elb load balancer does not exist")
303+
}
304+
254305
obj, err := CreateResource(runtime, ResourceAwsElb, map[string]*llx.RawData{})
255306
if err != nil {
256307
return nil, nil, err
257308
}
258309
elb := obj.(*mqlAwsElb)
259310

260-
arnVal := args["arn"].Value.(string)
261-
262311
rawResources := elb.GetLoadBalancers()
263312
if rawResources.Error != nil {
264313
return nil, nil, rawResources.Error
@@ -406,6 +455,11 @@ func (a *mqlAwsElbTargetgroup) id() (string, error) {
406455
}
407456

408457
func (a *mqlAwsElbLoadbalancer) targetGroups() ([]any, error) {
458+
// Classic load balancers don't have target groups
459+
if isV1LoadBalancerArn(a.Arn.Data) {
460+
return []any{}, nil
461+
}
462+
409463
conn := a.MqlRuntime.Connection.(*connection.AwsConnection)
410464

411465
regionVal := a.Region.Data

providers/aws/resources/discovery.go

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -877,17 +877,11 @@ func discover(runtime *plugin.Runtime, awsAccount *mqlAwsAccount, target string,
877877

878878
for i := range lbs.Data {
879879
f := lbs.Data[i].(*mqlAwsElbLoadbalancer)
880-
var region string
881-
if arn.IsARN(f.Arn.Data) {
882-
if p, err := arn.Parse(f.Arn.Data); err == nil {
883-
region = p.Region
884-
}
885-
}
886880
tags := mapStringInterfaceToStringString(f.Tags.Data)
887881
m := mqlObject{
888882
name: f.Name.Data, labels: tags,
889883
awsObject: awsObject{
890-
account: accountId, region: region, arn: f.Arn.Data,
884+
account: accountId, region: f.Region.Data, arn: f.Arn.Data,
891885
id: f.Name.Data, service: "elb", objectType: "loadbalancer",
892886
},
893887
}

0 commit comments

Comments
 (0)