@ -9,42 +9,52 @@ import (
"github.com/grafana/grafana/pkg/api/routing"
"github.com/grafana/grafana/pkg/middleware"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/ngalert/eval"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/tsdb"
"github.com/grafana/grafana/pkg/util"
)
func ( ng * AlertNG ) registerAPIEndpoints ( ) {
ng . RouteRegister . Group ( "/api/alert-definitions" , func ( alertDefinitions routing . RouteRegister ) {
alertDefinitions . Get ( "" , middleware . ReqSignedIn , routing . Wrap ( ng . listAlertDefinitions ) )
alertDefinitions . Get ( "/eval/:alertDefinitionUID" , middleware . ReqSignedIn , ng . validateOrgAlertDefinition , routing . Wrap ( ng . alertDefinitionEvalEndpoint ) )
alertDefinitions . Post ( "/eval" , middleware . ReqSignedIn , binding . Bind ( evalAlertConditionCommand { } ) , routing . Wrap ( ng . conditionEvalEndpoint ) )
alertDefinitions . Get ( "/:alertDefinitionUID" , middleware . ReqSignedIn , ng . validateOrgAlertDefinition , routing . Wrap ( ng . getAlertDefinitionEndpoint ) )
alertDefinitions . Delete ( "/:alertDefinitionUID" , middleware . ReqEditorRole , ng . validateOrgAlertDefinition , routing . Wrap ( ng . deleteAlertDefinitionEndpoint ) )
alertDefinitions . Post ( "/" , middleware . ReqEditorRole , binding . Bind ( saveAlertDefinitionCommand { } ) , routing . Wrap ( ng . createAlertDefinitionEndpoint ) )
alertDefinitions . Put ( "/:alertDefinitionUID" , middleware . ReqEditorRole , ng . validateOrgAlertDefinition , binding . Bind ( updateAlertDefinitionCommand { } ) , routing . Wrap ( ng . updateAlertDefinitionEndpoint ) )
alertDefinitions . Post ( "/pause" , middleware . ReqEditorRole , binding . Bind ( updateAlertDefinitionPausedCommand { } ) , routing . Wrap ( ng . alertDefinitionPauseEndpoint ) )
alertDefinitions . Post ( "/unpause" , middleware . ReqEditorRole , binding . Bind ( updateAlertDefinitionPausedCommand { } ) , routing . Wrap ( ng . alertDefinitionUnpauseEndpoint ) )
type apiImpl struct {
Cfg * setting . Cfg ` inject:"" `
DatasourceCache datasources . CacheService ` inject:"" `
RouteRegister routing . RouteRegister ` inject:"" `
schedule scheduleService
store store
}
func ( api * apiImpl ) registerAPIEndpoints ( ) {
api . RouteRegister . Group ( "/api/alert-definitions" , func ( alertDefinitions routing . RouteRegister ) {
alertDefinitions . Get ( "" , middleware . ReqSignedIn , routing . Wrap ( api . listAlertDefinitions ) )
alertDefinitions . Get ( "/eval/:alertDefinitionUID" , middleware . ReqSignedIn , api . validateOrgAlertDefinition , routing . Wrap ( api . alertDefinitionEvalEndpoint ) )
alertDefinitions . Post ( "/eval" , middleware . ReqSignedIn , binding . Bind ( evalAlertConditionCommand { } ) , routing . Wrap ( api . conditionEvalEndpoint ) )
alertDefinitions . Get ( "/:alertDefinitionUID" , middleware . ReqSignedIn , api . validateOrgAlertDefinition , routing . Wrap ( api . getAlertDefinitionEndpoint ) )
alertDefinitions . Delete ( "/:alertDefinitionUID" , middleware . ReqEditorRole , api . validateOrgAlertDefinition , routing . Wrap ( api . deleteAlertDefinitionEndpoint ) )
alertDefinitions . Post ( "/" , middleware . ReqEditorRole , binding . Bind ( saveAlertDefinitionCommand { } ) , routing . Wrap ( api . createAlertDefinitionEndpoint ) )
alertDefinitions . Put ( "/:alertDefinitionUID" , middleware . ReqEditorRole , api . validateOrgAlertDefinition , binding . Bind ( updateAlertDefinitionCommand { } ) , routing . Wrap ( api . updateAlertDefinitionEndpoint ) )
alertDefinitions . Post ( "/pause" , middleware . ReqEditorRole , binding . Bind ( updateAlertDefinitionPausedCommand { } ) , routing . Wrap ( api . alertDefinitionPauseEndpoint ) )
alertDefinitions . Post ( "/unpause" , middleware . ReqEditorRole , binding . Bind ( updateAlertDefinitionPausedCommand { } ) , routing . Wrap ( api . alertDefinitionUnpauseEndpoint ) )
} )
ng . RouteRegister . Group ( "/api/ngalert/" , func ( schedulerRouter routing . RouteRegister ) {
schedulerRouter . Post ( "/pause" , routing . Wrap ( ng . pauseScheduler ) )
schedulerRouter . Post ( "/unpause" , routing . Wrap ( ng . unpauseScheduler ) )
api . RouteRegister . Group ( "/api/ngalert/" , func ( schedulerRouter routing . RouteRegister ) {
schedulerRouter . Post ( "/pause" , routing . Wrap ( api . pauseScheduler ) )
schedulerRouter . Post ( "/unpause" , routing . Wrap ( api . unpauseScheduler ) )
} , middleware . ReqOrgAdmin )
ng . RouteRegister . Group ( "/api/alert-instances" , func ( alertInstances routing . RouteRegister ) {
alertInstances . Get ( "" , middleware . ReqSignedIn , routing . Wrap ( ng . listAlertInstancesEndpoint ) )
api . RouteRegister . Group ( "/api/alert-instances" , func ( alertInstances routing . RouteRegister ) {
alertInstances . Get ( "" , middleware . ReqSignedIn , routing . Wrap ( api . listAlertInstancesEndpoint ) )
} )
}
// conditionEvalEndpoint handles POST /api/alert-definitions/eval.
func ( ng * AlertNG ) conditionEvalEndpoint ( c * models . ReqContext , cmd evalAlertConditionCommand ) response . Response {
func ( api * apiImpl ) 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 {
if err := api . validateCondition ( evalCond , c . SignedInUser , c . SkipCache ) ; err != nil {
return response . Error ( 400 , "invalid condition" , err )
}
@ -53,9 +63,8 @@ func (ng *AlertNG) conditionEvalEndpoint(c *models.ReqContext, cmd evalAlertCond
now = timeNow ( )
}
evaluator := eval . Evaluator { Cfg : ng . Cfg }
evalResults , err := evaluator . ConditionEval ( & evalCond , now )
evaluator := eval . Evaluator { Cfg : api . Cfg }
evalResults , err := evaluator . ConditionEval ( & evalCond , timeNow ( ) )
if err != nil {
return response . Error ( 400 , "Failed to evaluate conditions" , err )
}
@ -72,20 +81,20 @@ func (ng *AlertNG) conditionEvalEndpoint(c *models.ReqContext, cmd evalAlertCond
} )
}
// alertDefinitionEvalEndpoint handles POS T /api/alert-definitions/eval/:alertDefinitionUID.
func ( ng * AlertNG ) alertDefinitionEvalEndpoint ( c * models . ReqContext ) response . Response {
// alertDefinitionEvalEndpoint handles GE T /api/alert-definitions/eval/:alertDefinitionUID.
func ( api * apiImpl ) alertDefinitionEvalEndpoint ( c * models . ReqContext ) response . Response {
alertDefinitionUID := c . Params ( ":alertDefinitionUID" )
condition , err := ng . LoadAlertCondition ( alertDefinitionUID , c . SignedInUser . OrgId )
condition , err := api . LoadAlertCondition ( alertDefinitionUID , c . SignedInUser . OrgId )
if err != nil {
return response . Error ( 400 , "Failed to load alert definition conditions" , err )
}
if err := ng . validateCondition ( * condition , c . SignedInUser , c . SkipCache ) ; err != nil {
if err := api . validateCondition ( * condition , c . SignedInUser , c . SkipCache ) ; err != nil {
return response . Error ( 400 , "invalid condition" , err )
}
evaluator := eval . Evaluator { Cfg : ng . Cfg }
evaluator := eval . Evaluator { Cfg : api . Cfg }
evalResults , err := evaluator . ConditionEval ( condition , timeNow ( ) )
if err != nil {
return response . Error ( 400 , "Failed to evaluate alert" , err )
@ -107,7 +116,7 @@ func (ng *AlertNG) alertDefinitionEvalEndpoint(c *models.ReqContext) response.Re
}
// getAlertDefinitionEndpoint handles GET /api/alert-definitions/:alertDefinitionUID.
func ( ng * AlertNG ) getAlertDefinitionEndpoint ( c * models . ReqContext ) response . Response {
func ( api * apiImpl ) getAlertDefinitionEndpoint ( c * models . ReqContext ) response . Response {
alertDefinitionUID := c . Params ( ":alertDefinitionUID" )
query := getAlertDefinitionByUIDQuery {
@ -115,7 +124,7 @@ func (ng *AlertNG) getAlertDefinitionEndpoint(c *models.ReqContext) response.Res
OrgID : c . SignedInUser . OrgId ,
}
if err := ng . getAlertDefinitionByUID ( & query ) ; err != nil {
if err := api . store . getAlertDefinitionByUID ( & query ) ; err != nil {
return response . Error ( 500 , "Failed to get alert definition" , err )
}
@ -123,7 +132,7 @@ func (ng *AlertNG) getAlertDefinitionEndpoint(c *models.ReqContext) response.Res
}
// deleteAlertDefinitionEndpoint handles DELETE /api/alert-definitions/:alertDefinitionUID.
func ( ng * AlertNG ) deleteAlertDefinitionEndpoint ( c * models . ReqContext ) response . Response {
func ( api * apiImpl ) deleteAlertDefinitionEndpoint ( c * models . ReqContext ) response . Response {
alertDefinitionUID := c . Params ( ":alertDefinitionUID" )
cmd := deleteAlertDefinitionByUIDCommand {
@ -131,7 +140,7 @@ func (ng *AlertNG) deleteAlertDefinitionEndpoint(c *models.ReqContext) response.
OrgID : c . SignedInUser . OrgId ,
}
if err := ng . deleteAlertDefinitionByUID ( & cmd ) ; err != nil {
if err := api . store . deleteAlertDefinitionByUID ( & cmd ) ; err != nil {
return response . Error ( 500 , "Failed to delete alert definition" , err )
}
@ -139,7 +148,7 @@ func (ng *AlertNG) deleteAlertDefinitionEndpoint(c *models.ReqContext) response.
}
// updateAlertDefinitionEndpoint handles PUT /api/alert-definitions/:alertDefinitionUID.
func ( ng * AlertNG ) updateAlertDefinitionEndpoint ( c * models . ReqContext , cmd updateAlertDefinitionCommand ) response . Response {
func ( api * apiImpl ) updateAlertDefinitionEndpoint ( c * models . ReqContext , cmd updateAlertDefinitionCommand ) response . Response {
cmd . UID = c . Params ( ":alertDefinitionUID" )
cmd . OrgID = c . SignedInUser . OrgId
@ -148,11 +157,11 @@ func (ng *AlertNG) updateAlertDefinitionEndpoint(c *models.ReqContext, cmd updat
OrgID : c . SignedInUser . OrgId ,
QueriesAndExpressions : cmd . Data ,
}
if err := ng . validateCondition ( evalCond , c . SignedInUser , c . SkipCache ) ; err != nil {
if err := api . validateCondition ( evalCond , c . SignedInUser , c . SkipCache ) ; err != nil {
return response . Error ( 400 , "invalid condition" , err )
}
if err := ng . updateAlertDefinition ( & cmd ) ; err != nil {
if err := api . store . updateAlertDefinition ( & cmd ) ; err != nil {
return response . Error ( 500 , "Failed to update alert definition" , err )
}
@ -160,7 +169,7 @@ func (ng *AlertNG) updateAlertDefinitionEndpoint(c *models.ReqContext, cmd updat
}
// createAlertDefinitionEndpoint handles POST /api/alert-definitions.
func ( ng * AlertNG ) createAlertDefinitionEndpoint ( c * models . ReqContext , cmd saveAlertDefinitionCommand ) response . Response {
func ( api * apiImpl ) createAlertDefinitionEndpoint ( c * models . ReqContext , cmd saveAlertDefinitionCommand ) response . Response {
cmd . OrgID = c . SignedInUser . OrgId
evalCond := eval . Condition {
@ -168,11 +177,11 @@ func (ng *AlertNG) createAlertDefinitionEndpoint(c *models.ReqContext, cmd saveA
OrgID : c . SignedInUser . OrgId ,
QueriesAndExpressions : cmd . Data ,
}
if err := ng . validateCondition ( evalCond , c . SignedInUser , c . SkipCache ) ; err != nil {
if err := api . validateCondition ( evalCond , c . SignedInUser , c . SkipCache ) ; err != nil {
return response . Error ( 400 , "invalid condition" , err )
}
if err := ng . saveAlertDefinition ( & cmd ) ; err != nil {
if err := api . store . saveAlertDefinition ( & cmd ) ; err != nil {
return response . Error ( 500 , "Failed to create alert definition" , err )
}
@ -180,26 +189,26 @@ func (ng *AlertNG) createAlertDefinitionEndpoint(c *models.ReqContext, cmd saveA
}
// listAlertDefinitions handles GET /api/alert-definitions.
func ( ng * AlertNG ) listAlertDefinitions ( c * models . ReqContext ) response . Response {
func ( api * apiImpl ) listAlertDefinitions ( c * models . ReqContext ) response . Response {
query := listAlertDefinitionsQuery { OrgID : c . SignedInUser . OrgId }
if err := ng . getOrgAlertDefinitions ( & query ) ; err != nil {
if err := api . store . getOrgAlertDefinitions ( & query ) ; err != nil {
return response . Error ( 500 , "Failed to list alert definitions" , err )
}
return response . JSON ( 200 , util . DynMap { "results" : query . Result } )
}
func ( ng * AlertNG ) pauseScheduler ( ) response . Response {
err := ng . schedule . p ause( )
func ( api * apiImpl ) pauseScheduler ( ) response . Response {
err := api . schedule . P ause( )
if err != nil {
return response . Error ( 500 , "Failed to pause scheduler" , err )
}
return response . JSON ( 200 , util . DynMap { "message" : "alert definition scheduler paused" } )
}
func ( ng * AlertNG ) unpauseScheduler ( ) response . Response {
err := ng . schedule . u npause( )
func ( api * apiImpl ) unpauseScheduler ( ) response . Response {
err := api . schedule . U npause( )
if err != nil {
return response . Error ( 500 , "Failed to unpause scheduler" , err )
}
@ -207,11 +216,11 @@ func (ng *AlertNG) unpauseScheduler() response.Response {
}
// alertDefinitionPauseEndpoint handles POST /api/alert-definitions/pause.
func ( ng * AlertNG ) alertDefinitionPauseEndpoint ( c * models . ReqContext , cmd updateAlertDefinitionPausedCommand ) response . Response {
func ( api * apiImpl ) alertDefinitionPauseEndpoint ( c * models . ReqContext , cmd updateAlertDefinitionPausedCommand ) response . Response {
cmd . OrgID = c . SignedInUser . OrgId
cmd . Paused = true
err := ng . updateAlertDefinitionPaused ( & cmd )
err := api . store . updateAlertDefinitionPaused ( & cmd )
if err != nil {
return response . Error ( 500 , "Failed to pause alert definition" , err )
}
@ -219,11 +228,11 @@ func (ng *AlertNG) alertDefinitionPauseEndpoint(c *models.ReqContext, cmd update
}
// alertDefinitionUnpauseEndpoint handles POST /api/alert-definitions/unpause.
func ( ng * AlertNG ) alertDefinitionUnpauseEndpoint ( c * models . ReqContext , cmd updateAlertDefinitionPausedCommand ) response . Response {
func ( api * apiImpl ) alertDefinitionUnpauseEndpoint ( c * models . ReqContext , cmd updateAlertDefinitionPausedCommand ) response . Response {
cmd . OrgID = c . SignedInUser . OrgId
cmd . Paused = false
err := ng . updateAlertDefinitionPaused ( & cmd )
err := api . store . updateAlertDefinitionPaused ( & cmd )
if err != nil {
return response . Error ( 500 , "Failed to unpause alert definition" , err )
}