diff --git a/pkg/services/ngalert/state/template/funcs.go b/pkg/services/ngalert/state/template/funcs.go index 4d89b606cfb..ad300969d2d 100644 --- a/pkg/services/ngalert/state/template/funcs.go +++ b/pkg/services/ngalert/state/template/funcs.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "net/url" + "regexp" "text/template" ) @@ -14,28 +15,77 @@ type query struct { var ( defaultFuncs = template.FuncMap{ - "graphLink": graphLink, - "tableLink": tableLink, + "filterLabels": filterLabelsFunc, + "filterLabelsRe": filterLabelsReFunc, + "graphLink": graphLinkFunc, + "removeLabels": removeLabelsFunc, + "removeLabelslRe": removeLabelsReFunc, + "tableLink": tableLinkFunc, } ) -var ( - graphLink = func(data string) string { - var q query - if err := json.Unmarshal([]byte(data), &q); err != nil { - return "" +// filterLabelsFunc removes all labels that do not match the string. +func filterLabelsFunc(m Labels, match string) Labels { + res := make(Labels) + for k, v := range m { + if k == match { + res[k] = v } - datasource := url.QueryEscape(q.Datasource) - expr := url.QueryEscape(q.Expr) - return fmt.Sprintf(`/explore?left={"datasource":%[1]q,"queries":[{"datasource":%[1]q,"expr":%q,"instant":false,"range":true,"refId":"A"}],"range":{"from":"now-1h","to":"now"}}`, datasource, expr) } - tableLink = func(data string) string { - var q query - if err := json.Unmarshal([]byte(data), &q); err != nil { - return "" + return res +} + +// filterLabelsReFunc removes all labels that do not match the regex. +func filterLabelsReFunc(m Labels, pattern string) Labels { + re := regexp.MustCompile(pattern) + res := make(Labels) + for k, v := range m { + if re.MatchString(k) { + res[k] = v } - datasource := url.QueryEscape(q.Datasource) - expr := url.QueryEscape(q.Expr) - return fmt.Sprintf(`/explore?left={"datasource":%[1]q,"queries":[{"datasource":%[1]q,"expr":%q,"instant":true,"range":false,"refId":"A"}],"range":{"from":"now-1h","to":"now"}}`, datasource, expr) } -) + return res +} + +func graphLinkFunc(data string) string { + var q query + if err := json.Unmarshal([]byte(data), &q); err != nil { + return "" + } + datasource := url.QueryEscape(q.Datasource) + expr := url.QueryEscape(q.Expr) + return fmt.Sprintf(`/explore?left={"datasource":%[1]q,"queries":[{"datasource":%[1]q,"expr":%q,"instant":false,"range":true,"refId":"A"}],"range":{"from":"now-1h","to":"now"}}`, datasource, expr) +} + +// removeLabelsFunc removes all labels that match the string. +func removeLabelsFunc(m Labels, match string) Labels { + res := make(Labels) + for k, v := range m { + if k != match { + res[k] = v + } + } + return res +} + +// removeLabelsReFunc removes all labels that match the regex. +func removeLabelsReFunc(m Labels, pattern string) Labels { + re := regexp.MustCompile(pattern) + res := make(Labels) + for k, v := range m { + if !re.MatchString(k) { + res[k] = v + } + } + return res +} + +func tableLinkFunc(data string) string { + var q query + if err := json.Unmarshal([]byte(data), &q); err != nil { + return "" + } + datasource := url.QueryEscape(q.Datasource) + expr := url.QueryEscape(q.Expr) + return fmt.Sprintf(`/explore?left={"datasource":%[1]q,"queries":[{"datasource":%[1]q,"expr":%q,"instant":true,"range":false,"refId":"A"}],"range":{"from":"now-1h","to":"now"}}`, datasource, expr) +} diff --git a/pkg/services/ngalert/state/template/funcs_test.go b/pkg/services/ngalert/state/template/funcs_test.go new file mode 100644 index 00000000000..4164208561f --- /dev/null +++ b/pkg/services/ngalert/state/template/funcs_test.go @@ -0,0 +1,27 @@ +package template + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestFilterLabelsFunc(t *testing.T) { + l := Labels{"foo": "bar", "bar": "baz"} + assert.Equal(t, Labels{"foo": "bar"}, filterLabelsFunc(l, "foo")) +} + +func TestFilterLabelsReFunc(t *testing.T) { + l := Labels{"foo": "bar", "bar": "baz"} + assert.Equal(t, Labels{"foo": "bar"}, filterLabelsReFunc(l, "f.*")) +} + +func TestRemoveLabelsFunc(t *testing.T) { + l := Labels{"foo": "bar", "bar": "baz"} + assert.Equal(t, Labels{"bar": "baz"}, removeLabelsFunc(l, "foo")) +} + +func TestRemoveLabelsReFunc(t *testing.T) { + l := Labels{"foo": "bar", "bar": "baz"} + assert.Equal(t, Labels{"bar": "baz"}, removeLabelsReFunc(l, "f.*")) +}