Skip to content

Commit 72353a6

Browse files
committed
WIP: azure cost scraper
1 parent 1a30d52 commit 72353a6

File tree

4 files changed

+92
-1
lines changed

4 files changed

+92
-1
lines changed

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ require (
99
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute v1.0.0
1010
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerregistry/armcontainerregistry v1.0.0
1111
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice v1.0.0
12+
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/costmanagement/armcostmanagement v1.1.0
1213
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork v1.1.0
1314
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.1.0
1415
github.com/Jeffail/gabs/v2 v2.7.0

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,8 @@ github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerregistry/armconta
475475
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerregistry/armcontainerregistry v1.0.0/go.mod h1:tOckqrJq0CXsb/AlUYCdD7DqpULgOaexk+5rz+isAjM=
476476
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice v1.0.0 h1:figxyQZXzZQIcP3njhC68bYUiTw45J8/SsHaLW8Ax0M=
477477
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice v1.0.0/go.mod h1:TmlMW4W5OvXOmOyKNnor8nlMMiO1ctIyzmHme/VHsrA=
478+
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/costmanagement/armcostmanagement v1.1.0 h1:1MRED2aeLx/BPHC23XRtr8Mk6zcc70HNRYPQ73R0gHw=
479+
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/costmanagement/armcostmanagement v1.1.0/go.mod h1:Am1cUioOk0HdZIsjpXJkQ4RIeQbwYsW6LkNIc5z/5XY=
478480
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal v1.1.2 h1:mLY+pNLjCUeKhgnAJWAKhEUQM+RJQo2H1fuGSw1Ky1E=
479481
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/managementgroups/armmanagementgroups v1.0.0 h1:pPvTJ1dY0sA35JOeFq6TsY2xj6Z85Yo23Pj4wCCvu4o=
480482
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork v1.1.0 h1:QM6sE5k2ZT/vI5BEe0r7mqjsUSnhVBFbOsVkEuaEfiA=

scrapers/azure/cost.go

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package azure
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
8+
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/costmanagement/armcostmanagement"
9+
"github.com/flanksource/commons/logger"
10+
v1 "github.com/flanksource/config-db/api/v1"
11+
"github.com/flanksource/duty"
12+
)
13+
14+
type CostScraper struct {
15+
cred *azidentity.ClientSecretCredential
16+
}
17+
18+
func (t CostScraper) CanScrape(config v1.ConfigScraper) bool {
19+
// At least one of the azure configuration must have the subscription ID set
20+
for _, c := range config.Azure {
21+
if c.SubscriptionID != "" {
22+
return true
23+
}
24+
}
25+
26+
return false
27+
}
28+
29+
func (t CostScraper) Scrape(ctx *v1.ScrapeContext, config v1.ConfigScraper) v1.ScrapeResults {
30+
var results v1.ScrapeResults
31+
for _, config := range config.Azure {
32+
clientId, err := duty.GetEnvValueFromCache(ctx.Kubernetes, config.ClientID, ctx.Namespace)
33+
if err != nil {
34+
results.Errorf(err, "failed to get client id")
35+
continue
36+
}
37+
38+
clientSecret, err := duty.GetEnvValueFromCache(ctx.Kubernetes, config.ClientSecret, ctx.Namespace)
39+
if err != nil {
40+
results.Errorf(err, "failed to get client secret")
41+
continue
42+
}
43+
44+
cred, err := azidentity.NewClientSecretCredential(config.TenantID, clientId, clientSecret, nil)
45+
if err != nil {
46+
results.Errorf(err, "failed to get credentials for azure")
47+
continue
48+
}
49+
t.cred = cred
50+
51+
if err := t.GetCost(ctx.Context, config.SubscriptionID); err != nil {
52+
results.Errorf(err, "failed to get cost")
53+
continue
54+
}
55+
}
56+
57+
return results
58+
}
59+
60+
func (t *CostScraper) GetCost(ctx context.Context, subscriptionID string) error {
61+
costClient, err := armcostmanagement.NewQueryClient(t.cred, nil)
62+
if err != nil {
63+
return fmt.Errorf("failed to create cost client: %w", err)
64+
}
65+
66+
var (
67+
scope = fmt.Sprintf("/subscriptions/%s", subscriptionID)
68+
timeFrame = armcostmanagement.TimeframeTypeTheLastBillingMonth
69+
queryType = armcostmanagement.ExportTypeActualCost
70+
granularity = armcostmanagement.GranularityTypeDaily
71+
)
72+
queryDef := armcostmanagement.QueryDefinition{
73+
Dataset: &armcostmanagement.QueryDataset{
74+
Granularity: &granularity,
75+
},
76+
Timeframe: &timeFrame,
77+
Type: &queryType,
78+
}
79+
usageRes, err := costClient.Usage(ctx, scope, queryDef, nil)
80+
if err != nil {
81+
return fmt.Errorf("failed to get usage: %w", err)
82+
}
83+
84+
logger.Debugf("usage: %v", usageRes)
85+
86+
return nil
87+
}

scrapers/common.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ import (
1717

1818
// All is the scrappers registry
1919
var All = []v1.Scraper{
20-
azure.Scraper{},
20+
// azure.Scraper{},
21+
azure.CostScraper{},
2122
aws.Scraper{},
2223
aws.CostScraper{},
2324
file.FileScraper{},

0 commit comments

Comments
 (0)