Skip to content

Instantly share code, notes, and snippets.

@JoramM
Created March 29, 2023 12:17
Show Gist options
  • Save JoramM/c0538593c80822e37f6cd6d0d2c0c65f to your computer and use it in GitHub Desktop.
Save JoramM/c0538593c80822e37f6cd6d0d2c0c65f to your computer and use it in GitHub Desktop.
How to pull multiple pages of results form the Azure query API (https://learn.microsoft.com/en-us/rest/api/cost-management/query/usage?tabs=HTTP)
// define query
// import "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/costmanagement/armcostmanagement"
query := armcostmanagement.QueryDefinition{
Type: to.Ptr(armcostmanagement.ExportTypeUsage),
Timeframe: to.Ptr(armcostmanagement.TimeframeTypeCustom),
TimePeriod: &armcostmanagement.QueryTimePeriod{
From: start,
To: end,
},
Dataset: &armcostmanagement.QueryDataset{
Granularity: to.Ptr(armcostmanagement.GranularityType("Monthly")),
Aggregation: map[string]*armcostmanagement.QueryAggregation{
"totalCost": {
Name: to.Ptr("PreTaxCost"),
Function: to.Ptr(armcostmanagement.FunctionTypeSum),
},
},
Grouping: []*armcostmanagement.QueryGrouping{{
Type: to.Ptr(armcostmanagement.QueryColumnTypeDimension),
Name: to.Ptr("SubscriptionId"),
}},
},
}
// stringify query
body, err := json.MarshalIndent(query, "", " ")
if err != nil {
return nil, err
}
// create http client
endpoint := microsoft.AzureADEndpoint("your-tenant-id") // from "golang.org/x/oauth2/microsoft"
endpoint.AuthStyle = oauth2.AuthStyleInParams
var azureConfig = &clientcredentials.Config{
ClientID: "your-client-id",
ClientSecret: "your-client-secret",
Scopes: []string{"https://management.azure.com/.default"},
TokenURL: endpoint.TokenURL,
AuthStyle: oauth2.AuthStyleInParams,
}
client := azureConfig.Client()
res := armcostmanagement.QueryProperties{
NextLink: to.Ptr("https://management.azure.com" + scope + "/providers/Microsoft.CostManagement/query?api-version=2021-10-01"),
Columns: nil,
Rows: [][]interface{}{},
}
// pull the data
for res.NextLink != nil && *res.NextLink != "" {
host, err := url.ParseRequestURI(path)
// TODO: error handling
request, err := http.NewRequest(http.MethodPost, host.String(), body)
// TODO: error handling
request.Header.Set("Content-Type", "application/json")
nextPage, err := client.Do(request)
// TODO: error handling
decoder := json.NewDecoder(nextPage.Body)
data := &armcostmanagement.QueryClientUsageResponse{}
if err = decoder.Decode(data); err != nil {
return nil, err
}
res.Columns = data.Properties.Columns
res.NextLink = data.Properties.NextLink
res.Rows = append(res.Rows, data.Properties.Rows...) // at the end you have all rows inside this struct
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment