diff --git a/main.go b/main.go index d28b59f..3b66358 100644 --- a/main.go +++ b/main.go @@ -11,6 +11,7 @@ import ( "github.com/app-sre/aws-resource-exporter/pkg" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/session" + "github.com/aws/aws-sdk-go/service/sts" "github.com/go-kit/kit/log/level" "github.com/prometheus/common/promlog" "github.com/prometheus/common/promlog/flag" @@ -37,6 +38,18 @@ func main() { os.Exit(run()) } +func getAwsAccountNumber(logger log.Logger) (string, error) { + config := aws.NewConfig().WithRegion("us-east-1") + sess := session.Must(session.NewSession(config)) + stsClient := sts.New(sess) + identityOutput, err := stsClient.GetCallerIdentity(&sts.GetCallerIdentityInput{}) + if err != nil { + level.Error(logger).Log("msg", "Could not retrieve caller identity of the aws account", "err", err) + return "", err + } + return *identityOutput.Account, nil +} + func setupCollectors(logger log.Logger, configFile string) ([]prometheus.Collector, error) { var collectors []prometheus.Collector config, err := pkg.LoadExporterConfiguration(logger, configFile) diff --git a/pkg/constats.go b/pkg/constats.go index 5d385ec..b41d463 100644 --- a/pkg/constats.go +++ b/pkg/constats.go @@ -1,5 +1,7 @@ package pkg const ( - namespace = "aws_resources_exporter" + namespace = "aws_resources_exporter" + SERVICE_CODE_KEY = "service_code" + QUOTA_CODE_KEY = "quota_code" ) diff --git a/pkg/ec2.go b/pkg/ec2.go index 7f97aa5..040ffdd 100644 --- a/pkg/ec2.go +++ b/pkg/ec2.go @@ -35,10 +35,10 @@ type EC2Exporter struct { func NewEC2Exporter(sessions []*session.Session, logger log.Logger, config EC2Config, awsAccountId string) *EC2Exporter { level.Info(logger).Log("msg", "Initializing EC2 exporter") - accountIdLabel := map[string]string{"aws_account_id": awsAccountId} + constLabels := map[string]string{"aws_account_id": awsAccountId, QUOTA_CODE_KEY: transitGatewayPerAccountQuotaCode, SERVICE_CODE_KEY: ec2ServiceCode} - TransitGatewaysQuota = prometheus.NewDesc(prometheus.BuildFQName(namespace, "", "ec2_transitgatewaysperregion_quota"), "Quota for maximum number of Transitgateways in this account", []string{"aws_region"}, accountIdLabel) - TransitGatewaysUsage = prometheus.NewDesc(prometheus.BuildFQName(namespace, "", "ec2_transitgatewaysperregion_usage"), "Number of Tranitgatewyas in the AWS Account", []string{"aws_region"}, accountIdLabel) + TransitGatewaysQuota = prometheus.NewDesc(prometheus.BuildFQName(namespace, "", "ec2_transitgatewaysperregion_quota"), "Quota for maximum number of Transitgateways in this account", []string{"aws_region"}, constLabels) + TransitGatewaysUsage = prometheus.NewDesc(prometheus.BuildFQName(namespace, "", "ec2_transitgatewaysperregion_usage"), "Number of Tranitgatewyas in the AWS Account", []string{"aws_region"}, constLabels) return &EC2Exporter{ sessions: sessions, diff --git a/pkg/route53.go b/pkg/route53.go index 4c31cc7..6b4a329 100644 --- a/pkg/route53.go +++ b/pkg/route53.go @@ -18,11 +18,12 @@ import ( ) const ( - maxRetries = 10 - route53MaxConcurrency = 5 - route53ServiceCode = "route53" - hostedZonesQuotaCode = "L-4EA4796A" - errorCodeThrottling = "Throttling" + maxRetries = 10 + route53MaxConcurrency = 5 + route53ServiceCode = "route53" + hostedZonesQuotaCode = "L-4EA4796A" + recordsPerHostedZoneQuotaCode = "L-E209CC9F" + errorCodeThrottling = "Throttling" ) type Route53Exporter struct { @@ -43,16 +44,16 @@ type Route53Exporter struct { func NewRoute53Exporter(sess *session.Session, logger log.Logger, config Route53Config, awsAccountId string) *Route53Exporter { level.Info(logger).Log("msg", "Initializing Route53 exporter") - accountIdLabel := map[string]string{"aws_account_id": awsAccountId} + constLabels := map[string]string{"aws_account_id": awsAccountId, SERVICE_CODE_KEY: route53ServiceCode} exporter := &Route53Exporter{ sess: sess, - RecordsPerHostedZoneQuota: prometheus.NewDesc(prometheus.BuildFQName(namespace, "", "route53_recordsperhostedzone_quota"), "Quota for maximum number of records in a Route53 hosted zone", []string{"hostedzoneid", "hostedzonename"}, accountIdLabel), - RecordsPerHostedZoneUsage: prometheus.NewDesc(prometheus.BuildFQName(namespace, "", "route53_recordsperhostedzone_total"), "Number of Resource records", []string{"hostedzoneid", "hostedzonename"}, accountIdLabel), - HostedZonesPerAccountQuota: prometheus.NewDesc(prometheus.BuildFQName(namespace, "", "route53_hostedzonesperaccount_quota"), "Quota for maximum number of Route53 hosted zones in an account", []string{}, accountIdLabel), - HostedZonesPerAccountUsage: prometheus.NewDesc(prometheus.BuildFQName(namespace, "", "route53_hostedzonesperaccount_total"), "Number of Resource records", []string{}, accountIdLabel), - LastUpdateTime: prometheus.NewDesc(prometheus.BuildFQName(namespace, "", "route53_last_updated_timestamp_seconds"), "Last time, the route53 metrics were sucessfully updated", []string{}, accountIdLabel), - cache: *pkg.NewMetricsCache(*config.CacheTTL), + RecordsPerHostedZoneQuota: prometheus.NewDesc(prometheus.BuildFQName(namespace, "", "route53_recordsperhostedzone_quota"), "Quota for maximum number of records in a Route53 hosted zone", []string{"hostedzoneid", "hostedzonename"}, WithKeyValue(constLabels, QUOTA_CODE_KEY, recordsPerHostedZoneQuotaCode)), + RecordsPerHostedZoneUsage: prometheus.NewDesc(prometheus.BuildFQName(namespace, "", "route53_recordsperhostedzone_total"), "Number of Resource records", []string{"hostedzoneid", "hostedzonename"}, WithKeyValue(constLabels, QUOTA_CODE_KEY, recordsPerHostedZoneQuotaCode)), + HostedZonesPerAccountQuota: prometheus.NewDesc(prometheus.BuildFQName(namespace, "", "route53_hostedzonesperaccount_quota"), "Quota for maximum number of Route53 hosted zones in an account", []string{}, WithKeyValue(constLabels, QUOTA_CODE_KEY, hostedZonesQuotaCode)), + HostedZonesPerAccountUsage: prometheus.NewDesc(prometheus.BuildFQName(namespace, "", "route53_hostedzonesperaccount_total"), "Number of Resource records", []string{}, WithKeyValue(constLabels, QUOTA_CODE_KEY, hostedZonesQuotaCode)), + LastUpdateTime: prometheus.NewDesc(prometheus.BuildFQName(namespace, "", "route53_last_updated_timestamp_seconds"), "Last time, the route53 metrics were sucessfully updated", []string{}, constLabels), + cache: *NewMetricsCache(*config.CacheTTL), logger: logger, interval: *config.Interval, timeout: *config.Timeout, diff --git a/pkg/util.go b/pkg/util.go index ea643af..a6331f1 100644 --- a/pkg/util.go +++ b/pkg/util.go @@ -23,3 +23,13 @@ func GetEnvIntValue(envname string) (*int, error) { func durationPtr(duration time.Duration) *time.Duration { return &duration } + +// Add a new key to the map and return the new map +func WithKeyValue(m map[string]string, key string, value string) map[string]string { + newMap := make(map[string]string) + for k, v := range m { + newMap[k] = v + } + newMap[key] = value + return newMap +} diff --git a/pkg/vpc.go b/pkg/vpc.go index 99d5124..454cbf8 100644 --- a/pkg/vpc.go +++ b/pkg/vpc.go @@ -56,22 +56,22 @@ type VPCCollector struct { func NewVPCExporter(sess []*session.Session, logger log.Logger, config VPCConfig, awsAccountId string) *VPCExporter { level.Info(logger).Log("msg", "Initializing VPC exporter") - accountIdLabel := map[string]string{"aws_account_id": awsAccountId} + constLabels := map[string]string{"aws_account_id": awsAccountId, SERVICE_CODE_KEY: SERVICE_CODE_VPC} return &VPCExporter{ awsAccountId: awsAccountId, sessions: sess, - VpcsPerRegionQuota: prometheus.NewDesc(prometheus.BuildFQName(namespace, "", "vpc_vpcsperregion_quota"), "The quota of VPCs per region", []string{"aws_region"}, accountIdLabel), - VpcsPerRegionUsage: prometheus.NewDesc(prometheus.BuildFQName(namespace, "", "vpc_vpcsperregion_usage"), "The usage of VPCs per region", []string{"aws_region"}, accountIdLabel), - SubnetsPerVpcQuota: prometheus.NewDesc(prometheus.BuildFQName(namespace, "", "vpc_subnetspervpc_quota"), "The quota of subnets per VPC", []string{"aws_region"}, accountIdLabel), - SubnetsPerVpcUsage: prometheus.NewDesc(prometheus.BuildFQName(namespace, "", "vpc_subnetspervpc_usage"), "The usage of subnets per VPC", []string{"aws_region", "vpcid"}, accountIdLabel), - RoutesPerRouteTableQuota: prometheus.NewDesc(prometheus.BuildFQName(namespace, "", "vpc_routesperroutetable_quota"), "The quota of routes per routetable", []string{"aws_region"}, accountIdLabel), - RoutesPerRouteTableUsage: prometheus.NewDesc(prometheus.BuildFQName(namespace, "", "vpc_routesperroutetable_usage"), "The usage of routes per routetable", []string{"aws_region", "vpcid", "routetableid"}, accountIdLabel), - InterfaceVpcEndpointsPerVpcQuota: prometheus.NewDesc(prometheus.BuildFQName(namespace, "", "vpc_interfacevpcendpointspervpc_quota"), "The quota of interface vpc endpoints per vpc", []string{"aws_region"}, accountIdLabel), - InterfaceVpcEndpointsPerVpcUsage: prometheus.NewDesc(prometheus.BuildFQName(namespace, "", "vpc_interfacevpcendpointspervpc_usage"), "The usage of interface vpc endpoints per vpc", []string{"aws_region", "vpcid"}, accountIdLabel), - RouteTablesPerVpcQuota: prometheus.NewDesc(prometheus.BuildFQName(namespace, "", "vpc_routetablespervpc_quota"), "The quota of route tables per vpc", []string{"aws_region"}, accountIdLabel), - RouteTablesPerVpcUsage: prometheus.NewDesc(prometheus.BuildFQName(namespace, "", "vpc_routetablespervpc_usage"), "The usage of route tables per vpc", []string{"aws_region", "vpcid"}, accountIdLabel), - IPv4BlocksPerVpcQuota: prometheus.NewDesc(prometheus.BuildFQName(namespace, "", "vpc_ipv4blockspervpc_quota"), "The quota of ipv4 blocks per vpc", []string{"aws_region"}, accountIdLabel), - IPv4BlocksPerVpcUsage: prometheus.NewDesc(prometheus.BuildFQName(namespace, "", "vpc_ipv4blockspervpc_usage"), "The usage of ipv4 blocks per vpc", []string{"aws_region", "vpcid"}, accountIdLabel), + VpcsPerRegionQuota: prometheus.NewDesc(prometheus.BuildFQName(namespace, "", "vpc_vpcsperregion_quota"), "The quota of VPCs per region", []string{"aws_region"}, WithKeyValue(constLabels, QUOTA_CODE_KEY, QUOTA_VPCS_PER_REGION)), + VpcsPerRegionUsage: prometheus.NewDesc(prometheus.BuildFQName(namespace, "", "vpc_vpcsperregion_usage"), "The usage of VPCs per region", []string{"aws_region"}, WithKeyValue(constLabels, QUOTA_CODE_KEY, QUOTA_VPCS_PER_REGION)), + SubnetsPerVpcQuota: prometheus.NewDesc(prometheus.BuildFQName(namespace, "", "vpc_subnetspervpc_quota"), "The quota of subnets per VPC", []string{"aws_region"}, WithKeyValue(constLabels, QUOTA_CODE_KEY, QUOTA_SUBNETS_PER_VPC)), + SubnetsPerVpcUsage: prometheus.NewDesc(prometheus.BuildFQName(namespace, "", "vpc_subnetspervpc_usage"), "The usage of subnets per VPC", []string{"aws_region", "vpcid"}, WithKeyValue(constLabels, QUOTA_CODE_KEY, QUOTA_SUBNETS_PER_VPC)), + RoutesPerRouteTableQuota: prometheus.NewDesc(prometheus.BuildFQName(namespace, "", "vpc_routesperroutetable_quota"), "The quota of routes per routetable", []string{"aws_region"}, WithKeyValue(constLabels, QUOTA_CODE_KEY, QUOTA_ROUTES_PER_ROUTE_TABLE)), + RoutesPerRouteTableUsage: prometheus.NewDesc(prometheus.BuildFQName(namespace, "", "vpc_routesperroutetable_usage"), "The usage of routes per routetable", []string{"aws_region", "vpcid", "routetableid"}, WithKeyValue(constLabels, QUOTA_CODE_KEY, QUOTA_ROUTES_PER_ROUTE_TABLE)), + InterfaceVpcEndpointsPerVpcQuota: prometheus.NewDesc(prometheus.BuildFQName(namespace, "", "vpc_interfacevpcendpointspervpc_quota"), "The quota of interface vpc endpoints per vpc", []string{"aws_region"}, WithKeyValue(constLabels, QUOTA_CODE_KEY, QUOTA_INTERFACE_VPC_ENDPOINTS_PER_VPC)), + InterfaceVpcEndpointsPerVpcUsage: prometheus.NewDesc(prometheus.BuildFQName(namespace, "", "vpc_interfacevpcendpointspervpc_usage"), "The usage of interface vpc endpoints per vpc", []string{"aws_region", "vpcid"}, WithKeyValue(constLabels, QUOTA_CODE_KEY, QUOTA_INTERFACE_VPC_ENDPOINTS_PER_VPC)), + RouteTablesPerVpcQuota: prometheus.NewDesc(prometheus.BuildFQName(namespace, "", "vpc_routetablespervpc_quota"), "The quota of route tables per vpc", []string{"aws_region"}, WithKeyValue(constLabels, QUOTA_CODE_KEY, QUOTA_ROUTE_TABLES_PER_VPC)), + RouteTablesPerVpcUsage: prometheus.NewDesc(prometheus.BuildFQName(namespace, "", "vpc_routetablespervpc_usage"), "The usage of route tables per vpc", []string{"aws_region", "vpcid"}, WithKeyValue(constLabels, QUOTA_CODE_KEY, QUOTA_ROUTE_TABLES_PER_VPC)), + IPv4BlocksPerVpcQuota: prometheus.NewDesc(prometheus.BuildFQName(namespace, "", "vpc_ipv4blockspervpc_quota"), "The quota of ipv4 blocks per vpc", []string{"aws_region"}, WithKeyValue(constLabels, QUOTA_CODE_KEY, QUOTA_IPV4_BLOCKS_PER_VPC)), + IPv4BlocksPerVpcUsage: prometheus.NewDesc(prometheus.BuildFQName(namespace, "", "vpc_ipv4blockspervpc_usage"), "The usage of ipv4 blocks per vpc", []string{"aws_region", "vpcid"}, WithKeyValue(constLabels, QUOTA_CODE_KEY, QUOTA_IPV4_BLOCKS_PER_VPC)), logger: logger, timeout: *config.Timeout, cache: *NewMetricsCache(*config.CacheTTL),