Skip to content

Commit 59a8dc3

Browse files
committed
awsfetcher: update ec2, elb, rds fetchers
1 parent 5c9126e commit 59a8dc3

14 files changed

Lines changed: 155 additions & 67 deletions

internal/inventory/awsfetcher/fetcher_ec2_instance.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,9 @@ func (e *ec2InstanceFetcher) buildDetails(i *ec2.Ec2Instance, tags map[string]st
213213
if v := awslib.LookupTag(tags, "costcenter", "cost-center", "cost_center"); v != "" {
214214
details["CostCenter"] = v
215215
}
216+
if v := awslib.LookupTag(tags, "role"); v != "" {
217+
details["Role"] = v
218+
}
216219
return details
217220
}
218221

internal/inventory/awsfetcher/fetcher_ec2_instance_test.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ func makeTestInstance(launchTime *time.Time) *ec2beat.Ec2Instance {
5252
{Key: pointers.Ref("key"), Value: pointers.Ref("value")},
5353
{Key: pointers.Ref("Owner"), Value: pointers.Ref("team-infra")},
5454
{Key: pointers.Ref("CostCenter"), Value: pointers.Ref("cc-1234")},
55+
{Key: pointers.Ref("Role"), Value: pointers.Ref("sre")},
5556
},
5657
InstanceId: pointers.Ref("234567890"),
5758
Architecture: ec2types.ArchitectureValuesX8664,
@@ -104,7 +105,7 @@ func TestEC2InstanceFetcher_Fetch(t *testing.T) {
104105
"private-dns",
105106
inventory.WithRelatedAssetIds([]string{"234567890"}),
106107
inventory.WithRawAsset(instance1),
107-
inventory.WithLabels(map[string]string{"Name": "test-server", "key": "value", "Owner": "team-infra", "CostCenter": "cc-1234"}),
108+
inventory.WithLabels(map[string]string{"Name": "test-server", "key": "value", "Owner": "team-infra", "CostCenter": "cc-1234", "Role": "sre"}),
108109
inventory.WithCloud(inventory.Cloud{
109110
Provider: inventory.AwsCloudProvider,
110111
Region: "us-east",
@@ -134,6 +135,7 @@ func TestEC2InstanceFetcher_Fetch(t *testing.T) {
134135
"RoleArn": testRoleArn,
135136
"Owner": "team-infra",
136137
"CostCenter": "cc-1234",
138+
"Role": "sre",
137139
}),
138140
inventory.WithCreatedAt(&launchTime),
139141
inventory.WithUser(inventory.User{
@@ -193,7 +195,7 @@ func TestEC2InstanceFetcher_Fetch_ResolverError(t *testing.T) {
193195
"private-dns",
194196
inventory.WithRelatedAssetIds([]string{"234567890"}),
195197
inventory.WithRawAsset(instance),
196-
inventory.WithLabels(map[string]string{"Name": "test-server", "key": "value", "Owner": "team-infra", "CostCenter": "cc-1234"}),
198+
inventory.WithLabels(map[string]string{"Name": "test-server", "key": "value", "Owner": "team-infra", "CostCenter": "cc-1234", "Role": "sre"}),
197199
inventory.WithCloud(inventory.Cloud{
198200
Provider: inventory.AwsCloudProvider,
199201
Region: "us-east",
@@ -223,6 +225,7 @@ func TestEC2InstanceFetcher_Fetch_ResolverError(t *testing.T) {
223225
// RoleArn is absent because the resolver failed.
224226
"Owner": "team-infra",
225227
"CostCenter": "cc-1234",
228+
"Role": "sre",
226229
}),
227230
inventory.WithCreatedAt(&launchTime),
228231
// WithUser falls back to the profile ARN when role resolution fails.

internal/inventory/awsfetcher/fetcher_elb_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ func TestELBv1Fetcher_Fetch(t *testing.T) {
8484
"PubliclyAccessible": false, // scheme is "internal"
8585
"AccountID": "123",
8686
"LoadBalancerType": "classic",
87+
"State": "active",
8788
}),
8889
inventory.WithCreatedAt(asset.GetCreatedAt()),
8990
),

internal/inventory/awsfetcher/fetcher_rds.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ func (s *rdsFetcher) Fetch(ctx context.Context, assetChannel chan<- inventory.As
7979
if item.EngineVersion != "" {
8080
details["EngineVersion"] = item.EngineVersion
8181
}
82+
if item.Status != "" {
83+
details["DBInstanceStatus"] = item.Status
84+
}
8285

8386
assetChannel <- inventory.NewAssetEvent(
8487
inventory.AssetClassificationAwsRds,

internal/inventory/awsfetcher/fetcher_rds_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ func TestRDSInstanceFetcher_Fetch(t *testing.T) {
4444
PubliclyAccessible: false,
4545
Engine: "postgres",
4646
EngineVersion: "15.4",
47+
Status: "available",
4748
CreatedAt: &createdAt,
4849
Subnets: []rds.Subnet{
4950
{
@@ -68,6 +69,7 @@ func TestRDSInstanceFetcher_Fetch(t *testing.T) {
6869
PubliclyAccessible: true,
6970
Engine: "mysql",
7071
EngineVersion: "8.0.35",
72+
Status: "available",
7173
Subnets: []rds.Subnet{
7274
{
7375
ID: "subnet-aabbccdd",
@@ -107,6 +109,7 @@ func TestRDSInstanceFetcher_Fetch(t *testing.T) {
107109
"PubliclyAccessible": false,
108110
"Engine": "postgres",
109111
"EngineVersion": "15.4",
112+
"DBInstanceStatus": "available",
110113
}),
111114
inventory.WithCreatedAt(&createdAt),
112115
),
@@ -126,6 +129,7 @@ func TestRDSInstanceFetcher_Fetch(t *testing.T) {
126129
"PubliclyAccessible": true,
127130
"Engine": "mysql",
128131
"EngineVersion": "8.0.35",
132+
"DBInstanceStatus": "available",
129133
}),
130134
),
131135
}

internal/resources/providers/awslib/elb/elb.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package elb
1919

2020
import (
2121
"context"
22+
"net"
2223

2324
"github.com/aws/aws-sdk-go-v2/aws"
2425
elb "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancing"
@@ -28,6 +29,12 @@ import (
2829
"github.com/elastic/cloudbeat/internal/resources/providers/awslib"
2930
)
3031

32+
// hostResolver abstracts DNS resolution so that tests can inject a fake without hitting the
33+
// real network. *net.Resolver satisfies this interface.
34+
type hostResolver interface {
35+
LookupHost(ctx context.Context, host string) ([]string, error)
36+
}
37+
3138
type Client interface {
3239
elb.DescribeLoadBalancersAPIClient
3340
DescribeTags(ctx context.Context, params *elb.DescribeTagsInput, optFns ...func(*elb.Options)) (*elb.DescribeTagsOutput, error)
@@ -43,6 +50,7 @@ type Provider struct {
4350
client Client
4451
clients map[string]Client
4552
awsAccountID string
53+
resolver hostResolver
4654
}
4755

4856
func NewElbProvider(ctx context.Context, log *clog.Logger, awsAccountID string, cfg aws.Config, factory awslib.CrossRegionFactory[Client]) *Provider {
@@ -55,5 +63,6 @@ func NewElbProvider(ctx context.Context, log *clog.Logger, awsAccountID string,
5563
client: elb.NewFromConfig(cfg),
5664
clients: m.GetMultiRegionsClientMap(),
5765
awsAccountID: awsAccountID,
66+
resolver: net.DefaultResolver,
5867
}
5968
}

internal/resources/providers/awslib/elb/load_balancer.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ type ElasticLoadBalancerInfo struct {
3333
awsAccount string
3434
region string
3535
tags map[string]string
36+
ipAddresses []string
3637
}
3738

3839
func (v ElasticLoadBalancerInfo) GetResourceArn() string {
@@ -73,14 +74,17 @@ func (v ElasticLoadBalancerInfo) GetLoadBalancerType() string {
7374
return "classic"
7475
}
7576

76-
// GetState is not exposed for classic load balancers by the AWS SDK.
77+
// GetState returns "active" for classic load balancers. The classic ELB API does not expose
78+
// a state field, but any LB returned by DescribeLoadBalancers is live.
7779
func (v ElasticLoadBalancerInfo) GetState() string {
78-
return ""
80+
return "active"
7981
}
8082

81-
// GetIPAddresses is not exposed for classic load balancers (they are DNS-only).
83+
// GetIPAddresses returns the IP addresses resolved from the load balancer's DNS name.
84+
// Classic ELBs do not expose IPs directly via the AWS API; the addresses are resolved at
85+
// fetch time (see Provider.DescribeAllLoadBalancers) and stored here.
8286
func (v ElasticLoadBalancerInfo) GetIPAddresses() []string {
83-
return nil
87+
return v.ipAddresses
8488
}
8589

8690
// GetOwnerTag returns the value of the "Owner" tag (case-insensitive), if present.

internal/resources/providers/awslib/elb/provider.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ package elb
2020
import (
2121
"context"
2222
"fmt"
23+
"sort"
2324

2425
elb "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancing"
2526
"github.com/aws/aws-sdk-go-v2/service/elasticloadbalancing/types"
@@ -78,12 +79,21 @@ func (p *Provider) DescribeAllLoadBalancers(ctx context.Context) ([]awslib.AwsRe
7879

7980
var result []awslib.AwsResource
8081
for _, item := range all {
81-
result = append(result, &ElasticLoadBalancerInfo{
82+
info := &ElasticLoadBalancerInfo{
8283
LoadBalancer: item,
8384
awsAccount: p.awsAccountID,
8485
region: region,
8586
tags: tagsByName[pointers.Deref(item.LoadBalancerName)],
86-
})
87+
}
88+
if dnsName := pointers.Deref(item.DNSName); dnsName != "" {
89+
if ips, err := p.resolver.LookupHost(ctx, dnsName); err != nil {
90+
p.log.Debugf("Could not resolve IPs for classic ELB %q: %v", dnsName, err)
91+
} else {
92+
sort.Strings(ips)
93+
info.ipAddresses = ips
94+
}
95+
}
96+
result = append(result, info)
8797
}
8898
return result, nil
8999
})

0 commit comments

Comments
 (0)