grafana/pkg/services/ngalert/database.go
Sofia Papagiannaki 43f580c299
AlertingNG: manage and evaluate alert definitions via the API (#28377)
* Alerting NG: prototype v2 (WIP)

* Separate eval package

* Modify eval alert definition endpoint

* Disable migration if ngalert is not enabled

* Remove premature test

* Fix lint issues

* Delete obsolete struct

* Apply suggestions from code review

* Update pkg/services/ngalert/ngalert.go

Co-authored-by: Kyle Brandt <kyle@grafana.com>

* Add API endpoint for listing alert definitions

* Introduce index for alert_definition table

* make ds object for expression to avoid panic

* wrap error

* Update pkg/services/ngalert/eval/eval.go

* Swith to backend.DataQuery

* Export TransformWrapper callback

* Fix lint issues

* Update pkg/services/ngalert/ngalert.go

Co-authored-by: Kyle Brandt <kyle@grafana.com>

* Validate alert definitions before storing them

* Introduce AlertQuery

* Add test

* Add QueryType in AlertQuery

* Accept only float64 (seconds) durations

* Apply suggestions from code review

* Get rid of bus

* Do not export symbols

* Fix failing test

* Fix failure due to service initialization order

Introduce MediumHigh service priority and assign it to backendplugin
service

* Fix test

* Apply suggestions from code review

* Fix renamed reference

Co-authored-by: Kyle Brandt <kyle@grafana.com>
2020-11-12 15:11:30 +02:00

122 lines
3.7 KiB
Go

package ngalert
import (
"context"
"github.com/grafana/grafana/pkg/services/sqlstore"
)
func getAlertDefinitionByID(alertDefinitionID int64, sess *sqlstore.DBSession) (*AlertDefinition, error) {
alertDefinition := AlertDefinition{}
has, err := sess.ID(alertDefinitionID).Get(&alertDefinition)
if !has {
return nil, errAlertDefinitionNotFound
}
if err != nil {
return nil, err
}
return &alertDefinition, nil
}
// deleteAlertDefinitionByID is a handler for deleting an alert definition.
// It returns models.ErrAlertDefinitionNotFound if no alert definition is found for the provided ID.
func (ng *AlertNG) deleteAlertDefinitionByID(query *deleteAlertDefinitionByIDQuery) error {
return ng.SQLStore.WithTransactionalDbSession(context.Background(), func(sess *sqlstore.DBSession) error {
res, err := sess.Exec("DELETE FROM alert_definition WHERE id = ?", query.ID)
if err != nil {
return err
}
rowsAffected, err := res.RowsAffected()
if err != nil {
return err
}
query.RowsAffected = rowsAffected
return nil
})
}
// getAlertDefinitionByID is a handler for retrieving an alert definition from that database by its ID.
// It returns models.ErrAlertDefinitionNotFound if no alert definition is found for the provided ID.
func (ng *AlertNG) getAlertDefinitionByID(query *getAlertDefinitionByIDQuery) error {
return ng.SQLStore.WithTransactionalDbSession(context.Background(), func(sess *sqlstore.DBSession) error {
alertDefinition, err := getAlertDefinitionByID(query.ID, sess)
if err != nil {
return err
}
query.Result = alertDefinition
return nil
})
}
// saveAlertDefinition is a handler for saving a new alert definition.
func (ng *AlertNG) saveAlertDefinition(cmd *saveAlertDefinitionCommand) error {
return ng.SQLStore.WithTransactionalDbSession(context.Background(), func(sess *sqlstore.DBSession) error {
alertDefinition := &AlertDefinition{
OrgId: cmd.OrgID,
Name: cmd.Name,
Condition: cmd.Condition.RefID,
Data: cmd.Condition.QueriesAndExpressions,
}
if err := ng.validateAlertDefinition(alertDefinition, cmd.SignedInUser, cmd.SkipCache); err != nil {
return err
}
if err := alertDefinition.preSave(); err != nil {
return err
}
if _, err := sess.Insert(alertDefinition); err != nil {
return err
}
cmd.Result = alertDefinition
return nil
})
}
// updateAlertDefinition is a handler for updating an existing alert definition.
// It returns models.ErrAlertDefinitionNotFound if no alert definition is found for the provided ID.
func (ng *AlertNG) updateAlertDefinition(cmd *updateAlertDefinitionCommand) error {
return ng.SQLStore.WithTransactionalDbSession(context.Background(), func(sess *sqlstore.DBSession) error {
alertDefinition := &AlertDefinition{
Id: cmd.ID,
Name: cmd.Name,
Condition: cmd.Condition.RefID,
Data: cmd.Condition.QueriesAndExpressions,
}
if err := ng.validateAlertDefinition(alertDefinition, cmd.SignedInUser, cmd.SkipCache); err != nil {
return err
}
if err := alertDefinition.preSave(); err != nil {
return err
}
affectedRows, err := sess.ID(cmd.ID).Update(alertDefinition)
if err != nil {
return err
}
cmd.Result = alertDefinition
cmd.RowsAffected = affectedRows
return nil
})
}
// getAlertDefinitions is a handler for retrieving alert definitions of specific organisation.
func (ng *AlertNG) getAlertDefinitions(cmd *listAlertDefinitionsCommand) error {
return ng.SQLStore.WithTransactionalDbSession(context.Background(), func(sess *sqlstore.DBSession) error {
alertDefinitions := make([]*AlertDefinition, 0)
q := "SELECT * FROM alert_definition WHERE org_id = ?"
if err := sess.SQL(q, cmd.OrgID).Find(&alertDefinitions); err != nil {
return err
}
cmd.Result = alertDefinitions
return nil
})
}