Browse Source

alerting: images in alert notifications is now optional

its now possible to turn of image uploading in alert notifications
for those who operate on very sensitive data.

closes #7419
bergquist 9 years ago
parent
commit
bd010289b2

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

@@ -21,6 +21,18 @@ type Notifier interface {
 	GetIsDefault() bool
 }
 
+type NotifierSlice []Notifier
+
+func (notifiers NotifierSlice) ShouldUploadImage() bool {
+	for _, notifier := range notifiers {
+		if notifier.NeedsImage() {
+			return true
+		}
+	}
+
+	return false
+}
+
 type ConditionResult struct {
 	Firing      bool
 	NoDataFound bool

+ 19 - 29
pkg/services/alerting/notifier.go

@@ -21,37 +21,25 @@ type NotifierPlugin struct {
 	Factory         NotifierFactory `json:"-"`
 }
 
-type RootNotifier struct {
-	log log.Logger
-}
-
-func NewRootNotifier() *RootNotifier {
-	return &RootNotifier{
-		log: log.New("alerting.notifier"),
-	}
-}
-
-func (n *RootNotifier) GetType() string {
-	return "root"
+type NotificationService interface {
+	Send(context *EvalContext) error
 }
 
-func (n *RootNotifier) NeedsImage() bool {
-	return false
+func NewNotificationService() NotificationService {
+	return newNotificationService()
 }
 
-func (n *RootNotifier) PassesFilter(rule *Rule) bool {
-	return false
-}
-
-func (n *RootNotifier) GetNotifierId() int64 {
-	return 0
+type notificationService struct {
+	log log.Logger
 }
 
-func (n *RootNotifier) GetIsDefault() bool {
-	return false
+func newNotificationService() *notificationService {
+	return &notificationService{
+		log: log.New("alerting.notifier"),
+	}
 }
 
-func (n *RootNotifier) Notify(context *EvalContext) error {
+func (n *notificationService) Send(context *EvalContext) error {
 	notifiers, err := n.getNotifiers(context.Rule.OrgId, context.Rule.Notifications, context)
 	if err != nil {
 		return err
@@ -63,14 +51,16 @@ func (n *RootNotifier) Notify(context *EvalContext) error {
 		return nil
 	}
 
-	if err = n.uploadImage(context); err != nil {
-		n.log.Error("Failed to upload alert panel image.", "error", err)
+	if notifiers.ShouldUploadImage() {
+		if err = n.uploadImage(context); err != nil {
+			n.log.Error("Failed to upload alert panel image.", "error", err)
+		}
 	}
 
 	return n.sendNotifications(context, notifiers)
 }
 
-func (n *RootNotifier) sendNotifications(context *EvalContext, notifiers []Notifier) error {
+func (n *notificationService) sendNotifications(context *EvalContext, notifiers []Notifier) error {
 	g, _ := errgroup.WithContext(context.Ctx)
 
 	for _, notifier := range notifiers {
@@ -82,7 +72,7 @@ func (n *RootNotifier) sendNotifications(context *EvalContext, notifiers []Notif
 	return g.Wait()
 }
 
-func (n *RootNotifier) uploadImage(context *EvalContext) (err error) {
+func (n *notificationService) uploadImage(context *EvalContext) (err error) {
 	uploader, err := imguploader.NewImageUploader()
 	if err != nil {
 		return err
@@ -116,7 +106,7 @@ func (n *RootNotifier) uploadImage(context *EvalContext) (err error) {
 	return nil
 }
 
-func (n *RootNotifier) getNotifiers(orgId int64, notificationIds []int64, context *EvalContext) ([]Notifier, error) {
+func (n *notificationService) getNotifiers(orgId int64, notificationIds []int64, context *EvalContext) (NotifierSlice, error) {
 	query := &m.GetAlertNotificationsToSendQuery{OrgId: orgId, Ids: notificationIds}
 
 	if err := bus.Dispatch(query); err != nil {
@@ -137,7 +127,7 @@ func (n *RootNotifier) getNotifiers(orgId int64, notificationIds []int64, contex
 	return result, nil
 }
 
-func (n *RootNotifier) createNotifierFor(model *m.AlertNotification) (Notifier, error) {
+func (n *notificationService) createNotifierFor(model *m.AlertNotification) (Notifier, error) {
 	notifierPlugin, found := notifierFactories[model.Type]
 	if !found {
 		return nil, errors.New("Unsupported notification type")

+ 13 - 9
pkg/services/alerting/notifiers/base.go

@@ -6,18 +6,22 @@ import (
 )
 
 type NotifierBase struct {
-	Name     string
-	Type     string
-	Id       int64
-	IsDeault bool
+	Name        string
+	Type        string
+	Id          int64
+	IsDeault    bool
+	UploadImage bool
 }
 
 func NewNotifierBase(id int64, isDefault bool, name, notifierType string, model *simplejson.Json) NotifierBase {
+	uploadImage := model.Get("uploadImage").MustBool(true)
+
 	return NotifierBase{
-		Id:       id,
-		Name:     name,
-		IsDeault: isDefault,
-		Type:     notifierType,
+		Id:          id,
+		Name:        name,
+		IsDeault:    isDefault,
+		Type:        notifierType,
+		UploadImage: uploadImage,
 	}
 }
 
@@ -30,7 +34,7 @@ func (n *NotifierBase) GetType() string {
 }
 
 func (n *NotifierBase) NeedsImage() bool {
-	return true
+	return n.UploadImage
 }
 
 func (n *NotifierBase) GetNotifierId() int64 {

+ 3 - 3
pkg/services/alerting/result_handler.go

@@ -16,14 +16,14 @@ type ResultHandler interface {
 }
 
 type DefaultResultHandler struct {
-	notifier Notifier
+	notifier NotificationService
 	log      log.Logger
 }
 
 func NewResultHandler() *DefaultResultHandler {
 	return &DefaultResultHandler{
 		log:      log.New("alerting.resultHandler"),
-		notifier: NewRootNotifier(),
+		notifier: NewNotificationService(),
 	}
 }
 
@@ -85,7 +85,7 @@ func (handler *DefaultResultHandler) Handle(evalContext *EvalContext) error {
 		}
 
 		if evalContext.ShouldSendNotification() {
-			handler.notifier.Notify(evalContext)
+			handler.notifier.Send(evalContext)
 		}
 	}
 

+ 6 - 4
pkg/services/alerting/test_notification.go

@@ -23,7 +23,7 @@ func init() {
 }
 
 func handleNotificationTestCommand(cmd *NotificationTestCommand) error {
-	notifier := NewRootNotifier()
+	notifier := newNotificationService()
 
 	model := &m.AlertNotification{
 		Name:     cmd.Name,
@@ -38,10 +38,10 @@ func handleNotificationTestCommand(cmd *NotificationTestCommand) error {
 		return err
 	}
 
-	return notifier.sendNotifications(createTestEvalContext(), []Notifier{notifiers})
+	return notifier.sendNotifications(createTestEvalContext(cmd), []Notifier{notifiers})
 }
 
-func createTestEvalContext() *EvalContext {
+func createTestEvalContext(cmd *NotificationTestCommand) *EvalContext {
 	testRule := &Rule{
 		DashboardId: 1,
 		PanelId:     1,
@@ -51,7 +51,9 @@ func createTestEvalContext() *EvalContext {
 	}
 
 	ctx := NewEvalContext(context.TODO(), testRule)
-	ctx.ImagePublicUrl = "http://grafana.org/assets/img/blog/mixed_styles.png"
+	if cmd.Settings.Get("uploadImage").MustBool(true) {
+		ctx.ImagePublicUrl = "http://grafana.org/assets/img/blog/mixed_styles.png"
+	}
 	ctx.IsTestRun = true
 	ctx.Firing = true
 	ctx.Error = nil

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

@@ -17,6 +17,7 @@ export class AlertNotificationEditCtrl {
     settings: {
       httpMethod: 'POST',
       autoResolve: true,
+      uploadImage: true,
     },
     isDefault: false
   };
@@ -32,7 +33,7 @@ export class AlertNotificationEditCtrl {
       }
 
       if (!this.$routeParams.id) {
-        return this.model;
+        return _.defaults(this.model, this.defaults);
       }
 
       return this.backendSrv.get(`/api/alert-notifications/${this.$routeParams.id}`).then(result => {

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

@@ -24,15 +24,20 @@
           </select>
         </div>
       </div>
-      <div class="gf-form">
-        <gf-form-switch
-           class="gf-form"
-           label="Send on all alerts"
-           label-class="width-12"
-           checked="ctrl.model.isDefault"
-           tooltip="Use this notification for all alerts">
-        </gf-form-switch>
-      </div>
+      <gf-form-switch
+          class="gf-form"
+          label="Send on all alerts"
+          label-class="width-12"
+          checked="ctrl.model.isDefault"
+          tooltip="Use this notification for all alerts">
+      </gf-form-switch>
+      <gf-form-switch
+          class="gf-form"
+          label="Include image"
+          label-class="width-12"
+          checked="ctrl.model.settings.uploadImage"
+          tooltip="Captures an image and include it in the notification">
+      </gf-form-switch>
     </div>
 
     <div class="gf-form-group" ng-include src="ctrl.notifierTemplateId">