Alerting: Display query from grafana-managed alert rules on /api/v1/rules (#45969)

* Aleting: Extract query from alerting rule model for api/v1/rules

* more changes and fixtures

* appease the linter
This commit is contained in:
gotjosh
2022-03-14 10:39:20 +00:00
committed by GitHub
parent ecf84be65a
commit a75d4fcbd8
7 changed files with 533 additions and 28 deletions

View File

@@ -2,6 +2,7 @@ package models
import (
"encoding/json"
"errors"
"fmt"
"time"
@@ -12,6 +13,8 @@ import (
const defaultMaxDataPoints float64 = 43200 // 12 hours at 1sec interval
const defaultIntervalMS float64 = 1000
var ErrNoQuery = errors.New("no `expr` property in the query model")
// Duration is a type used for marshalling durations.
type Duration time.Duration
@@ -174,6 +177,28 @@ func (aq *AlertQuery) GetDatasource() (string, error) {
return aq.DatasourceUID, nil
}
// GetQuery returns the query defined by `expr` within the model.
// Returns an ErrNoQuery if it is unable to find the query.
// Returns an error if it is not able to cast the query to a string.
func (aq *AlertQuery) GetQuery() (string, error) {
if aq.modelProps == nil {
err := aq.setModelProps()
if err != nil {
return "", err
}
}
query, ok := aq.modelProps["expr"]
if !ok {
return "", ErrNoQuery
}
q, ok := query.(string)
if !ok {
return "", fmt.Errorf("failed to cast query to string: %v", aq.modelProps["expr"])
}
return q, nil
}
func (aq *AlertQuery) GetModel() ([]byte, error) {
err := aq.setMaxDatapoints()
if err != nil {

View File

@@ -2,6 +2,7 @@ package models
import (
"encoding/json"
"errors"
"fmt"
"testing"
"time"
@@ -110,7 +111,7 @@ func TestAlertQuery(t *testing.T) {
Model: json.RawMessage(`{
"queryType": "metricQuery",
"intervalMs": "invalid",
"extraParam": "some text"
"extraParam": "some text"
}`),
},
expectedIsExpression: false,
@@ -245,3 +246,38 @@ func TestAlertQueryMarshalling(t *testing.T) {
}
}
}
func TestAlertQuery_GetQuery(t *testing.T) {
tc := []struct {
name string
alertQuery AlertQuery
expected string
err error
}{
{
name: "when a query is present",
alertQuery: AlertQuery{Model: json.RawMessage(`{"expr": "sum by (job) (up)"}`)},
expected: "sum by (job) (up)",
},
{
name: "when no query is found",
alertQuery: AlertQuery{Model: json.RawMessage(`{"exprisnot": "sum by (job) (up)"}`)},
err: ErrNoQuery,
},
{
name: "when we're unable to cast the query to a string",
alertQuery: AlertQuery{Model: json.RawMessage(`{"expr": {"key": 1}}`)},
err: errors.New("failed to cast query to string: map[key:1]"),
},
}
for _, tt := range tc {
t.Run(tt.name, func(t *testing.T) {
expected, err := tt.alertQuery.GetQuery()
if err != nil {
require.Equal(t, tt.err, err)
}
require.Equal(t, tt.expected, expected)
})
}
}