Skip to content

Commit f286985

Browse files
committed
improve quota (auto detection for apiversions)
Signed-off-by: Markus Blaschke <mblaschke82@gmail.com>
1 parent 1df60b1 commit f286985

5 files changed

Lines changed: 67 additions & 10 deletions

File tree

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/vendor/
22
/azure-resourcemanager-exporter*
33
/release-assets
4-
/.vscode
4+
/.vscode
5+
/example.dev.yaml

config/config_quota.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
package config
22

3+
import (
4+
"encoding/json"
5+
)
6+
37
type (
48
CollectorQuota struct {
59
*CollectorBase `yaml:",inline"`
@@ -12,3 +16,29 @@ type (
1216
ApiVersion string `json:"apiVersion"`
1317
}
1418
)
19+
20+
func (rp *CollectorQuotaResourceProvider) UnmarshalJSON(data []byte) error {
21+
var (
22+
valString string
23+
valResourceProvider struct {
24+
Provider string `json:"provider"`
25+
ApiVersion string `json:"apiVersion"`
26+
}
27+
)
28+
29+
// try string first
30+
if err := json.Unmarshal(data, &valString); err == nil {
31+
rp.Provider = valString
32+
rp.ApiVersion = "auto"
33+
return nil
34+
}
35+
36+
// try full version
37+
err := json.Unmarshal(data, &valResourceProvider)
38+
if err != nil {
39+
return err
40+
}
41+
rp.Provider = valResourceProvider.Provider
42+
rp.ApiVersion = valResourceProvider.ApiVersion
43+
return nil
44+
}

example.yaml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,11 @@ collectors:
3535
scrapeTime: 5m
3636

3737
resourceProviders:
38-
- {provider: Microsoft.App, apiVersion: "2025-06-01"}
39-
- {provider: Microsoft.Compute, apiVersion: "2025-04-01"}
40-
- {provider: Microsoft.Network, apiVersion: "2025-05-01"}
41-
- {provider: Microsoft.Storage, apiVersion: "2025-06-01"}
42-
- {provider: Microsoft.MachineLearningServices, apiVersion: "2025-06-01"}
38+
- Microsoft.App # simple version, uses auto detected apiVersion
39+
- {provider: Microsoft.Compute, apiVersion: "auto"} # full version
40+
- {provider: Microsoft.Network, apiVersion: "auto"}
41+
- {provider: Microsoft.Storage, apiVersion: "auto"}
42+
- {provider: Microsoft.MachineLearningServices, apiVersion: "2025-06-01"} # use specific apiVersion
4343

4444
# Azure Advisor recommendations
4545
advisor:

main.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ func initArgparser() {
102102
func initConfig() {
103103
var err error
104104

105-
err = yaml.UnmarshalWithOptions(defaultConfig, &Config, yaml.Strict())
105+
err = yaml.UnmarshalWithOptions(defaultConfig, &Config, yaml.Strict(), yaml.UseJSONUnmarshaler())
106106
if err != nil {
107107
logger.Fatal(err.Error())
108108
}
@@ -114,7 +114,7 @@ func initConfig() {
114114
logger.Fatal(err.Error())
115115
}
116116

117-
err = yaml.UnmarshalWithOptions(content, &Config, yaml.Strict())
117+
err = yaml.UnmarshalWithOptions(content, &Config, yaml.Strict(), yaml.UseJSONUnmarshaler())
118118
if err != nil {
119119
logger.Fatal(err.Error())
120120
}

metrics_azurerm_quota.go

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package main
22

33
import (
44
"errors"
5-
"fmt"
65
"io"
76
"log/slog"
87
"net/http"
@@ -198,6 +197,33 @@ func (m *MetricsCollectorAzureRmQuota) collectQuotaUsage(subscription *armsubscr
198197
quotaLimitMetric := m.Collector.GetMetricList("quotaLimit")
199198
quotaUsageMetric := m.Collector.GetMetricList("quotaUsage")
200199

200+
if provider.ApiVersion == "" || strings.EqualFold(provider.ApiVersion, "auto") {
201+
provider.ApiVersion = ""
202+
203+
// lookup api version
204+
providerInfo, err := AzureClient.GetResourceProvider(m.Context(), *subscription.SubscriptionID, provider.Provider)
205+
if err != nil {
206+
logger.Error("failed to lookup Azure resource provider", slog.Any("error", err))
207+
panic(err)
208+
}
209+
210+
if providerInfo != nil {
211+
for _, providerResource := range providerInfo.ResourceTypes {
212+
if to.String(providerResource.DefaultAPIVersion) != "" {
213+
provider.ApiVersion = to.String(providerResource.DefaultAPIVersion)
214+
break
215+
}
216+
}
217+
}
218+
219+
if provider.ApiVersion == "" {
220+
logger.Error("failed to lookup Azure resource provider apiVersion")
221+
panic("failed to lookup Azure resource provider apiVersion")
222+
}
223+
}
224+
225+
logger = logger.With(slog.String("apiVersion", provider.ApiVersion))
226+
201227
options := AzureClient.NewArmClientOptions()
202228
ep := cloud.AzurePublic.Services[cloud.ResourceManager].Endpoint
203229
if c, ok := options.Cloud.Services[cloud.ResourceManager]; ok {
@@ -215,8 +241,8 @@ func (m *MetricsCollectorAzureRmQuota) collectQuotaUsage(subscription *armsubscr
215241
urlPath = strings.ReplaceAll(urlPath, "{provider}", url.PathEscape(provider.Provider))
216242
urlPath = strings.ReplaceAll(urlPath, "{location}", url.PathEscape(location))
217243

244+
logger.Info("fetch resource usage and quota")
218245
requestUrl := runtime.JoinPaths(ep, urlPath)
219-
fmt.Println(requestUrl)
220246
for {
221247
req, err := runtime.NewRequest(m.Context(), http.MethodGet, requestUrl)
222248
if err != nil {

0 commit comments

Comments
 (0)