Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(1255): Integrated the AWS costexplorer API #1278

Merged
merged 7 commits into from
Dec 18, 2023
9 changes: 9 additions & 0 deletions providers/aws/apigateway/apis.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/aws/aws-sdk-go-v2/service/cloudwatch/types"
. "github.com/tailwarden/komiser/models"
. "github.com/tailwarden/komiser/providers"
awsUtils "github.com/tailwarden/komiser/providers/aws/utils"
"github.com/tailwarden/komiser/utils"
)

Expand All @@ -27,6 +28,11 @@ func Apis(ctx context.Context, client ProviderClient) ([]Resource, error) {
return resources, err
}

serviceCost, err := awsUtils.GetCostAndUsage(ctx, client.AWSClient.Region, "Amazon API Gateway")
if err != nil {
log.Warnln("Couldn't fetch Amazon API Gateway cost and usage:", err)
}

for _, api := range output.Items {
tags := make([]Tag, 0)
for key, value := range api.Tags {
Expand Down Expand Up @@ -72,6 +78,9 @@ func Apis(ctx context.Context, client ProviderClient) ([]Resource, error) {
Region: client.AWSClient.Region,
Name: *api.Name,
Cost: monthlyCost,
Metadata: map[string]string{
"serviceCost": fmt.Sprint(serviceCost),
},
Tags: tags,
CreatedAt: *api.CreatedDate,
FetchedAt: time.Now(),
Expand Down
8 changes: 8 additions & 0 deletions providers/aws/cloudfront/distributions.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/aws/aws-sdk-go-v2/service/cloudwatch/types"
. "github.com/tailwarden/komiser/models"
. "github.com/tailwarden/komiser/providers"
awsUtils "github.com/tailwarden/komiser/providers/aws/utils"
"github.com/tailwarden/komiser/utils"
)

Expand All @@ -26,6 +27,10 @@ func Distributions(ctx context.Context, client ProviderClient) ([]Resource, erro
cloudwatchClient := cloudwatch.NewFromConfig(*client.AWSClient)
client.AWSClient.Region = tempRegion

serviceCost, err := awsUtils.GetCostAndUsage(ctx, client.AWSClient.Region, "Amazon CloudFront")
if err != nil {
log.Warnln("Couldn't fetch Amazon CloudFront cost and usage:", err)
}
for {
output, err := cloudfrontClient.ListDistributions(ctx, &config)
if err != nil {
Expand Down Expand Up @@ -145,6 +150,9 @@ func Distributions(ctx context.Context, client ProviderClient) ([]Resource, erro
Region: client.AWSClient.Region,
Name: *distribution.DomainName,
Cost: monthlyCost,
Metadata: map[string]string{
"serviceCost": fmt.Sprint(serviceCost),
},
Tags: tags,
FetchedAt: time.Now(),
Link: fmt.Sprintf("https://%s.console.aws.amazon.com/cloudfront/v3/home?region=%s#/distributions/%s", client.AWSClient.Region, client.AWSClient.Region, *distribution.Id),
Expand Down
8 changes: 8 additions & 0 deletions providers/aws/cloudwatch/dashboards.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,18 @@ import (
"github.com/aws/aws-sdk-go-v2/service/cloudwatch"
. "github.com/tailwarden/komiser/models"
. "github.com/tailwarden/komiser/providers"
awsUtils "github.com/tailwarden/komiser/providers/aws/utils"
)

func Dashboards(ctx context.Context, client ProviderClient) ([]Resource, error) {
resources := make([]Resource, 0)
cloudWatchClient := cloudwatch.NewFromConfig(*client.AWSClient)

var nextToken *string
serviceCost, err := awsUtils.GetCostAndUsage(ctx, client.AWSClient.Region, "CloudWatch")
if err != nil {
log.Warnln("Couldn't fetch CloudWatch cost and usage:", err)
}

for {
input := &cloudwatch.ListDashboardsInput{
Expand Down Expand Up @@ -53,6 +58,9 @@ func Dashboards(ctx context.Context, client ProviderClient) ([]Resource, error)
Region: client.AWSClient.Region,
Name: *dashboard.DashboardName,
Cost: cost,
Metadata: map[string]string{
"serviceCost": fmt.Sprint(serviceCost),
},
Tags: tags,
FetchedAt: time.Now(),
Link: fmt.Sprintf("https://%s.console.aws.amazon.com/cloudwatch/home?region=%s#dashboards:name=%s", client.AWSClient.Region, client.AWSClient.Region, *dashboard.DashboardName),
Expand Down
8 changes: 8 additions & 0 deletions providers/aws/codebuild/projects.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/aws/aws-sdk-go-v2/service/sts"
"github.com/tailwarden/komiser/models"
"github.com/tailwarden/komiser/providers"
awsUtils "github.com/tailwarden/komiser/providers/aws/utils"
)

func BuildProjects(ctx context.Context, client providers.ProviderClient) ([]models.Resource, error) {
Expand All @@ -25,6 +26,10 @@ func BuildProjects(ctx context.Context, client providers.ProviderClient) ([]mode
return resources, err
}

serviceCost, err := awsUtils.GetCostAndUsage(ctx, client.AWSClient.Region, "CodeBuild")
if err != nil {
log.Warnln("Couldn't fetch CodeBuild cost and usage:", err)
}
accountId := stsOutput.Account

for {
Expand All @@ -44,6 +49,9 @@ func BuildProjects(ctx context.Context, client providers.ProviderClient) ([]mode
ResourceId: resourceArn,
Region: client.AWSClient.Region,
Name: project,
Metadata: map[string]string{
"serviceCost": fmt.Sprint(serviceCost),
},
Tags: tags,
FetchedAt: time.Now(),
Link: fmt.Sprintf("https://%s.console.aws.amazon.com/codesuite/codebuild/%s/projects/%s/details?region=%s", client.AWSClient.Region, *accountId, project, client.AWSClient.Region),
Expand Down
12 changes: 11 additions & 1 deletion providers/aws/codedeploy/deployment_groups.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ package codedeploy
import (
"context"
"fmt"
"time"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/codedeploy"
"github.com/aws/aws-sdk-go-v2/service/sts"
log "github.com/sirupsen/logrus"
"github.com/tailwarden/komiser/models"
"github.com/tailwarden/komiser/providers"
"time"
awsUtils "github.com/tailwarden/komiser/providers/aws/utils"
)

func DeploymentGroups(ctx context.Context, client providers.ProviderClient) ([]models.Resource, error) {
Expand All @@ -23,6 +25,11 @@ func DeploymentGroups(ctx context.Context, client providers.ProviderClient) ([]m
}
accountId := stsOutput.Account

serviceCost, err := awsUtils.GetCostAndUsage(ctx, client.AWSClient.Region, "CodeDeploy")
if err != nil {
log.Warnln("Couldn't fetch CodeDeploy cost and usage:", err)
}

for {
output, err := codedeployClient.ListApplications(ctx, &listApplicationParams)
if err != nil {
Expand All @@ -47,6 +54,9 @@ func DeploymentGroups(ctx context.Context, client providers.ProviderClient) ([]m
ResourceId: resourceArn,
Region: client.AWSClient.Region,
Name: deploymentGroup,
Metadata: map[string]string{
"serviceCost": fmt.Sprint(serviceCost),
},
Tags: tags,
FetchedAt: time.Now(),
})
Expand Down
9 changes: 8 additions & 1 deletion providers/aws/dynamodb/tables.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ import (
"github.com/aws/aws-sdk-go-v2/service/pricing"
"github.com/aws/aws-sdk-go-v2/service/pricing/types"
"github.com/aws/aws-sdk-go-v2/service/sts"
awsUtils "github.com/tailwarden/komiser/providers/aws/utils"
. "github.com/tailwarden/komiser/models"
. "github.com/tailwarden/komiser/providers"
awsUtils "github.com/tailwarden/komiser/providers/aws/utils"
)


Expand All @@ -30,6 +30,10 @@ func Tables(ctx context.Context, client ProviderClient) ([]Resource, error) {
client.AWSClient.Region = "us-east-1"
pricingClient := pricing.NewFromConfig(*client.AWSClient)
client.AWSClient.Region = oldRegion
serviceCost, err := awsUtils.GetCostAndUsage(ctx, client.AWSClient.Region, "DynamoDB")
if err != nil {
log.Warnln("Couldn't fetch DynamoDB cost and usage:", err)
}

pricingOutput, err := pricingClient.GetProducts(ctx, &pricing.GetProductsInput{
ServiceCode: aws.String("AmazonDynamoDB"),
Expand Down Expand Up @@ -110,6 +114,9 @@ func Tables(ctx context.Context, client ProviderClient) ([]Resource, error) {
Region: client.AWSClient.Region,
Name: table,
Cost: monthlyCost,
Metadata: map[string]string{
"serviceCost": fmt.Sprint(serviceCost),
},
Tags: tags,
FetchedAt: time.Now(),
Link: fmt.Sprintf("https://%s.console.aws.amazon.com/dynamodbv2/home?region=%s#table?initialTagKey=&name=%s", client.AWSClient.Region, client.AWSClient.Region, table),
Expand Down
7 changes: 7 additions & 0 deletions providers/aws/ec2/instances.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/aws/aws-sdk-go-v2/service/sts"
"github.com/tailwarden/komiser/models"
"github.com/tailwarden/komiser/providers"
awsUtils "github.com/tailwarden/komiser/providers/aws/utils"
"github.com/tailwarden/komiser/utils"
)

Expand All @@ -33,6 +34,11 @@ func Instances(ctx context.Context, client providers.ProviderClient) ([]models.R

accountId := stsOutput.Account

serviceCost, err := awsUtils.GetCostAndUsage(ctx, client.AWSClient.Region, "EC2")
if err != nil {
log.Warnln("Couldn't fetch EC2 cost and usage:", err)
}

oldRegion := client.AWSClient.Region
client.AWSClient.Region = "us-east-1"
pricingClient := pricing.NewFromConfig(*client.AWSClient)
Expand Down Expand Up @@ -151,6 +157,7 @@ func Instances(ctx context.Context, client providers.ProviderClient) ([]models.R
Metadata: map[string]string{
"instanceType": string(instance.InstanceType),
"state": string(instance.State.Name),
"serviceCost": fmt.Sprint(serviceCost),
},
Link: fmt.Sprintf("https://%s.console.aws.amazon.com/ec2/home?region=%s#InstanceDetails:instanceId=%s", client.AWSClient.Region, client.AWSClient.Region, *instance.InstanceId),
})
Expand Down
8 changes: 8 additions & 0 deletions providers/aws/ecr/repositories.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,17 @@ import (
"github.com/aws/aws-sdk-go-v2/service/ecr"
. "github.com/tailwarden/komiser/models"
. "github.com/tailwarden/komiser/providers"
awsUtils "github.com/tailwarden/komiser/providers/aws/utils"
)

func Repositories(ctx context.Context, client ProviderClient) ([]Resource, error) {
resources := make([]Resource, 0)
var config ecr.DescribeRepositoriesInput
ecrClient := ecr.NewFromConfig(*client.AWSClient)
serviceCost, err := awsUtils.GetCostAndUsage(ctx, client.AWSClient.Region, "ECR")
if err != nil {
log.Warnln("Couldn't fetch ECR cost and usage:", err)
}
for {
output, err := ecrClient.DescribeRepositories(context.Background(), &config)
if err != nil {
Expand Down Expand Up @@ -47,6 +52,9 @@ func Repositories(ctx context.Context, client ProviderClient) ([]Resource, error
Region: client.AWSClient.Region,
Name: *repository.RepositoryName,
Cost: 0.10,
Metadata: map[string]string{
"serviceCost": fmt.Sprint(serviceCost),
},
Tags: tags,
FetchedAt: time.Now(),
Link: fmt.Sprintf("https://%s.console.aws.amazon.com/ecr/repositories/%s", client.AWSClient.Region, *repository.RepositoryName),
Expand Down
8 changes: 8 additions & 0 deletions providers/aws/ecs/containers.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/aws/aws-sdk-go-v2/service/sts"
. "github.com/tailwarden/komiser/models"
. "github.com/tailwarden/komiser/providers"
awsUtils "github.com/tailwarden/komiser/providers/aws/utils"
)

func ContainerInstances(ctx context.Context, client ProviderClient) ([]Resource, error) {
Expand All @@ -26,6 +27,10 @@ func ContainerInstances(ctx context.Context, client ProviderClient) ([]Resource,
return resources, err
}

serviceCost, err := awsUtils.GetCostAndUsage(ctx, client.AWSClient.Region, "ECS")
if err != nil {
log.Warnln("Couldn't fetch ECS cost and usage:", err)
}
accountId := stsOutput.Account
for {
output, err := ecsContainer.ListContainerInstances(context.Background(), &config)
Expand All @@ -44,6 +49,9 @@ func ContainerInstances(ctx context.Context, client ProviderClient) ([]Resource,
Region: client.AWSClient.Region,
Name: containerInstance,
Cost: 0,
Metadata: map[string]string{
"serviceCost": fmt.Sprint(serviceCost),
},
FetchedAt: time.Now(),
Link: fmt.Sprintf("https://%s.console.aws.amazon.com/ecs/home?#/containers/%s", client.AWSClient.Region, containerInstance),
})
Expand Down
9 changes: 9 additions & 0 deletions providers/aws/efs/efs.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/aws/aws-sdk-go-v2/service/sts"
. "github.com/tailwarden/komiser/models"
. "github.com/tailwarden/komiser/providers"
awsUtils "github.com/tailwarden/komiser/providers/aws/utils"
)

func ElasticFileStorage(ctx context.Context, client ProviderClient) ([]Resource, error) {
Expand All @@ -27,6 +28,11 @@ func ElasticFileStorage(ctx context.Context, client ProviderClient) ([]Resource,

accountId := stsOutput.Account

serviceCost, err := awsUtils.GetCostAndUsage(ctx, client.AWSClient.Region, "EFS")
if err != nil {
log.Warnln("Couldn't fetch EFS cost and usage:", err)
}

for {
output, err := efsClient.DescribeFileSystems(ctx, &config)
if err != nil {
Expand Down Expand Up @@ -62,6 +68,9 @@ func ElasticFileStorage(ctx context.Context, client ProviderClient) ([]Resource,
Region: client.AWSClient.Region,
Name: *filesystem.Name,
Cost: monthlyCost,
Metadata: map[string]string{
"serviceCost": fmt.Sprint(serviceCost),
},
Tags: tags,
FetchedAt: time.Now(),
Link: fmt.Sprintf("https://%s.console.aws.amazon.com/efs/home?region=%s#/file-systems/%s", client.AWSClient.Region, client.AWSClient.Region, *filesystem.Name),
Expand Down
7 changes: 7 additions & 0 deletions providers/aws/eks/clusters.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/aws/aws-sdk-go-v2/service/sts"
. "github.com/tailwarden/komiser/models"
. "github.com/tailwarden/komiser/providers"
awsUtils "github.com/tailwarden/komiser/providers/aws/utils"
"github.com/tailwarden/komiser/utils"
)

Expand All @@ -28,6 +29,11 @@ func KubernetesClusters(ctx context.Context, client ProviderClient) ([]Resource,

accountId := stsOutput.Account

serviceCost, err := awsUtils.GetCostAndUsage(ctx, client.AWSClient.Region, "EKS")
if err != nil {
log.Warnln("Couldn't fetch EKS cost and usage:", err)
}

for {
output, err := eksClient.ListClusters(ctx, &config)
if err != nil {
Expand Down Expand Up @@ -96,6 +102,7 @@ func KubernetesClusters(ctx context.Context, client ProviderClient) ([]Resource,
"region": client.AWSClient.Region,
"service": "EKS",
"resources": len(resources),
"serviceCost":fmt.Sprint(serviceCost),
}).Info("Fetched resources")
return resources, nil
}
7 changes: 7 additions & 0 deletions providers/aws/elasticache/clusters.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/tailwarden/komiser/models"
. "github.com/tailwarden/komiser/models"
. "github.com/tailwarden/komiser/providers"
awsUtils "github.com/tailwarden/komiser/providers/aws/utils"
"github.com/tailwarden/komiser/utils"
)

Expand All @@ -26,6 +27,11 @@ func Clusters(ctx context.Context, client ProviderClient) ([]Resource, error) {

pricingClient := pricing.NewFromConfig(*client.AWSClient)

serviceCost, err := awsUtils.GetCostAndUsage(ctx, client.AWSClient.Region, "Elasticache")
if err != nil {
log.Warnln("Couldn't fetch Elasticache cost and usage:", err)
}

for {
output, err := elasticacheClient.DescribeCacheClusters(ctx, &config)
if err != nil {
Expand Down Expand Up @@ -122,6 +128,7 @@ func Clusters(ctx context.Context, client ProviderClient) ([]Resource, error) {
"nodeType": *cluster.CacheNodeType,
"status": *cluster.CacheClusterStatus,
"clusterId": *cluster.CacheClusterId,
"serviceCost": fmt.Sprint(serviceCost),
},
FetchedAt: time.Now(),
Link: fmt.Sprintf("https:/%s.console.aws.amazon.com/elasticache/home?region=%s#/%s/%s", client.AWSClient.Region, client.AWSClient.Region, *cluster.Engine, *cluster.CacheClusterId),
Expand Down
9 changes: 9 additions & 0 deletions providers/aws/elb/loadbalancers.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2"
. "github.com/tailwarden/komiser/models"
. "github.com/tailwarden/komiser/providers"
awsUtils "github.com/tailwarden/komiser/providers/aws/utils"
"github.com/tailwarden/komiser/utils"
)

Expand Down Expand Up @@ -38,6 +39,11 @@ func LoadBalancers(ctx context.Context, client ProviderClient) ([]Resource, erro
var configListeners elasticloadbalancingv2.DescribeListenersInput
var configRules elasticloadbalancingv2.DescribeRulesInput

serviceCost, err := awsUtils.GetCostAndUsage(ctx, client.AWSClient.Region, "ELB")
if err != nil {
log.Warnln("Couldn't fetch ELB cost and usage:", err)
}

for _, loadbalancer := range output.LoadBalancers {
resourceArn := *loadbalancer.LoadBalancerArn
resourceType := string(loadbalancer.Type)
Expand Down Expand Up @@ -76,6 +82,9 @@ func LoadBalancers(ctx context.Context, client ProviderClient) ([]Resource, erro
Region: client.AWSClient.Region,
Name: *loadbalancer.LoadBalancerName,
Cost: monthlyCost,
Metadata: map[string]string{
"serviceCost": fmt.Sprint(serviceCost),
},
Tags: tags,
CreatedAt: *loadbalancer.CreatedTime,
FetchedAt: time.Now(),
Expand Down
Loading