Browse Source

feat(notifications): add support for default notifications

ref #5883
bergquist 9 years ago
parent
commit
c893e5d241

+ 6 - 5
pkg/api/alerting.go

@@ -157,11 +157,12 @@ func GetAlertNotifications(c *middleware.Context) Response {
 
 	for _, notification := range query.Result {
 		result = append(result, dtos.AlertNotification{
-			Id:      notification.Id,
-			Name:    notification.Name,
-			Type:    notification.Type,
-			Created: notification.Created,
-			Updated: notification.Updated,
+			Id:        notification.Id,
+			Name:      notification.Name,
+			Type:      notification.Type,
+			IsDefault: notification.IsDefault,
+			Created:   notification.Created,
+			Updated:   notification.Updated,
 		})
 	}
 

+ 6 - 5
pkg/api/dtos/alerting.go

@@ -22,11 +22,12 @@ type AlertRule struct {
 }
 
 type AlertNotification struct {
-	Id      int64     `json:"id"`
-	Name    string    `json:"name"`
-	Type    string    `json:"type"`
-	Created time.Time `json:"created"`
-	Updated time.Time `json:"updated"`
+	Id        int64     `json:"id"`
+	Name      string    `json:"name"`
+	Type      string    `json:"type"`
+	IsDefault bool      `json:"isDefault"`
+	Created   time.Time `json:"created"`
+	Updated   time.Time `json:"updated"`
 }
 
 type AlertTestCommand struct {

+ 17 - 14
pkg/models/alert_notifications.go

@@ -7,29 +7,32 @@ import (
 )
 
 type AlertNotification struct {
-	Id       int64            `json:"id"`
-	OrgId    int64            `json:"-"`
-	Name     string           `json:"name"`
-	Type     string           `json:"type"`
-	Settings *simplejson.Json `json:"settings"`
-	Created  time.Time        `json:"created"`
-	Updated  time.Time        `json:"updated"`
+	Id        int64            `json:"id"`
+	OrgId     int64            `json:"-"`
+	Name      string           `json:"name"`
+	Type      string           `json:"type"`
+	IsDefault bool             `json:"isDefault"`
+	Settings  *simplejson.Json `json:"settings"`
+	Created   time.Time        `json:"created"`
+	Updated   time.Time        `json:"updated"`
 }
 
 type CreateAlertNotificationCommand struct {
-	Name     string           `json:"name"  binding:"Required"`
-	Type     string           `json:"type"  binding:"Required"`
-	Settings *simplejson.Json `json:"settings"`
+	Name      string           `json:"name"  binding:"Required"`
+	Type      string           `json:"type"  binding:"Required"`
+	IsDefault bool             `json:"isDefault"`
+	Settings  *simplejson.Json `json:"settings"`
 
 	OrgId  int64 `json:"-"`
 	Result *AlertNotification
 }
 
 type UpdateAlertNotificationCommand struct {
-	Id       int64            `json:"id"  binding:"Required"`
-	Name     string           `json:"name"  binding:"Required"`
-	Type     string           `json:"type"  binding:"Required"`
-	Settings *simplejson.Json `json:"settings"  binding:"Required"`
+	Id        int64            `json:"id"  binding:"Required"`
+	Name      string           `json:"name"  binding:"Required"`
+	Type      string           `json:"type"  binding:"Required"`
+	IsDefault bool             `json:"isDefault"`
+	Settings  *simplejson.Json `json:"settings"  binding:"Required"`
 
 	OrgId  int64 `json:"-"`
 	Result *AlertNotification

+ 3 - 2
pkg/services/alerting/notifier.go

@@ -88,11 +88,12 @@ func (n *RootNotifier) uploadImage(context *EvalContext) error {
 }
 
 func (n *RootNotifier) getNotifiers(orgId int64, notificationIds []int64) ([]Notifier, error) {
+	query := &m.GetAlertNotificationsQuery{OrgId: orgId}
+
 	if len(notificationIds) == 0 {
-		return []Notifier{}, nil
+		query.Ids = []int64{0}
 	}
 
-	query := &m.GetAlertNotificationsQuery{OrgId: orgId, Ids: notificationIds}
 	if err := bus.Dispatch(query); err != nil {
 		return nil, err
 	}

+ 34 - 27
pkg/services/sqlstore/alert_notification.go

@@ -40,33 +40,36 @@ func getAlertNotificationsInternal(query *m.GetAlertNotificationsQuery, sess *xo
 	params := make([]interface{}, 0)
 
 	sql.WriteString(`SELECT
-	   					  alert_notification.id,
-	   					  alert_notification.org_id,
-	   					  alert_notification.name,
-	              alert_notification.type,
-	   					  alert_notification.created,
-	              alert_notification.updated,
-	              alert_notification.settings
-	   					  FROM alert_notification
-	   					  `)
+										alert_notification.id,
+										alert_notification.org_id,
+										alert_notification.name,
+										alert_notification.type,
+										alert_notification.created,
+										alert_notification.updated,
+										alert_notification.settings,
+										alert_notification.is_default
+										FROM alert_notification
+	  							`)
 
 	sql.WriteString(` WHERE alert_notification.org_id = ?`)
 	params = append(params, query.OrgId)
 
-	if query.Name != "" {
-		sql.WriteString(` AND alert_notification.name = ?`)
-		params = append(params, query.Name)
-	}
+	if query.Name != "" || query.Id != 0 || len(query.Ids) > 0 {
+		if query.Name != "" {
+			sql.WriteString(` AND alert_notification.name = ?`)
+			params = append(params, query.Name)
+		}
 
-	if query.Id != 0 {
-		sql.WriteString(` AND alert_notification.id = ?`)
-		params = append(params, query.Id)
-	}
+		if query.Id != 0 {
+			sql.WriteString(` AND alert_notification.id = ?`)
+			params = append(params, query.Id)
+		}
 
-	if len(query.Ids) > 0 {
-		sql.WriteString(` AND alert_notification.id IN (?` + strings.Repeat(",?", len(query.Ids)-1) + ")")
-		for _, v := range query.Ids {
-			params = append(params, v)
+		if len(query.Ids) > 0 {
+			sql.WriteString(` AND ((alert_notification.is_default = 1) OR alert_notification.id IN (?` + strings.Repeat(",?", len(query.Ids)-1) + "))")
+			for _, v := range query.Ids {
+				params = append(params, v)
+			}
 		}
 	}
 
@@ -93,12 +96,13 @@ func CreateAlertNotificationCommand(cmd *m.CreateAlertNotificationCommand) error
 		}
 
 		alertNotification := &m.AlertNotification{
-			OrgId:    cmd.OrgId,
-			Name:     cmd.Name,
-			Type:     cmd.Type,
-			Settings: cmd.Settings,
-			Created:  time.Now(),
-			Updated:  time.Now(),
+			OrgId:     cmd.OrgId,
+			Name:      cmd.Name,
+			Type:      cmd.Type,
+			Settings:  cmd.Settings,
+			Created:   time.Now(),
+			Updated:   time.Now(),
+			IsDefault: cmd.IsDefault,
 		}
 
 		if _, err = sess.Insert(alertNotification); err != nil {
@@ -132,6 +136,9 @@ func UpdateAlertNotification(cmd *m.UpdateAlertNotificationCommand) error {
 		current.Settings = cmd.Settings
 		current.Name = cmd.Name
 		current.Type = cmd.Type
+		current.IsDefault = cmd.IsDefault
+
+		sess.UseBool("is_default")
 
 		if affected, err := sess.Id(cmd.Id).Update(current); err != nil {
 			return err

+ 3 - 1
pkg/services/sqlstore/alert_notification_test.go

@@ -63,10 +63,12 @@ func TestAlertNotificationSQLAccess(t *testing.T) {
 			cmd1 := m.CreateAlertNotificationCommand{Name: "nagios", Type: "webhook", OrgId: 1, Settings: simplejson.New()}
 			cmd2 := m.CreateAlertNotificationCommand{Name: "slack", Type: "webhook", OrgId: 1, Settings: simplejson.New()}
 			cmd3 := m.CreateAlertNotificationCommand{Name: "ops2", Type: "email", OrgId: 1, Settings: simplejson.New()}
+			cmd4 := m.CreateAlertNotificationCommand{IsDefault: true, Name: "default", Type: "email", OrgId: 1, Settings: simplejson.New()}
 
 			So(CreateAlertNotificationCommand(&cmd1), ShouldBeNil)
 			So(CreateAlertNotificationCommand(&cmd2), ShouldBeNil)
 			So(CreateAlertNotificationCommand(&cmd3), ShouldBeNil)
+			So(CreateAlertNotificationCommand(&cmd4), ShouldBeNil)
 
 			Convey("search", func() {
 				query := &m.GetAlertNotificationsQuery{
@@ -76,7 +78,7 @@ func TestAlertNotificationSQLAccess(t *testing.T) {
 
 				err := GetAlertNotifications(query)
 				So(err, ShouldBeNil)
-				So(len(query.Result), ShouldEqual, 2)
+				So(len(query.Result), ShouldEqual, 3)
 			})
 		})
 	})

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

@@ -62,5 +62,9 @@ func addAlertMigrations(mg *Migrator) {
 	}
 
 	mg.AddMigration("create alert_notification table v1", NewAddTableMigration(alert_notification))
+	mg.AddMigration("Add column is_default", NewAddColumnMigration(alert_notification, &Column{
+		Name: "is_default", Type: DB_Bool, Nullable: false, Default: "0",
+	}))
 	mg.AddMigration("add index alert_notification org_id & name", NewAddIndexMigration(alert_notification, alert_notification.Indices[0]))
+
 }

+ 2 - 1
public/app/features/alerting/notification_edit_ctrl.ts

@@ -17,7 +17,8 @@ export class AlertNotificationEditCtrl {
     } else {
       this.model = {
         type: 'email',
-        settings: {}
+        settings: {},
+        isDefault: false
       };
     }
   }

+ 9 - 0
public/app/features/alerting/partials/notification_edit.html

@@ -25,6 +25,15 @@
 				</select>
 			</div>
 		</div>
+		<div class="gf-form">
+			<gf-form-switch
+				class="gf-form"
+				label="All alerts"
+				label-class="width-8"
+				checked="ctrl.model.isDefault"
+				tooltip="Use this notification for all alerts">
+			</gf-form-switch>
+		</div>
 	</div>
 
 	<div class="gf-form-group" ng-show="ctrl.model.type === 'webhook'">

+ 5 - 2
public/app/features/alerting/partials/notifications_list.html

@@ -10,7 +10,7 @@
     </a>
   </div>
 
-	<table class="grafana-options-table" style="/*width: 600px;*/">
+	<table class="grafana-options-table">
 		<thead>
 			<th style="min-width: 200px"><strong>Name</strong></th>
 			<th style="min-width: 100px">Type</th>
@@ -25,7 +25,10 @@
 			<td>
 				{{notification.type}}
 			</td>
-			<td>
+			<td class="text-right">
+				<span class="btn btn-secondary btn-small" ng-show="notification.isDefault == true">
+					default
+				</span>
 				<a href="alerting/notification/{{notification.id}}/edit" class="btn btn-inverse btn-small">
 					<i class="fa fa-edit"></i>
 					edit