mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Alerting: Migrate old alerting templates to Go templates (#62911)
* Migrate old alerting templates to use $labels * Fix imports * Add test coverage and separate rewriting to Go templates * Fix lint * Check for additional closing braces * Add logging of invalid message templates * Fix tests * Small fixes * Update comments * Panic on empty token * Use logtest.Fake * Fix lint * Allow for spaces in variable names by not tokenizing spaces * Add template function to deduplicate Labels in a Value map * Fix behavior of mapLookupString * Reference deduplicated labels in migrated message template * Fix behavior of deduplicateLabelsFunc * Don't create variable for parent logger * Add more tests for deduplicateLabelsFunc * Remove unused function * Apply suggestions from code review Co-authored by: Yuri Tseretyan <yuriy.tseretyan@grafana.com> * Give label val merge function better name * Extract template migration and escape literal tokens * Consolidate + simplify template migration --------- Co-authored-by: William Wernert <william.wernert@grafana.com>
This commit is contained in:
@@ -5,7 +5,10 @@ import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
type query struct {
|
||||
@@ -13,14 +16,25 @@ type query struct {
|
||||
Expr string `json:"expr"`
|
||||
}
|
||||
|
||||
const (
|
||||
FilterLabelFuncName = "filterLabels"
|
||||
FilterLabelReFuncName = "filterLabelsRe"
|
||||
GraphLinkFuncName = "graphLink"
|
||||
RemoveLabelsFuncName = "removeLabels"
|
||||
RemoveLabelsReFuncName = "removeLabelsRe"
|
||||
TableLinkFuncName = "tableLink"
|
||||
MergeLabelValuesFuncName = "mergeLabelValues"
|
||||
)
|
||||
|
||||
var (
|
||||
defaultFuncs = template.FuncMap{
|
||||
"filterLabels": filterLabelsFunc,
|
||||
"filterLabelsRe": filterLabelsReFunc,
|
||||
"graphLink": graphLinkFunc,
|
||||
"removeLabels": removeLabelsFunc,
|
||||
"removeLabelslRe": removeLabelsReFunc,
|
||||
"tableLink": tableLinkFunc,
|
||||
FilterLabelFuncName: filterLabelsFunc,
|
||||
FilterLabelReFuncName: filterLabelsReFunc,
|
||||
GraphLinkFuncName: graphLinkFunc,
|
||||
RemoveLabelsFuncName: removeLabelsFunc,
|
||||
RemoveLabelsReFuncName: removeLabelsReFunc,
|
||||
TableLinkFuncName: tableLinkFunc,
|
||||
MergeLabelValuesFuncName: mergeLabelValuesFunc,
|
||||
}
|
||||
)
|
||||
|
||||
@@ -89,3 +103,32 @@ func tableLinkFunc(data string) string {
|
||||
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)
|
||||
}
|
||||
|
||||
// mergeLabelValuesFunc returns a map of label keys to deduplicated and comma separated values.
|
||||
func mergeLabelValuesFunc(values map[string]Value) Labels {
|
||||
type uniqueLabelVals map[string]struct{}
|
||||
|
||||
labels := make(map[string]uniqueLabelVals)
|
||||
for _, value := range values {
|
||||
for k, v := range value.Labels {
|
||||
var ul uniqueLabelVals
|
||||
var ok bool
|
||||
if ul, ok = labels[k]; !ok {
|
||||
ul = uniqueLabelVals{}
|
||||
labels[k] = ul
|
||||
}
|
||||
ul[v] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
res := make(Labels)
|
||||
for label, vals := range labels {
|
||||
keys := make([]string, 0, len(vals))
|
||||
for val := range vals {
|
||||
keys = append(keys, val)
|
||||
}
|
||||
slices.Sort(keys)
|
||||
res[label] = strings.Join(keys, ", ")
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
@@ -25,3 +25,27 @@ func TestRemoveLabelsReFunc(t *testing.T) {
|
||||
l := Labels{"foo": "bar", "bar": "baz"}
|
||||
assert.Equal(t, Labels{"bar": "baz"}, removeLabelsReFunc(l, "f.*"))
|
||||
}
|
||||
|
||||
func TestDeduplicateLabelsFunc(t *testing.T) {
|
||||
v := map[string]Value{
|
||||
"v1": {Labels: Labels{"foo": "bar", "bar": "foo"}, Value: 1},
|
||||
"v2": {Labels: Labels{"foo": "bar", "bar": "baz", "baz": "bat"}, Value: 2},
|
||||
}
|
||||
assert.Equal(t, Labels{"foo": "bar", "bar": "baz, foo", "baz": "bat"}, mergeLabelValuesFunc(v))
|
||||
}
|
||||
|
||||
func TestDeduplicateLabelsFuncAllSameVal(t *testing.T) {
|
||||
v := map[string]Value{
|
||||
"v1": {Labels: Labels{"foo": "bar", "bar": "baz"}, Value: 1},
|
||||
"v2": {Labels: Labels{"foo": "bar", "bar": "baz"}, Value: 2},
|
||||
}
|
||||
assert.Equal(t, Labels{"foo": "bar", "bar": "baz"}, mergeLabelValuesFunc(v))
|
||||
}
|
||||
|
||||
func TestDeduplicateLabelsFuncNoDuplicates(t *testing.T) {
|
||||
v := map[string]Value{
|
||||
"v1": {Labels: Labels{"foo": "bar"}, Value: 1},
|
||||
"v2": {Labels: Labels{"bar": "baz"}, Value: 2},
|
||||
}
|
||||
assert.Equal(t, Labels{"foo": "bar", "bar": "baz"}, mergeLabelValuesFunc(v))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user