ソースを参照

feat(alerting): removes pause per datasource

bergquist 9 年 前
コミット
ecdf1888c4

+ 2 - 44
pkg/api/alerting.go

@@ -287,20 +287,11 @@ func PauseAlert(c *middleware.Context, dto dtos.PauseAlertCommand) Response {
 }
 
 //POST /api/alerts/pause
-func PauseAlerts(c *middleware.Context, dto dtos.PauseAlertsCommand) Response {
-	updateCmd := models.PauseAlertCommand{
-		OrgId:  c.OrgId,
+func PauseAlerts(c *middleware.Context, dto dtos.PauseAllAlertsCommand) Response {
+	updateCmd := models.PauseAllAlertCommand{
 		Paused: dto.Paused,
 	}
 
-	if len(dto.DataSourceIds) > 0 {
-		alertIdsToUpdate, err := getAlertIdsToUpdate(dto)
-		if err != nil {
-			return ApiError(500, "Failed to pause alerts", err)
-		}
-		updateCmd.AlertIds = alertIdsToUpdate
-	}
-
 	if err := bus.Dispatch(&updateCmd); err != nil {
 		return ApiError(500, "Failed to pause alerts", err)
 	}
@@ -320,36 +311,3 @@ func PauseAlerts(c *middleware.Context, dto dtos.PauseAlertsCommand) Response {
 
 	return Json(200, result)
 }
-
-func getAlertIdsToUpdate(pauseAlertCmd dtos.PauseAlertsCommand) ([]int64, error) {
-	cmd := &models.GetAllAlertsQuery{}
-	if err := bus.Dispatch(cmd); err != nil {
-		return nil, err
-	}
-
-	var alertIdsToUpdate []int64
-	for _, alert := range cmd.Result {
-		alert, err := alerting.NewRuleFromDBAlert(alert)
-		if err != nil {
-			return nil, err
-		}
-
-		for _, condition := range alert.Conditions {
-			id, exist := condition.GetDatasourceId()
-			if exist && existInSlice(pauseAlertCmd.DataSourceIds, *id) {
-				alertIdsToUpdate = append(alertIdsToUpdate, alert.Id)
-			}
-		}
-	}
-
-	return alertIdsToUpdate, nil
-}
-
-func existInSlice(slice []int64, value int64) bool {
-	for _, v := range slice {
-		if v == value {
-			return true
-		}
-	}
-	return false
-}

+ 1 - 1
pkg/api/api.go

@@ -256,7 +256,6 @@ func Register(r *macaron.Macaron) {
 		r.Group("/alerts", func() {
 			r.Post("/test", bind(dtos.AlertTestCommand{}), wrap(AlertTest))
 			r.Post("/:alertId/pause", bind(dtos.PauseAlertCommand{}), wrap(PauseAlert), reqEditorRole)
-			r.Post("/pause", bind(dtos.PauseAlertsCommand{}), wrap(PauseAlerts), reqGrafanaAdmin)
 			r.Get("/:alertId", ValidateOrgAlert, wrap(GetAlert))
 			r.Get("/", wrap(GetAlerts))
 			r.Get("/states-for-dashboard", wrap(GetAlertStatesForDashboard))
@@ -290,6 +289,7 @@ func Register(r *macaron.Macaron) {
 		r.Get("/users/:id/quotas", wrap(GetUserQuotas))
 		r.Put("/users/:id/quotas/:target", bind(m.UpdateUserQuotaCmd{}), wrap(UpdateUserQuota))
 		r.Get("/stats", AdminGetStats)
+		r.Post("/pause-all-alerts", bind(dtos.PauseAllAlertsCommand{}), wrap(PauseAlerts))
 	}, reqGrafanaAdmin)
 
 	// rendering

+ 2 - 3
pkg/api/dtos/alerting.go

@@ -65,7 +65,6 @@ type PauseAlertCommand struct {
 	Paused  bool  `json:"paused"`
 }
 
-type PauseAlertsCommand struct {
-	DataSourceIds []int64 `json:"datasourceId"`
-	Paused        bool    `json:"paused"`
+type PauseAllAlertsCommand struct {
+	Paused bool `json:"paused"`
 }

+ 1 - 1
pkg/metrics/metrics.go

@@ -50,7 +50,7 @@ var (
 
 	// Timers
 	M_DataSource_ProxyReq_Timer Timer
-	M_Alerting_Execution_Time Timer
+	M_Alerting_Execution_Time   Timer
 
 	// StatTotals
 	M_Alerting_Active_Alerts Gauge

+ 11 - 0
pkg/models/alert.go

@@ -3,6 +3,8 @@ package models
 import (
 	"time"
 
+	"fmt"
+
 	"github.com/grafana/grafana/pkg/components/simplejson"
 )
 
@@ -31,6 +33,10 @@ const (
 	ExecutionErrorKeepState   ExecutionErrorOption = "keep_state"
 )
 
+var (
+	ErrCannotChangeStateOnPausedAlert error = fmt.Errorf("Cannot change state on pause alert")
+)
+
 func (s AlertStateType) IsValid() bool {
 	return s == AlertStateOK || s == AlertStateNoData || s == AlertStatePaused || s == AlertStatePending
 }
@@ -138,6 +144,11 @@ type PauseAlertCommand struct {
 	Paused      bool
 }
 
+type PauseAllAlertCommand struct {
+	ResultCount int64
+	Paused      bool
+}
+
 type SetAlertStateCommand struct {
 	AlertId  int64
 	OrgId    int64

+ 0 - 4
pkg/services/alerting/conditions/query.go

@@ -34,10 +34,6 @@ type AlertQuery struct {
 	To           string
 }
 
-func (c *QueryCondition) GetDatasourceId() (datasourceId *int64, exist bool) {
-	return &c.Query.DatasourceId, true
-}
-
 func (c *QueryCondition) Eval(context *alerting.EvalContext) (*alerting.ConditionResult, error) {
 	timeRange := tsdb.NewTimeRange(c.Query.From, c.Query.To)
 

+ 0 - 1
pkg/services/alerting/interfaces.go

@@ -30,5 +30,4 @@ type ConditionResult struct {
 
 type Condition interface {
 	Eval(result *EvalContext) (*ConditionResult, error)
-	GetDatasourceId() (datasourceId *int64, exist bool)
 }

+ 4 - 0
pkg/services/alerting/result_handler.go

@@ -86,6 +86,10 @@ func (handler *DefaultResultHandler) Handle(evalContext *EvalContext) error {
 		}
 
 		if err := bus.Dispatch(cmd); err != nil {
+			if err == m.ErrCannotChangeStateOnPausedAlert {
+				handler.log.Error("Cannot change state on alert thats pause", "error", err)
+				return err
+			}
 			handler.log.Error("Failed to save state", "error", err)
 		}
 

+ 0 - 4
pkg/services/alerting/rule_test.go

@@ -14,10 +14,6 @@ func (f *FakeCondition) Eval(context *EvalContext) (*ConditionResult, error) {
 	return &ConditionResult{}, nil
 }
 
-func (c *FakeCondition) GetDatasourceId() (datasourceId *int64, exist bool) {
-	return nil, false
-}
-
 func TestAlertRuleModel(t *testing.T) {
 	Convey("Testing alert rule", t, func() {
 

+ 31 - 7
pkg/services/sqlstore/alert.go

@@ -3,9 +3,8 @@ package sqlstore
 import (
 	"bytes"
 	"fmt"
-	"time"
-
 	"strings"
+	"time"
 
 	"github.com/go-xorm/xorm"
 	"github.com/grafana/grafana/pkg/bus"
@@ -21,6 +20,7 @@ func init() {
 	bus.AddHandler("sql", SetAlertState)
 	bus.AddHandler("sql", GetAlertStatesForDashboard)
 	bus.AddHandler("sql", PauseAlertRule)
+	bus.AddHandler("sql", PauseAllAlertRule)
 }
 
 func GetAlertById(query *m.GetAlertByIdQuery) error {
@@ -230,6 +230,10 @@ func SetAlertState(cmd *m.SetAlertStateCommand) error {
 			return fmt.Errorf("Could not find alert")
 		}
 
+		if alert.State == m.AlertStatePaused {
+			return m.ErrCannotChangeStateOnPausedAlert
+		}
+
 		alert.State = cmd.State
 		alert.StateChanges += 1
 		alert.NewStateDate = time.Now()
@@ -248,6 +252,10 @@ func SetAlertState(cmd *m.SetAlertStateCommand) error {
 
 func PauseAlertRule(cmd *m.PauseAlertCommand) error {
 	return inTransaction(func(sess *xorm.Session) error {
+		if len(cmd.AlertIds) == 0 {
+			return fmt.Errorf("command contains no alertids")
+		}
+
 		var buffer bytes.Buffer
 		params := make([]interface{}, 0)
 
@@ -258,11 +266,9 @@ func PauseAlertRule(cmd *m.PauseAlertCommand) error {
 			params = append(params, string(m.AlertStatePending))
 		}
 
-		if len(cmd.AlertIds) > 0 {
-			buffer.WriteString(` WHERE id IN (?` + strings.Repeat(",?", len(cmd.AlertIds)-1) + `)`)
-			for _, v := range cmd.AlertIds {
-				params = append(params, v)
-			}
+		buffer.WriteString(` WHERE id IN (?` + strings.Repeat(",?", len(cmd.AlertIds)-1) + `)`)
+		for _, v := range cmd.AlertIds {
+			params = append(params, v)
 		}
 
 		res, err := sess.Exec(buffer.String(), params...)
@@ -274,6 +280,24 @@ func PauseAlertRule(cmd *m.PauseAlertCommand) error {
 	})
 }
 
+func PauseAllAlertRule(cmd *m.PauseAllAlertCommand) error {
+	return inTransaction(func(sess *xorm.Session) error {
+		var newState string
+		if cmd.Paused {
+			newState = string(m.AlertStatePaused)
+		} else {
+			newState = string(m.AlertStatePending)
+		}
+
+		res, err := sess.Exec(`UPDATE alert SET state = ?`, newState)
+		if err != nil {
+			return err
+		}
+		cmd.ResultCount, _ = res.RowsAffected()
+		return nil
+	})
+}
+
 func GetAlertStatesForDashboard(query *m.GetAlertStatesForDashboardQuery) error {
 	var rawSql = `SELECT
 	                id,

+ 31 - 0
pkg/services/sqlstore/alert_test.go

@@ -39,6 +39,37 @@ func TestAlertingDataAccess(t *testing.T) {
 			So(err, ShouldBeNil)
 		})
 
+		Convey("Can set new states", func() {
+			Convey("new state ok", func() {
+				cmd := &m.SetAlertStateCommand{
+					AlertId: 1,
+					State:   m.AlertStateOK,
+				}
+
+				err = SetAlertState(cmd)
+				So(err, ShouldBeNil)
+			})
+
+			Convey("can pause alert", func() {
+				cmd := &m.PauseAllAlertCommand{
+					Paused: true,
+				}
+
+				err = PauseAllAlertRule(cmd)
+				So(err, ShouldBeNil)
+
+				Convey("cannot updated paused alert", func() {
+					cmd := &m.SetAlertStateCommand{
+						AlertId: 1,
+						State:   m.AlertStateOK,
+					}
+
+					err = SetAlertState(cmd)
+					So(err, ShouldNotBeNil)
+				})
+			})
+		})
+
 		Convey("Can read properties", func() {
 			alertQuery := m.GetAlertsQuery{DashboardId: testDash.Id, PanelId: 1, OrgId: 1}
 			err2 := HandleAlertsQuery(&alertQuery)