2016-06-11 03:13:33 -05:00
|
|
|
package alerting
|
|
|
|
|
|
|
|
import (
|
2021-10-18 10:06:19 -05:00
|
|
|
"context"
|
2020-07-23 01:17:20 -05:00
|
|
|
"encoding/json"
|
2016-06-11 03:13:33 -05:00
|
|
|
"errors"
|
2016-11-03 01:25:00 -05:00
|
|
|
"fmt"
|
|
|
|
|
2016-06-11 03:13:33 -05:00
|
|
|
"github.com/grafana/grafana/pkg/bus"
|
|
|
|
"github.com/grafana/grafana/pkg/components/simplejson"
|
2019-05-13 01:45:54 -05:00
|
|
|
"github.com/grafana/grafana/pkg/infra/log"
|
2019-05-14 01:15:05 -05:00
|
|
|
"github.com/grafana/grafana/pkg/models"
|
2016-06-11 03:13:33 -05:00
|
|
|
)
|
|
|
|
|
2019-05-20 05:13:32 -05:00
|
|
|
// DashAlertExtractor extracts alerts from the dashboard json.
|
2016-06-11 03:54:24 -05:00
|
|
|
type DashAlertExtractor struct {
|
2019-05-14 01:15:05 -05:00
|
|
|
User *models.SignedInUser
|
|
|
|
Dash *models.Dashboard
|
2018-03-28 04:31:33 -05:00
|
|
|
OrgID int64
|
2016-06-11 03:13:33 -05:00
|
|
|
log log.Logger
|
|
|
|
}
|
|
|
|
|
2019-05-20 05:13:32 -05:00
|
|
|
// NewDashAlertExtractor returns a new DashAlertExtractor.
|
2019-05-14 01:15:05 -05:00
|
|
|
func NewDashAlertExtractor(dash *models.Dashboard, orgID int64, user *models.SignedInUser) *DashAlertExtractor {
|
2016-06-11 03:54:24 -05:00
|
|
|
return &DashAlertExtractor{
|
2018-11-05 07:25:19 -06:00
|
|
|
User: user,
|
2016-06-11 03:13:33 -05:00
|
|
|
Dash: dash,
|
2018-03-28 04:31:33 -05:00
|
|
|
OrgID: orgID,
|
2016-06-11 03:13:33 -05:00
|
|
|
log: log.New("alerting.extractor"),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-29 12:57:24 -05:00
|
|
|
func (e *DashAlertExtractor) lookupQueryDataSource(panel *simplejson.Json, panelQuery *simplejson.Json) (*models.DataSource, error) {
|
|
|
|
dsName := ""
|
|
|
|
dsUid := ""
|
|
|
|
|
|
|
|
datasource, ok := panelQuery.CheckGet("datasource")
|
|
|
|
|
|
|
|
if !ok {
|
|
|
|
datasource = panel.Get("datasource")
|
|
|
|
}
|
|
|
|
|
|
|
|
if name, err := datasource.String(); err == nil {
|
|
|
|
dsName = name
|
|
|
|
} else if uid, ok := datasource.CheckGet("uid"); ok {
|
|
|
|
dsUid = uid.MustString()
|
|
|
|
}
|
|
|
|
|
|
|
|
if dsName == "" && dsUid == "" {
|
2021-01-07 14:33:17 -06:00
|
|
|
query := &models.GetDefaultDataSourceQuery{OrgId: e.OrgID}
|
2021-10-18 10:06:19 -05:00
|
|
|
if err := bus.DispatchCtx(context.TODO(), query); err != nil {
|
2016-06-20 04:44:06 -05:00
|
|
|
return nil, err
|
2018-03-28 04:31:33 -05:00
|
|
|
}
|
|
|
|
return query.Result, nil
|
2016-06-11 03:13:33 -05:00
|
|
|
}
|
|
|
|
|
2021-10-29 12:57:24 -05:00
|
|
|
query := &models.GetDataSourceQuery{Name: dsName, Uid: dsUid, OrgId: e.OrgID}
|
2021-10-18 10:06:19 -05:00
|
|
|
if err := bus.DispatchCtx(context.TODO(), query); err != nil {
|
2021-01-07 14:33:17 -06:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return query.Result, nil
|
2016-06-11 03:13:33 -05:00
|
|
|
}
|
|
|
|
|
2018-03-28 04:31:33 -05:00
|
|
|
func findPanelQueryByRefID(panel *simplejson.Json, refID string) *simplejson.Json {
|
2016-07-19 14:00:41 -05:00
|
|
|
for _, targetsObj := range panel.Get("targets").MustArray() {
|
|
|
|
target := simplejson.NewFromAny(targetsObj)
|
|
|
|
|
2018-03-28 04:31:33 -05:00
|
|
|
if target.Get("refId").MustString() == refID {
|
2016-07-19 14:00:41 -05:00
|
|
|
return target
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-07-23 01:17:20 -05:00
|
|
|
func copyJSON(in json.Marshaler) (*simplejson.Json, error) {
|
2018-03-28 04:31:33 -05:00
|
|
|
rawJSON, err := in.MarshalJSON()
|
2017-01-13 08:46:23 -06:00
|
|
|
if err != nil {
|
2021-03-17 10:06:10 -05:00
|
|
|
return nil, fmt.Errorf("JSON marshaling failed: %w", err)
|
2017-01-13 08:46:23 -06:00
|
|
|
}
|
|
|
|
|
2018-03-28 04:31:33 -05:00
|
|
|
return simplejson.NewJson(rawJSON)
|
2017-01-13 08:46:23 -06:00
|
|
|
}
|
|
|
|
|
2020-10-22 06:43:12 -05:00
|
|
|
func (e *DashAlertExtractor) getAlertFromPanels(jsonWithPanels *simplejson.Json, validateAlertFunc func(*models.Alert) bool, logTranslationFailures bool) ([]*models.Alert, error) {
|
2019-05-14 01:15:05 -05:00
|
|
|
alerts := make([]*models.Alert, 0)
|
2016-06-11 03:13:33 -05:00
|
|
|
|
2017-12-19 04:19:52 -06:00
|
|
|
for _, panelObj := range jsonWithPanels.Get("panels").MustArray() {
|
|
|
|
panel := simplejson.NewFromAny(panelObj)
|
2018-03-13 16:23:37 -05:00
|
|
|
|
2018-03-28 04:31:33 -05:00
|
|
|
collapsedJSON, collapsed := panel.CheckGet("collapsed")
|
2018-03-13 16:23:37 -05:00
|
|
|
// check if the panel is collapsed
|
2018-03-28 04:31:33 -05:00
|
|
|
if collapsed && collapsedJSON.MustBool() {
|
2018-03-13 16:23:37 -05:00
|
|
|
// extract alerts from sub panels for collapsed panels
|
2020-10-22 06:43:12 -05:00
|
|
|
alertSlice, err := e.getAlertFromPanels(panel, validateAlertFunc, logTranslationFailures)
|
2018-03-13 16:23:37 -05:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2018-09-21 04:51:26 -05:00
|
|
|
alerts = append(alerts, alertSlice...)
|
2018-03-13 16:23:37 -05:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2017-12-19 04:19:52 -06:00
|
|
|
jsonAlert, hasAlert := panel.CheckGet("alert")
|
2016-06-11 03:13:33 -05:00
|
|
|
|
2017-12-19 04:19:52 -06:00
|
|
|
if !hasAlert {
|
|
|
|
continue
|
|
|
|
}
|
2016-06-11 03:13:33 -05:00
|
|
|
|
2018-03-28 04:31:33 -05:00
|
|
|
panelID, err := panel.Get("id").Int64()
|
2017-12-19 04:19:52 -06:00
|
|
|
if err != nil {
|
2018-10-13 00:53:28 -05:00
|
|
|
return nil, ValidationError{Reason: "A numeric panel id property is missing"}
|
2017-12-19 04:19:52 -06:00
|
|
|
}
|
2016-06-11 03:13:33 -05:00
|
|
|
|
2021-06-16 07:56:55 -05:00
|
|
|
addIdentifiersToValidationError := func(err error) error {
|
|
|
|
if err == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
var validationErr ValidationError
|
|
|
|
if ok := errors.As(err, &validationErr); ok {
|
|
|
|
ve := ValidationError{
|
|
|
|
Reason: validationErr.Reason,
|
|
|
|
Err: validationErr.Err,
|
|
|
|
PanelID: panelID,
|
|
|
|
}
|
|
|
|
if e.Dash != nil {
|
|
|
|
ve.DashboardID = e.Dash.Id
|
|
|
|
}
|
|
|
|
return ve
|
|
|
|
}
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2017-12-19 04:19:52 -06:00
|
|
|
// backward compatibility check, can be removed later
|
|
|
|
enabled, hasEnabled := jsonAlert.CheckGet("enabled")
|
Simplify comparison to bool constant (gosimple)
This fixes:
build.go:553:6: should omit comparison to bool constant, can be simplified to !strings.Contains(path, ".sha256") (S1002)
pkg/cmd/grafana-cli/commands/ls_command.go:27:5: should omit comparison to bool constant, can be simplified to !pluginDirInfo.IsDir() (S1002)
pkg/components/dynmap/dynmap_test.go:24:5: should omit comparison to bool constant, can be simplified to !value (S1002)
pkg/components/dynmap/dynmap_test.go:122:14: should omit comparison to bool constant, can be simplified to b (S1002)
pkg/components/dynmap/dynmap_test.go:125:14: should omit comparison to bool constant, can be simplified to !b (S1002)
pkg/components/dynmap/dynmap_test.go:128:14: should omit comparison to bool constant, can be simplified to !b (S1002)
pkg/models/org_user.go:51:5: should omit comparison to bool constant, can be simplified to !(*r).IsValid() (S1002)
pkg/plugins/datasource/wrapper/datasource_plugin_wrapper_test.go:77:12: should omit comparison to bool constant, can be simplified to !haveBool (S1002)
pkg/services/alerting/conditions/evaluator.go:23:9: should omit comparison to bool constant, can be simplified to !reducedValue.Valid (S1002)
pkg/services/alerting/conditions/evaluator.go:48:5: should omit comparison to bool constant, can be simplified to !reducedValue.Valid (S1002)
pkg/services/alerting/conditions/evaluator.go:91:5: should omit comparison to bool constant, can be simplified to !reducedValue.Valid (S1002)
pkg/services/alerting/conditions/query.go:56:6: should omit comparison to bool constant, can be simplified to !reducedValue.Valid (S1002)
pkg/services/alerting/extractor.go:107:20: should omit comparison to bool constant, can be simplified to !enabled.MustBool() (S1002)
pkg/services/alerting/notifiers/telegram.go:222:41: should omit comparison to bool constant, can be simplified to this.UploadImage (S1002)
pkg/services/sqlstore/apikey.go:58:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/apikey.go:72:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/dashboard.go:66:33: should omit comparison to bool constant, can be simplified to !cmd.Overwrite (S1002)
pkg/services/sqlstore/dashboard.go:175:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/dashboard.go:311:13: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/dashboard.go:444:12: should omit comparison to bool constant, can be simplified to !exists (S1002)
pkg/services/sqlstore/dashboard.go:472:12: should omit comparison to bool constant, can be simplified to !exists (S1002)
pkg/services/sqlstore/dashboard.go:554:32: should omit comparison to bool constant, can be simplified to !cmd.Overwrite (S1002)
pkg/services/sqlstore/dashboard_snapshot.go:83:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/plugin_setting.go:39:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/quota.go:34:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/quota.go:111:6: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/quota.go:136:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/quota.go:213:6: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/temp_user.go:129:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/user.go:157:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/user.go:182:5: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/user.go:191:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/user.go:212:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/services/sqlstore/user.go:307:12: should omit comparison to bool constant, can be simplified to !has (S1002)
pkg/social/generic_oauth.go:185:5: should omit comparison to bool constant, can be simplified to !s.extractToken(&data, token) (S1002)
pkg/tsdb/mssql/mssql.go:148:39: should omit comparison to bool constant, can be simplified to ok (S1002)
pkg/tsdb/mssql/mssql.go:212:6: should omit comparison to bool constant, can be simplified to !query.Model.Get("fillNull").MustBool(false) (S1002)
pkg/tsdb/mssql/mssql.go:247:56: should omit comparison to bool constant, can be simplified to ok (S1002)
pkg/tsdb/mssql/mssql.go:274:7: should omit comparison to bool constant, can be simplified to !exist (S1002)
pkg/tsdb/mssql/mssql.go:282:8: should omit comparison to bool constant, can be simplified to !exist (S1002)
pkg/tsdb/mysql/mysql.go:221:6: should omit comparison to bool constant, can be simplified to !query.Model.Get("fillNull").MustBool(false) (S1002)
pkg/tsdb/mysql/mysql.go:256:56: should omit comparison to bool constant, can be simplified to ok (S1002)
pkg/tsdb/mysql/mysql.go:283:7: should omit comparison to bool constant, can be simplified to !exist (S1002)
pkg/tsdb/mysql/mysql.go:291:8: should omit comparison to bool constant, can be simplified to !exist (S1002)
pkg/tsdb/postgres/postgres.go:134:39: should omit comparison to bool constant, can be simplified to ok (S1002)
pkg/tsdb/postgres/postgres.go:201:6: should omit comparison to bool constant, can be simplified to !query.Model.Get("fillNull").MustBool(false) (S1002)
pkg/tsdb/postgres/postgres.go:236:56: should omit comparison to bool constant, can be simplified to ok (S1002)
pkg/tsdb/postgres/postgres.go:263:7: should omit comparison to bool constant, can be simplified to !exist (S1002)
pkg/tsdb/postgres/postgres.go:271:8: should omit comparison to bool constant, can be simplified to !exist (S1002)
2018-04-16 13:12:59 -05:00
|
|
|
if hasEnabled && !enabled.MustBool() {
|
2017-12-19 04:19:52 -06:00
|
|
|
continue
|
|
|
|
}
|
2016-06-11 03:13:33 -05:00
|
|
|
|
2017-12-19 04:19:52 -06:00
|
|
|
frequency, err := getTimeDurationStringToSeconds(jsonAlert.Get("frequency").MustString())
|
|
|
|
if err != nil {
|
2021-06-16 07:56:55 -05:00
|
|
|
return nil, addIdentifiersToValidationError(ValidationError{Reason: err.Error()})
|
2017-12-19 04:19:52 -06:00
|
|
|
}
|
|
|
|
|
2018-11-05 06:14:02 -06:00
|
|
|
rawFor := jsonAlert.Get("for").MustString()
|
2021-04-12 07:53:51 -05:00
|
|
|
|
|
|
|
forValue, err := getForValue(rawFor)
|
|
|
|
if err != nil {
|
2021-06-16 07:56:55 -05:00
|
|
|
return nil, addIdentifiersToValidationError(err)
|
2018-11-02 04:38:02 -05:00
|
|
|
}
|
|
|
|
|
2019-05-14 01:15:05 -05:00
|
|
|
alert := &models.Alert{
|
2017-12-19 04:19:52 -06:00
|
|
|
DashboardId: e.Dash.Id,
|
2018-03-28 04:31:33 -05:00
|
|
|
OrgId: e.OrgID,
|
|
|
|
PanelId: panelID,
|
2017-12-19 04:19:52 -06:00
|
|
|
Id: jsonAlert.Get("id").MustInt64(),
|
|
|
|
Name: jsonAlert.Get("name").MustString(),
|
|
|
|
Handler: jsonAlert.Get("handler").MustInt64(),
|
|
|
|
Message: jsonAlert.Get("message").MustString(),
|
|
|
|
Frequency: frequency,
|
2018-11-05 04:05:30 -06:00
|
|
|
For: forValue,
|
2017-12-19 04:19:52 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
for _, condition := range jsonAlert.Get("conditions").MustArray() {
|
|
|
|
jsonCondition := simplejson.NewFromAny(condition)
|
|
|
|
|
|
|
|
jsonQuery := jsonCondition.Get("query")
|
2018-03-28 04:31:33 -05:00
|
|
|
queryRefID := jsonQuery.Get("params").MustArray()[0].(string)
|
|
|
|
panelQuery := findPanelQueryByRefID(panel, queryRefID)
|
2017-09-18 03:31:45 -05:00
|
|
|
|
2017-12-19 04:19:52 -06:00
|
|
|
if panelQuery == nil {
|
2018-03-28 04:31:33 -05:00
|
|
|
reason := fmt.Sprintf("Alert on PanelId: %v refers to query(%s) that cannot be found", alert.PanelId, queryRefID)
|
2017-12-19 04:19:52 -06:00
|
|
|
return nil, ValidationError{Reason: reason}
|
2016-06-15 04:39:25 -05:00
|
|
|
}
|
|
|
|
|
2021-10-29 12:57:24 -05:00
|
|
|
datasource, err := e.lookupQueryDataSource(panel, panelQuery)
|
2018-03-28 04:31:33 -05:00
|
|
|
if err != nil {
|
2021-10-29 12:57:24 -05:00
|
|
|
return nil, err
|
2016-06-11 03:13:33 -05:00
|
|
|
}
|
|
|
|
|
2019-05-14 01:15:05 -05:00
|
|
|
dsFilterQuery := models.DatasourcesPermissionFilterQuery{
|
2018-11-05 07:25:19 -06:00
|
|
|
User: e.User,
|
2019-05-14 01:15:05 -05:00
|
|
|
Datasources: []*models.DataSource{datasource},
|
2018-11-05 07:25:19 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
if err := bus.Dispatch(&dsFilterQuery); err != nil {
|
2020-11-19 07:47:17 -06:00
|
|
|
if !errors.Is(err, bus.ErrHandlerNotFound) {
|
2018-11-05 07:25:19 -06:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if len(dsFilterQuery.Result) == 0 {
|
2019-05-14 01:15:05 -05:00
|
|
|
return nil, models.ErrDataSourceAccessDenied
|
2018-11-05 07:25:19 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-28 04:31:33 -05:00
|
|
|
jsonQuery.SetPath([]string{"datasourceId"}, datasource.Id)
|
|
|
|
|
2017-12-19 04:19:52 -06:00
|
|
|
if interval, err := panel.Get("interval").String(); err == nil {
|
|
|
|
panelQuery.Set("interval", interval)
|
|
|
|
}
|
2016-07-19 14:00:41 -05:00
|
|
|
|
2017-12-19 04:19:52 -06:00
|
|
|
jsonQuery.Set("model", panelQuery.Interface())
|
|
|
|
}
|
2016-07-19 14:00:41 -05:00
|
|
|
|
2017-12-19 04:19:52 -06:00
|
|
|
alert.Settings = jsonAlert
|
2016-07-19 14:00:41 -05:00
|
|
|
|
2017-12-19 04:19:52 -06:00
|
|
|
// validate
|
2020-10-22 06:43:12 -05:00
|
|
|
_, err = NewRuleFromDBAlert(alert, logTranslationFailures)
|
2018-03-07 09:20:05 -06:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2018-03-28 04:31:33 -05:00
|
|
|
if !validateAlertFunc(alert) {
|
2018-10-13 00:53:28 -05:00
|
|
|
return nil, ValidationError{Reason: fmt.Sprintf("Panel id is not correct, alertName=%v, panelId=%v", alert.Name, alert.PanelId)}
|
2017-12-19 04:19:52 -06:00
|
|
|
}
|
2018-03-28 04:31:33 -05:00
|
|
|
|
|
|
|
alerts = append(alerts, alert)
|
2017-12-19 04:19:52 -06:00
|
|
|
}
|
2016-07-19 14:00:41 -05:00
|
|
|
|
2017-12-19 04:19:52 -06:00
|
|
|
return alerts, nil
|
|
|
|
}
|
2016-07-19 14:00:41 -05:00
|
|
|
|
2019-05-14 01:15:05 -05:00
|
|
|
func validateAlertRule(alert *models.Alert) bool {
|
2018-03-28 04:31:33 -05:00
|
|
|
return alert.ValidToSave()
|
|
|
|
}
|
|
|
|
|
2019-05-20 05:13:32 -05:00
|
|
|
// GetAlerts extracts alerts from the dashboard json and does full validation on the alert json data.
|
2019-05-14 01:15:05 -05:00
|
|
|
func (e *DashAlertExtractor) GetAlerts() ([]*models.Alert, error) {
|
2020-10-22 06:43:12 -05:00
|
|
|
return e.extractAlerts(validateAlertRule, true)
|
2018-03-28 04:31:33 -05:00
|
|
|
}
|
2016-10-13 02:43:05 -05:00
|
|
|
|
2020-10-22 06:43:12 -05:00
|
|
|
func (e *DashAlertExtractor) extractAlerts(validateFunc func(alert *models.Alert) bool, logTranslationFailures bool) ([]*models.Alert, error) {
|
2018-03-28 04:31:33 -05:00
|
|
|
dashboardJSON, err := copyJSON(e.Dash.Data)
|
2017-12-19 04:19:52 -06:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2016-06-11 03:13:33 -05:00
|
|
|
|
2019-05-14 01:15:05 -05:00
|
|
|
alerts := make([]*models.Alert, 0)
|
2016-06-11 03:13:33 -05:00
|
|
|
|
2017-12-19 04:19:52 -06:00
|
|
|
// We extract alerts from rows to be backwards compatible
|
|
|
|
// with the old dashboard json model.
|
2018-03-28 04:31:33 -05:00
|
|
|
rows := dashboardJSON.Get("rows").MustArray()
|
2017-12-19 04:19:52 -06:00
|
|
|
if len(rows) > 0 {
|
|
|
|
for _, rowObj := range rows {
|
|
|
|
row := simplejson.NewFromAny(rowObj)
|
2020-10-22 06:43:12 -05:00
|
|
|
a, err := e.getAlertFromPanels(row, validateFunc, logTranslationFailures)
|
2017-12-19 04:19:52 -06:00
|
|
|
if err != nil {
|
2016-07-21 06:09:12 -05:00
|
|
|
return nil, err
|
2016-06-11 03:13:33 -05:00
|
|
|
}
|
2017-12-19 04:19:52 -06:00
|
|
|
|
|
|
|
alerts = append(alerts, a...)
|
|
|
|
}
|
|
|
|
} else {
|
2020-10-22 06:43:12 -05:00
|
|
|
a, err := e.getAlertFromPanels(dashboardJSON, validateFunc, logTranslationFailures)
|
2017-12-19 04:19:52 -06:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2016-06-11 03:13:33 -05:00
|
|
|
}
|
2017-12-19 04:19:52 -06:00
|
|
|
|
|
|
|
alerts = append(alerts, a...)
|
2016-06-11 03:13:33 -05:00
|
|
|
}
|
|
|
|
|
2016-06-11 04:54:46 -05:00
|
|
|
e.log.Debug("Extracted alerts from dashboard", "alertCount", len(alerts))
|
2016-06-11 03:54:24 -05:00
|
|
|
return alerts, nil
|
2016-06-11 03:13:33 -05:00
|
|
|
}
|
2018-03-28 04:31:33 -05:00
|
|
|
|
|
|
|
// ValidateAlerts validates alerts in the dashboard json but does not require a valid dashboard id
|
2019-05-20 05:13:32 -05:00
|
|
|
// in the first validation pass.
|
2018-03-28 04:31:33 -05:00
|
|
|
func (e *DashAlertExtractor) ValidateAlerts() error {
|
2021-03-17 10:06:10 -05:00
|
|
|
_, err := e.extractAlerts(func(alert *models.Alert) bool {
|
|
|
|
return alert.OrgId != 0 && alert.PanelId != 0
|
|
|
|
}, false)
|
2018-03-28 04:31:33 -05:00
|
|
|
return err
|
|
|
|
}
|