mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
AlertingNG: Edit Alert Definition (#30676)
* break out new and edit * changed model to match new model in backend * AlertingNG: API modifications (#30683) * Fix API consistency * Change eval alert definition to POST request * Fix eval endpoint to accept custom now parameter * Change JSON input property for create/update endpoints * model adjustments * set mixed datasource, fix put url * update snapshots * remove edit and add landing page * remove snapshot tests ans snapshots * wrap linkbutton in array Co-authored-by: Sofia Papagiannaki <papagian@users.noreply.github.com> Co-authored-by: Sofia Papagiannaki <sofia@grafana.com>
This commit is contained in:
@@ -38,13 +38,24 @@ func (ng *AlertNG) registerAPIEndpoints() {
|
||||
}
|
||||
|
||||
// conditionEvalEndpoint handles POST /api/alert-definitions/eval.
|
||||
func (ng *AlertNG) conditionEvalEndpoint(c *models.ReqContext, dto evalAlertConditionCommand) response.Response {
|
||||
if err := ng.validateCondition(dto.Condition, c.SignedInUser, c.SkipCache); err != nil {
|
||||
func (ng *AlertNG) conditionEvalEndpoint(c *models.ReqContext, cmd evalAlertConditionCommand) response.Response {
|
||||
evalCond := eval.Condition{
|
||||
RefID: cmd.Condition,
|
||||
OrgID: c.SignedInUser.OrgId,
|
||||
QueriesAndExpressions: cmd.Data,
|
||||
}
|
||||
if err := ng.validateCondition(evalCond, c.SignedInUser, c.SkipCache); err != nil {
|
||||
return response.Error(400, "invalid condition", err)
|
||||
}
|
||||
|
||||
now := cmd.Now
|
||||
if now.IsZero() {
|
||||
now = timeNow()
|
||||
}
|
||||
|
||||
evaluator := eval.Evaluator{Cfg: ng.Cfg}
|
||||
evalResults, err := evaluator.ConditionEval(&dto.Condition, timeNow())
|
||||
|
||||
evalResults, err := evaluator.ConditionEval(&evalCond, now)
|
||||
if err != nil {
|
||||
return response.Error(400, "Failed to evaluate conditions", err)
|
||||
}
|
||||
@@ -61,7 +72,7 @@ func (ng *AlertNG) conditionEvalEndpoint(c *models.ReqContext, dto evalAlertCond
|
||||
})
|
||||
}
|
||||
|
||||
// alertDefinitionEvalEndpoint handles GET /api/alert-definitions/eval/:alertDefinitionUID.
|
||||
// alertDefinitionEvalEndpoint handles POST /api/alert-definitions/eval/:alertDefinitionUID.
|
||||
func (ng *AlertNG) alertDefinitionEvalEndpoint(c *models.ReqContext) response.Response {
|
||||
alertDefinitionUID := c.Params(":alertDefinitionUID")
|
||||
|
||||
@@ -132,7 +143,12 @@ func (ng *AlertNG) updateAlertDefinitionEndpoint(c *models.ReqContext, cmd updat
|
||||
cmd.UID = c.Params(":alertDefinitionUID")
|
||||
cmd.OrgID = c.SignedInUser.OrgId
|
||||
|
||||
if err := ng.validateCondition(cmd.Condition, c.SignedInUser, c.SkipCache); err != nil {
|
||||
evalCond := eval.Condition{
|
||||
RefID: cmd.Condition,
|
||||
OrgID: c.SignedInUser.OrgId,
|
||||
QueriesAndExpressions: cmd.Data,
|
||||
}
|
||||
if err := ng.validateCondition(evalCond, c.SignedInUser, c.SkipCache); err != nil {
|
||||
return response.Error(400, "invalid condition", err)
|
||||
}
|
||||
|
||||
@@ -147,7 +163,12 @@ func (ng *AlertNG) updateAlertDefinitionEndpoint(c *models.ReqContext, cmd updat
|
||||
func (ng *AlertNG) createAlertDefinitionEndpoint(c *models.ReqContext, cmd saveAlertDefinitionCommand) response.Response {
|
||||
cmd.OrgID = c.SignedInUser.OrgId
|
||||
|
||||
if err := ng.validateCondition(cmd.Condition, c.SignedInUser, c.SkipCache); err != nil {
|
||||
evalCond := eval.Condition{
|
||||
RefID: cmd.Condition,
|
||||
OrgID: c.SignedInUser.OrgId,
|
||||
QueriesAndExpressions: cmd.Data,
|
||||
}
|
||||
if err := ng.validateCondition(evalCond, c.SignedInUser, c.SkipCache); err != nil {
|
||||
return response.Error(400, "invalid condition", err)
|
||||
}
|
||||
|
||||
|
||||
@@ -57,23 +57,21 @@ func overrideAlertNGInRegistry(cfg *setting.Cfg) AlertNG {
|
||||
|
||||
func createTestAlertDefinition(t *testing.T, ng *AlertNG, intervalSeconds int64) *AlertDefinition {
|
||||
cmd := saveAlertDefinitionCommand{
|
||||
OrgID: 1,
|
||||
Title: fmt.Sprintf("an alert definition %d", rand.Intn(1000)),
|
||||
Condition: eval.Condition{
|
||||
RefID: "A",
|
||||
QueriesAndExpressions: []eval.AlertQuery{
|
||||
{
|
||||
Model: json.RawMessage(`{
|
||||
OrgID: 1,
|
||||
Title: fmt.Sprintf("an alert definition %d", rand.Intn(1000)),
|
||||
Condition: "A",
|
||||
Data: []eval.AlertQuery{
|
||||
{
|
||||
Model: json.RawMessage(`{
|
||||
"datasource": "__expr__",
|
||||
"type":"math",
|
||||
"expression":"2 + 2 > 1"
|
||||
}`),
|
||||
RelativeTimeRange: eval.RelativeTimeRange{
|
||||
From: eval.Duration(5 * time.Hour),
|
||||
To: eval.Duration(3 * time.Hour),
|
||||
},
|
||||
RefID: "A",
|
||||
RelativeTimeRange: eval.RelativeTimeRange{
|
||||
From: eval.Duration(5 * time.Hour),
|
||||
To: eval.Duration(3 * time.Hour),
|
||||
},
|
||||
RefID: "A",
|
||||
},
|
||||
},
|
||||
IntervalSeconds: &intervalSeconds,
|
||||
|
||||
@@ -76,8 +76,8 @@ func (ng *AlertNG) saveAlertDefinition(cmd *saveAlertDefinitionCommand) error {
|
||||
alertDefinition := &AlertDefinition{
|
||||
OrgID: cmd.OrgID,
|
||||
Title: cmd.Title,
|
||||
Condition: cmd.Condition.RefID,
|
||||
Data: cmd.Condition.QueriesAndExpressions,
|
||||
Condition: cmd.Condition,
|
||||
Data: cmd.Data,
|
||||
IntervalSeconds: intervalSeconds,
|
||||
Version: initialVersion,
|
||||
UID: uid,
|
||||
@@ -133,11 +133,11 @@ func (ng *AlertNG) updateAlertDefinition(cmd *updateAlertDefinitionCommand) erro
|
||||
if title == "" {
|
||||
title = existingAlertDefinition.Title
|
||||
}
|
||||
condition := cmd.Condition.RefID
|
||||
condition := cmd.Condition
|
||||
if condition == "" {
|
||||
condition = existingAlertDefinition.Condition
|
||||
}
|
||||
data := cmd.Condition.QueriesAndExpressions
|
||||
data := cmd.Data
|
||||
if data == nil {
|
||||
data = existingAlertDefinition.Data
|
||||
}
|
||||
|
||||
@@ -74,22 +74,20 @@ func TestCreatingAlertDefinition(t *testing.T) {
|
||||
t.Cleanup(registry.ClearOverrides)
|
||||
|
||||
q := saveAlertDefinitionCommand{
|
||||
OrgID: 1,
|
||||
Title: tc.inputTitle,
|
||||
Condition: eval.Condition{
|
||||
RefID: "B",
|
||||
QueriesAndExpressions: []eval.AlertQuery{
|
||||
{
|
||||
Model: json.RawMessage(`{
|
||||
OrgID: 1,
|
||||
Title: tc.inputTitle,
|
||||
Condition: "B",
|
||||
Data: []eval.AlertQuery{
|
||||
{
|
||||
Model: json.RawMessage(`{
|
||||
"datasource": "__expr__",
|
||||
"type":"math",
|
||||
"expression":"2 + 3 > 1"
|
||||
}`),
|
||||
RefID: "B",
|
||||
RelativeTimeRange: eval.RelativeTimeRange{
|
||||
From: eval.Duration(time.Duration(5) * time.Hour),
|
||||
To: eval.Duration(time.Duration(3) * time.Hour),
|
||||
},
|
||||
RefID: "B",
|
||||
RelativeTimeRange: eval.RelativeTimeRange{
|
||||
From: eval.Duration(time.Duration(5) * time.Hour),
|
||||
To: eval.Duration(time.Duration(3) * time.Hour),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -117,22 +115,20 @@ func TestCreatingConflictionAlertDefinition(t *testing.T) {
|
||||
t.Cleanup(registry.ClearOverrides)
|
||||
|
||||
q := saveAlertDefinitionCommand{
|
||||
OrgID: 1,
|
||||
Title: "title",
|
||||
Condition: eval.Condition{
|
||||
RefID: "B",
|
||||
QueriesAndExpressions: []eval.AlertQuery{
|
||||
{
|
||||
Model: json.RawMessage(`{
|
||||
OrgID: 1,
|
||||
Title: "title",
|
||||
Condition: "B",
|
||||
Data: []eval.AlertQuery{
|
||||
{
|
||||
Model: json.RawMessage(`{
|
||||
"datasource": "__expr__",
|
||||
"type":"math",
|
||||
"expression":"2 + 3 > 1"
|
||||
}`),
|
||||
RefID: "B",
|
||||
RelativeTimeRange: eval.RelativeTimeRange{
|
||||
From: eval.Duration(time.Duration(5) * time.Hour),
|
||||
To: eval.Duration(time.Duration(3) * time.Hour),
|
||||
},
|
||||
RefID: "B",
|
||||
RelativeTimeRange: eval.RelativeTimeRange{
|
||||
From: eval.Duration(time.Duration(5) * time.Hour),
|
||||
To: eval.Duration(time.Duration(3) * time.Hour),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -156,23 +152,21 @@ func TestUpdatingAlertDefinition(t *testing.T) {
|
||||
t.Cleanup(registry.ClearOverrides)
|
||||
|
||||
q := updateAlertDefinitionCommand{
|
||||
UID: "unknown",
|
||||
OrgID: 1,
|
||||
Title: "something completely different",
|
||||
Condition: eval.Condition{
|
||||
RefID: "A",
|
||||
QueriesAndExpressions: []eval.AlertQuery{
|
||||
{
|
||||
Model: json.RawMessage(`{
|
||||
UID: "unknown",
|
||||
OrgID: 1,
|
||||
Title: "something completely different",
|
||||
Condition: "A",
|
||||
Data: []eval.AlertQuery{
|
||||
{
|
||||
Model: json.RawMessage(`{
|
||||
"datasource": "__expr__",
|
||||
"type":"math",
|
||||
"expression":"2 + 2 > 1"
|
||||
}`),
|
||||
RefID: "A",
|
||||
RelativeTimeRange: eval.RelativeTimeRange{
|
||||
From: eval.Duration(time.Duration(5) * time.Hour),
|
||||
To: eval.Duration(time.Duration(3) * time.Hour),
|
||||
},
|
||||
RefID: "A",
|
||||
RelativeTimeRange: eval.RelativeTimeRange{
|
||||
From: eval.Duration(time.Duration(5) * time.Hour),
|
||||
To: eval.Duration(time.Duration(3) * time.Hour),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -250,21 +244,19 @@ func TestUpdatingAlertDefinition(t *testing.T) {
|
||||
}
|
||||
|
||||
q := updateAlertDefinitionCommand{
|
||||
UID: (*alertDefinition).UID,
|
||||
Condition: eval.Condition{
|
||||
RefID: "B",
|
||||
QueriesAndExpressions: []eval.AlertQuery{
|
||||
{
|
||||
Model: json.RawMessage(`{
|
||||
UID: (*alertDefinition).UID,
|
||||
Condition: "B",
|
||||
Data: []eval.AlertQuery{
|
||||
{
|
||||
Model: json.RawMessage(`{
|
||||
"datasource": "__expr__",
|
||||
"type":"math",
|
||||
"expression":"2 + 3 > 1"
|
||||
}`),
|
||||
RefID: "B",
|
||||
RelativeTimeRange: eval.RelativeTimeRange{
|
||||
From: eval.Duration(5 * time.Hour),
|
||||
To: eval.Duration(3 * time.Hour),
|
||||
},
|
||||
RefID: "B",
|
||||
RelativeTimeRange: eval.RelativeTimeRange{
|
||||
From: eval.Duration(5 * time.Hour),
|
||||
To: eval.Duration(3 * time.Hour),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -335,22 +327,20 @@ func TestUpdatingConflictingAlertDefinition(t *testing.T) {
|
||||
alertDef2 := createTestAlertDefinition(t, ng, initialInterval)
|
||||
|
||||
q := updateAlertDefinitionCommand{
|
||||
UID: (*alertDef2).UID,
|
||||
Title: alertDef1.Title,
|
||||
Condition: eval.Condition{
|
||||
RefID: "B",
|
||||
QueriesAndExpressions: []eval.AlertQuery{
|
||||
{
|
||||
Model: json.RawMessage(`{
|
||||
UID: (*alertDef2).UID,
|
||||
Title: alertDef1.Title,
|
||||
Condition: "B",
|
||||
Data: []eval.AlertQuery{
|
||||
{
|
||||
Model: json.RawMessage(`{
|
||||
"datasource": "__expr__",
|
||||
"type":"math",
|
||||
"expression":"2 + 3 > 1"
|
||||
}`),
|
||||
RefID: "B",
|
||||
RelativeTimeRange: eval.RelativeTimeRange{
|
||||
From: eval.Duration(5 * time.Hour),
|
||||
To: eval.Duration(3 * time.Hour),
|
||||
},
|
||||
RefID: "B",
|
||||
RelativeTimeRange: eval.RelativeTimeRange{
|
||||
From: eval.Duration(5 * time.Hour),
|
||||
To: eval.Duration(3 * time.Hour),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -73,28 +73,31 @@ type deleteAlertDefinitionByUIDCommand struct {
|
||||
|
||||
// saveAlertDefinitionCommand is the query for saving a new alert definition.
|
||||
type saveAlertDefinitionCommand struct {
|
||||
Title string `json:"title"`
|
||||
OrgID int64 `json:"-"`
|
||||
Condition eval.Condition `json:"condition"`
|
||||
IntervalSeconds *int64 `json:"interval_seconds"`
|
||||
Title string `json:"title"`
|
||||
OrgID int64 `json:"-"`
|
||||
Condition string `json:"condition"`
|
||||
Data []eval.AlertQuery `json:"data"`
|
||||
IntervalSeconds *int64 `json:"intervalSeconds"`
|
||||
|
||||
Result *AlertDefinition
|
||||
}
|
||||
|
||||
// updateAlertDefinitionCommand is the query for updating an existing alert definition.
|
||||
type updateAlertDefinitionCommand struct {
|
||||
Title string `json:"title"`
|
||||
OrgID int64 `json:"-"`
|
||||
Condition eval.Condition `json:"condition"`
|
||||
IntervalSeconds *int64 `json:"interval_seconds"`
|
||||
UID string `json:"-"`
|
||||
Title string `json:"title"`
|
||||
OrgID int64 `json:"-"`
|
||||
Condition string `json:"condition"`
|
||||
Data []eval.AlertQuery `json:"data"`
|
||||
IntervalSeconds *int64 `json:"intervalSeconds"`
|
||||
UID string `json:"-"`
|
||||
|
||||
Result *AlertDefinition
|
||||
}
|
||||
|
||||
type evalAlertConditionCommand struct {
|
||||
Condition eval.Condition `json:"condition"`
|
||||
Now time.Time `json:"now"`
|
||||
Condition string `json:"condition"`
|
||||
Data []eval.AlertQuery `json:"data"`
|
||||
Now time.Time `json:"now"`
|
||||
}
|
||||
|
||||
type listAlertDefinitionsQuery struct {
|
||||
|
||||
Reference in New Issue
Block a user