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

Remaining Cost Explorer API integration #1351

Merged
merged 24 commits into from
Feb 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 17 additions & 8 deletions providers/aws/cloudwatch/alarms.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,17 @@ import (

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/cloudwatch"
. "github.com/tailwarden/komiser/models"
. "github.com/tailwarden/komiser/providers"
"github.com/tailwarden/komiser/models"
"github.com/tailwarden/komiser/providers"
awsUtils "github.com/tailwarden/komiser/providers/aws/utils"
)

const (
AverageHoursPerMonth = 730
)

func Alarms(ctx context.Context, client ProviderClient) ([]Resource, error) {
resources := make([]Resource, 0)
func Alarms(ctx context.Context, client providers.ProviderClient) ([]models.Resource, error) {
resources := make([]models.Resource, 0)
var config cloudwatch.DescribeAlarmsInput
// This code temporarily changes the region to "us-east-1" and creates a new Pricing client
// then changes the region back to what it was before.
Expand All @@ -33,6 +34,11 @@ func Alarms(ctx context.Context, client ProviderClient) ([]Resource, error) {
pricingClient := pricing.NewFromConfig(*client.AWSClient)
client.AWSClient.Region = oldRegion
cloudWatchClient := cloudwatch.NewFromConfig(*client.AWSClient)

serviceCost, err := awsUtils.GetCostAndUsage(ctx, client.AWSClient.Region, "AmazonCloudWatch")
if err != nil {
log.Warnln("Couldn't fetch AmazonCloudWatch cost and usage:", err)
}
for {
output, err := cloudWatchClient.DescribeAlarms(ctx, &config)
if err != nil {
Expand All @@ -44,11 +50,11 @@ func Alarms(ctx context.Context, client ProviderClient) ([]Resource, error) {
ResourceARN: alarm.AlarmArn,
})

tags := make([]Tag, 0)
tags := make([]models.Tag, 0)

if err == nil {
for _, tag := range outputTags.Tags {
tags = append(tags, Tag{
tags = append(tags, models.Tag{
Key: *tag.Key,
Value: *tag.Value,
})
Expand Down Expand Up @@ -82,7 +88,7 @@ func Alarms(ctx context.Context, client ProviderClient) ([]Resource, error) {
continue
}

resources = append(resources, Resource{
resources = append(resources, models.Resource{
Provider: "AWS",
Account: client.Name,
Service: "CloudWatch",
Expand All @@ -92,7 +98,10 @@ func Alarms(ctx context.Context, client ProviderClient) ([]Resource, error) {
Cost: costPerMonth,
Tags: tags,
FetchedAt: time.Now(),
Link: fmt.Sprintf("https://%s.console.aws.amazon.com/cloudwatch/home?region=%s#alarmsV2:alarm/%s", client.AWSClient.Region, client.AWSClient.Region, *alarm.AlarmName),
Metadata: map[string]string{
"serviceCost": fmt.Sprint(serviceCost),
},
Link: fmt.Sprintf("https://%s.console.aws.amazon.com/cloudwatch/home?region=%s#alarmsV2:alarm/%s", client.AWSClient.Region, client.AWSClient.Region, *alarm.AlarmName),
})
}

Expand Down
21 changes: 15 additions & 6 deletions providers/aws/cloudwatch/log_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,38 @@ import (
"github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs"
log "github.com/sirupsen/logrus"

. "github.com/tailwarden/komiser/models"
. "github.com/tailwarden/komiser/providers"
"github.com/tailwarden/komiser/models"
"github.com/tailwarden/komiser/providers"
awsUtils "github.com/tailwarden/komiser/providers/aws/utils"
)

func LogGroups(ctx context.Context, client ProviderClient) ([]Resource, error) {
resources := make([]Resource, 0)
func LogGroups(ctx context.Context, client providers.ProviderClient) ([]models.Resource, error) {
resources := make([]models.Resource, 0)
cloudWatchLogsClient := cloudwatchlogs.NewFromConfig(*client.AWSClient)
input := &cloudwatchlogs.DescribeLogGroupsInput{}

serviceCost, err := awsUtils.GetCostAndUsage(ctx, client.AWSClient.Region, "AmazonCloudWatch")
if err != nil {
log.Warnln("Couldn't fetch AmazonCloudWatch cost and usage:", err)
}
for {
output, err := cloudWatchLogsClient.DescribeLogGroups(ctx, input)
if err != nil {
return resources, err
}
for _, group := range output.LogGroups {
resources = append(resources, Resource{
resources = append(resources, models.Resource{
Provider: "AWS",
Account: client.Name,
Service: "CloudWatch Log Group",
ResourceId: aws.ToString(group.Arn),
Region: client.AWSClient.Region,
Name: aws.ToString(group.LogGroupName),
FetchedAt: time.Now(),
Link: fmt.Sprintf("https://%s.console.aws.amazon.com/cloudwatch/home?region=%s#logsV2:log-groups/log-group/%s", client.AWSClient.Region, client.AWSClient.Region, aws.ToString(group.LogGroupName)),
Metadata: map[string]string{
"serviceCost": fmt.Sprint(serviceCost),
},
Link: fmt.Sprintf("https://%s.console.aws.amazon.com/cloudwatch/home?region=%s#logsV2:log-groups/log-group/%s", client.AWSClient.Region, client.AWSClient.Region, aws.ToString(group.LogGroupName)),
})
}
if output.NextToken == nil {
Expand Down
11 changes: 10 additions & 1 deletion providers/aws/cloudwatch/log_metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (

"github.com/tailwarden/komiser/models"
"github.com/tailwarden/komiser/providers"
awsUtils "github.com/tailwarden/komiser/providers/aws/utils"
)

func getRate(pricingOutput *pricing.GetProductsOutput) (float64, error) {
Expand Down Expand Up @@ -86,6 +87,11 @@ func MetricStreams(ctx context.Context, client providers.ProviderClient) ([]mode
return resources, err
}

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

input := &cloudwatch.ListMetricStreamsInput{}
for {
output, err := cloudWatchMetricsClient.ListMetricStreams(ctx, input)
Expand Down Expand Up @@ -138,7 +144,10 @@ func MetricStreams(ctx context.Context, client providers.ProviderClient) ([]mode
Cost: monthlyCost,
Tags: tags,
FetchedAt: time.Now(),
Link: fmt.Sprintf("https://%s.console.aws.amazon.com/cloudwatch/home?region=%s#metric-streams:streamsList/%s", client.AWSClient.Region, client.AWSClient.Region, aws.ToString(stream.Name)),
Metadata: map[string]string{
"serviceCost": fmt.Sprint(serviceCost),
},
Link: fmt.Sprintf("https://%s.console.aws.amazon.com/cloudwatch/home?region=%s#metric-streams:streamsList/%s", client.AWSClient.Region, client.AWSClient.Region, aws.ToString(stream.Name)),
})
}

Expand Down
25 changes: 17 additions & 8 deletions providers/aws/elb/targetgroups.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ import (
log "github.com/sirupsen/logrus"

"github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2"
. "github.com/tailwarden/komiser/models"
. "github.com/tailwarden/komiser/providers"
"github.com/tailwarden/komiser/models"
"github.com/tailwarden/komiser/providers"
awsUtils "github.com/tailwarden/komiser/providers/aws/utils"
)

func TargetGroups(ctx context.Context, client ProviderClient) ([]Resource, error) {
resources := make([]Resource, 0)
func TargetGroups(ctx context.Context, client providers.ProviderClient) ([]models.Resource, error) {
resources := make([]models.Resource, 0)

var config elasticloadbalancingv2.DescribeTargetGroupsInput
elbtgClient := elasticloadbalancingv2.NewFromConfig(*client.AWSClient)
Expand All @@ -24,6 +25,11 @@ func TargetGroups(ctx context.Context, client ProviderClient) ([]Resource, error
return resources, err
}

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

for _, targetgroup := range output.TargetGroups {
resourceArn := *targetgroup.TargetGroupArn
outputTags, err := elbtgClient.DescribeTags(ctx, &elasticloadbalancingv2.DescribeTagsInput{
Expand All @@ -33,17 +39,17 @@ func TargetGroups(ctx context.Context, client ProviderClient) ([]Resource, error
return resources, err
}

tags := make([]Tag, 0)
tags := make([]models.Tag, 0)
for _, tagDescription := range outputTags.TagDescriptions {
for _, tag := range tagDescription.Tags {
tags = append(tags, Tag{
tags = append(tags, models.Tag{
Key: *tag.Key,
Value: *tag.Value,
})
}
}

resources = append(resources, Resource{
resources = append(resources, models.Resource{
Provider: "AWS",
Account: client.Name,
Service: "Target Group",
Expand All @@ -52,7 +58,10 @@ func TargetGroups(ctx context.Context, client ProviderClient) ([]Resource, error
Name: *targetgroup.TargetGroupName,
Tags: tags,
FetchedAt: time.Now(),
Link: fmt.Sprintf("https://%s.console.aws.amazon.com/ec2/home?region=%s#TargetGroup:targetGroupArn=%s", client.AWSClient.Region, client.AWSClient.Region, resourceArn),
Metadata: map[string]string{
"serviceCost": fmt.Sprint(serviceCost),
},
Link: fmt.Sprintf("https://%s.console.aws.amazon.com/ec2/home?region=%s#TargetGroup:targetGroupArn=%s", client.AWSClient.Region, client.AWSClient.Region, resourceArn),
})
}

Expand Down
9 changes: 5 additions & 4 deletions providers/aws/neptune/clusters.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ func Clusters(ctx context.Context, client providers.ProviderClient) ([]models.Re
}

for _, cluster := range output.DBClusters {

clusterName := *cluster.DatabaseName

clusterName := ""
if cluster.DatabaseName != nil {
clusterName = *cluster.DatabaseName
}
resources = append(resources, models.Resource{
Provider: "AWS",
Account: client.Name,
Expand All @@ -33,7 +34,7 @@ func Clusters(ctx context.Context, client providers.ProviderClient) ([]models.Re
ResourceId: *cluster.DBClusterArn,
Name: clusterName,
FetchedAt: time.Now(),
Link: fmt.Sprintf("https://%s.console.aws.amazon.com/neptune/home?region=%s#database-details:id=%s;resource-type=cluster;tab=connectivity", client.AWSClient.Region, client.AWSClient.Region, *cluster.DatabaseName),
Link: fmt.Sprintf("https://%s.console.aws.amazon.com/neptune/home?region=%s#database-details:id=%s;resource-type=cluster;tab=connectivity", client.AWSClient.Region, client.AWSClient.Region, clusterName),
})
}

Expand Down
7 changes: 6 additions & 1 deletion providers/aws/rds/auto_backups.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,17 @@ import (
log "github.com/sirupsen/logrus"
"github.com/tailwarden/komiser/models"
"github.com/tailwarden/komiser/providers"
awsUtils "github.com/tailwarden/komiser/providers/aws/utils"
)

func AutoBackups(ctx context.Context, client providers.ProviderClient) ([]models.Resource, error) {
var config rds.DescribeDBInstanceAutomatedBackupsInput
resources := make([]models.Resource, 0)
rdsClient := rds.NewFromConfig(*client.AWSClient)

serviceCost, err := awsUtils.GetCostAndUsage(ctx, client.AWSClient.Region, "RDS")
if err != nil {
log.Warnln("Couldn't fetch S3 cost and usage:", err)
}
for {
output, err := rdsClient.DescribeDBInstanceAutomatedBackups(ctx, &config)
if err != nil {
Expand All @@ -37,6 +41,7 @@ func AutoBackups(ctx context.Context, client providers.ProviderClient) ([]models
FetchedAt: time.Now(),
Link: fmt.Sprintf("https:/%s.console.aws.amazon.com/rds/home?region=%s#dbinstance:id=%s", client.AWSClient.Region, client.AWSClient.Region, *backup.DBInstanceIdentifier),
Metadata: map[string]string{
"serviceCost": fmt.Sprint(serviceCost),
"Engine": *backup.Engine,
"EngineVersion": *backup.EngineVersion,
},
Expand Down
7 changes: 6 additions & 1 deletion providers/aws/rds/cluster_snapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,18 @@ import (
"github.com/aws/aws-sdk-go-v2/service/rds"
"github.com/tailwarden/komiser/models"
"github.com/tailwarden/komiser/providers"
awsUtils "github.com/tailwarden/komiser/providers/aws/utils"
"github.com/tailwarden/komiser/utils"
)

func ClusterSnapshots(ctx context.Context, client providers.ProviderClient) ([]models.Resource, error) {
var config rds.DescribeDBClusterSnapshotsInput
resources := make([]models.Resource, 0)
rdsClient := rds.NewFromConfig(*client.AWSClient)

serviceCost, err := awsUtils.GetCostAndUsage(ctx, client.AWSClient.Region, "RDS")
if err != nil {
log.Warnln("Couldn't fetch S3 cost and usage:", err)
}
for {
output, err := rdsClient.DescribeDBClusterSnapshots(ctx, &config)
if err != nil {
Expand Down Expand Up @@ -58,6 +62,7 @@ func ClusterSnapshots(ctx context.Context, client providers.ProviderClient) ([]m
Tags: tags,
Link: fmt.Sprintf("https:/%s.console.aws.amazon.com/rds/home?region=%s#snapshots-list:id=%s", client.AWSClient.Region, client.AWSClient.Region, *clusterSnapshot.DBClusterSnapshotIdentifier),
Metadata: map[string]string{
"serviceCost": fmt.Sprint(serviceCost),
"Engine": *clusterSnapshot.Engine,
"EngineVersion": *clusterSnapshot.EngineVersion,
},
Expand Down
21 changes: 13 additions & 8 deletions providers/aws/rds/clusters.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,29 @@ import (

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/rds"
. "github.com/tailwarden/komiser/models"
. "github.com/tailwarden/komiser/providers"
"github.com/tailwarden/komiser/models"
"github.com/tailwarden/komiser/providers"
awsUtils "github.com/tailwarden/komiser/providers/aws/utils"
)

func Clusters(ctx context.Context, client ProviderClient) ([]Resource, error) {
func Clusters(ctx context.Context, client providers.ProviderClient) ([]models.Resource, error) {
var config rds.DescribeDBClustersInput
resources := make([]Resource, 0)
resources := make([]models.Resource, 0)
rdsClient := rds.NewFromConfig(*client.AWSClient)

serviceCost, err := awsUtils.GetCostAndUsage(ctx, client.AWSClient.Region, "RDS")
if err != nil {
log.Warnln("Couldn't fetch S3 cost and usage:", err)
}
for {
output, err := rdsClient.DescribeDBClusters(ctx, &config)
if err != nil {
return resources, err
}

for _, cluster := range output.DBClusters {
tags := make([]Tag, 0)
tags := make([]models.Tag, 0)
for _, tag := range cluster.TagList {
tags = append(tags, Tag{
tags = append(tags, models.Tag{
Key: *tag.Key,
Value: *tag.Value,
})
Expand All @@ -40,7 +44,7 @@ func Clusters(ctx context.Context, client ProviderClient) ([]Resource, error) {
_clusterName = *cluster.DatabaseName
}

resources = append(resources, Resource{
resources = append(resources, models.Resource{
Provider: "AWS",
Account: client.Name,
Service: "RDS",
Expand All @@ -54,6 +58,7 @@ func Clusters(ctx context.Context, client ProviderClient) ([]Resource, error) {
Metadata: map[string]string{
"Engine": *cluster.Engine,
"EngineVersion": *cluster.EngineVersion,
"serviceCost": fmt.Sprint(serviceCost),
},
})
}
Expand Down
14 changes: 11 additions & 3 deletions providers/aws/rds/db_proxy_endpoints.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ package rds
import (
"context"
"fmt"
"time"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/rds"
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 ProxyEndpoints(ctx context.Context, client providers.ProviderClient) ([]models.Resource, error) {
Expand All @@ -17,7 +19,10 @@ func ProxyEndpoints(ctx context.Context, client providers.ProviderClient) ([]mod
}
resources := make([]models.Resource, 0)
rdsClient := rds.NewFromConfig(*client.AWSClient)

serviceCost, err := awsUtils.GetCostAndUsage(ctx, client.AWSClient.Region, "RDS")
if err != nil {
log.Warnln("Couldn't fetch S3 cost and usage:", err)
}
for {
output, err := rdsClient.DescribeDBProxyEndpoints(ctx, &config)
if err != nil {
Expand Down Expand Up @@ -67,7 +72,10 @@ func ProxyEndpoints(ctx context.Context, client providers.ProviderClient) ([]mod
Name: _endpointName,
FetchedAt: time.Now(),
Tags: tags,
Link: fmt.Sprintf("https://%s.console.aws.amazon.com/rds/home?region=%s#db-proxy-details:id=%s", client.AWSClient.Region, client.AWSClient.Region, *endpoint.DBProxyEndpointName),
Metadata: map[string]string{
"serviceCost": fmt.Sprint(serviceCost),
},
Link: fmt.Sprintf("https://%s.console.aws.amazon.com/rds/home?region=%s#db-proxy-details:id=%s", client.AWSClient.Region, client.AWSClient.Region, *endpoint.DBProxyEndpointName),
})
}

Expand Down
Loading
Loading