Commit 7333d7b8 by bergquist

alerting: invert sendOnce to sendReminder

parent 0c6d8398
...@@ -49,28 +49,28 @@ func formatShort(interval time.Duration) string { ...@@ -49,28 +49,28 @@ func formatShort(interval time.Duration) string {
func NewAlertNotification(notification *models.AlertNotification) *AlertNotification { func NewAlertNotification(notification *models.AlertNotification) *AlertNotification {
return &AlertNotification{ return &AlertNotification{
Id: notification.Id, Id: notification.Id,
Name: notification.Name, Name: notification.Name,
Type: notification.Type, Type: notification.Type,
IsDefault: notification.IsDefault, IsDefault: notification.IsDefault,
Created: notification.Created, Created: notification.Created,
Updated: notification.Updated, Updated: notification.Updated,
Frequency: formatShort(notification.Frequency), Frequency: formatShort(notification.Frequency),
NotifyOnce: notification.NotifyOnce, SendReminder: notification.SendReminder,
Settings: notification.Settings, Settings: notification.Settings,
} }
} }
type AlertNotification struct { type AlertNotification struct {
Id int64 `json:"id"` Id int64 `json:"id"`
Name string `json:"name"` Name string `json:"name"`
Type string `json:"type"` Type string `json:"type"`
IsDefault bool `json:"isDefault"` IsDefault bool `json:"isDefault"`
NotifyOnce bool `json:"notifyOnce"` SendReminder bool `json:"sendReminder"`
Frequency string `json:"frequency"` Frequency string `json:"frequency"`
Created time.Time `json:"created"` Created time.Time `json:"created"`
Updated time.Time `json:"updated"` Updated time.Time `json:"updated"`
Settings *simplejson.Json `json:"settings"` Settings *simplejson.Json `json:"settings"`
} }
type AlertTestCommand struct { type AlertTestCommand struct {
...@@ -100,11 +100,11 @@ type EvalMatch struct { ...@@ -100,11 +100,11 @@ type EvalMatch struct {
} }
type NotificationTestCommand struct { type NotificationTestCommand struct {
Name string `json:"name"` Name string `json:"name"`
Type string `json:"type"` Type string `json:"type"`
NotifyOnce bool `json:"notifyOnce"` SendReminder bool `json:"sendReminder"`
Frequency string `json:"frequency"` Frequency string `json:"frequency"`
Settings *simplejson.Json `json:"settings"` Settings *simplejson.Json `json:"settings"`
} }
type PauseAlertCommand struct { type PauseAlertCommand struct {
......
...@@ -14,6 +14,7 @@ func TestFormatShort(t *testing.T) { ...@@ -14,6 +14,7 @@ func TestFormatShort(t *testing.T) {
{interval: time.Duration(time.Hour + time.Minute), expected: "1h1m"}, {interval: time.Duration(time.Hour + time.Minute), expected: "1h1m"},
{interval: time.Duration((time.Hour * 10) + time.Minute), expected: "10h1m"}, {interval: time.Duration((time.Hour * 10) + time.Minute), expected: "10h1m"},
{interval: time.Duration((time.Hour * 10) + (time.Minute * 10) + time.Second), expected: "10h10m1s"}, {interval: time.Duration((time.Hour * 10) + (time.Minute * 10) + time.Second), expected: "10h10m1s"},
{interval: time.Duration(time.Minute * 10), expected: "10m"},
} }
for _, tc := range tcs { for _, tc := range tcs {
......
...@@ -12,38 +12,38 @@ var ( ...@@ -12,38 +12,38 @@ var (
) )
type AlertNotification struct { type AlertNotification struct {
Id int64 `json:"id"` Id int64 `json:"id"`
OrgId int64 `json:"-"` OrgId int64 `json:"-"`
Name string `json:"name"` Name string `json:"name"`
Type string `json:"type"` Type string `json:"type"`
NotifyOnce bool `json:"notifyOnce"` SendReminder bool `json:"sendReminder"`
Frequency time.Duration `json:"frequency"` Frequency time.Duration `json:"frequency"`
IsDefault bool `json:"isDefault"` IsDefault bool `json:"isDefault"`
Settings *simplejson.Json `json:"settings"` Settings *simplejson.Json `json:"settings"`
Created time.Time `json:"created"` Created time.Time `json:"created"`
Updated time.Time `json:"updated"` Updated time.Time `json:"updated"`
} }
type CreateAlertNotificationCommand struct { type CreateAlertNotificationCommand struct {
Name string `json:"name" binding:"Required"` Name string `json:"name" binding:"Required"`
Type string `json:"type" binding:"Required"` Type string `json:"type" binding:"Required"`
NotifyOnce bool `json:"notifyOnce"` SendReminder bool `json:"sendReminder"`
Frequency string `json:"frequency"` Frequency string `json:"frequency"`
IsDefault bool `json:"isDefault"` IsDefault bool `json:"isDefault"`
Settings *simplejson.Json `json:"settings"` Settings *simplejson.Json `json:"settings"`
OrgId int64 `json:"-"` OrgId int64 `json:"-"`
Result *AlertNotification Result *AlertNotification
} }
type UpdateAlertNotificationCommand struct { type UpdateAlertNotificationCommand struct {
Id int64 `json:"id" binding:"Required"` Id int64 `json:"id" binding:"Required"`
Name string `json:"name" binding:"Required"` Name string `json:"name" binding:"Required"`
Type string `json:"type" binding:"Required"` Type string `json:"type" binding:"Required"`
NotifyOnce bool `json:"notifyOnce"` SendReminder bool `json:"sendReminder"`
Frequency string `json:"frequency"` Frequency string `json:"frequency"`
IsDefault bool `json:"isDefault"` IsDefault bool `json:"isDefault"`
Settings *simplejson.Json `json:"settings" binding:"Required"` Settings *simplejson.Json `json:"settings" binding:"Required"`
OrgId int64 `json:"-"` OrgId int64 `json:"-"`
Result *AlertNotification Result *AlertNotification
......
...@@ -19,7 +19,7 @@ type Notifier interface { ...@@ -19,7 +19,7 @@ type Notifier interface {
GetNotifierId() int64 GetNotifierId() int64
GetIsDefault() bool GetIsDefault() bool
GetNotifyOnce() bool GetSendReminder() bool
GetFrequency() time.Duration GetFrequency() time.Duration
} }
......
...@@ -33,7 +33,7 @@ func NewAlertmanagerNotifier(model *m.AlertNotification) (alerting.Notifier, err ...@@ -33,7 +33,7 @@ func NewAlertmanagerNotifier(model *m.AlertNotification) (alerting.Notifier, err
} }
return &AlertmanagerNotifier{ return &AlertmanagerNotifier{
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.NotifyOnce, model.Frequency, model.Settings), NotifierBase: NewNotifierBase(model),
Url: url, Url: url,
log: log.New("alerting.notifier.prometheus-alertmanager"), log: log.New("alerting.notifier.prometheus-alertmanager"),
}, nil }, nil
......
...@@ -3,54 +3,56 @@ package notifiers ...@@ -3,54 +3,56 @@ package notifiers
import ( import (
"time" "time"
"github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/models"
m "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting" "github.com/grafana/grafana/pkg/services/alerting"
) )
type NotifierBase struct { type NotifierBase struct {
Name string Name string
Type string Type string
Id int64 Id int64
IsDeault bool IsDeault bool
UploadImage bool UploadImage bool
NotifyOnce bool SendReminder bool
Frequency time.Duration Frequency time.Duration
} }
func NewNotifierBase(id int64, isDefault bool, name, notifierType string, notifyOnce bool, frequency time.Duration, model *simplejson.Json) NotifierBase { func NewNotifierBase(model *models.AlertNotification) NotifierBase {
uploadImage := true uploadImage := true
value, exist := model.CheckGet("uploadImage") value, exist := model.Settings.CheckGet("uploadImage")
if exist { if exist {
uploadImage = value.MustBool() uploadImage = value.MustBool()
} }
return NotifierBase{ return NotifierBase{
Id: id, Id: model.Id,
Name: name, Name: model.Name,
IsDeault: isDefault, IsDeault: model.IsDefault,
Type: notifierType, Type: model.Type,
UploadImage: uploadImage, UploadImage: uploadImage,
NotifyOnce: notifyOnce, SendReminder: model.SendReminder,
Frequency: frequency, Frequency: model.Frequency,
} }
} }
func defaultShouldNotify(context *alerting.EvalContext, notifyOnce bool, frequency time.Duration, lastNotify *time.Time) bool { func defaultShouldNotify(context *alerting.EvalContext, sendReminder bool, frequency time.Duration, lastNotify *time.Time) bool {
// Only notify on state change. // Only notify on state change.
if context.PrevAlertState == context.Rule.State && notifyOnce { if context.PrevAlertState == context.Rule.State && !sendReminder {
return false return false
} }
// Do not notify if interval has not elapsed // Do not notify if interval has not elapsed
if !notifyOnce && lastNotify != nil && lastNotify.Add(frequency).After(time.Now()) { if sendReminder && lastNotify != nil && lastNotify.Add(frequency).After(time.Now()) {
return false return false
} }
// Do not notify if alert state if OK or pending even on repeated notify // Do not notify if alert state if OK or pending even on repeated notify
if !notifyOnce && (context.Rule.State == m.AlertStateOK || context.Rule.State == m.AlertStatePending) { if sendReminder && (context.Rule.State == models.AlertStateOK || context.Rule.State == models.AlertStatePending) {
return false return false
} }
// Do not notify when we become OK for the first time. // Do not notify when we become OK for the first time.
if (context.PrevAlertState == m.AlertStatePending) && (context.Rule.State == m.AlertStateOK) { if (context.PrevAlertState == models.AlertStatePending) && (context.Rule.State == models.AlertStateOK) {
return false return false
} }
return true return true
...@@ -58,7 +60,7 @@ func defaultShouldNotify(context *alerting.EvalContext, notifyOnce bool, frequen ...@@ -58,7 +60,7 @@ func defaultShouldNotify(context *alerting.EvalContext, notifyOnce bool, frequen
func (n *NotifierBase) ShouldNotify(context *alerting.EvalContext) bool { func (n *NotifierBase) ShouldNotify(context *alerting.EvalContext) bool {
lastNotify := context.LastNotify(n.Id) lastNotify := context.LastNotify(n.Id)
return defaultShouldNotify(context, n.NotifyOnce, n.Frequency, lastNotify) return defaultShouldNotify(context, n.SendReminder, n.Frequency, lastNotify)
} }
func (n *NotifierBase) GetType() string { func (n *NotifierBase) GetType() string {
...@@ -77,8 +79,8 @@ func (n *NotifierBase) GetIsDefault() bool { ...@@ -77,8 +79,8 @@ func (n *NotifierBase) GetIsDefault() bool {
return n.IsDeault return n.IsDeault
} }
func (n *NotifierBase) GetNotifyOnce() bool { func (n *NotifierBase) GetSendReminder() bool {
return n.NotifyOnce return n.SendReminder
} }
func (n *NotifierBase) GetFrequency() time.Duration { func (n *NotifierBase) GetFrequency() time.Duration {
......
...@@ -16,22 +16,29 @@ func TestBaseNotifier(t *testing.T) { ...@@ -16,22 +16,29 @@ func TestBaseNotifier(t *testing.T) {
Convey("default constructor for notifiers", func() { Convey("default constructor for notifiers", func() {
bJson := simplejson.New() bJson := simplejson.New()
model := &m.AlertNotification{
Id: 1,
Name: "name",
Type: "email",
Settings: bJson,
}
Convey("can parse false value", func() { Convey("can parse false value", func() {
bJson.Set("uploadImage", false) bJson.Set("uploadImage", false)
base := NewNotifierBase(1, false, "name", "email", true, 0, bJson) base := NewNotifierBase(model)
So(base.UploadImage, ShouldBeFalse) So(base.UploadImage, ShouldBeFalse)
}) })
Convey("can parse true value", func() { Convey("can parse true value", func() {
bJson.Set("uploadImage", true) bJson.Set("uploadImage", true)
base := NewNotifierBase(1, false, "name", "email", true, 0, bJson) base := NewNotifierBase(model)
So(base.UploadImage, ShouldBeTrue) So(base.UploadImage, ShouldBeTrue)
}) })
Convey("default value should be true for backwards compatibility", func() { Convey("default value should be true for backwards compatibility", func() {
base := NewNotifierBase(1, false, "name", "email", true, 0, bJson) base := NewNotifierBase(model)
So(base.UploadImage, ShouldBeTrue) So(base.UploadImage, ShouldBeTrue)
}) })
}) })
......
...@@ -32,7 +32,7 @@ func NewDingDingNotifier(model *m.AlertNotification) (alerting.Notifier, error) ...@@ -32,7 +32,7 @@ func NewDingDingNotifier(model *m.AlertNotification) (alerting.Notifier, error)
} }
return &DingDingNotifier{ return &DingDingNotifier{
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.NotifyOnce, model.Frequency, model.Settings), NotifierBase: NewNotifierBase(model),
Url: url, Url: url,
log: log.New("alerting.notifier.dingding"), log: log.New("alerting.notifier.dingding"),
}, nil }, nil
......
...@@ -39,7 +39,7 @@ func NewDiscordNotifier(model *m.AlertNotification) (alerting.Notifier, error) { ...@@ -39,7 +39,7 @@ func NewDiscordNotifier(model *m.AlertNotification) (alerting.Notifier, error) {
} }
return &DiscordNotifier{ return &DiscordNotifier{
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.NotifyOnce, model.Frequency, model.Settings), NotifierBase: NewNotifierBase(model),
WebhookURL: url, WebhookURL: url,
log: log.New("alerting.notifier.discord"), log: log.New("alerting.notifier.discord"),
}, nil }, nil
......
...@@ -52,7 +52,7 @@ func NewEmailNotifier(model *m.AlertNotification) (alerting.Notifier, error) { ...@@ -52,7 +52,7 @@ func NewEmailNotifier(model *m.AlertNotification) (alerting.Notifier, error) {
}) })
return &EmailNotifier{ return &EmailNotifier{
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.NotifyOnce, model.Frequency, model.Settings), NotifierBase: NewNotifierBase(model),
Addresses: addresses, Addresses: addresses,
log: log.New("alerting.notifier.email"), log: log.New("alerting.notifier.email"),
}, nil }, nil
......
...@@ -59,7 +59,7 @@ func NewHipChatNotifier(model *models.AlertNotification) (alerting.Notifier, err ...@@ -59,7 +59,7 @@ func NewHipChatNotifier(model *models.AlertNotification) (alerting.Notifier, err
roomId := model.Settings.Get("roomid").MustString() roomId := model.Settings.Get("roomid").MustString()
return &HipChatNotifier{ return &HipChatNotifier{
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.NotifyOnce, model.Frequency, model.Settings), NotifierBase: NewNotifierBase(model),
Url: url, Url: url,
ApiKey: apikey, ApiKey: apikey,
RoomId: roomId, RoomId: roomId,
......
...@@ -43,7 +43,7 @@ func NewKafkaNotifier(model *m.AlertNotification) (alerting.Notifier, error) { ...@@ -43,7 +43,7 @@ func NewKafkaNotifier(model *m.AlertNotification) (alerting.Notifier, error) {
} }
return &KafkaNotifier{ return &KafkaNotifier{
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.NotifyOnce, model.Frequency, model.Settings), NotifierBase: NewNotifierBase(model),
Endpoint: endpoint, Endpoint: endpoint,
Topic: topic, Topic: topic,
log: log.New("alerting.notifier.kafka"), log: log.New("alerting.notifier.kafka"),
......
...@@ -39,7 +39,7 @@ func NewLINENotifier(model *m.AlertNotification) (alerting.Notifier, error) { ...@@ -39,7 +39,7 @@ func NewLINENotifier(model *m.AlertNotification) (alerting.Notifier, error) {
} }
return &LineNotifier{ return &LineNotifier{
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.NotifyOnce, model.Frequency, model.Settings), NotifierBase: NewNotifierBase(model),
Token: token, Token: token,
log: log.New("alerting.notifier.line"), log: log.New("alerting.notifier.line"),
}, nil }, nil
......
...@@ -56,7 +56,7 @@ func NewOpsGenieNotifier(model *m.AlertNotification) (alerting.Notifier, error) ...@@ -56,7 +56,7 @@ func NewOpsGenieNotifier(model *m.AlertNotification) (alerting.Notifier, error)
} }
return &OpsGenieNotifier{ return &OpsGenieNotifier{
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.NotifyOnce, model.Frequency, model.Settings), NotifierBase: NewNotifierBase(model),
ApiKey: apiKey, ApiKey: apiKey,
ApiUrl: apiUrl, ApiUrl: apiUrl,
AutoClose: autoClose, AutoClose: autoClose,
......
...@@ -51,7 +51,7 @@ func NewPagerdutyNotifier(model *m.AlertNotification) (alerting.Notifier, error) ...@@ -51,7 +51,7 @@ func NewPagerdutyNotifier(model *m.AlertNotification) (alerting.Notifier, error)
} }
return &PagerdutyNotifier{ return &PagerdutyNotifier{
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.NotifyOnce, model.Frequency, model.Settings), NotifierBase: NewNotifierBase(model),
Key: key, Key: key,
AutoResolve: autoResolve, AutoResolve: autoResolve,
log: log.New("alerting.notifier.pagerduty"), log: log.New("alerting.notifier.pagerduty"),
......
...@@ -99,7 +99,7 @@ func NewPushoverNotifier(model *m.AlertNotification) (alerting.Notifier, error) ...@@ -99,7 +99,7 @@ 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.Id, model.IsDefault, model.Name, model.Type, model.NotifyOnce, model.Frequency, model.Settings), NotifierBase: NewNotifierBase(model),
UserKey: userKey, UserKey: userKey,
ApiToken: apiToken, ApiToken: apiToken,
Priority: priority, Priority: priority,
......
...@@ -51,7 +51,7 @@ func NewSensuNotifier(model *m.AlertNotification) (alerting.Notifier, error) { ...@@ -51,7 +51,7 @@ func NewSensuNotifier(model *m.AlertNotification) (alerting.Notifier, error) {
} }
return &SensuNotifier{ return &SensuNotifier{
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.NotifyOnce, model.Frequency, model.Settings), NotifierBase: NewNotifierBase(model),
Url: url, Url: url,
User: model.Settings.Get("username").MustString(), User: model.Settings.Get("username").MustString(),
Source: model.Settings.Get("source").MustString(), Source: model.Settings.Get("source").MustString(),
......
...@@ -78,7 +78,7 @@ func NewSlackNotifier(model *m.AlertNotification) (alerting.Notifier, error) { ...@@ -78,7 +78,7 @@ func NewSlackNotifier(model *m.AlertNotification) (alerting.Notifier, error) {
uploadImage := model.Settings.Get("uploadImage").MustBool(true) uploadImage := model.Settings.Get("uploadImage").MustBool(true)
return &SlackNotifier{ return &SlackNotifier{
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.NotifyOnce, model.Frequency, model.Settings), NotifierBase: NewNotifierBase(model),
Url: url, Url: url,
Recipient: recipient, Recipient: recipient,
Mention: mention, Mention: mention,
......
...@@ -33,7 +33,7 @@ func NewTeamsNotifier(model *m.AlertNotification) (alerting.Notifier, error) { ...@@ -33,7 +33,7 @@ func NewTeamsNotifier(model *m.AlertNotification) (alerting.Notifier, error) {
} }
return &TeamsNotifier{ return &TeamsNotifier{
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.NotifyOnce, model.Frequency, model.Settings), NotifierBase: NewNotifierBase(model),
Url: url, Url: url,
log: log.New("alerting.notifier.teams"), log: log.New("alerting.notifier.teams"),
}, nil }, nil
......
...@@ -78,7 +78,7 @@ func NewTelegramNotifier(model *m.AlertNotification) (alerting.Notifier, error) ...@@ -78,7 +78,7 @@ func NewTelegramNotifier(model *m.AlertNotification) (alerting.Notifier, error)
} }
return &TelegramNotifier{ return &TelegramNotifier{
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.NotifyOnce, model.Frequency, model.Settings), NotifierBase: NewNotifierBase(model),
BotToken: botToken, BotToken: botToken,
ChatID: chatId, ChatID: chatId,
UploadImage: uploadImage, UploadImage: uploadImage,
......
...@@ -106,7 +106,7 @@ func NewThreemaNotifier(model *m.AlertNotification) (alerting.Notifier, error) { ...@@ -106,7 +106,7 @@ func NewThreemaNotifier(model *m.AlertNotification) (alerting.Notifier, error) {
} }
return &ThreemaNotifier{ return &ThreemaNotifier{
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.NotifyOnce, model.Frequency, model.Settings), NotifierBase: NewNotifierBase(model),
GatewayID: gatewayID, GatewayID: gatewayID,
RecipientID: recipientID, RecipientID: recipientID,
APISecret: apiSecret, APISecret: apiSecret,
......
...@@ -51,7 +51,7 @@ func NewVictoropsNotifier(model *models.AlertNotification) (alerting.Notifier, e ...@@ -51,7 +51,7 @@ func NewVictoropsNotifier(model *models.AlertNotification) (alerting.Notifier, e
} }
return &VictoropsNotifier{ return &VictoropsNotifier{
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.NotifyOnce, model.Frequency, model.Settings), NotifierBase: NewNotifierBase(model),
URL: url, URL: url,
AutoResolve: autoResolve, AutoResolve: autoResolve,
log: log.New("alerting.notifier.victorops"), log: log.New("alerting.notifier.victorops"),
......
...@@ -47,7 +47,7 @@ func NewWebHookNotifier(model *m.AlertNotification) (alerting.Notifier, error) { ...@@ -47,7 +47,7 @@ func NewWebHookNotifier(model *m.AlertNotification) (alerting.Notifier, error) {
} }
return &WebhookNotifier{ return &WebhookNotifier{
NotifierBase: NewNotifierBase(model.Id, model.IsDefault, model.Name, model.Type, model.NotifyOnce, model.Frequency, model.Settings), NotifierBase: NewNotifierBase(model),
Url: url, Url: url,
User: model.Settings.Get("username").MustString(), User: model.Settings.Get("username").MustString(),
Password: model.Settings.Get("password").MustString(), Password: model.Settings.Get("password").MustString(),
......
...@@ -57,7 +57,7 @@ func GetAlertNotificationsToSend(query *m.GetAlertNotificationsToSendQuery) erro ...@@ -57,7 +57,7 @@ func GetAlertNotificationsToSend(query *m.GetAlertNotificationsToSendQuery) erro
alert_notification.updated, alert_notification.updated,
alert_notification.settings, alert_notification.settings,
alert_notification.is_default, alert_notification.is_default,
alert_notification.notify_once, alert_notification.send_reminder,
alert_notification.frequency alert_notification.frequency
FROM alert_notification FROM alert_notification
`) `)
...@@ -97,7 +97,7 @@ func getAlertNotificationInternal(query *m.GetAlertNotificationsQuery, sess *DBS ...@@ -97,7 +97,7 @@ func getAlertNotificationInternal(query *m.GetAlertNotificationsQuery, sess *DBS
alert_notification.updated, alert_notification.updated,
alert_notification.settings, alert_notification.settings,
alert_notification.is_default, alert_notification.is_default,
alert_notification.notify_once, alert_notification.send_reminder,
alert_notification.frequency alert_notification.frequency
FROM alert_notification FROM alert_notification
`) `)
...@@ -145,7 +145,7 @@ func CreateAlertNotificationCommand(cmd *m.CreateAlertNotificationCommand) error ...@@ -145,7 +145,7 @@ func CreateAlertNotificationCommand(cmd *m.CreateAlertNotificationCommand) error
} }
var frequency time.Duration var frequency time.Duration
if !cmd.NotifyOnce { if cmd.SendReminder {
if cmd.Frequency == "" { if cmd.Frequency == "" {
return m.ErrNotificationFrequencyNotFound return m.ErrNotificationFrequencyNotFound
} }
...@@ -157,18 +157,18 @@ func CreateAlertNotificationCommand(cmd *m.CreateAlertNotificationCommand) error ...@@ -157,18 +157,18 @@ func CreateAlertNotificationCommand(cmd *m.CreateAlertNotificationCommand) error
} }
alertNotification := &m.AlertNotification{ alertNotification := &m.AlertNotification{
OrgId: cmd.OrgId, OrgId: cmd.OrgId,
Name: cmd.Name, Name: cmd.Name,
Type: cmd.Type, Type: cmd.Type,
Settings: cmd.Settings, Settings: cmd.Settings,
NotifyOnce: cmd.NotifyOnce, SendReminder: cmd.SendReminder,
Frequency: frequency, Frequency: frequency,
Created: time.Now(), Created: time.Now(),
Updated: time.Now(), Updated: time.Now(),
IsDefault: cmd.IsDefault, IsDefault: cmd.IsDefault,
} }
if _, err = sess.MustCols("notify_once").Insert(alertNotification); err != nil { if _, err = sess.MustCols("send_reminder").Insert(alertNotification); err != nil {
return err return err
} }
...@@ -200,9 +200,9 @@ func UpdateAlertNotification(cmd *m.UpdateAlertNotificationCommand) error { ...@@ -200,9 +200,9 @@ func UpdateAlertNotification(cmd *m.UpdateAlertNotificationCommand) error {
current.Name = cmd.Name current.Name = cmd.Name
current.Type = cmd.Type current.Type = cmd.Type
current.IsDefault = cmd.IsDefault current.IsDefault = cmd.IsDefault
current.NotifyOnce = cmd.NotifyOnce current.SendReminder = cmd.SendReminder
if !current.NotifyOnce { if current.SendReminder {
if cmd.Frequency == "" { if cmd.Frequency == "" {
return m.ErrNotificationFrequencyNotFound return m.ErrNotificationFrequencyNotFound
} }
...@@ -215,7 +215,7 @@ func UpdateAlertNotification(cmd *m.UpdateAlertNotificationCommand) error { ...@@ -215,7 +215,7 @@ func UpdateAlertNotification(cmd *m.UpdateAlertNotificationCommand) error {
current.Frequency = frequency current.Frequency = frequency
} }
sess.UseBool("is_default", "notify_once") sess.UseBool("is_default", "send_reminder")
if affected, err := sess.ID(cmd.Id).Update(current); err != nil { if affected, err := sess.ID(cmd.Id).Update(current); err != nil {
return err return err
......
...@@ -23,13 +23,13 @@ func TestAlertNotificationSQLAccess(t *testing.T) { ...@@ -23,13 +23,13 @@ func TestAlertNotificationSQLAccess(t *testing.T) {
So(cmd.Result, ShouldBeNil) So(cmd.Result, ShouldBeNil)
}) })
Convey("Cannot save alert notifier with notitfyonce = false", func() { Convey("Cannot save alert notifier with send reminder = true", func() {
cmd := &m.CreateAlertNotificationCommand{ cmd := &m.CreateAlertNotificationCommand{
Name: "ops", Name: "ops",
Type: "email", Type: "email",
OrgId: 1, OrgId: 1,
NotifyOnce: false, SendReminder: true,
Settings: simplejson.New(), Settings: simplejson.New(),
} }
Convey("and missing frequency", func() { Convey("and missing frequency", func() {
...@@ -47,19 +47,19 @@ func TestAlertNotificationSQLAccess(t *testing.T) { ...@@ -47,19 +47,19 @@ func TestAlertNotificationSQLAccess(t *testing.T) {
Convey("Cannot update alert notifier with notitfyonce = false", func() { Convey("Cannot update alert notifier with notitfyonce = false", func() {
cmd := &m.CreateAlertNotificationCommand{ cmd := &m.CreateAlertNotificationCommand{
Name: "ops update", Name: "ops update",
Type: "email", Type: "email",
OrgId: 1, OrgId: 1,
NotifyOnce: true, SendReminder: false,
Settings: simplejson.New(), Settings: simplejson.New(),
} }
err := CreateAlertNotificationCommand(cmd) err := CreateAlertNotificationCommand(cmd)
So(err, ShouldBeNil) So(err, ShouldBeNil)
updateCmd := &m.UpdateAlertNotificationCommand{ updateCmd := &m.UpdateAlertNotificationCommand{
Id: cmd.Result.Id, Id: cmd.Result.Id,
NotifyOnce: false, SendReminder: true,
} }
Convey("and missing frequency", func() { Convey("and missing frequency", func() {
...@@ -71,18 +71,19 @@ func TestAlertNotificationSQLAccess(t *testing.T) { ...@@ -71,18 +71,19 @@ func TestAlertNotificationSQLAccess(t *testing.T) {
updateCmd.Frequency = "invalid duration" updateCmd.Frequency = "invalid duration"
err := UpdateAlertNotification(updateCmd) err := UpdateAlertNotification(updateCmd)
So(err, ShouldNotBeNil)
So(err.Error(), ShouldEqual, "time: invalid duration invalid duration") So(err.Error(), ShouldEqual, "time: invalid duration invalid duration")
}) })
}) })
Convey("Can save Alert Notification", func() { Convey("Can save Alert Notification", func() {
cmd := &m.CreateAlertNotificationCommand{ cmd := &m.CreateAlertNotificationCommand{
Name: "ops", Name: "ops",
Type: "email", Type: "email",
OrgId: 1, OrgId: 1,
NotifyOnce: true, SendReminder: true,
Frequency: "10s", Frequency: "10s",
Settings: simplejson.New(), Settings: simplejson.New(),
} }
err := CreateAlertNotificationCommand(cmd) err := CreateAlertNotificationCommand(cmd)
...@@ -98,13 +99,13 @@ func TestAlertNotificationSQLAccess(t *testing.T) { ...@@ -98,13 +99,13 @@ func TestAlertNotificationSQLAccess(t *testing.T) {
Convey("Can update alert notification", func() { Convey("Can update alert notification", func() {
newCmd := &m.UpdateAlertNotificationCommand{ newCmd := &m.UpdateAlertNotificationCommand{
Name: "NewName", Name: "NewName",
Type: "webhook", Type: "webhook",
OrgId: cmd.Result.OrgId, OrgId: cmd.Result.OrgId,
NotifyOnce: true, SendReminder: true,
Frequency: "10s", Frequency: "10s",
Settings: simplejson.New(), Settings: simplejson.New(),
Id: cmd.Result.Id, Id: cmd.Result.Id,
} }
err := UpdateAlertNotification(newCmd) err := UpdateAlertNotification(newCmd)
So(err, ShouldBeNil) So(err, ShouldBeNil)
...@@ -113,12 +114,12 @@ func TestAlertNotificationSQLAccess(t *testing.T) { ...@@ -113,12 +114,12 @@ func TestAlertNotificationSQLAccess(t *testing.T) {
}) })
Convey("Can search using an array of ids", func() { Convey("Can search using an array of ids", func() {
cmd1 := m.CreateAlertNotificationCommand{Name: "nagios", Type: "webhook", OrgId: 1, NotifyOnce: true, Frequency: "10s", Settings: simplejson.New()} cmd1 := m.CreateAlertNotificationCommand{Name: "nagios", Type: "webhook", OrgId: 1, SendReminder: true, Frequency: "10s", Settings: simplejson.New()}
cmd2 := m.CreateAlertNotificationCommand{Name: "slack", Type: "webhook", OrgId: 1, NotifyOnce: true, Frequency: "10s", Settings: simplejson.New()} cmd2 := m.CreateAlertNotificationCommand{Name: "slack", Type: "webhook", OrgId: 1, SendReminder: true, Frequency: "10s", Settings: simplejson.New()}
cmd3 := m.CreateAlertNotificationCommand{Name: "ops2", Type: "email", OrgId: 1, NotifyOnce: true, Frequency: "10s", Settings: simplejson.New()} cmd3 := m.CreateAlertNotificationCommand{Name: "ops2", Type: "email", OrgId: 1, SendReminder: true, Frequency: "10s", Settings: simplejson.New()}
cmd4 := m.CreateAlertNotificationCommand{IsDefault: true, Name: "default", Type: "email", OrgId: 1, NotifyOnce: true, Frequency: "10s", Settings: simplejson.New()} cmd4 := m.CreateAlertNotificationCommand{IsDefault: true, Name: "default", Type: "email", OrgId: 1, SendReminder: true, Frequency: "10s", Settings: simplejson.New()}
otherOrg := m.CreateAlertNotificationCommand{Name: "default", Type: "email", OrgId: 2, NotifyOnce: true, Frequency: "10s", Settings: simplejson.New()} otherOrg := m.CreateAlertNotificationCommand{Name: "default", Type: "email", OrgId: 2, SendReminder: true, Frequency: "10s", Settings: simplejson.New()}
So(CreateAlertNotificationCommand(&cmd1), ShouldBeNil) So(CreateAlertNotificationCommand(&cmd1), ShouldBeNil)
So(CreateAlertNotificationCommand(&cmd2), ShouldBeNil) So(CreateAlertNotificationCommand(&cmd2), ShouldBeNil)
......
...@@ -68,9 +68,10 @@ func addAlertMigrations(mg *Migrator) { ...@@ -68,9 +68,10 @@ func addAlertMigrations(mg *Migrator) {
mg.AddMigration("Add column frequency", NewAddColumnMigration(alert_notification, &Column{ mg.AddMigration("Add column frequency", NewAddColumnMigration(alert_notification, &Column{
Name: "frequency", Type: DB_BigInt, Nullable: true, Name: "frequency", Type: DB_BigInt, Nullable: true,
})) }))
mg.AddMigration("Add column notify_once", NewAddColumnMigration(alert_notification, &Column{ mg.AddMigration("Add column send_reminder", NewAddColumnMigration(alert_notification, &Column{
Name: "notify_once", Type: DB_Bool, Nullable: false, Default: "1", Name: "send_reminder", Type: DB_Bool, Nullable: true, Default: "0",
})) }))
mg.AddMigration("add index alert_notification org_id & name", NewAddIndexMigration(alert_notification, alert_notification.Indices[0])) mg.AddMigration("add index alert_notification org_id & name", NewAddIndexMigration(alert_notification, alert_notification.Indices[0]))
notification_journal := Table{ notification_journal := Table{
......
...@@ -11,7 +11,7 @@ export class AlertNotificationEditCtrl { ...@@ -11,7 +11,7 @@ export class AlertNotificationEditCtrl {
model: any; model: any;
defaults: any = { defaults: any = {
type: 'email', type: 'email',
notifyOnce: true, sendReminder: false,
frequency: '15m', frequency: '15m',
settings: { settings: {
httpMethod: 'POST', httpMethod: 'POST',
......
...@@ -34,14 +34,27 @@ ...@@ -34,14 +34,27 @@
</gf-form-switch> </gf-form-switch>
<gf-form-switch <gf-form-switch
class="gf-form" class="gf-form"
label="Notify once" label="Send reminder"
label-class="width-12" label-class="width-12"
checked="ctrl.model.notifyOnce" checked="ctrl.model.sendReminder"
tooltip="Choose to either notify on state change or at every interval"> tooltip="Choose to either notify on state change or at every interval">
</gf-form-switch> </gf-form-switch>
<div class="gf-form"> <div class="gf-form-inline">
<span class="gf-form-label width-12" ng-if="!ctrl.model.notifyOnce">Notify every</span> <div class="gf-form">
<input class="gf-form-input max-width-15" type="text" required ng-model="ctrl.model.frequency" required ng-if="!ctrl.model.notifyOnce"></input> <span class="gf-form-label width-12" ng-if="ctrl.model.sendReminder">Send reminder every</span>
<input
class="gf-form-input max-width-15"
type="text"
ng-model="ctrl.model.frequency"
ng-required="ctrl.model.sendReminder"
ng-if="ctrl.model.sendReminder"
spellcheck='false'
placeholder='15m'></input>
<info-popover mode="right-absolute">
Specify at what interval you want reminder's about this alerting beeing triggered.
Ex. 60s, 10m, 30m, 1h
</info-popover>
</div>
</div> </div>
</div> </div>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment