diff --git a/api/v1/aws.go b/api/v1/aws.go index b9f5b1a9..9000386b 100644 --- a/api/v1/aws.go +++ b/api/v1/aws.go @@ -60,6 +60,7 @@ const ( AWSEC2Subnet = "AWS::EC2::Subnet" AWSAccount = "AWS::::Account" AWSAvailabilityZone = "AWS::AvailabilityZone" + AWSAvailabilityZoneID = "AWS::AvailabilityZoneID" AWSEC2SecurityGroup = "AWS::EC2::SecurityGroup" AWSIAMUser = "AWS::IAM::User" AWSIAMRole = "AWS::IAM::Role" diff --git a/scrapers/aws/aws.go b/scrapers/aws/aws.go index 6e5ecf3f..fefd53ae 100644 --- a/scrapers/aws/aws.go +++ b/scrapers/aws/aws.go @@ -315,18 +315,47 @@ func (aws Scraper) account(ctx *AWSContext, config v1.AWS, results *v1.ScrapeRes return } + var uniqueAvailabilityZoneIDs = map[string]struct{}{} for _, az := range azDescribeOutput.AvailabilityZones { *results = append(*results, v1.ScrapeResult{ - ID: lo.FromPtr(az.ZoneId), + ID: lo.FromPtr(az.ZoneName), Type: v1.AWSAvailabilityZone, BaseScraper: config.BaseScraper, Config: az, ConfigClass: "AvailabilityZone", - Aliases: []string{lo.FromPtr(az.ZoneName)}, + Aliases: nil, Name: lo.FromPtr(az.ZoneName), - ParentExternalID: lo.FromPtr(az.RegionName), - ParentType: v1.AWSRegion, + ParentExternalID: lo.FromPtr(ctx.Caller.Account), + ParentType: v1.AWSAccount, + RelationshipResults: []v1.RelationshipResult{ + { + ConfigExternalID: v1.ExternalID{ConfigType: v1.AWSAvailabilityZone, ExternalID: []string{lo.FromPtr(az.ZoneName)}}, + RelatedExternalID: v1.ExternalID{ConfigType: v1.AWSAvailabilityZoneID, ExternalID: []string{lo.FromPtr(az.ZoneId)}}, + Relationship: "AvailabilityZoneIDAvailabilityZone", + }, + { + ConfigExternalID: v1.ExternalID{ConfigType: v1.AWSAvailabilityZone, ExternalID: []string{lo.FromPtr(az.ZoneName)}}, + RelatedExternalID: v1.ExternalID{ConfigType: v1.AWSRegion, ExternalID: []string{lo.FromPtr(az.RegionName)}}, + Relationship: "RegionAvailabilityZone", + }, + }, }) + + if _, ok := uniqueAvailabilityZoneIDs[lo.FromPtr(az.ZoneId)]; !ok { + *results = append(*results, v1.ScrapeResult{ + ID: lo.FromPtr(az.ZoneId), + Type: v1.AWSAvailabilityZoneID, + BaseScraper: config.BaseScraper, + Config: map[string]string{"RegionName": *az.RegionName}, + ConfigClass: "AvailabilityZone", + Aliases: nil, + Name: lo.FromPtr(az.ZoneId), + ParentExternalID: lo.FromPtr(az.RegionName), + ParentType: v1.AWSRegion, + }) + + uniqueAvailabilityZoneIDs[lo.FromPtr(az.ZoneId)] = struct{}{} + } } } @@ -965,6 +994,13 @@ func (aws Scraper) subnets(ctx *AWSContext, config v1.AWS, results *v1.ScrapeRes Relationship: "AvailabilityZoneSubnet", }) + // Subnet to availability zone relationship + relationships = append(relationships, v1.RelationshipResult{ + RelatedExternalID: selfExternalID, + ConfigExternalID: v1.ExternalID{ExternalID: []string{lo.FromPtr(subnet.AvailabilityZoneId)}, ConfigType: v1.AWSAvailabilityZoneID}, + Relationship: "AvailabilityZoneIDSubnet", + }) + result := v1.ScrapeResult{ Type: v1.AWSEC2Subnet, BaseScraper: config.BaseScraper,