-
Notifications
You must be signed in to change notification settings - Fork 29
/
Copy pathsettings.go
196 lines (161 loc) · 4.9 KB
/
settings.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
package metrics
import (
"fmt"
"net/http"
"strconv"
"strings"
"time"
iso8601 "github.com/channelmeter/iso8601duration"
"github.com/webdevops/azure-metrics-exporter/config"
)
const (
PrometheusMetricNameDefault = "azurerm_resource_metric"
)
type (
RequestMetricSettings struct {
Name string
Subscriptions []string
ResourceType string
Filter string
Timespan string
Interval *string
Metrics []string
MetricNamespace string
Aggregations []string
Regions []string
// needed for dimension support
MetricTop *int32
MetricFilter string
MetricOrderBy string
ValidateDimensions bool
MetricTemplate string
HelpTemplate string
DimensionLowercase bool
// cache
Cache *time.Duration
}
)
func NewRequestMetricSettingsForAzureResourceApi(r *http.Request, opts config.Opts) (RequestMetricSettings, error) {
settings, err := NewRequestMetricSettings(r, opts)
if err != nil {
return settings, err
}
if r.URL.Path == config.ProbeMetricsResourceUrl {
return settings, nil
} else if settings.ResourceType != "" && settings.Filter != "" {
return settings, fmt.Errorf("parameter \"resourceType\" and \"filter\" are mutually exclusive")
} else if settings.ResourceType != "" {
settings.Filter = fmt.Sprintf(
"resourceType eq '%s'",
strings.ReplaceAll(settings.ResourceType, "'", "\\'"),
)
} else if settings.Filter == "" {
return settings, fmt.Errorf("parameter \"resourceType\" or \"filter\" is missing")
}
return settings, nil
}
func NewRequestMetricSettings(r *http.Request, opts config.Opts) (RequestMetricSettings, error) {
ret := RequestMetricSettings{
// force lowercasing of dimensions
DimensionLowercase: opts.Metrics.Dimensions.Lowercase,
}
params := r.URL.Query()
// param name
ret.Name = paramsGetWithDefault(params, "name", PrometheusMetricNameDefault)
// param subscription
if subscriptionList, err := paramsGetListRequired(params, "subscription"); err == nil {
for _, subscription := range subscriptionList {
subscription = strings.TrimSpace(subscription)
ret.Subscriptions = append(ret.Subscriptions, subscription)
}
} else {
return ret, err
}
// param region
if val, err := paramsGetList(params, "region"); err == nil {
ret.Regions = val
} else {
return ret, err
}
// param filter
ret.ResourceType = paramsGetWithDefault(params, "resourceType", "")
ret.Filter = paramsGetWithDefault(params, "filter", "")
if val, err := strconv.ParseBool(paramsGetWithDefault(params, "validateDimensions", "true")); err == nil {
ret.ValidateDimensions = val
} else {
return ret, err
}
// param timespan
ret.Timespan = paramsGetWithDefault(params, "timespan", "PT1M")
// param interval
if val := params.Get("interval"); val != "" {
ret.Interval = &val
}
// param metric
if val, err := paramsGetList(params, "metric"); err == nil {
ret.Metrics = val
} else {
return ret, err
}
// param metricNamespace
ret.MetricNamespace = paramsGetWithDefault(params, "metricNamespace", "")
// param aggregation
if val, err := paramsGetList(params, "aggregation"); err == nil {
ret.Aggregations = val
} else {
return ret, err
}
// param metricTop
if val := params.Get("metricTop"); val != "" {
valInt64, err := strconv.ParseInt(val, 10, 32)
if err != nil {
return ret, err
}
valInt32 := int32(valInt64)
ret.MetricTop = &valInt32
}
// param metricFilter
ret.MetricFilter = paramsGetWithDefault(params, "metricFilter", "")
// param metricOrderBy
ret.MetricOrderBy = paramsGetWithDefault(params, "metricOrderBy", "")
// param template
ret.MetricTemplate = paramsGetWithDefault(params, "template", opts.Metrics.Template)
// param help
ret.HelpTemplate = paramsGetWithDefault(params, "help", opts.Metrics.Help)
// param cache (timespan as default)
if opts.Prober.Cache {
cacheDefaultDuration, err := iso8601.FromString(ret.Timespan)
cacheDefaultDurationString := ""
if err == nil {
cacheDefaultDurationString = cacheDefaultDuration.ToDuration().String()
}
// get value from query (with default from timespan)
cacheDurationString := paramsGetWithDefault(params, "cache", cacheDefaultDurationString)
// only enable caching if value is set
if cacheDurationString != "" {
if val, err := time.ParseDuration(cacheDurationString); err == nil {
ret.Cache = &val
} else {
return ret, err
}
}
}
return ret, nil
}
func (s *RequestMetricSettings) CacheDuration(requestTime time.Time) (ret *time.Duration) {
if s.Cache != nil {
bufferDuration := 2 * time.Second
cachedUntilTime := requestTime.Add(*s.Cache).Add(-bufferDuration)
cacheDuration := time.Until(cachedUntilTime)
if cacheDuration.Seconds() > 0 {
ret = &cacheDuration
}
}
return
}
func (s *RequestMetricSettings) SetMetrics(val string) {
s.Metrics = stringToStringList(val, ",")
}
func (s *RequestMetricSettings) SetAggregations(val string) {
s.Aggregations = stringToStringList(val, ",")
}