diff --git a/pkg/services/alerting/extractor.go b/pkg/services/alerting/extractor.go index 7f14e195799..b8579ffdc6a 100644 --- a/pkg/services/alerting/extractor.go +++ b/pkg/services/alerting/extractor.go @@ -89,6 +89,11 @@ func (e *DashAlertExtractor) GetAlerts() ([]*m.Alert, error) { continue } + panelId, err := panel.Get("id").Int64() + if err != nil { + return nil, fmt.Errorf("panel id is required. err %v", err) + } + // backward compatibility check, can be removed later enabled, hasEnabled := jsonAlert.CheckGet("enabled") if hasEnabled && enabled.MustBool() == false { @@ -103,7 +108,7 @@ func (e *DashAlertExtractor) GetAlerts() ([]*m.Alert, error) { alert := &m.Alert{ DashboardId: e.Dash.Id, OrgId: e.OrgId, - PanelId: panel.Get("id").MustInt64(), + PanelId: panelId, Id: jsonAlert.Get("id").MustInt64(), Name: jsonAlert.Get("name").MustString(), Handler: jsonAlert.Get("handler").MustInt64(), diff --git a/pkg/services/alerting/extractor_test.go b/pkg/services/alerting/extractor_test.go index cb174783478..b7f83404452 100644 --- a/pkg/services/alerting/extractor_test.go +++ b/pkg/services/alerting/extractor_test.go @@ -200,6 +200,83 @@ func TestAlertRuleExtraction(t *testing.T) { }) }) + Convey("Panels missing id should return error", func() { + panelWithoutId := ` + { + "id": 57, + "title": "Graphite 4", + "originalTitle": "Graphite 4", + "tags": ["graphite"], + "rows": [ + { + "panels": [ + { + "title": "Active desktop users", + "editable": true, + "type": "graph", + "targets": [ + { + "refId": "A", + "target": "aliasByNode(statsd.fakesite.counters.session_start.desktop.count, 4)" + } + ], + "datasource": null, + "alert": { + "name": "name1", + "message": "desc1", + "handler": 1, + "frequency": "60s", + "conditions": [ + { + "type": "query", + "query": {"params": ["A", "5m", "now"]}, + "reducer": {"type": "avg", "params": []}, + "evaluator": {"type": ">", "params": [100]} + } + ] + } + }, + { + "title": "Active mobile users", + "id": 4, + "targets": [ + {"refId": "A", "target": ""}, + {"refId": "B", "target": "aliasByNode(statsd.fakesite.counters.session_start.mobile.count, 4)"} + ], + "datasource": "graphite2", + "alert": { + "name": "name2", + "message": "desc2", + "handler": 0, + "frequency": "60s", + "severity": "warning", + "conditions": [ + { + "type": "query", + "query": {"params": ["B", "5m", "now"]}, + "reducer": {"type": "avg", "params": []}, + "evaluator": {"type": ">", "params": [100]} + } + ] + } + } + ] + } + ] + }` + + dashJson, err := simplejson.NewJson([]byte(panelWithoutId)) + So(err, ShouldBeNil) + dash := m.NewDashboardFromJson(dashJson) + extractor := NewDashAlertExtractor(dash, 1) + + _, err = extractor.GetAlerts() + + Convey("panels without Id should return error", func() { + So(err, ShouldNotBeNil) + }) + }) + Convey("Parse and validate dashboard containing influxdb alert", func() { json2 := `{