Skip to content

Commit 5407693

Browse files
committed
WIP: azure cost scraper
1 parent aa0c220 commit 5407693

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
@@ -10,6 +10,7 @@ require (
1010
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute v1.0.0
1111
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerregistry/armcontainerregistry v1.0.0
1212
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice v1.0.0
13+
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/costmanagement/armcostmanagement v1.1.0
1314
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/dns/armdns v1.1.0
1415
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork v1.1.0
1516
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/privatedns/armprivatedns v1.1.0

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,8 @@ github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerregistry/armconta
477477
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerregistry/armcontainerregistry v1.0.0/go.mod h1:tOckqrJq0CXsb/AlUYCdD7DqpULgOaexk+5rz+isAjM=
478478
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice v1.0.0 h1:figxyQZXzZQIcP3njhC68bYUiTw45J8/SsHaLW8Ax0M=
479479
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice v1.0.0/go.mod h1:TmlMW4W5OvXOmOyKNnor8nlMMiO1ctIyzmHme/VHsrA=
480+
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/costmanagement/armcostmanagement v1.1.0 h1:1MRED2aeLx/BPHC23XRtr8Mk6zcc70HNRYPQ73R0gHw=
481+
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/costmanagement/armcostmanagement v1.1.0/go.mod h1:Am1cUioOk0HdZIsjpXJkQ4RIeQbwYsW6LkNIc5z/5XY=
480482
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/dns/armdns v1.1.0 h1:8iR6OLffWWorFdzL2JFCab5xpD8VKEE2DUBBl+HNTDY=
481483
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/dns/armdns v1.1.0/go.mod h1:copqlcjMWc/wgQ1N2fzsJFQxDdqKGg1EQt8T5wJMOGE=
482484
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal v1.1.2 h1:mLY+pNLjCUeKhgnAJWAKhEUQM+RJQo2H1fuGSw1Ky1E=

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
@@ -18,7 +18,8 @@ import (
1818

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

0 commit comments

Comments
 (0)