Files
cloudfox/aws/inventory.go
Seth Art 11652a9a6e Fix service slug mismatches for awsservicemap v1.1.0 across all commands
awsservicemap v1.1.0 switched to URL-based service slugs, breaking all
commands that used the old identifiers. Affected slugs and their fixes:

  secretsmanager  -> secrets-manager   (resource-trusts, inventory)
  ssm             -> systems-manager   (inventory)
  elb             -> elasticloadbalancing (endpoints, inventory, network-ports)
  es              -> opensearch-service   (endpoints, inventory, resource-trusts)
  mq              -> amazon-mq            (endpoints, inventory)
  stepfunctions   -> step-functions       (inventory)
  sagemaker       -> sagemaker-ai         (env-vars)
  clouddirectory  -> directoryservice     (directory-services)
  kinesis         -> streams              (inventory)
  lightsail       -> amazonlightsail.com  (endpoints, env-vars, network-ports)

Each mismatch caused IsServiceInRegion to return false for all regions,
silently skipping enumeration of that service entirely.
2026-04-11 11:40:48 -04:00

3239 lines
97 KiB
Go

package aws
import (
"fmt"
"os"
"path/filepath"
"sort"
"strconv"
"sync"
"github.com/BishopFox/cloudfox/aws/sdk"
"github.com/BishopFox/cloudfox/internal"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/apigateway"
"github.com/aws/aws-sdk-go-v2/service/apigatewayv2"
"github.com/aws/aws-sdk-go-v2/service/apprunner"
"github.com/aws/aws-sdk-go-v2/service/athena"
"github.com/aws/aws-sdk-go-v2/service/cloud9"
"github.com/aws/aws-sdk-go-v2/service/cloudformation"
"github.com/aws/aws-sdk-go-v2/service/cloudfront"
"github.com/aws/aws-sdk-go-v2/service/dynamodb"
"github.com/aws/aws-sdk-go-v2/service/ec2"
"github.com/aws/aws-sdk-go-v2/service/ecs"
"github.com/aws/aws-sdk-go-v2/service/elasticloadbalancing"
"github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2"
"github.com/aws/aws-sdk-go-v2/service/grafana"
"github.com/aws/aws-sdk-go-v2/service/iam"
"github.com/aws/aws-sdk-go-v2/service/lambda"
"github.com/aws/aws-sdk-go-v2/service/lightsail"
"github.com/aws/aws-sdk-go-v2/service/mq"
"github.com/aws/aws-sdk-go-v2/service/opensearch"
"github.com/aws/aws-sdk-go-v2/service/rds"
"github.com/aws/aws-sdk-go-v2/service/s3"
"github.com/aws/aws-sdk-go-v2/service/secretsmanager"
"github.com/aws/aws-sdk-go-v2/service/sns"
"github.com/aws/aws-sdk-go-v2/service/sqs"
"github.com/aws/aws-sdk-go-v2/service/ssm"
"github.com/aws/aws-sdk-go-v2/service/sts"
"github.com/bishopfox/awsservicemap"
"github.com/sirupsen/logrus"
)
type Inventory2Module struct {
// General configuration data
APIGatewayClient *apigateway.Client
APIGatewayv2Client *apigatewayv2.Client
AppRunnerClient *apprunner.Client
AthenaClient *athena.Client
Cloud9Client *cloud9.Client
CloudFormationClient *cloudformation.Client
CloudfrontClient *cloudfront.Client
CodeArtifactClient sdk.AWSCodeArtifactClientInterface
CodeBuildClient sdk.CodeBuildClientInterface
CodeCommitClient sdk.AWSCodeCommitClientInterface
CodeDeployClient sdk.AWSCodeDeployClientInterface
DataPipelineClient sdk.AWSDataPipelineClientInterface
DynamoDBClient *dynamodb.Client
EC2Client *ec2.Client
ECRClient sdk.AWSECRClientInterface
ECSClient *ecs.Client
EKSClient sdk.EKSClientInterface
ELBClient *elasticloadbalancing.Client
ELBv2Client *elasticloadbalancingv2.Client
ElasticacheClient sdk.AWSElastiCacheClientInterface
ElasticBeanstalkClient sdk.AWSElasticBeanstalkClientInterface
EMRClient sdk.AWSEMRClientInterface
GrafanaClient *grafana.Client
GlueClient sdk.AWSGlueClientInterface
KinesisClient sdk.AWSKinesisClientInterface
IAMClient *iam.Client
LambdaClient *lambda.Client
LightsailClient *lightsail.Client
MQClient *mq.Client
OpenSearchClient *opensearch.Client
RDSClient *rds.Client
RedshiftClient sdk.AWSRedShiftClientInterface
Route53Client sdk.AWSRoute53ClientInterface
S3Client *s3.Client
SQSClient *sqs.Client
SSMClient *ssm.Client
SNSClient *sns.Client
SecretsManagerClient *secretsmanager.Client
StepFunctionClient sdk.StepFunctionsClientInterface
Caller sts.GetCallerIdentityOutput
AWSRegions []string
AWSOutputType string
AWSTableCols string
Goroutines int
AWSProfile string
WrapTable bool
ServiceMap *awsservicemap.AwsServiceMap // Shared service map to avoid repeated HTTP requests
// Main module data
RegionResourceCount int
CommandCounter internal.CommandCounter
GlobalResourceCounts []GlobalResourceCount2
serviceMap map[string]map[string]int
services []string
totalRegionCounts map[string]int
mu sync.Mutex
resources []string
// Used to store output data for pretty printing
output internal.OutputData2
globalOutput internal.OutputData2
modLog *logrus.Entry
}
type GlobalResourceCount2 struct {
resourceType string
count int
}
func (m *Inventory2Module) PrintInventoryPerRegion(outputDirectory string, verbosity int) {
// These struct values are used by the output module
m.output.Verbosity = verbosity
m.output.Directory = outputDirectory
m.output.CallingModule = "inventory"
m.modLog = internal.TxtLog.WithFields(logrus.Fields{
"module": "inventory",
},
)
m.services = []string{
"total",
"APIGateway RestAPIs",
"APIGatewayv2 APIs",
"Athena Databases",
//"Athena Data Catalogs",
"AppRunner Services",
"Cloud9 Environments",
"CloudFormation Stacks",
"Cloudfront Distributions",
"CodeArtifact Repositories",
"CodeArtifact Domains",
"CodeBuild Projects",
"CodeCommit Repositories",
"CodeDeploy Applications",
"CodeDeploy Deployments",
"DataPipeline Pipelines",
"DynamoDB Tables",
"EC2 Instances",
"EC2 AMIs",
"EC2 Volumes",
"EC2 Snapshots",
"ECS Clusters",
"ECS Tasks",
"ECS Services",
"ECR Repositories",
"EKS Clusters",
"EKS Cluster NodeGroups",
"Elasticache Clusters",
"ElasticBeanstalk Applications",
"ELB Load Balancers",
"ELBv2 Load Balancers",
"EMR Clusters",
"EMR Instances",
"Glue Databases",
"Glue Dev Endpoints",
"Glue Jobs",
"Glue Tables",
"Grafana Workspaces",
"IAM Access Keys",
"IAM Roles",
"IAM Users",
"IAM Groups",
"Kinesis Data Streams",
"Lambda Functions",
"Lightsail Instances/Containers",
"MQ Brokers",
"OpenSearch DomainNames",
"Redshift Clusters",
"RDS DB Instances",
"Route53 Zones",
"Route53 Records",
"S3 Buckets",
"SecretsManager Secrets",
"SNS Topics",
"SQS Queues",
"SSM Parameters",
"StepFunctions State Machines",
}
m.serviceMap = map[string]map[string]int{}
m.totalRegionCounts = map[string]int{}
if m.AWSProfile == "" {
m.AWSProfile = internal.BuildAWSPath(m.Caller)
}
//initialize servicemap and total
for _, service := range m.services {
m.serviceMap[service] = map[string]int{}
for _, region := range m.AWSRegions {
m.serviceMap[service][region] = 0
m.totalRegionCounts[region] = 0
}
m.serviceMap[service]["Global"] = 0
}
fmt.Printf("[%s][%s] Enumerating selected services in all regions for account %s.\n", cyan(m.output.CallingModule), cyan(m.AWSProfile), aws.ToString(m.Caller.Account))
fmt.Printf("[%s][%s] Supported Services: ApiGateway, ApiGatewayv2, AppRunner, CloudFormation, Cloudfront, CodeBuild, DynamoDB, \n", cyan(m.output.CallingModule), cyan(m.AWSProfile))
fmt.Printf("[%s][%s] \t\t\tEC2, ECS, ECR, EKS, ELB, ELBv2, Glue, Grafana, IAM, Lambda, Lightsail, MQ, \n", cyan(m.output.CallingModule), cyan(m.AWSProfile))
fmt.Printf("[%s][%s] \t\t\tOpenSearch, RedShift, RDS, Route53, S3, SecretsManager, SNS, SQS, SSM, Step Functions\n", cyan(m.output.CallingModule), cyan(m.AWSProfile))
wg := new(sync.WaitGroup)
semaphore := make(chan struct{}, m.Goroutines)
// Create a channel to signal the spinner aka task status goroutine to finish
spinnerDone := make(chan bool)
//fire up the the task status spinner/updated
go internal.SpinUntil(m.output.CallingModule, &m.CommandCounter, spinnerDone, "tasks")
//create a channel to receive the objects
dataReceiver := make(chan GlobalResourceCount2)
// Create a channel to signal to stop
receiverDone := make(chan bool)
go m.Receiver(dataReceiver, receiverDone)
for _, region := range m.AWSRegions {
m.CommandCounter.Total++
wg.Add(1)
m.CommandCounter.Pending++
go m.executeChecks(region, wg, semaphore, dataReceiver)
}
// Time for the non-concurrent global checks
m.getBuckets(verbosity, dataReceiver)
m.getIAMUsers(verbosity, dataReceiver)
m.getIAMRoles(verbosity, dataReceiver)
m.getIAMGroups(verbosity, dataReceiver)
m.getIAMAccessKeys(verbosity, dataReceiver)
m.getCloudfrontDistros(verbosity, dataReceiver)
m.getRoute53Zones(verbosity, dataReceiver)
m.getRoute53Records(verbosity, dataReceiver)
wg.Wait()
// Send a message to the spinner goroutine to close the channel and stop
spinnerDone <- true
<-spinnerDone
// This creates the header row (columns) dynamically - a region only gets printed if it has at least one resource.
m.output.Headers = append(m.output.Headers, "Resource Type")
type kv struct {
Key string
Value int
}
var ss []kv
for k, v := range m.totalRegionCounts {
ss = append(ss, kv{k, v})
}
sort.Slice(ss, func(i, j int) bool {
return ss[i].Value > ss[j].Value
})
// move the Global column to the front
for i, v := range ss {
if v.Key == "Global" {
ss[0], ss[i] = ss[i], ss[0]
}
}
//add the regions to the header row
for _, region := range ss {
if region.Value != 0 {
m.output.Headers = append(m.output.Headers, region.Key)
}
}
//move total up here.
var totalRow []string
var temprow []string
temprow = append(temprow, "Total")
for _, region := range ss {
if region.Value != 0 {
if m.serviceMap["total"][region.Key] > 0 {
temprow = append(temprow, strconv.Itoa(m.serviceMap["total"][region.Key]))
} else {
temprow = append(temprow, "-")
}
}
}
for _, val := range temprow {
totalRow = append(totalRow, val)
}
m.output.Body = append(m.output.Body, totalRow)
// This is where we create the per service row with variable number of columns as well, using the same logic we used for the header
for _, service := range m.services {
if service != "total" {
var outputRow []string
var temprow []string
temprow = append(temprow, service)
for _, region := range ss {
if region.Value != 0 {
if m.serviceMap[service][region.Key] > 0 {
temprow = append(temprow, strconv.Itoa(m.serviceMap[service][region.Key]))
} else {
temprow = append(temprow, "-")
}
}
}
// check to see if all regions have no resources for the service. Skip the first column, which is the resource type.
// If any value is other than "-" set rowEmpty to false.
var rowEmtpy bool = true
for _, val := range temprow[1:] {
if val != "-" {
rowEmtpy = false
}
}
// If rowEmpty is still true at the end of the row, we dont add the row to the output, otherwise we do.
if !rowEmtpy {
// Convert the slice of strings to a slice of interfaces??? not sure, but this was needed. I couldn't just pass temp row to the output.Body
for _, val := range temprow {
outputRow = append(outputRow, val)
}
// Finally write the row to the table if the service has at least one resource
m.output.Body = append(m.output.Body, outputRow)
}
}
}
m.output.FilePath = filepath.Join(outputDirectory, "cloudfox-output", "aws", fmt.Sprintf("%s-%s", m.AWSProfile, aws.ToString(m.Caller.Account)))
// if verbosity > 1 {
// fmt.Printf("\nAnalyzed Global Resources\n\n")
// }
if len(m.output.Body) > 0 {
o := internal.OutputClient{
Verbosity: verbosity,
CallingModule: m.output.CallingModule,
Table: internal.TableClient{
Wrap: m.WrapTable,
},
}
o.Table.TableFiles = append(o.Table.TableFiles, internal.TableFile{
Header: m.output.Headers,
Body: m.output.Body,
Name: m.output.CallingModule,
})
o.PrefixIdentifier = m.AWSProfile
o.Table.DirectoryName = filepath.Join(outputDirectory, "cloudfox-output", "aws", fmt.Sprintf("%s-%s", m.AWSProfile, aws.ToString(m.Caller.Account)))
o.WriteFullOutput(o.Table.TableFiles, nil)
m.writeLoot(o.Table.DirectoryName, verbosity)
m.PrintTotalResources(m.AWSOutputType)
//m.writeLoot(m.output.FilePath, verbosity)
} else {
fmt.Printf("[%s][%s] No resources identified, skipping the creation of an output file.\n", cyan(m.output.CallingModule), cyan(m.AWSProfile))
}
fmt.Printf("[%s][%s] For context and next steps: https://github.com/BishopFox/cloudfox/wiki/AWS-Commands#%s\n", cyan(m.output.CallingModule), cyan(m.AWSProfile), m.output.CallingModule)
receiverDone <- true
<-receiverDone
}
func (m *Inventory2Module) writeLoot(outputDirectory string, verbosity int) {
path := filepath.Join(outputDirectory, "loot")
err := os.MkdirAll(path, os.ModePerm)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
}
lootFile := filepath.Join(path, "inventory.txt")
var out string
for _, resource := range m.resources {
out += fmt.Sprintf("%s\n", resource)
}
err = os.WriteFile(lootFile, []byte(out), 0644)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
}
if verbosity > 2 {
fmt.Println()
fmt.Printf("[%s][%s] %s \n", cyan(m.output.CallingModule), cyan(m.AWSProfile), green("All identified resources"))
fmt.Print(out)
fmt.Printf("[%s][%s] %s \n\n", cyan(m.output.CallingModule), cyan(m.AWSProfile), green("End of loot file."))
}
fmt.Printf("[%s][%s] Loot written to [%s]\n", cyan(m.output.CallingModule), cyan(m.AWSProfile), lootFile)
}
func (m *Inventory2Module) Receiver(receiver chan GlobalResourceCount2, receiverDone chan bool) {
defer close(receiverDone)
for {
select {
case data := <-receiver:
m.GlobalResourceCounts = append(m.GlobalResourceCounts, data)
case <-receiverDone:
receiverDone <- true
return
}
}
}
func (m *Inventory2Module) executeChecks(r string, wg *sync.WaitGroup, semaphore chan struct{}, dataReceiver chan GlobalResourceCount2) {
defer wg.Done()
// Use shared ServiceMap instance if provided, otherwise create a new one
servicemap := m.ServiceMap
if servicemap == nil {
servicemap = &awsservicemap.AwsServiceMap{
JsonFileSource: "DOWNLOAD_FROM_AWS",
}
}
// AppRunner is not supported in the aws service region catalog so we have to run it in all regions
m.CommandCounter.Total++
wg.Add(1)
go m.getAppRunnerServicesPerRegion(r, wg, semaphore)
res, err := servicemap.IsServiceInRegion("api-gateway", r)
if err != nil {
m.modLog.Error(err)
}
if res {
m.CommandCounter.Total++
wg.Add(1)
go m.getAPIGatewayvAPIsPerRegion(r, wg, semaphore)
m.CommandCounter.Total++
wg.Add(1)
go m.getAPIGatewayv2APIsPerRegion(r, wg, semaphore)
}
res, err = servicemap.IsServiceInRegion("athena", r)
if err != nil {
m.modLog.Error(err)
}
if res {
m.CommandCounter.Total++
wg.Add(1)
go m.getAthenaDatabasesPerRegion(r, wg, semaphore)
// wg.Add(1)
// go m.getAthenaDataCatalogsPerRegion(r, wg, semaphore)
}
res, err = servicemap.IsServiceInRegion("cloud9", r)
if err != nil {
m.modLog.Error(err)
}
if res {
m.CommandCounter.Total++
wg.Add(1)
go m.getCloud9EnvironmentsPerRegion(r, wg, semaphore)
}
res, err = servicemap.IsServiceInRegion("cloudformation", r)
if err != nil {
m.modLog.Error(err)
}
if res {
m.CommandCounter.Total++
wg.Add(1)
go m.getCloudFormationStacksPerRegion(r, wg, semaphore)
}
res, err = servicemap.IsServiceInRegion("codeartifact", r)
if err != nil {
m.modLog.Error(err)
}
if res {
m.CommandCounter.Total++
wg.Add(1)
go m.getCodeArtifactDomainsPerRegion(r, wg, semaphore)
}
res, err = servicemap.IsServiceInRegion("codebuild", r)
if err != nil {
m.modLog.Error(err)
}
if res {
m.CommandCounter.Total++
wg.Add(1)
go m.getCodeBuildProjectsPerRegion(r, wg, semaphore)
}
res, err = servicemap.IsServiceInRegion("codecommit", r)
if err != nil {
m.modLog.Error(err)
}
if res {
m.CommandCounter.Total++
wg.Add(1)
go m.getCodeCommitRepositoriesPerRegion(r, wg, semaphore)
}
res, err = servicemap.IsServiceInRegion("codedeploy", r)
if err != nil {
m.modLog.Error(err)
}
if res {
m.CommandCounter.Total++
wg.Add(1)
go m.getCodeDeployApplicationsPerRegion(r, wg, semaphore)
wg.Add(1)
go m.getCodeDeployDeploymentsPerRegion(r, wg, semaphore)
}
res, err = servicemap.IsServiceInRegion("datapipeline", r)
if err != nil {
m.modLog.Error(err)
}
if res {
m.CommandCounter.Total++
wg.Add(1)
go m.getDataPipelinePipelinesPerRegion(r, wg, semaphore)
}
res, err = servicemap.IsServiceInRegion("dynamodb", r)
if err != nil {
m.modLog.Error(err)
}
if res {
m.CommandCounter.Total++
wg.Add(1)
go m.getDynamoDBTablesPerRegion(r, wg, semaphore)
}
res, err = servicemap.IsServiceInRegion("ec2", r)
if err != nil {
m.modLog.Error(err)
}
if res {
m.CommandCounter.Total++
wg.Add(1)
go m.getEc2InstancesPerRegion(r, wg, semaphore)
wg.Add(1)
go m.getEc2ImagesPerRegion(r, wg, semaphore)
wg.Add(1)
go m.getEc2SnapshotsPerRegion(r, wg, semaphore)
wg.Add(1)
go m.getEc2VolumesPerRegion(r, wg, semaphore)
}
res, err = servicemap.IsServiceInRegion("ecs", r)
if err != nil {
m.modLog.Error(err)
}
if res {
m.CommandCounter.Total++
wg.Add(1)
go m.getEcsTasksPerRegion(r, wg, semaphore)
wg.Add(1)
go m.getEcsClustersPerRegion(r, wg, semaphore)
wg.Add(1)
go m.getEcsServicesPerRegion(r, wg, semaphore)
}
res, err = servicemap.IsServiceInRegion("ecr", r)
if err != nil {
m.modLog.Error(err)
}
if res {
m.CommandCounter.Total++
wg.Add(1)
go m.getEcrRepositoriesPerRegion(r, wg, semaphore)
}
res, err = servicemap.IsServiceInRegion("eks", r)
if err != nil {
m.modLog.Error(err)
}
if res {
m.CommandCounter.Total++
wg.Add(1)
go m.getEksClustersPerRegion(r, wg, semaphore)
wg.Add(1)
go m.getEKSNodeGroupsPerRegion(r, wg, semaphore)
}
res, err = servicemap.IsServiceInRegion("elasticloadbalancing", r)
if err != nil {
m.modLog.Error(err)
}
if res {
m.CommandCounter.Total++
wg.Add(1)
go m.getELBv2ListenersPerRegion(r, wg, semaphore)
m.CommandCounter.Total++
wg.Add(1)
go m.getELBListenersPerRegion(r, wg, semaphore)
}
res, err = servicemap.IsServiceInRegion("elasticache", r)
if err != nil {
m.modLog.Error(err)
}
if res {
m.CommandCounter.Total++
wg.Add(1)
go m.getElasticacheClustersPerRegion(r, wg, semaphore)
}
res, err = servicemap.IsServiceInRegion("elasticbeanstalk", r)
if err != nil {
m.modLog.Error(err)
}
if res {
m.CommandCounter.Total++
wg.Add(1)
go m.getElasticBeanstalkApplicationsPerRegion(r, wg, semaphore)
}
res, err = servicemap.IsServiceInRegion("elasticbeanstalk", r)
if err != nil {
m.modLog.Error(err)
}
if res {
m.CommandCounter.Total++
wg.Add(1)
go m.getEMRClustersPerRegion(r, wg, semaphore)
wg.Add(1)
go m.GetEMRInstancesPerRegion(r, wg, semaphore)
}
res, err = servicemap.IsServiceInRegion("opensearch-service", r)
if err != nil {
m.modLog.Error(err)
}
if res {
m.CommandCounter.Total++
wg.Add(1)
m.getOpenSearchPerRegion(r, wg, semaphore)
}
res, err = servicemap.IsServiceInRegion("grafana", r)
if err != nil {
m.modLog.Error(err)
}
if res {
m.CommandCounter.Total++
wg.Add(1)
go m.getGrafanaWorkspacesPerRegion(r, wg, semaphore)
}
res, err = servicemap.IsServiceInRegion("glue", r)
if err != nil {
m.modLog.Error(err)
}
if res {
m.CommandCounter.Total++
wg.Add(1)
go m.getGlueDevEndpointsPerRegion(r, wg, semaphore)
wg.Add(1)
go m.getGlueJobsPerRegion(r, wg, semaphore)
wg.Add(1)
go m.getGlueTablesPerRegion(r, wg, semaphore)
wg.Add(1)
go m.getGlueDatabasesPerRegion(r, wg, semaphore)
}
res, err = servicemap.IsServiceInRegion("streams", r)
if err != nil {
m.modLog.Error(err)
}
if res {
m.CommandCounter.Total++
wg.Add(1)
go m.getKinesisDatastreamsPerRegion(r, wg, semaphore)
}
res, err = servicemap.IsServiceInRegion("lambda", r)
if err != nil {
m.modLog.Error(err)
}
if res {
m.CommandCounter.Total++
wg.Add(1)
go m.getLambdaFunctionsPerRegion(r, wg, semaphore)
}
res, err = servicemap.IsServiceInRegion("amazonlightsail.com", r)
if err != nil {
m.modLog.Error(err)
}
if res {
m.CommandCounter.Total++
wg.Add(1)
go m.getLightsailInstancesAndContainersPerRegion(r, wg, semaphore)
}
res, err = servicemap.IsServiceInRegion("amazon-mq", r)
if err != nil {
m.modLog.Error(err)
}
if res {
m.CommandCounter.Total++
wg.Add(1)
m.getMqBrokersPerRegion(r, wg, semaphore)
}
res, err = servicemap.IsServiceInRegion("rds", r)
if err != nil {
m.modLog.Error(err)
}
if res {
m.CommandCounter.Total++
wg.Add(1)
go m.getRdsClustersPerRegion(r, wg, semaphore)
}
res, err = servicemap.IsServiceInRegion("redshift", r)
if err != nil {
m.modLog.Error(err)
}
if res {
m.CommandCounter.Total++
wg.Add(1)
go m.getRedshiftClustersPerRegion(r, wg, semaphore)
}
res, err = servicemap.IsServiceInRegion("secrets-manager", r)
if err != nil {
m.modLog.Error(err)
}
if res {
m.CommandCounter.Total++
wg.Add(1)
go m.getSecretsManagerSecretsPerRegion(r, wg, semaphore)
}
res, err = servicemap.IsServiceInRegion("sns", r)
if err != nil {
m.modLog.Error(err)
}
if res {
m.CommandCounter.Total++
wg.Add(1)
go m.getSNSTopicsPerRegion(r, wg, semaphore)
}
res, err = servicemap.IsServiceInRegion("sqs", r)
if err != nil {
m.modLog.Error(err)
}
if res {
m.CommandCounter.Total++
wg.Add(1)
go m.getSQSQueuesPerRegion(r, wg, semaphore)
}
res, err = servicemap.IsServiceInRegion("systems-manager", r)
if err != nil {
m.modLog.Error(err)
}
if res {
m.CommandCounter.Total++
wg.Add(1)
go m.getSSMParametersPerRegion(r, wg, semaphore)
}
res, err = servicemap.IsServiceInRegion("step-functions", r)
if err != nil {
m.modLog.Error(err)
}
if res {
m.CommandCounter.Total++
wg.Add(1)
m.getStepFunctionsPerRegion(r, wg, semaphore)
}
}
func (m *Inventory2Module) PrintTotalResources(AWSOutputType string) {
totalResources := len(m.resources)
fmt.Printf("[%s][%s] %d resources found in the services we looked at. This is NOT the total number of resources in the account.\n", cyan(m.output.CallingModule), cyan(m.AWSProfile), totalResources)
}
func (m *Inventory2Module) getLambdaFunctionsPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
defer func() {
wg.Done()
m.CommandCounter.Executing--
m.CommandCounter.Complete++
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
// m.CommandCounter.Total++
m.CommandCounter.Pending--
m.CommandCounter.Executing++
var totalCountThisServiceThisRegion = 0
var service = "Lambda Functions"
var resourceNames []string
ListFunctions, err := sdk.CachedLambdaListFunctions(m.LambdaClient, aws.ToString(m.Caller.Account), r)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(ListFunctions)
// Add this page of resources to the module's resource list
for _, f := range ListFunctions {
resourceNames = append(resourceNames, aws.ToString(f.FunctionArn))
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getAthenaDatabasesPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
defer func() {
wg.Done()
m.CommandCounter.Executing--
m.CommandCounter.Complete++
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
// m.CommandCounter.Total++
m.CommandCounter.Pending--
m.CommandCounter.Executing++
var totalCountThisServiceThisRegion = 0
var service = "Athena Databases"
var resourceNames []string
ListDataCatalogs, err := sdk.CachedAthenaListDataCatalogs(m.AthenaClient, aws.ToString(m.Caller.Account), r)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
for _, dc := range ListDataCatalogs {
ListDatabases, err := sdk.CachedAthenaListDatabases(m.AthenaClient, aws.ToString(m.Caller.Account), r, aws.ToString(dc.CatalogName))
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(ListDatabases)
for _, d := range ListDatabases {
arn := "arn:aws:athena:" + r + ":" + aws.ToString(m.Caller.Account) + ":database/" + d
resourceNames = append(resourceNames, arn)
}
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
// func (m *Inventory2Module) getAthenaDataCatalogsPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
// defer func() {
// wg.Done()
// m.CommandCounter.Executing--
// m.CommandCounter.Complete++
// }()
// semaphore <- struct{}{}
// defer func() {
// <-semaphore
// }()
// // m.CommandCounter.Total++
// m.CommandCounter.Pending--
// m.CommandCounter.Executing++
// var totalCountThisServiceThisRegion = 0
// var service = "Athena Data Catalogs"
// var resourceNames []string
// ListDataCatalogs, err := sdk.CachedAthenaListDataCatalogs(m.AthenaClient, aws.ToString(m.Caller.Account), r)
// if err != nil {
// m.modLog.Error(err.Error())
// m.CommandCounter.Error++
// return
// }
// // Add this page of resources to the total count
// totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(ListDataCatalogs)
// // Add this page of resources to the module's resource list
// for _, d := range ListDataCatalogs {
// arn := "arn:aws:athena:" + r + ":" + aws.ToString(m.Caller.Account) + ":datacatalog/" + aws.ToString(d.CatalogName)
// resourceNames = append(resourceNames, arn)
// }
// m.mu.Lock()
// m.resources = append(m.resources, resourceNames...)
// m.serviceMap[service][r] = totalCountThisServiceThisRegion
// m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
// m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
// m.mu.Unlock()
// }
func (m *Inventory2Module) getEc2InstancesPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
defer func() {
wg.Done()
m.CommandCounter.Executing--
m.CommandCounter.Complete++
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
// m.CommandCounter.Total++
m.CommandCounter.Pending--
m.CommandCounter.Executing++
// "PaginationMarker" is a control variable used for output continuity, as AWS return the output in pages.
var totalCountThisServiceThisRegion = 0
var service = "EC2 Instances"
var resourceNames []string
// used CachedDescribeInstancesInput to avoid the need to call DescribeInstancesInput
DescribeInstances, err := sdk.CachedEC2DescribeInstances(m.EC2Client, aws.ToString(m.Caller.Account), r)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(DescribeInstances)
// Add this page of resources to the module's resource list
for _, instance := range DescribeInstances {
arn := "arn:aws:ec2:" + r + ":" + aws.ToString(m.Caller.Account) + ":instance/" + aws.ToString(instance.InstanceId)
resourceNames = append(resourceNames, arn)
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getEc2ImagesPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
defer func() {
wg.Done()
m.CommandCounter.Executing--
m.CommandCounter.Complete++
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
// m.CommandCounter.Total++
m.CommandCounter.Pending--
m.CommandCounter.Executing++
// "PaginationMarker" is a control variable used for output continuity, as AWS return the output in pages.
var totalCountThisServiceThisRegion = 0
var service = "EC2 AMIs"
var resourceNames []string
// used CachedDescribeImagesInput to avoid the need to call DescribeImagesInput
DescribeImages, err := sdk.CachedEC2DescribeImages(m.EC2Client, aws.ToString(m.Caller.Account), r)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(DescribeImages)
// Add this page of resources to the module's resource list
for _, image := range DescribeImages {
arn := "arn:aws:ec2:" + r + ":" + aws.ToString(m.Caller.Account) + ":image/" + aws.ToString(image.ImageId)
resourceNames = append(resourceNames, arn)
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getEc2SnapshotsPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
defer func() {
wg.Done()
m.CommandCounter.Executing--
m.CommandCounter.Complete++
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
// m.CommandCounter.Total++
m.CommandCounter.Pending--
m.CommandCounter.Executing++
// "PaginationMarker" is a control variable used for output continuity, as AWS return the output in pages.
var totalCountThisServiceThisRegion = 0
var service = "EC2 Snapshots"
var resourceNames []string
// used CachedDescribeSnapshotsInput to avoid the need to call DescribeSnapshotsInput
DescribeSnapshots, err := sdk.CachedEC2DescribeSnapshots(m.EC2Client, aws.ToString(m.Caller.Account), r)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(DescribeSnapshots)
// Add this page of resources to the module's resource list
for _, snapshot := range DescribeSnapshots {
arn := "arn:aws:ec2:" + r + ":" + aws.ToString(m.Caller.Account) + ":snapshot/" + aws.ToString(snapshot.SnapshotId)
resourceNames = append(resourceNames, arn)
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getEc2VolumesPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
defer func() {
wg.Done()
m.CommandCounter.Executing--
m.CommandCounter.Complete++
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
// m.CommandCounter.Total++
m.CommandCounter.Pending--
m.CommandCounter.Executing++
// "PaginationMarker" is a control variable used for output continuity, as AWS return the output in pages.
var totalCountThisServiceThisRegion = 0
var service = "EC2 Volumes"
var resourceNames []string
// used CachedDescribeVolumesInput to avoid the need to call DescribeVolumesInput
DescribeVolumes, err := sdk.CachedEC2DescribeVolumes(m.EC2Client, aws.ToString(m.Caller.Account), r)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(DescribeVolumes)
// Add this page of resources to the module's resource list
for _, volume := range DescribeVolumes {
arn := "arn:aws:ec2:" + r + ":" + aws.ToString(m.Caller.Account) + ":volume/" + aws.ToString(volume.VolumeId)
resourceNames = append(resourceNames, arn)
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getEksClustersPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
defer func() {
wg.Done()
m.CommandCounter.Executing--
m.CommandCounter.Complete++
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
// m.CommandCounter.Total++
m.CommandCounter.Pending--
m.CommandCounter.Executing++
// "PaginationMarker" is a control variable used for output continuity, as AWS return the output in pages.
var totalCountThisServiceThisRegion = 0
var service = "EKS Clusters"
var resourceNames []string
ListClusters, err := sdk.CachedEKSListClusters(m.EKSClient, aws.ToString(m.Caller.Account), r)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(ListClusters)
// Add this page of resources to the module's resource list
for _, cluster := range ListClusters {
arn := "arn:aws:eks:" + r + ":" + aws.ToString(m.Caller.Account) + ":cluster/" + cluster
resourceNames = append(resourceNames, arn)
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getEKSNodeGroupsPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
defer func() {
wg.Done()
m.CommandCounter.Executing--
m.CommandCounter.Complete++
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
// m.CommandCounter.Total++
m.CommandCounter.Pending--
m.CommandCounter.Executing++
// "PaginationMarker" is a control variable used for output continuity, as AWS return the output in pages.
var totalCountThisServiceThisRegion = 0
var service = "EKS Cluster NodeGroups"
var resourceNames []string
ListClusters, err := sdk.CachedEKSListClusters(m.EKSClient, aws.ToString(m.Caller.Account), r)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
for _, cluster := range ListClusters {
NodeGroups, err := sdk.CachedEKSListNodeGroups(m.EKSClient, aws.ToString(m.Caller.Account), r, cluster)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(NodeGroups)
// Add this page of resources to the module's resource list
for _, nodegroup := range NodeGroups {
arn := "arn:aws:eks:" + r + ":" + aws.ToString(m.Caller.Account) + ":nodegroup/" + cluster + "/" + nodegroup
resourceNames = append(resourceNames, arn)
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
}
func (m *Inventory2Module) getCloudFormationStacksPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
defer func() {
wg.Done()
m.CommandCounter.Executing--
m.CommandCounter.Complete++
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
// m.CommandCounter.Total++
m.CommandCounter.Pending--
m.CommandCounter.Executing++
// "PaginationMarker" is a control variable used for output continuity, as AWS return the output in pages.
var totalCountThisServiceThisRegion = 0
var service = "CloudFormation Stacks"
var resourceNames []string
ListStacks, err := sdk.CachedCloudFormationListStacks(m.CloudFormationClient, aws.ToString(m.Caller.Account), r)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of resources to the total count
// Currently this counts both active and deleted stacks as they technically still exist. Might
// change this to only count active ones in the future.
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(ListStacks)
// Add this page of resources to the module's resource list
for _, stack := range ListStacks {
resourceNames = append(resourceNames, aws.ToString(stack.StackId))
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getElasticacheClustersPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
defer func() {
wg.Done()
m.CommandCounter.Executing--
m.CommandCounter.Complete++
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
// m.CommandCounter.Total++
m.CommandCounter.Pending--
m.CommandCounter.Executing++
// "PaginationMarker" is a control variable used for output continuity, as AWS return the output in pages.
var totalCountThisServiceThisRegion = 0
var service = "Elasticache Clusters"
var resourceNames []string
ListClusters, err := sdk.CachedElastiCacheDescribeCacheClusters(m.ElasticacheClient, aws.ToString(m.Caller.Account), r)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(ListClusters)
// Add this page of resources to the module's resource list
for _, cluster := range ListClusters {
resourceNames = append(resourceNames, aws.ToString(cluster.ARN))
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getElasticBeanstalkApplicationsPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
defer func() {
wg.Done()
m.CommandCounter.Executing--
m.CommandCounter.Complete++
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
// m.CommandCounter.Total++
m.CommandCounter.Pending--
m.CommandCounter.Executing++
// "PaginationMarker" is a control variable used for output continuity, as AWS return the output in pages.
var totalCountThisServiceThisRegion = 0
var service = "ElasticBeanstalk Applications"
var resourceNames []string
ListApplications, err := sdk.CachedElasticBeanstalkDescribeApplications(m.ElasticBeanstalkClient, aws.ToString(m.Caller.Account), r)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(ListApplications)
// Add this page of resources to the module's resource list
for _, application := range ListApplications {
arn := aws.ToString(application.ApplicationArn)
resourceNames = append(resourceNames, arn)
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getEMRClustersPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
defer func() {
wg.Done()
m.CommandCounter.Executing--
m.CommandCounter.Complete++
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
// m.CommandCounter.Total++
m.CommandCounter.Pending--
m.CommandCounter.Executing++
// "PaginationMarker" is a control variable used for output continuity, as AWS return the output in pages.
var totalCountThisServiceThisRegion = 0
var service = "EMR Clusters"
var resourceNames []string
ListClusters, err := sdk.CachedEMRListClusters(m.EMRClient, aws.ToString(m.Caller.Account), r)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(ListClusters)
// Add this page of resources to the module's resource list
for _, cluster := range ListClusters {
resourceNames = append(resourceNames, aws.ToString(cluster.ClusterArn))
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) GetEMRInstancesPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
defer func() {
wg.Done()
m.CommandCounter.Executing--
m.CommandCounter.Complete++
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
// m.CommandCounter.Total++
m.CommandCounter.Pending--
m.CommandCounter.Executing++
var totalCountThisServiceThisRegion = 0
var service = "EMR Instances"
var resourceNames []string
ListClusters, err := sdk.CachedEMRListClusters(m.EMRClient, aws.ToString(m.Caller.Account), r)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
for _, cluster := range ListClusters {
ListInstances, err := sdk.CachedEMRListInstances(m.EMRClient, aws.ToString(m.Caller.Account), r, aws.ToString(cluster.Id))
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(ListInstances)
// Add this page of resources to the module's resource list
for _, instance := range ListInstances {
arn := "arn:aws:elasticmapreduce:" + r + ":" + aws.ToString(m.Caller.Account) + ":instance/" + aws.ToString(instance.Id)
resourceNames = append(resourceNames, arn)
}
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getSecretsManagerSecretsPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
defer func() {
wg.Done()
m.CommandCounter.Executing--
m.CommandCounter.Complete++
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
// m.CommandCounter.Total++
m.CommandCounter.Pending--
m.CommandCounter.Executing++
// "PaginationMarker" is a control variable used for output continuity, as AWS return the output in pages.
var totalCountThisServiceThisRegion = 0
var service = "SecretsManager Secrets"
var resourceNames []string
ListSecrets, err := sdk.CachedSecretsManagerListSecrets(m.SecretsManagerClient, aws.ToString(m.Caller.Account), r)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of results to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(ListSecrets)
// Add this page of resources to the module's resource list
for _, secret := range ListSecrets {
resourceNames = append(resourceNames, aws.ToString(secret.ARN))
}
// No more pages, update the module's service map
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getRdsClustersPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
defer func() {
wg.Done()
m.CommandCounter.Executing--
m.CommandCounter.Complete++
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
// m.CommandCounter.Total++
m.CommandCounter.Pending--
m.CommandCounter.Executing++
// "PaginationMarker" is a control variable used for output continuity, as AWS return the output in pages.
var totalCountThisServiceThisRegion = 0
var service = "RDS DB Instances"
var resourceNames []string
DescribeDBInstances, err := sdk.CachedRDSDescribeDBInstances(m.RDSClient, aws.ToString(m.Caller.Account), r)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(DescribeDBInstances)
// Add this page of resources to the module's resource list
for _, instance := range DescribeDBInstances {
resourceNames = append(resourceNames, aws.ToString(instance.DBInstanceArn))
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getAPIGatewayvAPIsPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
defer func() {
wg.Done()
m.CommandCounter.Executing--
m.CommandCounter.Complete++
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
// m.CommandCounter.Total++
m.CommandCounter.Pending--
m.CommandCounter.Executing++
// "PaginationMarker" is a control variable used for output continuity, as AWS return the output in pages.
var totalCountThisServiceThisRegion = 0
var service = "APIGateway RestAPIs"
var resourceNames []string
GetRestApis, err := sdk.CachedApiGatewayGetRestAPIs(m.APIGatewayClient, aws.ToString(m.Caller.Account), r)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(GetRestApis)
// Add this page of resources to the module's resource list
for _, restAPI := range GetRestApis {
arn := aws.ToString(restAPI.Id)
resourceNames = append(resourceNames, arn)
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getAPIGatewayv2APIsPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
defer func() {
wg.Done()
m.CommandCounter.Executing--
m.CommandCounter.Complete++
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
// m.CommandCounter.Total++
m.CommandCounter.Pending--
m.CommandCounter.Executing++
// "PaginationMarker" is a control variable used for output continuity, as AWS return the output in pages.
var totalCountThisServiceThisRegion = 0
var service = "APIGatewayv2 APIs"
var resourceNames []string
GetApis, err := sdk.CachedAPIGatewayv2GetAPIs(m.APIGatewayv2Client, aws.ToString(m.Caller.Account), r)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(GetApis)
// Add this page of resources to the module's resource list
for _, api := range GetApis {
arn := aws.ToString(api.ApiId)
resourceNames = append(resourceNames, arn)
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getELBv2ListenersPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
defer func() {
wg.Done()
m.CommandCounter.Executing--
m.CommandCounter.Complete++
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
m.CommandCounter.Pending--
m.CommandCounter.Executing++
var totalCountThisServiceThisRegion = 0
var service = "ELBv2 Load Balancers"
var resourceNames []string
DescribeLoadBalancers, err := sdk.CachedELBv2DescribeLoadBalancers(m.ELBv2Client, aws.ToString(m.Caller.Account), r)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(DescribeLoadBalancers)
// Add this page of resources to the module's resource list
for _, loadBalancer := range DescribeLoadBalancers {
arn := aws.ToString(loadBalancer.LoadBalancerArn)
resourceNames = append(resourceNames, arn)
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getELBListenersPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
defer func() {
wg.Done()
m.CommandCounter.Executing--
m.CommandCounter.Complete++
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
// m.CommandCounter.Total++
m.CommandCounter.Pending--
m.CommandCounter.Executing++
// "PaginationMarker" is a control variable used for output continuity, as AWS return the output in pages.
var totalCountThisServiceThisRegion = 0
var service = "ELB Load Balancers"
var resourceNames []string
DescribeLoadBalancers, err := sdk.CachedELBDescribeLoadBalancers(m.ELBClient, aws.ToString(m.Caller.Account), r)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(DescribeLoadBalancers)
// Add this page of resources to the module's resource list
for _, loadBalancer := range DescribeLoadBalancers {
arn := "arn:aws:elasticloadbalancing:" + r + ":" + aws.ToString(m.Caller.Account) + ":loadbalancer/" + aws.ToString(loadBalancer.LoadBalancerName)
resourceNames = append(resourceNames, arn)
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getMqBrokersPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
defer func() {
wg.Done()
m.CommandCounter.Executing--
m.CommandCounter.Complete++
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
m.CommandCounter.Pending--
m.CommandCounter.Executing++
var totalCountThisServiceThisRegion = 0
var service = "MQ Brokers"
var resourceNames []string
ListBrokers, err := sdk.CachedMQListBrokers(m.MQClient, aws.ToString(m.Caller.Account), r)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(ListBrokers)
// Add this page of resources to the module's resource list
for _, broker := range ListBrokers {
resourceNames = append(resourceNames, aws.ToString(broker.BrokerArn))
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getOpenSearchPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
defer func() {
wg.Done()
m.CommandCounter.Executing--
m.CommandCounter.Complete++
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
// m.CommandCounter.Total++
m.CommandCounter.Pending--
m.CommandCounter.Executing++
// "PaginationMarker" is a control variable used for output continuity, as AWS return the output in pages.
var totalCountThisServiceThisRegion = 0
var service = "OpenSearch DomainNames"
var resourceNames []string
ListDomainNames, err := sdk.CachedOpenSearchListDomainNames(m.OpenSearchClient, aws.ToString(m.Caller.Account), r)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(ListDomainNames)
// Add this page of resources to the module's resource list
for _, domain := range ListDomainNames {
arn := "arn:aws:opensearch:" + r + ":" + aws.ToString(m.Caller.Account) + ":domain/" + aws.ToString(domain.DomainName)
resourceNames = append(resourceNames, arn)
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getGrafanaWorkspacesPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
defer func() {
wg.Done()
m.CommandCounter.Executing--
m.CommandCounter.Complete++
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
// m.CommandCounter.Total++
m.CommandCounter.Pending--
m.CommandCounter.Executing++
// "PaginationMarker" is a control variable used for output continuity, as AWS return the output in pages.
var totalCountThisServiceThisRegion = 0
var service = "Grafana Workspaces"
var resourceNames []string
ListWorkspaces, err := sdk.CachedGrafanaListWorkspaces(m.GrafanaClient, aws.ToString(m.Caller.Account), r)
// This for loop exits at the end depending on whether the output hits its last page (see pagination control block at the end of the loop).
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(ListWorkspaces)
// Add this page of resources to the module's resource list
for _, workspace := range ListWorkspaces {
arn := "arn:aws:grafana:" + r + ":" + aws.ToString(m.Caller.Account) + ":workspace/" + aws.ToString(workspace.Id)
resourceNames = append(resourceNames, arn)
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getAppRunnerServicesPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
defer func() {
wg.Done()
m.CommandCounter.Executing--
m.CommandCounter.Complete++
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
// m.CommandCounter.Total++
m.CommandCounter.Pending--
m.CommandCounter.Executing++
var totalCountThisServiceThisRegion = 0
var service = "AppRunner Services"
var resourceNames []string
ServiceSummaryList, err := sdk.CachedAppRunnerListServices(m.AppRunnerClient, aws.ToString(m.Caller.Account), r)
if err != nil {
//modLog.Error(err.Error())
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(ServiceSummaryList)
// Add this page of resources to the module's resource list
for _, service := range ServiceSummaryList {
resourceNames = append(resourceNames, aws.ToString(service.ServiceArn))
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getLightsailInstancesAndContainersPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
defer func() {
wg.Done()
m.CommandCounter.Executing--
m.CommandCounter.Complete++
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
// m.CommandCounter.Total++
m.CommandCounter.Pending--
m.CommandCounter.Executing++
// "PaginationMarker" is a control variable used for output continuity, as AWS return the output in pages.
var totalCountThisServiceThisRegion = 0
var service = "Lightsail Instances/Containers"
var resourceNames []string
ContainerServices, err := sdk.CachedLightsailGetContainerServices(m.LightsailClient, aws.ToString(m.Caller.Account), r)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
} else {
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(ContainerServices)
// Add this page of resources to the module's resource list
for _, containerService := range ContainerServices {
resourceNames = append(resourceNames, aws.ToString(containerService.Arn))
}
}
Instances, err := sdk.CachedLightsailGetInstances(m.LightsailClient, aws.ToString(m.Caller.Account), r)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(Instances)
// Add this page of resources to the module's resource list
for _, instance := range Instances {
resourceNames = append(resourceNames, aws.ToString(instance.Arn))
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getSSMParametersPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
defer func() {
wg.Done()
m.CommandCounter.Executing--
m.CommandCounter.Complete++
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
// m.CommandCounter.Total++
m.CommandCounter.Pending--
m.CommandCounter.Executing++
var totalCountThisServiceThisRegion = 0
var service = "SSM Parameters"
var resourceNames []string
Parameters, err := sdk.CachedSSMDescribeParameters(m.SSMClient, aws.ToString(m.Caller.Account), r)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(Parameters)
// Add this page of resources to the module's resource list
for _, parameter := range Parameters {
arn := "arn:aws:ssm:" + r + ":" + aws.ToString(m.Caller.Account) + ":parameter/" + aws.ToString(parameter.Name)
resourceNames = append(resourceNames, arn)
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getEcsTasksPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
defer func() {
wg.Done()
m.CommandCounter.Executing--
m.CommandCounter.Complete++
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
// m.CommandCounter.Total++
m.CommandCounter.Pending--
m.CommandCounter.Executing++
var totalCountThisServiceThisRegion = 0
var service = "ECS Tasks"
var resourceNames []string
Clusters, err := sdk.CachedECSListClusters(m.ECSClient, aws.ToString(m.Caller.Account), r)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
for _, cluster := range Clusters {
Tasks, err := sdk.CachedECSListTasks(m.ECSClient, aws.ToString(m.Caller.Account), r, cluster)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(Tasks)
// Add this page of resources to the module's resource list
for _, task := range Tasks {
resourceNames = append(resourceNames, task)
}
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getEcsServicesPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
defer func() {
wg.Done()
m.CommandCounter.Executing--
m.CommandCounter.Complete++
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
// m.CommandCounter.Total++
m.CommandCounter.Pending--
m.CommandCounter.Executing++
var totalCountThisServiceThisRegion = 0
var service = "ECS Services"
var resourceNames []string
Clusters, err := sdk.CachedECSListClusters(m.ECSClient, aws.ToString(m.Caller.Account), r)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
for _, cluster := range Clusters {
Services, err := sdk.CachedECSListServices(m.ECSClient, aws.ToString(m.Caller.Account), r, cluster)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(Services)
// Add this page of resources to the module's resource list
for _, service := range Services {
arn := "arn:aws:ecs:" + r + ":" + aws.ToString(m.Caller.Account) + ":service/" + service
resourceNames = append(resourceNames, arn)
}
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getEcsClustersPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
defer func() {
wg.Done()
m.CommandCounter.Executing--
m.CommandCounter.Complete++
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
// m.CommandCounter.Total++
m.CommandCounter.Pending--
m.CommandCounter.Executing++
var totalCountThisServiceThisRegion = 0
var service = "ECS Clusters"
var resourceNames []string
Clusters, err := sdk.CachedECSListClusters(m.ECSClient, aws.ToString(m.Caller.Account), r)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(Clusters)
// Add this page of resources to the module's resource list
for _, cluster := range Clusters {
resourceNames = append(resourceNames, cluster)
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getEcrRepositoriesPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
// Don't use this method as a template for future ones. There is a one off in the way the NextToken is handled.
defer func() {
wg.Done()
m.CommandCounter.Executing--
m.CommandCounter.Complete++
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
// m.CommandCounter.Total++
m.CommandCounter.Pending--
m.CommandCounter.Executing++
var totalCountThisServiceThisRegion = 0
var service = "ECR Repositories"
var resourceNames []string
Repositories, err := sdk.CachedECRDescribeRepositories(m.ECRClient, aws.ToString(m.Caller.Account), r)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(Repositories)
// Add this page of resources to the module's resource list
for _, repo := range Repositories {
resourceNames = append(resourceNames, aws.ToString(repo.RepositoryArn))
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getGlueDevEndpointsPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
// Don't use this method as a template for future ones. There is a one off in the way the NextToken is handled.
defer func() {
wg.Done()
m.CommandCounter.Executing--
m.CommandCounter.Complete++
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
// m.CommandCounter.Total++
m.CommandCounter.Pending--
m.CommandCounter.Executing++
var totalCountThisServiceThisRegion = 0
var service = "Glue Dev Endpoints"
var resourceNames []string
DevEndpointNames, err := sdk.CachedGlueListDevEndpoints(m.GlueClient, aws.ToString(m.Caller.Account), r)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(DevEndpointNames)
// Add this page of resources to the module's resource list
for _, devEndpoint := range DevEndpointNames {
arn := "arn:aws:glue:" + r + ":" + aws.ToString(m.Caller.Account) + ":devEndpoint/" + devEndpoint
resourceNames = append(resourceNames, arn)
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getGlueJobsPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
defer func() {
wg.Done()
m.CommandCounter.Executing--
m.CommandCounter.Complete++
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
// m.CommandCounter.Total++
m.CommandCounter.Pending--
m.CommandCounter.Executing++
var totalCountThisServiceThisRegion = 0
var service = "Glue Jobs"
var resourceNames []string
JobNames, err := sdk.CachedGlueListJobs(m.GlueClient, aws.ToString(m.Caller.Account), r)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(JobNames)
// Add this page of resources to the module's resource list
for _, job := range JobNames {
arn := "arn:aws:glue:" + r + ":" + aws.ToString(m.Caller.Account) + ":job/" + job
resourceNames = append(resourceNames, arn)
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getGlueDatabasesPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
defer func() {
wg.Done()
m.CommandCounter.Executing--
m.CommandCounter.Complete++
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
// m.CommandCounter.Total++
m.CommandCounter.Pending--
m.CommandCounter.Executing++
var totalCountThisServiceThisRegion = 0
var service = "Glue Databases"
var resourceNames []string
Databases, err := sdk.CachedGlueGetDatabases(m.GlueClient, aws.ToString(m.Caller.Account), r)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
for _, database := range Databases {
arn := "arn:aws:glue:" + r + ":" + aws.ToString(m.Caller.Account) + ":database/" + aws.ToString(database.Name)
resourceNames = append(resourceNames, arn)
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(Databases)
// Add this page of resources to the module's resource list
for _, database := range Databases {
resourceNames = append(resourceNames, aws.ToString(database.Name))
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getGlueTablesPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
defer func() {
wg.Done()
m.CommandCounter.Executing--
m.CommandCounter.Complete++
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
// m.CommandCounter.Total++
m.CommandCounter.Pending--
m.CommandCounter.Executing++
var totalCountThisServiceThisRegion = 0
var service = "Glue Jobs"
var resourceNames []string
Databases, err := sdk.CachedGlueGetDatabases(m.GlueClient, aws.ToString(m.Caller.Account), r)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
for _, database := range Databases {
TableNames, err := sdk.CachedGlueGetTables(m.GlueClient, aws.ToString(m.Caller.Account), r, aws.ToString(database.Name))
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(TableNames)
// Add this page of resources to the module's resource list
for _, table := range TableNames {
arn := "arn:aws:glue:" + r + ":" + aws.ToString(m.Caller.Account) + ":table/" + aws.ToString(database.Name) + "/" + aws.ToString(table.Name)
resourceNames = append(resourceNames, arn)
}
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getKinesisDatastreamsPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
defer func() {
wg.Done()
m.CommandCounter.Executing--
m.CommandCounter.Complete++
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
// m.CommandCounter.Total++
m.CommandCounter.Pending--
m.CommandCounter.Executing++
var totalCountThisServiceThisRegion = 0
var service = "Kinesis Data Streams"
var resourceNames []string
Datastreams, err := sdk.CachedKinesisListStreams(m.KinesisClient, aws.ToString(m.Caller.Account), r)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(Datastreams)
// Add this page of resources to the module's resource list
for _, stream := range Datastreams {
arn := "arn:aws:kinesis:" + r + ":" + aws.ToString(m.Caller.Account) + ":stream/" + stream
resourceNames = append(resourceNames, arn)
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getSNSTopicsPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
defer func() {
wg.Done()
m.CommandCounter.Executing--
m.CommandCounter.Complete++
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
// m.CommandCounter.Total++
m.CommandCounter.Pending--
m.CommandCounter.Executing++
// "PaginationMarker" is a control variable used for output continuity, as AWS return the output in pages.
var totalCountThisServiceThisRegion = 0
var service = "SNS Topics"
var resourceNames []string
Topics, err := sdk.CachedSNSListTopics(m.SNSClient, aws.ToString(m.Caller.Account), r)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(Topics)
// Add this page of resources to the module's resource list
resourceNames = append(resourceNames, Topics...)
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getSQSQueuesPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
defer func() {
wg.Done()
m.CommandCounter.Executing--
m.CommandCounter.Complete++
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
// m.CommandCounter.Total++
m.CommandCounter.Pending--
m.CommandCounter.Executing++
var totalCountThisServiceThisRegion = 0
var service = "SQS Queues"
var resourceNames []string
QueueUrls, err := sdk.CachedSQSListQueues(m.SQSClient, aws.ToString(m.Caller.Account), r)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(QueueUrls)
// Add this page of resources to the module's resource list
for _, queue := range QueueUrls {
arn := "arn:aws:sqs:" + r + ":" + aws.ToString(m.Caller.Account) + ":" + queue
resourceNames = append(resourceNames, arn)
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getDynamoDBTablesPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
defer func() {
wg.Done()
m.CommandCounter.Executing--
m.CommandCounter.Complete++
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
// m.CommandCounter.Total++
m.CommandCounter.Pending--
m.CommandCounter.Executing++
var totalCountThisServiceThisRegion = 0
var service = "DynamoDB Tables"
var resourceNames []string
TableNames, err := sdk.CachedDynamoDBListTables(m.DynamoDBClient, aws.ToString(m.Caller.Account), r)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(TableNames)
// Add this page of resources to the module's resource list
for _, table := range TableNames {
arn := "arn:aws:dynamodb:" + r + ":" + aws.ToString(m.Caller.Account) + ":table/" + table
resourceNames = append(resourceNames, arn)
}
// No more pages, update the module's service map
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getRedshiftClustersPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
defer func() {
wg.Done()
m.CommandCounter.Executing--
m.CommandCounter.Complete++
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
// m.CommandCounter.Total++
m.CommandCounter.Pending--
m.CommandCounter.Executing++
var totalCountThisServiceThisRegion = 0
var service = "Redshift Clusters"
var resourceNames []string
Clusters, err := sdk.CachedRedShiftDescribeClusters(m.RedshiftClient, aws.ToString(m.Caller.Account), r)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(Clusters)
// Add this page of resources to the module's resource list
for _, cluster := range Clusters {
//arn := "arn:aws:redshift:" + r + ":" + aws.ToString(m.Caller.Account) + ":cluster:" + cluster
resourceNames = append(resourceNames, aws.ToString(cluster.ClusterNamespaceArn))
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getCodeArtifactDomainsPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
defer func() {
wg.Done()
m.CommandCounter.Executing--
m.CommandCounter.Complete++
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
// m.CommandCounter.Total++
m.CommandCounter.Pending--
m.CommandCounter.Executing++
var totalCountThisServiceThisRegion = 0
var service = "CodeArtifact Domains"
var resourceNames []string
Domains, err := sdk.CachedCodeArtifactListDomains(m.CodeArtifactClient, aws.ToString(m.Caller.Account), r)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(Domains)
// Add this page of resources to the module's resource list
for _, domain := range Domains {
arn := aws.ToString(domain.Arn)
resourceNames = append(resourceNames, arn)
}
// No more pages, update the module's service map
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getCodeBuildProjectsPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
defer func() {
wg.Done()
m.CommandCounter.Executing--
m.CommandCounter.Complete++
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
// m.CommandCounter.Total++
m.CommandCounter.Pending--
m.CommandCounter.Executing++
var totalCountThisServiceThisRegion = 0
var service = "CodeBuild Projects"
var resourceNames []string
projects, err := sdk.CachedCodeBuildListProjects(m.CodeBuildClient, aws.ToString(m.Caller.Account), r)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(projects)
// Add this page of resources to the module's resource list
for _, project := range projects {
arn := "arn:aws:codebuild:" + r + ":" + aws.ToString(m.Caller.Account) + ":project/" + project
resourceNames = append(resourceNames, arn)
}
// No more pages, update the module's service map
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getCodeCommitRepositoriesPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
defer func() {
wg.Done()
m.CommandCounter.Executing--
m.CommandCounter.Complete++
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
// m.CommandCounter.Total++
m.CommandCounter.Pending--
m.CommandCounter.Executing++
var totalCountThisServiceThisRegion = 0
var service = "CodeCommit Repositories"
var resourceNames []string
repos, err := sdk.CachedCodeCommitListRepositories(m.CodeCommitClient, aws.ToString(m.Caller.Account), r)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(repos)
// Add this page of resources to the module's resource list
for _, repo := range repos {
arn := "arn:aws:codecommit:" + r + ":" + aws.ToString(m.Caller.Account) + ":" + aws.ToString(repo.RepositoryName)
resourceNames = append(resourceNames, arn)
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getCodeDeployApplicationsPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
defer func() {
wg.Done()
m.CommandCounter.Executing--
m.CommandCounter.Complete++
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
// m.CommandCounter.Total++
m.CommandCounter.Pending--
m.CommandCounter.Executing++
var totalCountThisServiceThisRegion = 0
var service = "CodeDeploy Applications"
var resourceNames []string
apps, err := sdk.CachedCodeDeployListApplications(m.CodeDeployClient, aws.ToString(m.Caller.Account), r)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(apps)
// Add this page of resources to the module's resource list
for _, app := range apps {
arn := "arn:aws:codedeploy:" + r + ":" + aws.ToString(m.Caller.Account) + ":application:" + app
resourceNames = append(resourceNames, arn)
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getCodeDeployDeploymentsPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
defer func() {
wg.Done()
m.CommandCounter.Executing--
m.CommandCounter.Complete++
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
// m.CommandCounter.Total++
m.CommandCounter.Pending--
m.CommandCounter.Executing++
var totalCountThisServiceThisRegion = 0
var service = "CodeDeploy Deployments"
var resourceNames []string
deployments, err := sdk.CachedCodeDeployListDeployments(m.CodeDeployClient, aws.ToString(m.Caller.Account), r)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(deployments)
// Add this page of resources to the module's resource list
for _, d := range deployments {
arn := "arn:aws:codedeploy:" + r + ":" + aws.ToString(m.Caller.Account) + ":application:" + d
resourceNames = append(resourceNames, arn)
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getDataPipelinePipelinesPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
defer func() {
wg.Done()
m.CommandCounter.Executing--
m.CommandCounter.Complete++
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
// m.CommandCounter.Total++
m.CommandCounter.Pending--
m.CommandCounter.Executing++
var totalCountThisServiceThisRegion = 0
var service = "DataPipeline Pipelines"
var resourceNames []string
pipelines, err := sdk.CachedDataPipelineListPipelines(m.DataPipelineClient, aws.ToString(m.Caller.Account), r)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(pipelines)
// Add this page of resources to the module's resource list
for _, p := range pipelines {
arn := "arn:aws:datapipeline:" + r + ":" + aws.ToString(m.Caller.Account) + ":pipeline:" + aws.ToString(p.Id)
resourceNames = append(resourceNames, arn)
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getStepFunctionsPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
defer func() {
wg.Done()
m.CommandCounter.Executing--
m.CommandCounter.Complete++
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
// m.CommandCounter.Total++
m.CommandCounter.Pending--
m.CommandCounter.Executing++
var totalCountThisServiceThisRegion = 0
var service = "StepFunctions State Machines"
var resourceNames []string
ListStateMachines, err := sdk.CachedStepFunctionsListStateMachines(m.StepFunctionClient, aws.ToString(m.Caller.Account), r)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(ListStateMachines)
// Add this page of resources to the module's resource list
for _, stateMachine := range ListStateMachines {
arn := "arn:aws:states:" + r + ":" + aws.ToString(m.Caller.Account) + ":stateMachine:" + aws.ToString(stateMachine.Name)
resourceNames = append(resourceNames, arn)
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getCloud9EnvironmentsPerRegion(r string, wg *sync.WaitGroup, semaphore chan struct{}) {
defer func() {
wg.Done()
m.CommandCounter.Executing--
}()
semaphore <- struct{}{}
defer func() {
<-semaphore
}()
m.CommandCounter.Total++
m.CommandCounter.Pending--
m.CommandCounter.Executing++
var totalCountThisServiceThisRegion = 0
var service = "Cloud9 Environments"
var resourceNames []string
Environments, err := sdk.CachedCloud9ListEnvironments(m.Cloud9Client, aws.ToString(m.Caller.Account), r)
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(Environments)
// Add this page of resources to the module's resource list
for _, env := range Environments {
arn := "arn:aws:cloud9:" + r + ":" + aws.ToString(m.Caller.Account) + ":environment:" + env
resourceNames = append(resourceNames, arn)
}
// No more pages, update the module's service map
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.mu.Unlock()
}
// Global Resources
func (m *Inventory2Module) getBuckets(verbosity int, dataReceiver chan GlobalResourceCount2) {
// "PaginationMarker" is a control variable used for output continuity, as AWS return the output in pages.
var total int
resourceType := "S3 Buckets"
service := "S3 Buckets"
var r string = "Global"
var totalCountThisServiceThisRegion = 0
var resourceNames []string
Buckets, err := sdk.CachedListBuckets(m.S3Client, aws.ToString(m.Caller.Account))
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
total = len(Buckets)
// Add this page of resources to the module's resource list
for _, bucket := range Buckets {
arn := "arn:aws:s3:::" + aws.ToString(bucket.Name)
m.resources = append(m.resources, arn)
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(Buckets)
dataReceiver <- GlobalResourceCount2{
resourceType: resourceType,
count: total,
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
// if verbosity > 1 {
// fmt.Printf("S3 Buckets: %d\n", total_buckets)
// }
}
func (m *Inventory2Module) getCloudfrontDistros(verbosity int, dataReceiver chan GlobalResourceCount2) {
var total int
var r string = "Global"
service := "Cloudfront Distributions"
resourceType := "Cloudfront Distributions"
var totalCountThisServiceThisRegion = 0
var resourceNames []string
Items, err := sdk.CachedCloudFrontListDistributions(m.CloudfrontClient, aws.ToString(m.Caller.Account))
// This for loop exits at the end depending on whether the output hits its last page (see pagination control block at the end of the loop).
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
// Add this page of resources to the total count
total = total + len(Items)
// Add this page of resources to the module's resource list
for _, distro := range Items {
resourceNames = append(resourceNames, aws.ToString(distro.ARN))
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(Items)
dataReceiver <- GlobalResourceCount2{
resourceType: resourceType,
count: total,
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getIAMUsers(verbosity int, dataReceiver chan GlobalResourceCount2) {
var total int
var r string = "Global"
service := "IAM Users"
var totalCountThisServiceThisRegion = 0
resourceType := "IAM Users"
var resourceNames []string
Users, err := sdk.CachedIamListUsers(m.IAMClient, aws.ToString(m.Caller.Account))
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
total = total + len(Users)
// Add this page of resources to the module's resource list
for _, user := range Users {
resourceNames = append(resourceNames, aws.ToString(user.Arn))
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(Users)
dataReceiver <- GlobalResourceCount2{
resourceType: resourceType,
count: total,
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getIAMRoles(verbosity int, dataReceiver chan GlobalResourceCount2) {
var total int
var r string = "Global"
service := "IAM Roles"
var totalCountThisServiceThisRegion = 0
resourceType := "IAM Roles"
var resourceNames []string
Roles, err := sdk.CachedIamListRoles(m.IAMClient, aws.ToString(m.Caller.Account))
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
total = total + len(Roles)
// Add this page of resources to the module's resource list
for _, role := range Roles {
resourceNames = append(resourceNames, aws.ToString(role.Arn))
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(Roles)
dataReceiver <- GlobalResourceCount2{
resourceType: resourceType,
count: total,
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getIAMGroups(verbosity int, dataReceiver chan GlobalResourceCount2) {
var total int
var r string = "Global"
service := "IAM Groups"
var totalCountThisServiceThisRegion = 0
resourceType := "IAM Groups"
var resourceNames []string
Groups, err := sdk.CachedIamListGroups(m.IAMClient, aws.ToString(m.Caller.Account))
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
total = total + len(Groups)
// Add this page of resources to the module's resource list
for _, group := range Groups {
resourceNames = append(resourceNames, aws.ToString(group.Arn))
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(Groups)
dataReceiver <- GlobalResourceCount2{
resourceType: resourceType,
count: total,
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getIAMAccessKeys(verbosity int, dataReceiver chan GlobalResourceCount2) {
var total int
var r string = "Global"
service := "IAM Access Keys"
var totalCountThisServiceThisRegion = 0
resourceType := "IAM Access Keys"
var resourceNames []string
Users, err := sdk.CachedIamListUsers(m.IAMClient, aws.ToString(m.Caller.Account))
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
for _, user := range Users {
AccessKeys, err := sdk.CachedIamListAccessKeys(m.IAMClient, aws.ToString(m.Caller.Account), aws.ToString(user.UserName))
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
total = total + len(AccessKeys)
// Add this page of resources to the module's resource list
for _, key := range AccessKeys {
resourceNames = append(resourceNames, aws.ToString(key.UserName))
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(AccessKeys)
dataReceiver <- GlobalResourceCount2{
resourceType: resourceType,
count: total,
}
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getRoute53Zones(verbosity int, dataReceiver chan GlobalResourceCount2) {
var total int
var r string = "Global"
service := "Route53 Zones"
var totalCountThisServiceThisRegion = 0
resourceType := "Route53 Zones"
var resourceNames []string
Zones, err := sdk.CachedRoute53ListHostedZones(m.Route53Client, aws.ToString(m.Caller.Account))
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
total = total + len(Zones)
// Add this page of resources to the module's resource list
for _, zone := range Zones {
resourceNames = append(resourceNames, aws.ToString(zone.Id))
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(Zones)
dataReceiver <- GlobalResourceCount2{
resourceType: resourceType,
count: total,
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}
func (m *Inventory2Module) getRoute53Records(verbosity int, dataReceiver chan GlobalResourceCount2) {
var total int
var r string = "Global"
service := "Route53 Records"
var totalCountThisServiceThisRegion = 0
resourceType := "Route53 Records"
var resourceNames []string
Zones, err := sdk.CachedRoute53ListHostedZones(m.Route53Client, aws.ToString(m.Caller.Account))
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
for _, zone := range Zones {
Records, err := sdk.CachedRoute53ListResourceRecordSets(m.Route53Client, aws.ToString(m.Caller.Account), aws.ToString(zone.Id))
if err != nil {
m.modLog.Error(err.Error())
m.CommandCounter.Error++
return
}
total = total + len(Records)
// Add this page of resources to the module's resource list
for _, record := range Records {
resourceNames = append(resourceNames, aws.ToString(record.Name))
}
// Add this page of resources to the total count
totalCountThisServiceThisRegion = totalCountThisServiceThisRegion + len(Records)
}
dataReceiver <- GlobalResourceCount2{
resourceType: resourceType,
count: total,
}
m.mu.Lock()
m.resources = append(m.resources, resourceNames...)
m.serviceMap[service][r] = totalCountThisServiceThisRegion
m.totalRegionCounts[r] = m.totalRegionCounts[r] + totalCountThisServiceThisRegion
m.serviceMap["total"][r] = m.serviceMap["total"][r] + totalCountThisServiceThisRegion
m.mu.Unlock()
}