[v9.4.x] Expressions: Fixes the issue showing expressions editor (#62622)

Expressions: Fixes the issue showing expressions editor (#62510)

* Use suggested value for uid

* update the snapshot

* use __expr__

* replace all -100 with __expr__

* update snapshot

* more changes

* revert redundant change

* Use expr.DatasourceUID where it's possible

* generate files

(cherry picked from commit 91221bc436)

Co-authored-by: ismail simsek <ismailsimsek09@gmail.com>
This commit is contained in:
Grot (@grafanabot)
2023-01-31 18:10:13 +00:00
committed by GitHub
co-authored by ismail simsek
parent bd9707e8f3
commit 4bdfc2d926
54 changed files with 254 additions and 236 deletions
@@ -8,6 +8,7 @@ import (
"testing"
"time"
"github.com/grafana/grafana/pkg/expr"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -737,7 +738,7 @@ func insertTestRule(t *testing.T, sqlStore db.DB, foderOrgID int64, folderUID st
Data: []alertQuery{
{
RefID: "A",
DatasourceUID: "-100",
DatasourceUID: expr.DatasourceUID,
Model: json.RawMessage(`{
"type": "math",
"expression": "2 + 3 > 1"
@@ -11,6 +11,7 @@ import (
alertingModels "github.com/grafana/alerting/alerting/models"
"github.com/grafana/grafana-plugin-sdk-go/data"
"github.com/grafana/grafana/pkg/expr"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -571,7 +572,7 @@ func withClassicConditionSingleQuery() func(r *ngmodels.AlertRule) {
RefID: "B",
QueryType: "",
RelativeTimeRange: ngmodels.RelativeTimeRange{From: ngmodels.Duration(0), To: ngmodels.Duration(0)},
DatasourceUID: "-100",
DatasourceUID: expr.DatasourceUID,
Model: json.RawMessage(fmt.Sprintf(classicConditionsModel, "A", "B")),
},
}
@@ -600,21 +601,21 @@ func withExpressionsMultiQuery() func(r *ngmodels.AlertRule) {
RefID: "C",
QueryType: "",
RelativeTimeRange: ngmodels.RelativeTimeRange{From: ngmodels.Duration(0), To: ngmodels.Duration(0)},
DatasourceUID: "-100",
DatasourceUID: expr.DatasourceUID,
Model: json.RawMessage(fmt.Sprintf(reduceLastExpressionModel, "A", "C")),
},
{
RefID: "D",
QueryType: "",
RelativeTimeRange: ngmodels.RelativeTimeRange{From: ngmodels.Duration(0), To: ngmodels.Duration(0)},
DatasourceUID: "-100",
DatasourceUID: expr.DatasourceUID,
Model: json.RawMessage(fmt.Sprintf(reduceLastExpressionModel, "B", "D")),
},
{
RefID: "E",
QueryType: "",
RelativeTimeRange: ngmodels.RelativeTimeRange{From: ngmodels.Duration(0), To: ngmodels.Duration(0)},
DatasourceUID: "-100",
DatasourceUID: expr.DatasourceUID,
Model: json.RawMessage(fmt.Sprintf(mathExpressionModel, "A", "B", "E")),
},
}
@@ -38,7 +38,7 @@ const classicConditionsModel = `
}],
"datasource": {
"type": "__expr__",
"uid": "-100"
"uid": "__expr__"
},
"hide": false,
"intervalMs": 1000,
@@ -480,7 +480,7 @@ func TestProvisioningApi(t *testing.T) {
insertRule(t, sut, createTestAlertRule("rule1", 1))
insertRule(t, sut, createTestAlertRule("rule2", 1))
expectedResponse := `{"apiVersion":1,"groups":[{"orgId":1,"name":"my-cool-group","folder":"Folder Title","interval":"1m","rules":[{"uid":"rule1","title":"rule1","condition":"A","data":[{"refId":"A","relativeTimeRange":{"from":0,"to":0},"datasourceUid":"","model":{"conditions":[{"evaluator":{"params":[3],"type":"gt"},"operator":{"type":"and"},"query":{"params":["A"]},"reducer":{"type":"last"},"type":"query"}],"datasource":{"type":"__expr__","uid":"-100"},"expression":"1==0","intervalMs":1000,"maxDataPoints":43200,"refId":"A","type":"math"}}],"noDataState":"OK","execErrState":"OK","for":"0s","isPaused":false},{"uid":"rule2","title":"rule2","condition":"A","data":[{"refId":"A","relativeTimeRange":{"from":0,"to":0},"datasourceUid":"","model":{"conditions":[{"evaluator":{"params":[3],"type":"gt"},"operator":{"type":"and"},"query":{"params":["A"]},"reducer":{"type":"last"},"type":"query"}],"datasource":{"type":"__expr__","uid":"-100"},"expression":"1==0","intervalMs":1000,"maxDataPoints":43200,"refId":"A","type":"math"}}],"noDataState":"OK","execErrState":"OK","for":"0s","isPaused":false}]}]}`
expectedResponse := `{"apiVersion":1,"groups":[{"orgId":1,"name":"my-cool-group","folder":"Folder Title","interval":"1m","rules":[{"uid":"rule1","title":"rule1","condition":"A","data":[{"refId":"A","relativeTimeRange":{"from":0,"to":0},"datasourceUid":"","model":{"conditions":[{"evaluator":{"params":[3],"type":"gt"},"operator":{"type":"and"},"query":{"params":["A"]},"reducer":{"type":"last"},"type":"query"}],"datasource":{"type":"__expr__","uid":"__expr__"},"expression":"1==0","intervalMs":1000,"maxDataPoints":43200,"refId":"A","type":"math"}}],"noDataState":"OK","execErrState":"OK","for":"0s","isPaused":false},{"uid":"rule2","title":"rule2","condition":"A","data":[{"refId":"A","relativeTimeRange":{"from":0,"to":0},"datasourceUid":"","model":{"conditions":[{"evaluator":{"params":[3],"type":"gt"},"operator":{"type":"and"},"query":{"params":["A"]},"reducer":{"type":"last"},"type":"query"}],"datasource":{"type":"__expr__","uid":"__expr__"},"expression":"1==0","intervalMs":1000,"maxDataPoints":43200,"refId":"A","type":"math"}}],"noDataState":"OK","execErrState":"OK","for":"0s","isPaused":false}]}]}`
response := sut.RouteGetAlertRuleGroupExport(&rc, "folder-uid", "my-cool-group")
@@ -495,7 +495,11 @@ func TestProvisioningApi(t *testing.T) {
insertRule(t, sut, createTestAlertRule("rule2", 1))
rc.Context.Req.Header.Add("Accept", "application/yaml")
expectedResponse := "apiVersion: 1\ngroups:\n - orgId: 1\n name: my-cool-group\n folder: Folder Title\n interval: 1m\n rules:\n - uid: rule1\n title: rule1\n condition: A\n data:\n - refId: A\n datasourceUid: \"\"\n model:\n conditions:\n - evaluator:\n params:\n - 3\n type: gt\n operator:\n type: and\n query:\n params:\n - A\n reducer:\n type: last\n type: query\n datasource:\n type: __expr__\n uid: \"-100\"\n expression: 1==0\n intervalMs: 1000\n maxDataPoints: 43200\n refId: A\n type: math\n noDataState: OK\n execErrState: OK\n for: 0s\n isPaused: false\n - uid: rule2\n title: rule2\n condition: A\n data:\n - refId: A\n datasourceUid: \"\"\n model:\n conditions:\n - evaluator:\n params:\n - 3\n type: gt\n operator:\n type: and\n query:\n params:\n - A\n reducer:\n type: last\n type: query\n datasource:\n type: __expr__\n uid: \"-100\"\n expression: 1==0\n intervalMs: 1000\n maxDataPoints: 43200\n refId: A\n type: math\n noDataState: OK\n execErrState: OK\n for: 0s\n isPaused: false\n"
expectedResponse := "apiVersion: 1\ngroups:\n - orgId: 1\n name: my-cool-group\n folder" +
": Folder Title\n interval: 1m\n rules:\n - uid: rule1\n title: rule1\n" +
" condition: A\n data:\n - refId: A\n datasourceUid" +
": \"\"\n model:\n conditions:\n - evaluator:\n" +
" params:\n - 3\n type: gt\n operator:\n type: and\n query:\n params:\n - A\n reducer:\n type: last\n type: query\n datasource:\n type: __expr__\n uid: __expr__\n expression: 1==0\n intervalMs: 1000\n maxDataPoints: 43200\n refId: A\n type: math\n noDataState: OK\n execErrState: OK\n for: 0s\n isPaused: false\n - uid: rule2\n title: rule2\n condition: A\n data:\n - refId: A\n datasourceUid: \"\"\n model:\n conditions:\n - evaluator:\n params:\n - 3\n type: gt\n operator:\n type: and\n query:\n params:\n - A\n reducer:\n type: last\n type: query\n datasource:\n type: __expr__\n uid: __expr__\n expression: 1==0\n intervalMs: 1000\n maxDataPoints: 43200\n refId: A\n type: math\n noDataState: OK\n execErrState: OK\n for: 0s\n isPaused: false\n"
response := sut.RouteGetAlertRuleGroupExport(&rc, "folder-uid", "my-cool-group")
@@ -607,7 +611,7 @@ func TestProvisioningApi(t *testing.T) {
rc := createTestRequestCtx()
insertRule(t, sut, createTestAlertRule("rule1", 1))
expectedResponse := `{"apiVersion":1,"groups":[{"orgId":1,"name":"my-cool-group","folder":"Folder Title","interval":"1m","rules":[{"uid":"rule1","title":"rule1","condition":"A","data":[{"refId":"A","relativeTimeRange":{"from":0,"to":0},"datasourceUid":"","model":{"conditions":[{"evaluator":{"params":[3],"type":"gt"},"operator":{"type":"and"},"query":{"params":["A"]},"reducer":{"type":"last"},"type":"query"}],"datasource":{"type":"__expr__","uid":"-100"},"expression":"1==0","intervalMs":1000,"maxDataPoints":43200,"refId":"A","type":"math"}}],"noDataState":"OK","execErrState":"OK","for":"0s","isPaused":false}]}]}`
expectedResponse := `{"apiVersion":1,"groups":[{"orgId":1,"name":"my-cool-group","folder":"Folder Title","interval":"1m","rules":[{"uid":"rule1","title":"rule1","condition":"A","data":[{"refId":"A","relativeTimeRange":{"from":0,"to":0},"datasourceUid":"","model":{"conditions":[{"evaluator":{"params":[3],"type":"gt"},"operator":{"type":"and"},"query":{"params":["A"]},"reducer":{"type":"last"},"type":"query"}],"datasource":{"type":"__expr__","uid":"__expr__"},"expression":"1==0","intervalMs":1000,"maxDataPoints":43200,"refId":"A","type":"math"}}],"noDataState":"OK","execErrState":"OK","for":"0s","isPaused":false}]}]}`
response := sut.RouteGetAlertRuleExport(&rc, "rule1")
@@ -621,7 +625,7 @@ func TestProvisioningApi(t *testing.T) {
insertRule(t, sut, createTestAlertRule("rule1", 1))
rc.Context.Req.Header.Add("Accept", "application/yaml")
expectedResponse := "apiVersion: 1\ngroups:\n - orgId: 1\n name: my-cool-group\n folder: Folder Title\n interval: 1m\n rules:\n - uid: rule1\n title: rule1\n condition: A\n data:\n - refId: A\n datasourceUid: \"\"\n model:\n conditions:\n - evaluator:\n params:\n - 3\n type: gt\n operator:\n type: and\n query:\n params:\n - A\n reducer:\n type: last\n type: query\n datasource:\n type: __expr__\n uid: \"-100\"\n expression: 1==0\n intervalMs: 1000\n maxDataPoints: 43200\n refId: A\n type: math\n noDataState: OK\n execErrState: OK\n for: 0s\n isPaused: false\n"
expectedResponse := "apiVersion: 1\ngroups:\n - orgId: 1\n name: my-cool-group\n folder: Folder Title\n interval: 1m\n rules:\n - uid: rule1\n title: rule1\n condition: A\n data:\n - refId: A\n datasourceUid: \"\"\n model:\n conditions:\n - evaluator:\n params:\n - 3\n type: gt\n operator:\n type: and\n query:\n params:\n - A\n reducer:\n type: last\n type: query\n datasource:\n type: __expr__\n uid: __expr__\n expression: 1==0\n intervalMs: 1000\n maxDataPoints: 43200\n refId: A\n type: math\n noDataState: OK\n execErrState: OK\n for: 0s\n isPaused: false\n"
response := sut.RouteGetAlertRuleExport(&rc, "rule1")
@@ -725,7 +729,7 @@ func TestProvisioningApi(t *testing.T) {
insertRule(t, sut, createTestAlertRuleWithFolderAndGroup("rule2", 1, "folder-uid", "groupb"))
insertRule(t, sut, createTestAlertRuleWithFolderAndGroup("rule3", 1, "folder-uid2", "groupb"))
expectedResponse := `{"apiVersion":1,"groups":[{"orgId":1,"name":"groupa","folder":"Folder Title","interval":"1m","rules":[{"uid":"rule1","title":"rule1","condition":"A","data":[{"refId":"A","relativeTimeRange":{"from":0,"to":0},"datasourceUid":"","model":{"conditions":[{"evaluator":{"params":[3],"type":"gt"},"operator":{"type":"and"},"query":{"params":["A"]},"reducer":{"type":"last"},"type":"query"}],"datasource":{"type":"__expr__","uid":"-100"},"expression":"1==0","intervalMs":1000,"maxDataPoints":43200,"refId":"A","type":"math"}}],"noDataState":"OK","execErrState":"OK","for":"0s","isPaused":false}]},{"orgId":1,"name":"groupb","folder":"Folder Title","interval":"1m","rules":[{"uid":"rule2","title":"rule2","condition":"A","data":[{"refId":"A","relativeTimeRange":{"from":0,"to":0},"datasourceUid":"","model":{"conditions":[{"evaluator":{"params":[3],"type":"gt"},"operator":{"type":"and"},"query":{"params":["A"]},"reducer":{"type":"last"},"type":"query"}],"datasource":{"type":"__expr__","uid":"-100"},"expression":"1==0","intervalMs":1000,"maxDataPoints":43200,"refId":"A","type":"math"}}],"noDataState":"OK","execErrState":"OK","for":"0s","isPaused":false}]},{"orgId":1,"name":"groupb","folder":"Folder Title2","interval":"1m","rules":[{"uid":"rule3","title":"rule3","condition":"A","data":[{"refId":"A","relativeTimeRange":{"from":0,"to":0},"datasourceUid":"","model":{"conditions":[{"evaluator":{"params":[3],"type":"gt"},"operator":{"type":"and"},"query":{"params":["A"]},"reducer":{"type":"last"},"type":"query"}],"datasource":{"type":"__expr__","uid":"-100"},"expression":"1==0","intervalMs":1000,"maxDataPoints":43200,"refId":"A","type":"math"}}],"noDataState":"OK","execErrState":"OK","for":"0s","isPaused":false}]}]}`
expectedResponse := `{"apiVersion":1,"groups":[{"orgId":1,"name":"groupa","folder":"Folder Title","interval":"1m","rules":[{"uid":"rule1","title":"rule1","condition":"A","data":[{"refId":"A","relativeTimeRange":{"from":0,"to":0},"datasourceUid":"","model":{"conditions":[{"evaluator":{"params":[3],"type":"gt"},"operator":{"type":"and"},"query":{"params":["A"]},"reducer":{"type":"last"},"type":"query"}],"datasource":{"type":"__expr__","uid":"__expr__"},"expression":"1==0","intervalMs":1000,"maxDataPoints":43200,"refId":"A","type":"math"}}],"noDataState":"OK","execErrState":"OK","for":"0s","isPaused":false}]},{"orgId":1,"name":"groupb","folder":"Folder Title","interval":"1m","rules":[{"uid":"rule2","title":"rule2","condition":"A","data":[{"refId":"A","relativeTimeRange":{"from":0,"to":0},"datasourceUid":"","model":{"conditions":[{"evaluator":{"params":[3],"type":"gt"},"operator":{"type":"and"},"query":{"params":["A"]},"reducer":{"type":"last"},"type":"query"}],"datasource":{"type":"__expr__","uid":"__expr__"},"expression":"1==0","intervalMs":1000,"maxDataPoints":43200,"refId":"A","type":"math"}}],"noDataState":"OK","execErrState":"OK","for":"0s","isPaused":false}]},{"orgId":1,"name":"groupb","folder":"Folder Title2","interval":"1m","rules":[{"uid":"rule3","title":"rule3","condition":"A","data":[{"refId":"A","relativeTimeRange":{"from":0,"to":0},"datasourceUid":"","model":{"conditions":[{"evaluator":{"params":[3],"type":"gt"},"operator":{"type":"and"},"query":{"params":["A"]},"reducer":{"type":"last"},"type":"query"}],"datasource":{"type":"__expr__","uid":"__expr__"},"expression":"1==0","intervalMs":1000,"maxDataPoints":43200,"refId":"A","type":"math"}}],"noDataState":"OK","execErrState":"OK","for":"0s","isPaused":false}]}]}`
response := sut.RouteGetAlertRulesExport(&rc)
@@ -741,7 +745,7 @@ func TestProvisioningApi(t *testing.T) {
insertRule(t, sut, createTestAlertRuleWithFolderAndGroup("rule3", 1, "folder-uid2", "groupb"))
rc.Context.Req.Header.Add("Accept", "application/yaml")
expectedResponse := "apiVersion: 1\ngroups:\n - orgId: 1\n name: groupa\n folder: Folder Title\n interval: 1m\n rules:\n - uid: rule1\n title: rule1\n condition: A\n data:\n - refId: A\n datasourceUid: \"\"\n model:\n conditions:\n - evaluator:\n params:\n - 3\n type: gt\n operator:\n type: and\n query:\n params:\n - A\n reducer:\n type: last\n type: query\n datasource:\n type: __expr__\n uid: \"-100\"\n expression: 1==0\n intervalMs: 1000\n maxDataPoints: 43200\n refId: A\n type: math\n noDataState: OK\n execErrState: OK\n for: 0s\n isPaused: false\n - orgId: 1\n name: groupb\n folder: Folder Title\n interval: 1m\n rules:\n - uid: rule2\n title: rule2\n condition: A\n data:\n - refId: A\n datasourceUid: \"\"\n model:\n conditions:\n - evaluator:\n params:\n - 3\n type: gt\n operator:\n type: and\n query:\n params:\n - A\n reducer:\n type: last\n type: query\n datasource:\n type: __expr__\n uid: \"-100\"\n expression: 1==0\n intervalMs: 1000\n maxDataPoints: 43200\n refId: A\n type: math\n noDataState: OK\n execErrState: OK\n for: 0s\n isPaused: false\n - orgId: 1\n name: groupb\n folder: Folder Title2\n interval: 1m\n rules:\n - uid: rule3\n title: rule3\n condition: A\n data:\n - refId: A\n datasourceUid: \"\"\n model:\n conditions:\n - evaluator:\n params:\n - 3\n type: gt\n operator:\n type: and\n query:\n params:\n - A\n reducer:\n type: last\n type: query\n datasource:\n type: __expr__\n uid: \"-100\"\n expression: 1==0\n intervalMs: 1000\n maxDataPoints: 43200\n refId: A\n type: math\n noDataState: OK\n execErrState: OK\n for: 0s\n isPaused: false\n"
expectedResponse := "apiVersion: 1\ngroups:\n - orgId: 1\n name: groupa\n folder: Folder Title\n interval: 1m\n rules:\n - uid: rule1\n title: rule1\n condition: A\n data:\n - refId: A\n datasourceUid: \"\"\n model:\n conditions:\n - evaluator:\n params:\n - 3\n type: gt\n operator:\n type: and\n query:\n params:\n - A\n reducer:\n type: last\n type: query\n datasource:\n type: __expr__\n uid: __expr__\n expression: 1==0\n intervalMs: 1000\n maxDataPoints: 43200\n refId: A\n type: math\n noDataState: OK\n execErrState: OK\n for: 0s\n isPaused: false\n - orgId: 1\n name: groupb\n folder: Folder Title\n interval: 1m\n rules:\n - uid: rule2\n title: rule2\n condition: A\n data:\n - refId: A\n datasourceUid: \"\"\n model:\n conditions:\n - evaluator:\n params:\n - 3\n type: gt\n operator:\n type: and\n query:\n params:\n - A\n reducer:\n type: last\n type: query\n datasource:\n type: __expr__\n uid: __expr__\n expression: 1==0\n intervalMs: 1000\n maxDataPoints: 43200\n refId: A\n type: math\n noDataState: OK\n execErrState: OK\n for: 0s\n isPaused: false\n - orgId: 1\n name: groupb\n folder: Folder Title2\n interval: 1m\n rules:\n - uid: rule3\n title: rule3\n condition: A\n data:\n - refId: A\n datasourceUid: \"\"\n model:\n conditions:\n - evaluator:\n params:\n - 3\n type: gt\n operator:\n type: and\n query:\n params:\n - A\n reducer:\n type: last\n type: query\n datasource:\n type: __expr__\n uid: __expr__\n expression: 1==0\n intervalMs: 1000\n maxDataPoints: 43200\n refId: A\n type: math\n noDataState: OK\n execErrState: OK\n for: 0s\n isPaused: false\n"
response := sut.RouteGetAlertRulesExport(&rc)
@@ -1034,7 +1038,7 @@ var testModel = `
],
"datasource": {
"type": "__expr__",
"uid": "-100"
"uid": "__expr__"
},
"expression": "1==0",
"intervalMs": 1000,
+3 -1
View File
@@ -236,7 +236,9 @@ func (api *API) authorize(method, path string) web.Handler {
// authorizeDatasourceAccessForRule checks that user has access to all data sources declared by the rule
func authorizeDatasourceAccessForRule(rule *ngmodels.AlertRule, evaluator func(evaluator ac.Evaluator) bool) bool {
for _, query := range rule.Data {
if query.QueryType == expr.DatasourceType || query.DatasourceUID == expr.OldDatasourceUID {
if query.QueryType == expr.DatasourceType || query.DatasourceUID == expr.DatasourceUID || query.
DatasourceUID == expr.
OldDatasourceUID {
continue
}
if !evaluator(ac.EvalPermission(datasources.ActionQuery, datasources.ScopeProvider.GetResourceScopeUID(query.DatasourceUID))) {
@@ -401,7 +401,7 @@ func TestCheckDatasourcePermissionsForRule(t *testing.T) {
expressionByType := models.GenerateAlertQuery()
expressionByType.QueryType = expr.DatasourceType
expressionByUID := models.GenerateAlertQuery()
expressionByUID.DatasourceUID = expr.OldDatasourceUID
expressionByUID.DatasourceUID = expr.DatasourceUID
var data []models.AlertQuery
var scopes []string
@@ -32,7 +32,7 @@
"from": 18000,
"to": 10800
},
"datasourceUid": "-100",
"datasourceUid": "__expr__",
"model": {
"expression": "query",
"hide": false,
@@ -50,7 +50,7 @@
"from": 18000,
"to": 10800
},
"datasourceUid": "-100",
"datasourceUid": "__expr__",
"model": {
"expression": "$reduced > 10",
"hide": false,
@@ -95,7 +95,7 @@
"from": 18000,
"to": 10800
},
"datasourceUid": "-100",
"datasourceUid": "__expr__",
"model": {
"expression": "$A",
"intervalMs": 2000,
@@ -112,4 +112,4 @@
}
}
]
}
}
@@ -39,7 +39,7 @@
"from": 18000,
"to": 10800
},
"datasourceUid": "-100",
"datasourceUid": "__expr__",
"model": {
"expression": "query",
"hide": false,
@@ -57,7 +57,7 @@
"from": 18000,
"to": 10800
},
"datasourceUid": "-100",
"datasourceUid": "__expr__",
"model": {
"expression": "$reduced > 10",
"hide": false,
@@ -102,7 +102,7 @@
"from": 18000,
"to": 10800
},
"datasourceUid": "-100",
"datasourceUid": "__expr__",
"model": {
"expression": "$A",
"intervalMs": 2000,
@@ -119,4 +119,4 @@
}
}
]
}
}
@@ -98,7 +98,7 @@ content-type: application/json
"from": 18000,
"to": 10800
},
"datasourceUid": "-100",
"datasourceUid": "__expr__",
"model": {
"expression": "query",
"hide": false,
@@ -116,7 +116,7 @@ content-type: application/json
"from": 18000,
"to": 10800
},
"datasourceUid": "-100",
"datasourceUid": "__expr__",
"model": {
"expression": "$reduced > 10",
"hide": false,
@@ -184,7 +184,7 @@ content-type: application/json
"from": 18000,
"to": 10800
},
"datasourceUid": "-100",
"datasourceUid": "__expr__",
"model": {
"expression": "query",
"hide": false,
@@ -202,7 +202,7 @@ content-type: application/json
"from": 18000,
"to": 10800
},
"datasourceUid": "-100",
"datasourceUid": "__expr__",
"model": {
"expression": "$reduced > 42",
"hide": false,
@@ -283,7 +283,7 @@ Content-Type: application/json
"from": 18000,
"to": 10800
},
"datasourceUid": "-100",
"datasourceUid": "__expr__",
"model": {
"expression": "query",
"hide": false,
@@ -301,7 +301,7 @@ Content-Type: application/json
"from": 18000,
"to": 10800
},
"datasourceUid": "-100",
"datasourceUid": "__expr__",
"model": {
"expression": "$reduced > 42",
"hide": false,
@@ -317,4 +317,4 @@ Content-Type: application/json
}
}
]
}
}
@@ -9,7 +9,7 @@
"from": 18000,
"to": 10800
},
"datasourceUid": "-100",
"datasourceUid": "__expr__",
"model": {
"type": "math",
"expression": "2 + 2 > 1"
@@ -18,4 +18,4 @@
],
"now": "2021-03-11T14:50:42.218+02:00"
}
}
}
+5 -5
View File
@@ -15,7 +15,7 @@ content-type: application/json
"from": 18000,
"to": 10800
},
"datasourceUid": "-100",
"datasourceUid": "__expr__",
"model": {
"type":"math",
"expression":"1 < 2"
@@ -56,7 +56,7 @@ content-type: application/json
"from": 18000,
"to": 10800
},
"datasourceUid": "-100",
"datasourceUid": "__expr__",
"model": {
"expression": "$A",
"intervalMs": 2000,
@@ -113,7 +113,7 @@ content-type: application/json
"from": 18000,
"to": 10800
},
"datasourceUid": "-100",
"datasourceUid": "__expr__",
"model": {
"type":"math",
"expression":"1 < 2"
@@ -121,7 +121,7 @@ content-type: application/json
}
]
}
}}
}
### grafana recipient - lotex payload
POST http://admin:admin@localhost:3000/api/v1/rule/test/{{grafanaRecipient}}
@@ -129,4 +129,4 @@ content-type: application/json
{
"expr": "rate({cluster=\"us-central1\", job=\"loki-prod/loki-canary\"}[1m]) > 0"
}
}
+7 -6
View File
@@ -99,7 +99,7 @@
"AlertQuery": {
"properties": {
"datasourceUid": {
"description": "Grafana data source unique identifier; it should be '-100' for a Server Side Expression operation.",
"description": "Grafana data source unique identifier; it should be '__expr__' for a Server Side Expression operation.",
"type": "string"
},
"model": {
@@ -2212,7 +2212,7 @@
"data": {
"example": [
{
"datasourceUid": "-100",
"datasourceUid": "__expr__",
"model": {
"conditions": [
{
@@ -3284,7 +3284,6 @@
"type": "object"
},
"URL": {
"description": "The general form represented is:\n\n[scheme:][//[userinfo@]host][/]path[?query][#fragment]\n\nURLs that do not start with a slash after the scheme are interpreted as:\n\nscheme:opaque[?query][#fragment]\n\nNote that the Path field is stored in decoded form: /%47%6f%2f becomes /Go/.\nA consequence is that it is impossible to tell which slashes in the Path were\nslashes in the raw URL and which were %2f. This distinction is rarely important,\nbut when it is, the code should use RawPath, an optional field which only gets\nset if the default encoding is different from Path.\n\nURL's String method uses the EscapedPath method to obtain the path. See the\nEscapedPath method for more details.",
"properties": {
"ForceQuery": {
"type": "boolean"
@@ -3320,7 +3319,7 @@
"$ref": "#/definitions/Userinfo"
}
},
"title": "A URL represents a parsed URL (technically, a URI reference).",
"title": "URL is a custom URL type that allows validation at configuration load time.",
"type": "object"
},
"Userinfo": {
@@ -3497,6 +3496,7 @@
"type": "object"
},
"alertGroup": {
"description": "AlertGroup alert group",
"properties": {
"alerts": {
"description": "alerts",
@@ -3624,6 +3624,7 @@
"type": "object"
},
"gettableAlert": {
"description": "GettableAlert gettable alert",
"properties": {
"annotations": {
"$ref": "#/definitions/labelSet"
@@ -3685,7 +3686,6 @@
"type": "array"
},
"gettableSilence": {
"description": "GettableSilence gettable silence",
"properties": {
"comment": {
"description": "comment",
@@ -3734,6 +3734,7 @@
"type": "object"
},
"gettableSilences": {
"description": "GettableSilences gettable silences",
"items": {
"$ref": "#/definitions/gettableSilence"
},
@@ -4854,4 +4855,4 @@
}
},
"swagger": "2.0"
}
}
@@ -118,7 +118,7 @@ type ProvisionedAlertRule struct {
// example: A
Condition string `json:"condition"`
// required: true
// example: [{"refId":"A","queryType":"","relativeTimeRange":{"from":0,"to":0},"datasourceUid":"-100","model":{"conditions":[{"evaluator":{"params":[0,0],"type":"gt"},"operator":{"type":"and"},"query":{"params":[]},"reducer":{"params":[],"type":"avg"},"type":"query"}],"datasource":{"type":"__expr__","uid":"__expr__"},"expression":"1 == 1","hide":false,"intervalMs":1000,"maxDataPoints":43200,"refId":"A","type":"math"}}]
// example: [{"refId":"A","queryType":"","relativeTimeRange":{"from":0,"to":0},"datasourceUid":"__expr__","model":{"conditions":[{"evaluator":{"params":[0,0],"type":"gt"},"operator":{"type":"and"},"query":{"params":[]},"reducer":{"params":[],"type":"avg"},"type":"query"}],"datasource":{"type":"__expr__","uid":"__expr__"},"expression":"1 == 1","hide":false,"intervalMs":1000,"maxDataPoints":43200,"refId":"A","type":"math"}}]
Data []models.AlertQuery `json:"data"`
// readonly: true
Updated time.Time `json:"updated,omitempty"`
+6 -7
View File
@@ -99,7 +99,7 @@
"AlertQuery": {
"properties": {
"datasourceUid": {
"description": "Grafana data source unique identifier; it should be '-100' for a Server Side Expression operation.",
"description": "Grafana data source unique identifier; it should be '__expr__' for a Server Side Expression operation.",
"type": "string"
},
"model": {
@@ -2212,7 +2212,7 @@
"data": {
"example": [
{
"datasourceUid": "-100",
"datasourceUid": "__expr__",
"model": {
"conditions": [
{
@@ -3284,7 +3284,6 @@
"type": "object"
},
"URL": {
"description": "The general form represented is:\n\n[scheme:][//[userinfo@]host][/]path[?query][#fragment]\n\nURLs that do not start with a slash after the scheme are interpreted as:\n\nscheme:opaque[?query][#fragment]\n\nNote that the Path field is stored in decoded form: /%47%6f%2f becomes /Go/.\nA consequence is that it is impossible to tell which slashes in the Path were\nslashes in the raw URL and which were %2f. This distinction is rarely important,\nbut when it is, the code should use RawPath, an optional field which only gets\nset if the default encoding is different from Path.\n\nURL's String method uses the EscapedPath method to obtain the path. See the\nEscapedPath method for more details.",
"properties": {
"ForceQuery": {
"type": "boolean"
@@ -3320,7 +3319,7 @@
"$ref": "#/definitions/Userinfo"
}
},
"title": "A URL represents a parsed URL (technically, a URI reference).",
"title": "URL is a custom URL type that allows validation at configuration load time.",
"type": "object"
},
"Userinfo": {
@@ -3497,7 +3496,6 @@
"type": "object"
},
"alertGroup": {
"description": "AlertGroup alert group",
"properties": {
"alerts": {
"description": "alerts",
@@ -3742,6 +3740,7 @@
"type": "array"
},
"integration": {
"description": "Integration integration",
"properties": {
"lastNotifyAttempt": {
"description": "A timestamp indicating the last attempt to deliver a notification regardless of the outcome.\nFormat: date-time",
@@ -3885,7 +3884,6 @@
"type": "array"
},
"postableSilence": {
"description": "PostableSilence postable silence",
"properties": {
"comment": {
"description": "comment",
@@ -3923,6 +3921,7 @@
"type": "object"
},
"receiver": {
"description": "Receiver receiver",
"properties": {
"active": {
"description": "active",
@@ -6636,4 +6635,4 @@
}
},
"swagger": "2.0"
}
}
+6 -7
View File
@@ -2711,7 +2711,7 @@
"title": "AlertQuery represents a single query associated with an alert definition.",
"properties": {
"datasourceUid": {
"description": "Grafana data source unique identifier; it should be '-100' for a Server Side Expression operation.",
"description": "Grafana data source unique identifier; it should be '__expr__' for a Server Side Expression operation.",
"type": "string"
},
"model": {
@@ -4843,7 +4843,7 @@
},
"example": [
{
"datasourceUid": "-100",
"datasourceUid": "__expr__",
"model": {
"conditions": [
{
@@ -5899,9 +5899,8 @@
}
},
"URL": {
"description": "The general form represented is:\n\n[scheme:][//[userinfo@]host][/]path[?query][#fragment]\n\nURLs that do not start with a slash after the scheme are interpreted as:\n\nscheme:opaque[?query][#fragment]\n\nNote that the Path field is stored in decoded form: /%47%6f%2f becomes /Go/.\nA consequence is that it is impossible to tell which slashes in the Path were\nslashes in the raw URL and which were %2f. This distinction is rarely important,\nbut when it is, the code should use RawPath, an optional field which only gets\nset if the default encoding is different from Path.\n\nURL's String method uses the EscapedPath method to obtain the path. See the\nEscapedPath method for more details.",
"type": "object",
"title": "A URL represents a parsed URL (technically, a URI reference).",
"title": "URL is a custom URL type that allows validation at configuration load time.",
"properties": {
"ForceQuery": {
"type": "boolean"
@@ -6112,7 +6111,6 @@
}
},
"alertGroup": {
"description": "AlertGroup alert group",
"type": "object",
"required": [
"alerts",
@@ -6363,6 +6361,7 @@
"$ref": "#/definitions/gettableSilences"
},
"integration": {
"description": "Integration integration",
"type": "object",
"required": [
"name",
@@ -6507,7 +6506,6 @@
}
},
"postableSilence": {
"description": "PostableSilence postable silence",
"type": "object",
"required": [
"comment",
@@ -6546,6 +6544,7 @@
"$ref": "#/definitions/postableSilence"
},
"receiver": {
"description": "Receiver receiver",
"type": "object",
"required": [
"active",
@@ -6676,4 +6675,4 @@
"type": "basic"
}
}
}
}
+1 -1
View File
@@ -88,7 +88,7 @@ type AlertQuery struct {
// RelativeTimeRange is the relative Start and End of the query as sent by the frontend.
RelativeTimeRange RelativeTimeRange `json:"relativeTimeRange"`
// Grafana data source unique identifier; it should be '-100' for a Server Side Expression operation.
// Grafana data source unique identifier; it should be '__expr__' for a Server Side Expression operation.
DatasourceUID string `json:"datasourceUid"`
// JSON is the raw JSON query and includes the above properties as well as custom properties.
@@ -7,6 +7,7 @@ import (
"testing"
"time"
"github.com/grafana/grafana/pkg/expr"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@@ -29,7 +30,7 @@ func TestAlertQuery(t *testing.T) {
"queryType": "metricQuery",
"extraParam": "some text"
}`),
DatasourceUID: "-100",
DatasourceUID: expr.DatasourceUID,
},
expectedIsExpression: true,
expectedMaxPoints: int64(defaultMaxDataPoints),
+2 -2
View File
@@ -300,7 +300,7 @@ func CreateClassicConditionExpression(refID string, inputRefID string, reducer s
return AlertQuery{
RefID: refID,
QueryType: expr.DatasourceType,
DatasourceUID: expr.OldDatasourceUID,
DatasourceUID: expr.DatasourceUID,
// the format corresponds to model `ClassicConditionJSON` in /pkg/expr/classic/classic.go
Model: json.RawMessage(fmt.Sprintf(`
{
@@ -334,7 +334,7 @@ func CreateClassicConditionExpression(refID string, inputRefID string, reducer s
}
}
]
}`, refID, inputRefID, operation, threshold, reducer, expr.OldDatasourceUID, expr.DatasourceType)),
}`, refID, inputRefID, operation, threshold, reducer, expr.DatasourceUID, expr.DatasourceType)),
}
}
@@ -7,6 +7,7 @@ import (
"testing"
"time"
"github.com/grafana/grafana/pkg/expr"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/infra/db"
@@ -371,7 +372,7 @@ func createTestRule(title string, groupTitle string, orgID int64) models.AlertRu
{
RefID: "A",
Model: json.RawMessage("{}"),
DatasourceUID: "-100",
DatasourceUID: expr.DatasourceUID,
RelativeTimeRange: models.RelativeTimeRange{
From: models.Duration(60),
To: models.Duration(0),
@@ -719,13 +719,13 @@ func withQueryForState(t *testing.T, evalResult eval.State) models.AlertRuleMuta
switch evalResult {
case eval.Normal:
expression = `{
"datasourceUid": "-100",
"datasourceUid": "__expr__",
"type":"math",
"expression":"2 + 1 < 1"
}`
case eval.Pending, eval.Alerting:
expression = `{
"datasourceUid": "-100",
"datasourceUid": "__expr__",
"type":"math",
"expression":"2 + 2 > 1"
}`
@@ -734,7 +734,7 @@ func withQueryForState(t *testing.T, evalResult eval.State) models.AlertRuleMuta
}
case eval.Error:
expression = `{
"datasourceUid": "-100",
"datasourceUid": "__expr__",
"type":"math",
"expression":"$A"
}`
@@ -746,7 +746,7 @@ func withQueryForState(t *testing.T, evalResult eval.State) models.AlertRuleMuta
rule.Condition = "A"
rule.Data = []models.AlertQuery{
{
DatasourceUID: "-100",
DatasourceUID: expr.DatasourceUID,
Model: json.RawMessage(expression),
RelativeTimeRange: models.RelativeTimeRange{
From: models.Duration(5 * time.Hour),
+1 -1
View File
@@ -139,7 +139,7 @@ func CreateTestAlertRuleWithLabels(t testing.TB, ctx context.Context, dbstore *s
Data: []models.AlertQuery{
{
Model: json.RawMessage(`{
"datasourceUid": "-100",
"datasourceUid": "__expr__",
"type":"math",
"expression":"2 + 2 > 1"
}`),
@@ -31,7 +31,7 @@ groups:
relativeTimeRange:
from: 0
to: 0
datasourceUID: "-100"
datasourceUid: "__expr__"
model:
conditions:
- evaluator:
@@ -49,7 +49,7 @@ groups:
type: query
datasource:
type: __expr__
uid: "-100"
uid: "__expr__"
hide: false
intervalMs: 1000
maxDataPoints: 43200
@@ -30,7 +30,7 @@ groups:
relativeTimeRange:
from: 0
to: 0
datasourceUID: "-100"
datasourceUid: "__expr__"
model:
conditions:
- evaluator:
@@ -48,7 +48,7 @@ groups:
type: query
datasource:
type: __expr__
uid: "-100"
uid: "__expr__"
hide: false
intervalMs: 1000
maxDataPoints: 43200
@@ -30,7 +30,7 @@ groups:
relativeTimeRange:
from: 0
to: 0
datasourceUID: "-100"
datasourceUid: "__expr__"
model:
conditions:
- evaluator:
@@ -48,7 +48,7 @@ groups:
type: query
datasource:
type: __expr__
uid: "-100"
uid: "__expr__"
hide: false
intervalMs: 1000
maxDataPoints: 43200
@@ -30,7 +30,7 @@ groups:
relativeTimeRange:
from: 0
to: 0
datasourceUID: "-100"
datasourceUid: "__expr__"
model:
conditions:
- evaluator:
@@ -48,7 +48,7 @@ groups:
type: query
datasource:
type: __expr__
uid: "-100"
uid: "__expr__"
hide: false
intervalMs: 1000
maxDataPoints: 43200
@@ -30,7 +30,7 @@ groups:
relativeTimeRange:
from: 0
to: 0
datasourceUID: "-100"
datasourceUid: "__expr__"
model:
conditions:
- evaluator:
@@ -48,7 +48,7 @@ groups:
type: query
datasource:
type: __expr__
uid: "-100"
uid: "__expr__"
hide: false
intervalMs: 1000
maxDataPoints: 43200
@@ -84,7 +84,7 @@ groups:
relativeTimeRange:
from: 0
to: 0
datasourceUID: "-100"
datasourceUid: "__expr__"
model:
conditions:
- evaluator:
@@ -102,9 +102,9 @@ groups:
type: query
datasource:
type: __expr__
uid: "-100"
uid: "__expr__"
hide: false
intervalMs: 1000
maxDataPoints: 43200
refId: B
type: classic_conditions
type: classic_conditions
@@ -30,7 +30,7 @@ apiVersion: 1
relativeTimeRange:
from: 0
to: 0
datasourceUID: "-100"
datasourceUid: "__expr__"
model:
conditions:
- evaluator:
@@ -48,7 +48,7 @@ apiVersion: 1
type: query
datasource:
type: __expr__
uid: "-100"
uid: "__expr__"
hide: false
intervalMs: 1000
maxDataPoints: 43200
@@ -41,7 +41,7 @@
"from": 0,
"to": 0
},
"datasourceUID": "-100",
"datasourceUid": "__expr__",
"model": {
"conditions": [
{
@@ -61,7 +61,7 @@
},
"reducer": {
"params": [
],
"type": "last"
},
@@ -70,7 +70,7 @@
],
"datasource": {
"type": "__expr__",
"uid": "-100"
"uid": "__expr__"
},
"hide": false,
"intervalMs": 1000,
@@ -84,4 +84,4 @@
]
}
]
}
}
@@ -30,7 +30,7 @@ groups:
relativeTimeRange:
from: 0
to: 0
datasourceUID: "-100"
datasourceUid: "__expr__"
model:
conditions:
- evaluator:
@@ -48,7 +48,7 @@ groups:
type: query
datasource:
type: __expr__
uid: "-100"
uid: "__expr__"
hide: false
intervalMs: 1000
maxDataPoints: 43200
@@ -30,7 +30,7 @@ groups:
relativeTimeRange:
from: 0
to: 0
datasourceUID: "-100"
datasourceUid: "__expr__"
model:
conditions:
- evaluator:
@@ -48,7 +48,7 @@ groups:
type: query
datasource:
type: __expr__
uid: "-100"
uid: "__expr__"
hide: false
intervalMs: 1000
maxDataPoints: 43200
+1 -1
View File
@@ -467,7 +467,7 @@ func (c *fakePluginClient) QueryData(ctx context.Context, req *backend.QueryData
c.req = req
// If an expression query ends up getting directly queried, we want it to return an error in our test.
if req.PluginContext.PluginID == "__expr__" {
if req.PluginContext.PluginID == expr.DatasourceUID {
return nil, errors.New("cant query an expression datasource")
}
@@ -171,7 +171,7 @@ func migrateAlertRuleQueries(data []alertQuery) ([]alertQuery, error) {
result := make([]alertQuery, 0, len(data))
for _, d := range data {
// queries that are expression are not relevant, skip them.
if d.DatasourceUID == expr.OldDatasourceUID {
if d.DatasourceUID == expr.DatasourceType {
result = append(result, d)
continue
}
@@ -7,6 +7,7 @@ import (
"strings"
"time"
"github.com/grafana/grafana/pkg/expr"
"github.com/grafana/grafana/pkg/util"
)
@@ -187,7 +188,7 @@ func transConditions(set dashAlertSettings, orgID int64, dsUIDMap dsUIDLookup) (
ccAlertQuery := alertQuery{
RefID: ccRefID,
Model: exprModelJSON,
DatasourceUID: "-100",
DatasourceUID: expr.DatasourceUID,
}
newCond.Data = append(newCond.Data, ccAlertQuery)