Selaa lähdekoodia

feat(alerting): more model changes

Torkel Ödegaard 9 vuotta sitten
vanhempi
commit
382f396247

+ 5 - 5
pkg/services/alerting/commands.go

@@ -18,20 +18,20 @@ func init() {
 }
 }
 
 
 func updateDashboardAlerts(cmd *UpdateDashboardAlertsCommand) error {
 func updateDashboardAlerts(cmd *UpdateDashboardAlertsCommand) error {
-	saveRulesCmd := m.SaveAlertsCommand{
+	saveAlerts := m.SaveAlertsCommand{
 		OrgId:  cmd.OrgId,
 		OrgId:  cmd.OrgId,
 		UserId: cmd.UserId,
 		UserId: cmd.UserId,
 	}
 	}
 
 
-	extractor := NewAlertRuleExtractor(cmd.Dashboard, cmd.OrgId)
+	extractor := NewDashAlertExtractor(cmd.Dashboard, cmd.OrgId)
 
 
-	rules, err := extractor.GetRuleModels()
+	alerts, err := extractor.GetRuleModels()
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
 
 
-	saveRulesCmd.Alerts = rules
-	if bus.Dispatch(&saveRulesCmd); err != nil {
+	saveAlerts.Alerts = alerts
+	if bus.Dispatch(&saveAlerts); err != nil {
 		return err
 		return err
 	}
 	}
 
 

+ 23 - 23
pkg/services/alerting/extractor.go

@@ -9,21 +9,21 @@ import (
 	m "github.com/grafana/grafana/pkg/models"
 	m "github.com/grafana/grafana/pkg/models"
 )
 )
 
 
-type AlertRuleExtractor struct {
+type DashAlertExtractor struct {
 	Dash  *m.Dashboard
 	Dash  *m.Dashboard
 	OrgId int64
 	OrgId int64
 	log   log.Logger
 	log   log.Logger
 }
 }
 
 
-func NewAlertRuleExtractor(dash *m.Dashboard, orgId int64) *AlertRuleExtractor {
-	return &AlertRuleExtractor{
+func NewDashAlertExtractor(dash *m.Dashboard, orgId int64) *DashAlertExtractor {
+	return &DashAlertExtractor{
 		Dash:  dash,
 		Dash:  dash,
 		OrgId: orgId,
 		OrgId: orgId,
 		log:   log.New("alerting.extractor"),
 		log:   log.New("alerting.extractor"),
 	}
 	}
 }
 }
 
 
-func (e *AlertRuleExtractor) lookupDatasourceId(dsName string) (int64, error) {
+func (e *DashAlertExtractor) lookupDatasourceId(dsName string) (int64, error) {
 	if dsName == "" {
 	if dsName == "" {
 		query := &m.GetDataSourcesQuery{OrgId: e.OrgId}
 		query := &m.GetDataSourcesQuery{OrgId: e.OrgId}
 		if err := bus.Dispatch(query); err != nil {
 		if err := bus.Dispatch(query); err != nil {
@@ -47,36 +47,36 @@ func (e *AlertRuleExtractor) lookupDatasourceId(dsName string) (int64, error) {
 	return 0, errors.New("Could not find datasource id for " + dsName)
 	return 0, errors.New("Could not find datasource id for " + dsName)
 }
 }
 
 
-func (e *AlertRuleExtractor) GetRuleModels() (m.AlertRules, error) {
+func (e *DashAlertExtractor) GetRuleModels() ([]*m.Alert, error) {
 
 
-	rules := make(m.AlertRules, 0)
+	alerts := make([]*m.Alert, 0)
 
 
 	for _, rowObj := range e.Dash.Data.Get("rows").MustArray() {
 	for _, rowObj := range e.Dash.Data.Get("rows").MustArray() {
 		row := simplejson.NewFromAny(rowObj)
 		row := simplejson.NewFromAny(rowObj)
 
 
 		for _, panelObj := range row.Get("panels").MustArray() {
 		for _, panelObj := range row.Get("panels").MustArray() {
 			panel := simplejson.NewFromAny(panelObj)
 			panel := simplejson.NewFromAny(panelObj)
-			jsonRule := panel.Get("alerting")
+			jsonAlert := panel.Get("alert")
 
 
 			// check if marked for deletion
 			// check if marked for deletion
-			deleted := jsonRule.Get("deleted").MustBool()
+			deleted := jsonAlert.Get("deleted").MustBool()
 			if deleted {
 			if deleted {
 				e.log.Info("Deleted alert rule found")
 				e.log.Info("Deleted alert rule found")
 				continue
 				continue
 			}
 			}
 
 
-			ruleModel := &m.Alert{
+			alert := &m.Alert{
 				DashboardId: e.Dash.Id,
 				DashboardId: e.Dash.Id,
 				OrgId:       e.OrgId,
 				OrgId:       e.OrgId,
 				PanelId:     panel.Get("id").MustInt64(),
 				PanelId:     panel.Get("id").MustInt64(),
-				Id:          jsonRule.Get("id").MustInt64(),
-				Name:        jsonRule.Get("name").MustString(),
-				Scheduler:   jsonRule.Get("scheduler").MustInt64(),
-				Enabled:     jsonRule.Get("enabled").MustBool(),
-				Description: jsonRule.Get("description").MustString(),
+				Id:          jsonAlert.Get("id").MustInt64(),
+				Name:        jsonAlert.Get("name").MustString(),
+				Scheduler:   jsonAlert.Get("scheduler").MustInt64(),
+				Enabled:     jsonAlert.Get("enabled").MustBool(),
+				Description: jsonAlert.Get("description").MustString(),
 			}
 			}
 
 
-			valueQuery := jsonRule.Get("query")
+			valueQuery := jsonAlert.Get("query")
 			valueQueryRef := valueQuery.Get("refId").MustString()
 			valueQueryRef := valueQuery.Get("refId").MustString()
 			for _, targetsObj := range panel.Get("targets").MustArray() {
 			for _, targetsObj := range panel.Get("targets").MustArray() {
 				target := simplejson.NewFromAny(targetsObj)
 				target := simplejson.NewFromAny(targetsObj)
@@ -97,24 +97,24 @@ func (e *AlertRuleExtractor) GetRuleModels() (m.AlertRules, error) {
 
 
 					targetQuery := target.Get("target").MustString()
 					targetQuery := target.Get("target").MustString()
 					if targetQuery != "" {
 					if targetQuery != "" {
-						jsonRule.SetPath([]string{"query", "query"}, targetQuery)
+						jsonAlert.SetPath([]string{"query", "query"}, targetQuery)
 					}
 					}
 				}
 				}
 			}
 			}
 
 
-			ruleModel.Expression = jsonRule
+			alert.Expression = jsonAlert
 
 
 			// validate
 			// validate
-			_, err := NewAlertRuleFromDBModel(ruleModel)
-			if err == nil && ruleModel.ValidToSave() {
-				rules = append(rules, ruleModel)
+			_, err := NewAlertRuleFromDBModel(alert)
+			if err == nil && alert.ValidToSave() {
+				alerts = append(alerts, alert)
 			} else {
 			} else {
-				e.log.Error("Failed to extract alert rules from dashboard", "error", err)
-				return nil, errors.New("Failed to extract alert rules from dashboard")
+				e.log.Error("Failed to extract alerts from dashboard", "error", err)
+				return nil, errors.New("Failed to extract alerts from dashboard")
 			}
 			}
 
 
 		}
 		}
 	}
 	}
 
 
-	return rules, nil
+	return alerts, nil
 }
 }

+ 4 - 4
pkg/services/alerting/extractor_test.go

@@ -36,7 +36,7 @@ func TestAlertRuleExtraction(t *testing.T) {
             }
             }
           ],
           ],
           "datasource": null,
           "datasource": null,
-          "alerting": {
+          "alert": {
             "name": "name1",
             "name": "name1",
             "description": "desc1",
             "description": "desc1",
 						"scheduler": 1,
 						"scheduler": 1,
@@ -71,7 +71,7 @@ func TestAlertRuleExtraction(t *testing.T) {
             }
             }
           ],
           ],
           "datasource": "graphite2",
           "datasource": "graphite2",
-          "alerting": {
+          "alert": {
             "name": "name2",
             "name": "name2",
             "description": "desc2",
             "description": "desc2",
 						"scheduler": 0,
 						"scheduler": 0,
@@ -150,7 +150,7 @@ func TestAlertRuleExtraction(t *testing.T) {
           "title": "Broken influxdb panel",
           "title": "Broken influxdb panel",
           "transform": "table",
           "transform": "table",
           "type": "table",
           "type": "table",
-					"alerting": {
+					"alert": {
 						"deleted": true
 						"deleted": true
 					}
 					}
         }
         }
@@ -164,7 +164,7 @@ func TestAlertRuleExtraction(t *testing.T) {
 			So(err, ShouldBeNil)
 			So(err, ShouldBeNil)
 
 
 			dash := m.NewDashboardFromJson(dashJson)
 			dash := m.NewDashboardFromJson(dashJson)
-			extractor := NewAlertRuleExtractor(dash, 1)
+			extractor := NewDashAlertExtractor(dash, 1)
 
 
 			// mock data
 			// mock data
 			defaultDs := &m.DataSource{Id: 12, OrgId: 2, Name: "I am default", IsDefault: true}
 			defaultDs := &m.DataSource{Id: 12, OrgId: 2, Name: "I am default", IsDefault: true}

+ 13 - 6
pkg/services/sqlstore/alert.go

@@ -79,7 +79,7 @@ func GetAlertById(query *m.GetAlertByIdQuery) error {
 
 
 func GetAllAlertQueryHandler(query *m.GetAllAlertsQuery) error {
 func GetAllAlertQueryHandler(query *m.GetAllAlertsQuery) error {
 	var alerts []*m.Alert
 	var alerts []*m.Alert
-	err := x.Sql("select * from alert_rule").Find(&alerts)
+	err := x.Sql("select * from alert").Find(&alerts)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
@@ -90,7 +90,7 @@ func GetAllAlertQueryHandler(query *m.GetAllAlertsQuery) error {
 
 
 func DeleteAlertById(cmd *m.DeleteAlertCommand) error {
 func DeleteAlertById(cmd *m.DeleteAlertCommand) error {
 	return inTransaction(func(sess *xorm.Session) error {
 	return inTransaction(func(sess *xorm.Session) error {
-		if _, err := sess.Exec("DELETE FROM alert_rule WHERE id = ?", cmd.AlertId); err != nil {
+		if _, err := sess.Exec("DELETE FROM alert WHERE id = ?", cmd.AlertId); err != nil {
 			return err
 			return err
 		}
 		}
 
 
@@ -103,7 +103,7 @@ func HandleAlertsQuery(query *m.GetAlertsQuery) error {
 	params := make([]interface{}, 0)
 	params := make([]interface{}, 0)
 
 
 	sql.WriteString(`SELECT *
 	sql.WriteString(`SELECT *
-						from alert_rule
+						from alert
 						`)
 						`)
 
 
 	sql.WriteString(`WHERE org_id = ?`)
 	sql.WriteString(`WHERE org_id = ?`)
@@ -141,15 +141,17 @@ func HandleAlertsQuery(query *m.GetAlertsQuery) error {
 }
 }
 
 
 func DeleteAlertDefinition(dashboardId int64, sess *xorm.Session) error {
 func DeleteAlertDefinition(dashboardId int64, sess *xorm.Session) error {
-	alerts := make(m.Alerts, 0)
+	alerts := make([]*m.Alert, 0)
 	sess.Where("dashboard_id = ?", dashboardId).Find(&alerts)
 	sess.Where("dashboard_id = ?", dashboardId).Find(&alerts)
 
 
 	for _, alert := range alerts {
 	for _, alert := range alerts {
-		_, err := sess.Exec("DELETE FROM alert_rule WHERE id = ? ", alert.Id)
+		_, err := sess.Exec("DELETE FROM alert WHERE id = ? ", alert.Id)
 		if err != nil {
 		if err != nil {
 			return err
 			return err
 		}
 		}
 
 
+		sqlog.Debug("Alert deleted (due to dashboard deletion)", "name", alert.Name, "id", alert.Id)
+
 		if err := SaveAlertChange("DELETED", alert, sess); err != nil {
 		if err := SaveAlertChange("DELETED", alert, sess); err != nil {
 			return err
 			return err
 		}
 		}
@@ -194,6 +196,7 @@ func upsertAlerts(alerts []*m.Alert, posted []*m.Alert, sess *xorm.Session) erro
 					return err
 					return err
 				}
 				}
 
 
+				sqlog.Debug("Alert updated", "name", alert.Name, "id", alert.Id)
 				SaveAlertChange("UPDATED", alert, sess)
 				SaveAlertChange("UPDATED", alert, sess)
 			}
 			}
 
 
@@ -205,6 +208,8 @@ func upsertAlerts(alerts []*m.Alert, posted []*m.Alert, sess *xorm.Session) erro
 			if err != nil {
 			if err != nil {
 				return err
 				return err
 			}
 			}
+
+			sqlog.Debug("Alert inserted", "name", alert.Name, "id", alert.Id)
 			SaveAlertChange("CREATED", alert, sess)
 			SaveAlertChange("CREATED", alert, sess)
 		}
 		}
 	}
 	}
@@ -223,11 +228,13 @@ func deleteMissingAlerts(alerts []*m.Alert, posted []*m.Alert, sess *xorm.Sessio
 		}
 		}
 
 
 		if missing {
 		if missing {
-			_, err := sess.Exec("DELETE FROM alert_rule WHERE id = ?", missingAlert.Id)
+			_, err := sess.Exec("DELETE FROM alert WHERE id = ?", missingAlert.Id)
 			if err != nil {
 			if err != nil {
 				return err
 				return err
 			}
 			}
 
 
+			sqlog.Debug("Alert deleted", "name", missingAlert.Name, "id", missingAlert.Id)
+
 			err = SaveAlertChange("DELETED", missingAlert, sess)
 			err = SaveAlertChange("DELETED", missingAlert, sess)
 			if err != nil {
 			if err != nil {
 				return err
 				return err

+ 2 - 2
pkg/services/sqlstore/alert_rule_changes.go

@@ -39,7 +39,7 @@ func GetAlertRuleChanges(query *m.GetAlertChangesQuery) error {
 		params = append(params, query.Limit)
 		params = append(params, query.Limit)
 	}
 	}
 
 
-	alertChanges := make([]*m.AlertRuleChange, 0)
+	alertChanges := make([]*m.AlertChange, 0)
 	if err := x.Sql(sql.String(), params...).Find(&alertChanges); err != nil {
 	if err := x.Sql(sql.String(), params...).Find(&alertChanges); err != nil {
 		return err
 		return err
 	}
 	}
@@ -49,7 +49,7 @@ func GetAlertRuleChanges(query *m.GetAlertChangesQuery) error {
 }
 }
 
 
 func SaveAlertChange(change string, alert *m.Alert, sess *xorm.Session) error {
 func SaveAlertChange(change string, alert *m.Alert, sess *xorm.Session) error {
-	_, err := sess.Insert(&m.AlertRuleChange{
+	_, err := sess.Insert(&m.AlertChange{
 		OrgId:   alert.OrgId,
 		OrgId:   alert.OrgId,
 		Type:    change,
 		Type:    change,
 		Created: time.Now(),
 		Created: time.Now(),

+ 4 - 4
pkg/services/sqlstore/migrations/alert_mig.go

@@ -7,7 +7,7 @@ import (
 func addAlertMigrations(mg *Migrator) {
 func addAlertMigrations(mg *Migrator) {
 
 
 	alertV1 := Table{
 	alertV1 := Table{
-		Name: "alert_rule",
+		Name: "alert",
 		Columns: []*Column{
 		Columns: []*Column{
 			{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
 			{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
 			{Name: "dashboard_id", Type: DB_BigInt, Nullable: false},
 			{Name: "dashboard_id", Type: DB_BigInt, Nullable: false},
@@ -26,10 +26,10 @@ func addAlertMigrations(mg *Migrator) {
 	}
 	}
 
 
 	// create table
 	// create table
-	mg.AddMigration("create alert_rule table v2", NewAddTableMigration(alertV1))
+	mg.AddMigration("create alert table v1", NewAddTableMigration(alertV1))
 
 
 	alert_changes := Table{
 	alert_changes := Table{
-		Name: "alert_rule_change",
+		Name: "alert_change",
 		Columns: []*Column{
 		Columns: []*Column{
 			{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
 			{Name: "id", Type: DB_BigInt, IsPrimaryKey: true, IsAutoIncrement: true},
 			{Name: "alert_id", Type: DB_BigInt, Nullable: false},
 			{Name: "alert_id", Type: DB_BigInt, Nullable: false},
@@ -39,7 +39,7 @@ func addAlertMigrations(mg *Migrator) {
 		},
 		},
 	}
 	}
 
 
-	mg.AddMigration("create alert_rules_updates table v1", NewAddTableMigration(alert_changes))
+	mg.AddMigration("create alert_change table v1", NewAddTableMigration(alert_changes))
 
 
 	alert_state_log := Table{
 	alert_state_log := Table{
 		Name: "alert_state",
 		Name: "alert_state",

+ 1 - 1
pkg/services/sqlstore/migrator/migrator.go

@@ -107,7 +107,7 @@ func (mg *Migrator) Start() error {
 }
 }
 
 
 func (mg *Migrator) exec(m Migration) error {
 func (mg *Migrator) exec(m Migration) error {
-	log.Info("Executing migration", "id", m.Id())
+	mg.Logger.Info("Executing migration", "id", m.Id())
 
 
 	err := mg.inTransaction(func(sess *xorm.Session) error {
 	err := mg.inTransaction(func(sess *xorm.Session) error {
 
 

+ 32 - 40
public/app/plugins/panel/graph/alert_tab_ctrl.ts

@@ -22,7 +22,6 @@ var alertQueryDef = new QueryPartDef({
 export class AlertTabCtrl {
 export class AlertTabCtrl {
   panel: any;
   panel: any;
   panelCtrl: any;
   panelCtrl: any;
-  alerting: any;
   metricTargets = [{ refId: '- select query -' } ];
   metricTargets = [{ refId: '- select query -' } ];
   schedulers = [{text: 'Grafana', value: 1}, {text: 'External', value: 0}];
   schedulers = [{text: 'Grafana', value: 1}, {text: 'External', value: 0}];
   transforms = [
   transforms = [
@@ -36,7 +35,7 @@ export class AlertTabCtrl {
     },
     },
   ];
   ];
   aggregators = ['avg', 'sum', 'min', 'max', 'last'];
   aggregators = ['avg', 'sum', 'min', 'max', 'last'];
-  rule: any;
+  alert: any;
   query: any;
   query: any;
   queryParams: any;
   queryParams: any;
   transformDef: any;
   transformDef: any;
@@ -71,33 +70,37 @@ export class AlertTabCtrl {
     $scope.ctrl = this;
     $scope.ctrl = this;
 
 
     this.metricTargets = this.panel.targets.map(val => val);
     this.metricTargets = this.panel.targets.map(val => val);
-    this.rule = this.panel.alerting = this.panel.alerting || {};
+
+    this.initAlertModel();
+  }
+
+  initAlertModel() {
+    this.alert = this.panel.alert = this.panel.alert || {};
 
 
     // set defaults
     // set defaults
-    _.defaults(this.rule, this.defaultValues);
+    _.defaults(this.alert, this.defaultValues);
 
 
     var defaultName = (this.panelCtrl.dashboard.title + ' ' + this.panel.title + ' alert');
     var defaultName = (this.panelCtrl.dashboard.title + ' ' + this.panel.title + ' alert');
-    this.rule.name = this.rule.name || defaultName;
-    this.rule.description = this.rule.description || defaultName;
-    this.rule.queryRef = this.panel.alerting.queryRef || this.metricTargets[0].refId;
+    this.alert.name = this.alert.name || defaultName;
+    this.alert.description = this.alert.description || defaultName;
 
 
     // great temp working model
     // great temp working model
     this.queryParams = {
     this.queryParams = {
       params: [
       params: [
-        this.rule.query.refId,
-        this.rule.query.from,
-        this.rule.query.to
+        this.alert.query.refId,
+        this.alert.query.from,
+        this.alert.query.to
       ]
       ]
     };
     };
 
 
     // init the query part components model
     // init the query part components model
     this.query = new QueryPart(this.queryParams, alertQueryDef);
     this.query = new QueryPart(this.queryParams, alertQueryDef);
     this.convertThresholdsToAlertThresholds();
     this.convertThresholdsToAlertThresholds();
-    this.transformDef = _.findWhere(this.transforms, {type: this.rule.transform.type});
+    this.transformDef = _.findWhere(this.transforms, {type: this.alert.transform.type});
   }
   }
 
 
   queryUpdated() {
   queryUpdated() {
-    this.rule.query = {
+    this.alert.query = {
       refId: this.query.params[0],
       refId: this.query.params[0],
       from: this.query.params[1],
       from: this.query.params[1],
       to: this.query.params[2],
       to: this.query.params[2],
@@ -106,16 +109,16 @@ export class AlertTabCtrl {
 
 
   transformChanged() {
   transformChanged() {
     // clear model
     // clear model
-    this.rule.transform = {type: this.rule.transform.type};
-    this.transformDef = _.findWhere(this.transforms, {type: this.rule.transform.type});
+    this.alert.transform = {type: this.alert.transform.type};
+    this.transformDef = _.findWhere(this.transforms, {type: this.alert.transform.type});
 
 
-    switch (this.rule.transform.type) {
+    switch (this.alert.transform.type) {
       case 'aggregation':  {
       case 'aggregation':  {
-        this.rule.transform.method = 'avg';
+        this.alert.transform.method = 'avg';
         break;
         break;
       }
       }
       case "forecast": {
       case "forecast": {
-        this.rule.transform.timespan = '7d';
+        this.alert.transform.timespan = '7d';
         break;
         break;
       }
       }
     }
     }
@@ -124,45 +127,34 @@ export class AlertTabCtrl {
   convertThresholdsToAlertThresholds() {
   convertThresholdsToAlertThresholds() {
     if (this.panel.grid
     if (this.panel.grid
         && this.panel.grid.threshold1
         && this.panel.grid.threshold1
-        && this.rule.warnLevel === undefined
+        && this.alert.warnLevel === undefined
        ) {
        ) {
-      this.rule.warning.op = '>';
-      this.rule.warning.level = this.panel.grid.threshold1;
+      this.alert.warning.op = '>';
+      this.alert.warning.level = this.panel.grid.threshold1;
     }
     }
 
 
     if (this.panel.grid
     if (this.panel.grid
         && this.panel.grid.threshold2
         && this.panel.grid.threshold2
-        && this.rule.critical.level === undefined
+        && this.alert.critical.level === undefined
        ) {
        ) {
-      this.rule.critical.op = '>';
-      this.rule.critical.level = this.panel.grid.threshold2;
+      this.alert.critical.op = '>';
+      this.alert.critical.level = this.panel.grid.threshold2;
     }
     }
   }
   }
 
 
   delete() {
   delete() {
-    this.rule = this.panel.alerting = this.defaultValues;
-    this.rule.deleted = true;
+    this.alert = this.panel.alert = {};
+    this.alert.deleted = true;
+    this.initAlertModel();
   }
   }
 
 
   enable() {
   enable() {
-    delete this.rule.deleted;
-    this.rule.enabled = true;
+    delete this.alert.deleted;
+    this.alert.enabled = true;
   }
   }
 
 
   disable() {
   disable() {
-    this.rule.enabled = false;
-  }
-
-  thresholdsUpdated() {
-    if (this.panel.alerting.warnLevel) {
-      this.panel.grid.threshold1 = parseInt(this.panel.alerting.warnLevel);
-    }
-
-    if (this.panel.alerting.critLevel) {
-      this.panel.grid.threshold2 = parseInt(this.panel.alerting.critLevel);
-    }
-
-    this.panelCtrl.render();
+    this.alert.enabled = false;
   }
   }
 }
 }
 
 

+ 13 - 13
public/app/plugins/panel/graph/partials/tab_alerting.html

@@ -13,7 +13,7 @@
         <span class="gf-form-label">Transform using</span>
         <span class="gf-form-label">Transform using</span>
         <div class="gf-form-select-wrapper">
         <div class="gf-form-select-wrapper">
           <select   class="gf-form-input"
           <select   class="gf-form-input"
-                    ng-model="ctrl.rule.transform.type"
+                    ng-model="ctrl.alert.transform.type"
                     ng-options="f.type as f.text for f in ctrl.transforms"
                     ng-options="f.type as f.text for f in ctrl.transforms"
                     ng-change="ctrl.transformChanged()"
                     ng-change="ctrl.transformChanged()"
                     >
                     >
@@ -24,14 +24,14 @@
         <span class="gf-form-label">Method</span>
         <span class="gf-form-label">Method</span>
         <div class="gf-form-select-wrapper">
         <div class="gf-form-select-wrapper">
           <select   class="gf-form-input"
           <select   class="gf-form-input"
-                    ng-model="ctrl.rule.transform.method"
+                    ng-model="ctrl.alert.transform.method"
                     ng-options="f for f in ctrl.aggregators">
                     ng-options="f for f in ctrl.aggregators">
           </select>
           </select>
         </div>
         </div>
       </div>
       </div>
       <div class="gf-form" ng-if="ctrl.transformDef.type === 'forecast'">
       <div class="gf-form" ng-if="ctrl.transformDef.type === 'forecast'">
         <span class="gf-form-label">Timespan</span>
         <span class="gf-form-label">Timespan</span>
-        <input class="gf-form-input max-width-5" type="text" ng-model="ctrl.rule.transform.timespan" ng-change="ctrl.ruleUpdated()"></input>
+        <input class="gf-form-input max-width-5" type="text" ng-model="ctrl.alert.transform.timespan" ng-change="ctrl.ruleUpdated()"></input>
       </div>
       </div>
     </div>
     </div>
   </div>
   </div>
@@ -44,16 +44,16 @@
           <i class="icon-gf icon-gf-warn alert-icon-warn"></i>
           <i class="icon-gf icon-gf-warn alert-icon-warn"></i>
           Warn if
           Warn if
         </span>
         </span>
-        <metric-segment-model property="ctrl.rule.warning.op" options="ctrl.levelOpList" custom="false" css-class="query-segment-operator"></metric-segment-model>
-        <input class="gf-form-input max-width-7" type="number" ng-model="ctrl.rule.warnLevel" ng-change="ctrl.thresholdsUpdated()"></input>
+        <metric-segment-model property="ctrl.alert.warning.op" options="ctrl.levelOpList" custom="false" css-class="query-segment-operator"></metric-segment-model>
+        <input class="gf-form-input max-width-7" type="number" ng-model="ctrl.alert.warnLevel" ng-change="ctrl.thresholdsUpdated()"></input>
       </div>
       </div>
       <div class="gf-form">
       <div class="gf-form">
         <span class="gf-form-label">
         <span class="gf-form-label">
           <i class="icon-gf icon-gf-warn alert-icon-critical"></i>
           <i class="icon-gf icon-gf-warn alert-icon-critical"></i>
           Critcal if
           Critcal if
         </span>
         </span>
-        <metric-segment-model property="ctrl.rule.critical.op" options="ctrl.levelOpList" custom="false" css-class="query-segment-operator"></metric-segment-model>
-        <input class="gf-form-input max-width-7" type="number" ng-model="ctrl.rule.critLevel" ng-change="ctrl.thresholdsUpdated()"></input>
+        <metric-segment-model property="ctrl.alert.critical.op" options="ctrl.levelOpList" custom="false" css-class="query-segment-operator"></metric-segment-model>
+        <input class="gf-form-input max-width-7" type="number" ng-model="ctrl.alert.critLevel" ng-change="ctrl.thresholdsUpdated()"></input>
       </div>
       </div>
     </div>
     </div>
   </div>
   </div>
@@ -67,14 +67,14 @@
         <span class="gf-form-label">Scheduler</span>
         <span class="gf-form-label">Scheduler</span>
         <div class="gf-form-select-wrapper">
         <div class="gf-form-select-wrapper">
           <select   class="gf-form-input"
           <select   class="gf-form-input"
-                    ng-model="ctrl.rule.scheduler"
+                    ng-model="ctrl.alert.scheduler"
                     ng-options="f.value as f.text for f in ctrl.schedulers">
                     ng-options="f.value as f.text for f in ctrl.schedulers">
           </select>
           </select>
         </div>
         </div>
       </div>
       </div>
       <div class="gf-form">
       <div class="gf-form">
         <span class="gf-form-label">Evaluate every</span>
         <span class="gf-form-label">Evaluate every</span>
-        <input class="gf-form-input max-width-7" type="text" ng-model="ctrl.rule.frequency"></input>
+        <input class="gf-form-input max-width-7" type="text" ng-model="ctrl.alert.frequency"></input>
       </div>
       </div>
     </div>
     </div>
   </div>
   </div>
@@ -83,7 +83,7 @@
     <div class="gf-form-inline">
     <div class="gf-form-inline">
       <div class="gf-form">
       <div class="gf-form">
         <span class="gf-form-label">Groups</span>
         <span class="gf-form-label">Groups</span>
-        <bootstrap-tagsinput ng-model="ctrl.rule.notify" tagclass="label label-tag" placeholder="add tags">
+        <bootstrap-tagsinput ng-model="ctrl.alert.notify" tagclass="label label-tag" placeholder="add tags">
 				</bootstrap-tagsinput>
 				</bootstrap-tagsinput>
       </div>
       </div>
     </div>
     </div>
@@ -109,8 +109,8 @@
 
 
 <div class="editor-row">
 <div class="editor-row">
   <div class="gf-form-button-row">
   <div class="gf-form-button-row">
-    <button class="btn btn-danger" ng-click="ctrl.delete()" ng-show="ctrl.rule.enabled">Delete</button>
-    <button class="btn btn-success" ng-click="ctrl.enable()" ng-hide="ctrl.rule.enabled">Enable</button>
-    <button class="btn btn-secondary" ng-click="ctrl.disable()" ng-show="ctrl.rule.enabled">Disable</button>
+    <button class="btn btn-danger" ng-click="ctrl.delete()" ng-show="ctrl.alert.enabled">Delete</button>
+    <button class="btn btn-success" ng-click="ctrl.enable()" ng-hide="ctrl.alert.enabled">Enable</button>
+    <button class="btn btn-secondary" ng-click="ctrl.disable()" ng-show="ctrl.alert.enabled">Disable</button>
   </div>
   </div>
 </div>
 </div>