mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Pushover alert, support for different sound for OK (#16525)
Closes #15889
This commit is contained in:
parent
e8d6995737
commit
c17226af95
@ -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 == "" {
|
||||||
@ -103,30 +113,32 @@ func NewPushoverNotifier(model *m.AlertNotification) (alerting.Notifier, error)
|
|||||||
return nil, alerting.ValidationError{Reason: "API token not given"}
|
return nil, alerting.ValidationError{Reason: "API token not given"}
|
||||||
}
|
}
|
||||||
return &PushoverNotifier{
|
return &PushoverNotifier{
|
||||||
NotifierBase: NewNotifierBase(model),
|
NotifierBase: NewNotifierBase(model),
|
||||||
UserKey: userKey,
|
UserKey: userKey,
|
||||||
ApiToken: apiToken,
|
ApiToken: apiToken,
|
||||||
Priority: priority,
|
Priority: priority,
|
||||||
Retry: retry,
|
Retry: retry,
|
||||||
Expire: expire,
|
Expire: expire,
|
||||||
Device: device,
|
Device: device,
|
||||||
Sound: sound,
|
AlertingSound: alertingSound,
|
||||||
Upload: uploadImage,
|
OkSound: okSound,
|
||||||
log: log.New("alerting.notifier.pushover"),
|
Upload: uploadImage,
|
||||||
|
log: log.New("alerting.notifier.pushover"),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type PushoverNotifier struct {
|
type PushoverNotifier struct {
|
||||||
NotifierBase
|
NotifierBase
|
||||||
UserKey string
|
UserKey string
|
||||||
ApiToken string
|
ApiToken string
|
||||||
Priority int
|
Priority int
|
||||||
Retry int
|
Retry int
|
||||||
Expire int
|
Expire int
|
||||||
Device string
|
Device string
|
||||||
Sound string
|
AlertingSound string
|
||||||
Upload bool
|
OkSound string
|
||||||
log log.Logger
|
Upload bool
|
||||||
|
log log.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *PushoverNotifier) Notify(evalContext *alerting.EvalContext) error {
|
func (this *PushoverNotifier) Notify(evalContext *alerting.EvalContext) error {
|
||||||
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user