forked from LinTechSo/sloth
-
Notifications
You must be signed in to change notification settings - Fork 0
/
plugin.go
72 lines (61 loc) 路 1.55 KB
/
plugin.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
package availability
import (
"bytes"
"context"
"fmt"
"regexp"
"strings"
"text/template"
)
const (
SLIPluginVersion = "prometheus/v1"
SLIPluginID = "integration_test"
)
var tpl = template.Must(template.New("").Parse(`
sum(rate(integration_test{ {{.filter}}job="{{.job}}",code=~"(5..|429)" }[{{"{{.window}}"}}]))
/
sum(rate(integration_test{ {{.filter}}job="{{.job}}" }[{{"{{.window}}"}}]))`))
var filterRegex = regexp.MustCompile(`([^=]+="[^=,"]+",)+`)
func SLIPlugin(ctx context.Context, meta, labels, options map[string]string) (string, error) {
// Get job.
job, ok := options["job"]
if !ok {
return "", fmt.Errorf("job options is required")
}
// Validate labels.
err := validateLabels(labels, "owner", "tier")
if err != nil {
return "", fmt.Errorf("invalid labels: %w", err)
}
// Sanitize filter.
filter := options["filter"]
if filter != "" {
filter = strings.Trim(filter, "{}")
filter = strings.Trim(filter, ",")
filter = filter + ","
match := filterRegex.MatchString(filter)
if !match {
return "", fmt.Errorf("invalid prometheus filter: %s", filter)
}
}
// Create query.
var b bytes.Buffer
data := map[string]string{
"job": job,
"filter": filter,
}
err = tpl.Execute(&b, data)
if err != nil {
return "", fmt.Errorf("could not execute template: %w", err)
}
return b.String(), nil
}
func validateLabels(labels map[string]string, requiredKeys ...string) error {
for _, k := range requiredKeys {
v, ok := labels[k]
if !ok || (ok && v == "") {
return fmt.Errorf("%q label is required", k)
}
}
return nil
}