Pushover alert, support for different sound for OK (#16525)

Closes #15889
This commit is contained in:
Hofls 2019-04-12 17:57:17 +05:00 committed by Carl Bergquist
parent e8d6995737
commit c17226af95
2 changed files with 103 additions and 48 deletions

View File

@ -17,6 +17,31 @@ import (
const PUSHOVER_ENDPOINT = "https://api.pushover.net/1/messages.json" const PUSHOVER_ENDPOINT = "https://api.pushover.net/1/messages.json"
func init() { func init() {
sounds := `
'default',
'pushover',
'bike',
'bugle',
'cashregister',
'classical',
'cosmic',
'falling',
'gamelan',
'incoming',
'intermission',
'magic',
'mechanical',
'pianobar',
'siren',
'spacealarm',
'tugboat',
'alien',
'climb',
'persistent',
'echo',
'updown',
'none'`
alerting.RegisterNotifier(&alerting.NotifierPlugin{ alerting.RegisterNotifier(&alerting.NotifierPlugin{
Type: "pushover", Type: "pushover",
Name: "Pushover", Name: "Pushover",
@ -55,33 +80,17 @@ func init() {
<input type="text" class="gf-form-input max-width-14" ng-required="ctrl.model.settings.priority == '2'" placeholder="maximum 86400 seconds" ng-model="ctrl.model.settings.expire" ng-init="ctrl.model.settings.expire=ctrl.model.settings.expire||'3600'"></input> <input type="text" class="gf-form-input max-width-14" ng-required="ctrl.model.settings.priority == '2'" placeholder="maximum 86400 seconds" ng-model="ctrl.model.settings.expire" ng-init="ctrl.model.settings.expire=ctrl.model.settings.expire||'3600'"></input>
</div> </div>
<div class="gf-form"> <div class="gf-form">
<span class="gf-form-label width-10">Sound</span> <span class="gf-form-label width-10">Alerting sound</span>
<select class="gf-form-input max-width-14" ng-model="ctrl.model.settings.sound" ng-options="s for s in [ <select class="gf-form-input max-width-14" ng-model="ctrl.model.settings.sound" ng-options="s for s in [
'default', ` + sounds + `
'pushover',
'bike',
'bugle',
'cashregister',
'classical',
'cosmic',
'falling',
'gamelan',
'incoming',
'intermission',
'magic',
'mechanical',
'pianobar',
'siren',
'spacealarm',
'tugboat',
'alien',
'climb',
'persistent',
'echo',
'updown',
'none'
]" ng-init="ctrl.model.settings.sound=ctrl.model.settings.sound||'default'"></select> ]" ng-init="ctrl.model.settings.sound=ctrl.model.settings.sound||'default'"></select>
</div> </div>
<div class="gf-form">
<span class="gf-form-label width-10">OK sound</span>
<select class="gf-form-input max-width-14" ng-model="ctrl.model.settings.okSound" ng-options="s for s in [
` + sounds + `
]" ng-init="ctrl.model.settings.okSound=ctrl.model.settings.okSound||'default'"></select>
</div>
`, `,
}) })
} }
@ -93,7 +102,8 @@ func NewPushoverNotifier(model *m.AlertNotification) (alerting.Notifier, error)
priority, _ := strconv.Atoi(model.Settings.Get("priority").MustString()) priority, _ := strconv.Atoi(model.Settings.Get("priority").MustString())
retry, _ := strconv.Atoi(model.Settings.Get("retry").MustString()) retry, _ := strconv.Atoi(model.Settings.Get("retry").MustString())
expire, _ := strconv.Atoi(model.Settings.Get("expire").MustString()) expire, _ := strconv.Atoi(model.Settings.Get("expire").MustString())
sound := model.Settings.Get("sound").MustString() alertingSound := model.Settings.Get("sound").MustString()
okSound := model.Settings.Get("okSound").MustString()
uploadImage := model.Settings.Get("uploadImage").MustBool(true) uploadImage := model.Settings.Get("uploadImage").MustBool(true)
if userKey == "" { if userKey == "" {
@ -110,7 +120,8 @@ func NewPushoverNotifier(model *m.AlertNotification) (alerting.Notifier, error)
Retry: retry, Retry: retry,
Expire: expire, Expire: expire,
Device: device, Device: device,
Sound: sound, AlertingSound: alertingSound,
OkSound: okSound,
Upload: uploadImage, Upload: uploadImage,
log: log.New("alerting.notifier.pushover"), log: log.New("alerting.notifier.pushover"),
}, nil }, nil
@ -124,7 +135,8 @@ type PushoverNotifier struct {
Retry int Retry int
Expire int Expire int
Device string Device string
Sound string AlertingSound string
OkSound string
Upload bool Upload bool
log log.Logger log log.Logger
} }
@ -235,8 +247,12 @@ func (this *PushoverNotifier) genPushoverBody(evalContext *alerting.EvalContext,
} }
// Add sound // Add sound
if this.Sound != "default" { sound := this.AlertingSound
err = w.WriteField("sound", this.Sound) if evalContext.Rule.State == m.AlertStateOK {
sound = this.OkSound
}
if sound != "default" {
err = w.WriteField("sound", sound)
if err != nil { if err != nil {
return nil, b, err return nil, b, err
} }

View File

@ -1,6 +1,9 @@
package notifiers package notifiers
import ( import (
"context"
"github.com/grafana/grafana/pkg/services/alerting"
"strings"
"testing" "testing"
"github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/components/simplejson"
@ -32,7 +35,8 @@ func TestPushoverNotifier(t *testing.T) {
"apiToken": "4SrUFQL4A5V5TQ1z5Pg9nxHXPXSTve", "apiToken": "4SrUFQL4A5V5TQ1z5Pg9nxHXPXSTve",
"userKey": "tzNZYf36y0ohWwXo4XoUrB61rz1A4o", "userKey": "tzNZYf36y0ohWwXo4XoUrB61rz1A4o",
"priority": "1", "priority": "1",
"sound": "pushover" "sound": "pushover",
"okSound": "magic"
}` }`
settingsJSON, _ := simplejson.NewJson([]byte(json)) settingsJSON, _ := simplejson.NewJson([]byte(json))
@ -51,8 +55,43 @@ func TestPushoverNotifier(t *testing.T) {
So(pushoverNotifier.ApiToken, ShouldEqual, "4SrUFQL4A5V5TQ1z5Pg9nxHXPXSTve") So(pushoverNotifier.ApiToken, ShouldEqual, "4SrUFQL4A5V5TQ1z5Pg9nxHXPXSTve")
So(pushoverNotifier.UserKey, ShouldEqual, "tzNZYf36y0ohWwXo4XoUrB61rz1A4o") So(pushoverNotifier.UserKey, ShouldEqual, "tzNZYf36y0ohWwXo4XoUrB61rz1A4o")
So(pushoverNotifier.Priority, ShouldEqual, 1) So(pushoverNotifier.Priority, ShouldEqual, 1)
So(pushoverNotifier.Sound, ShouldEqual, "pushover") So(pushoverNotifier.AlertingSound, ShouldEqual, "pushover")
So(pushoverNotifier.OkSound, ShouldEqual, "magic")
}) })
}) })
}) })
} }
func TestGenPushoverBody(t *testing.T) {
Convey("Pushover body generation tests", t, func() {
Convey("Given common sounds", func() {
sirenSound := "siren_sound_tst"
successSound := "success_sound_tst"
notifier := &PushoverNotifier{AlertingSound: sirenSound, OkSound: successSound}
Convey("When alert is firing - should use siren sound", func() {
evalContext := alerting.NewEvalContext(context.Background(),
&alerting.Rule{
State: m.AlertStateAlerting,
})
_, pushoverBody, err := notifier.genPushoverBody(evalContext, "", "")
So(err, ShouldBeNil)
So(strings.Contains(pushoverBody.String(), sirenSound), ShouldBeTrue)
})
Convey("When alert is ok - should use success sound", func() {
evalContext := alerting.NewEvalContext(context.Background(),
&alerting.Rule{
State: m.AlertStateOK,
})
_, pushoverBody, err := notifier.genPushoverBody(evalContext, "", "")
So(err, ShouldBeNil)
So(strings.Contains(pushoverBody.String(), successSound), ShouldBeTrue)
})
})
})
}