Instantiating notifiers from config before using

This commit is contained in:
Pavel Bakulev 2018-12-05 17:42:53 +02:00
parent e1b87fc597
commit 5c10a897f8
12 changed files with 90 additions and 36 deletions

View File

@ -1,20 +1,23 @@
# # config file version # # config file version
apiVersion: 1 apiVersion: 1
# alert_notifications: alert_notifications:
# - name: default-slack - name: default-slack
# type: slack type: slack
# org_id: 1 org_id: 1
# is_default: true is_default: true
# settings: settings:
# recipient: "XXX" recipient: "XXX"
# token: "xoxb" token: "xoxb"
# uploadImage: true uploadImage: true
# - name: default-email url: https://slack.com
# type: email - name: default-email
# org_id: 1 type: email
# is_default: false org_id: 1
# delete_alert_notifications: is_default: false
# - name: default-slack settings:
# org_id: 1 addresses: example@example.com
# - name: default-email delete_alert_notifications:
- name: default-slack
org_id: 1
- name: default-email

View File

@ -278,6 +278,7 @@ alert_notifications:
recipient: "XXX" recipient: "XXX"
token: "xoxb" token: "xoxb"
uploadImage: true uploadImage: true
url: https://slack.com
delete_alert_notifications: delete_alert_notifications:
- name: notification-channel-1 - name: notification-channel-1

View File

@ -4,7 +4,6 @@ import (
"errors" "errors"
"github.com/grafana/grafana/pkg/bus" "github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/log" "github.com/grafana/grafana/pkg/log"
"github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/models"
) )
@ -92,20 +91,13 @@ func (dc *NotificationProvisioner) mergeNotifications(notificationToMerge []*not
return err return err
} }
settings := simplejson.New()
if len(notification.Settings) > 0 {
for k, v := range notification.Settings {
settings.Set(k, v)
}
}
if cmd.Result == nil { if cmd.Result == nil {
dc.log.Info("Inserting alert notification from configuration ", "name", notification.Name) dc.log.Info("Inserting alert notification from configuration ", "name", notification.Name)
insertCmd := &models.CreateAlertNotificationCommand{ insertCmd := &models.CreateAlertNotificationCommand{
Name: notification.Name, Name: notification.Name,
Type: notification.Type, Type: notification.Type,
IsDefault: notification.IsDefault, IsDefault: notification.IsDefault,
Settings: settings, Settings: notification.SettingsToJson(),
OrgId: notification.OrgId, OrgId: notification.OrgId,
} }
if err := bus.Dispatch(insertCmd); err != nil { if err := bus.Dispatch(insertCmd); err != nil {
@ -118,7 +110,7 @@ func (dc *NotificationProvisioner) mergeNotifications(notificationToMerge []*not
Name: notification.Name, Name: notification.Name,
Type: notification.Type, Type: notification.Type,
IsDefault: notification.IsDefault, IsDefault: notification.IsDefault,
Settings: settings, Settings: notification.SettingsToJson(),
OrgId: notification.OrgId, OrgId: notification.OrgId,
} }
if err := bus.Dispatch(updateCmd); err != nil { if err := bus.Dispatch(updateCmd); err != nil {

View File

@ -7,6 +7,7 @@ import (
"strings" "strings"
"github.com/grafana/grafana/pkg/log" "github.com/grafana/grafana/pkg/log"
m "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting" "github.com/grafana/grafana/pkg/services/alerting"
"gopkg.in/yaml.v2" "gopkg.in/yaml.v2"
) )
@ -109,10 +110,17 @@ func validateType(notifications []*notificationsAsConfig) error {
for _, notifier := range notifierTypes { for _, notifier := range notifierTypes {
if notifier.Type == notification.Type { if notifier.Type == notification.Type {
foundNotifier = true foundNotifier = true
_, notifierError := notifier.Factory(&m.AlertNotification{
Name: notification.Name,
Settings: notification.SettingsToJson(),
Type: notification.Type,
})
if notifierError != nil {
return notifierError
}
break break
} }
} }
if !foundNotifier { if !foundNotifier {
return ErrInvalidNotifierType return ErrInvalidNotifierType
} }

View File

@ -7,6 +7,7 @@ import (
"github.com/grafana/grafana/pkg/log" "github.com/grafana/grafana/pkg/log"
"github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting" "github.com/grafana/grafana/pkg/services/alerting"
"github.com/grafana/grafana/pkg/services/alerting/notifiers"
. "github.com/smartystreets/goconvey/convey" . "github.com/smartystreets/goconvey/convey"
) )
@ -14,6 +15,7 @@ var (
logger = log.New("fake.log") logger = log.New("fake.log")
correct_properties = "./test-configs/correct-properties" correct_properties = "./test-configs/correct-properties"
incorrect_properties = "./test-configs/incorrect-properties"
correct_properties_with_orgName = "./test-configs/correct-properties-with-orgName" correct_properties_with_orgName = "./test-configs/correct-properties-with-orgName"
brokenYaml = "./test-configs/broken-yaml" brokenYaml = "./test-configs/broken-yaml"
doubleNotificationsConfig = "./test-configs/double-default" doubleNotificationsConfig = "./test-configs/double-default"
@ -36,12 +38,14 @@ func TestNotificationAsConfig(t *testing.T) {
bus.AddHandler("test", mockGetOrg) bus.AddHandler("test", mockGetOrg)
alerting.RegisterNotifier(&alerting.NotifierPlugin{ alerting.RegisterNotifier(&alerting.NotifierPlugin{
Type: "slack", Type: "slack",
Name: "slack", Name: "slack",
Factory: notifiers.NewSlackNotifier,
}) })
alerting.RegisterNotifier(&alerting.NotifierPlugin{ alerting.RegisterNotifier(&alerting.NotifierPlugin{
Type: "email", Type: "email",
Name: "email", Name: "email",
Factory: notifiers.NewEmailNotifier,
}) })
Convey("Can read correct properties", func() { Convey("Can read correct properties", func() {
cfgProvifer := &configReader{log: log.New("test logger")} cfgProvifer := &configReader{log: log.New("test logger")}
@ -61,7 +65,7 @@ func TestNotificationAsConfig(t *testing.T) {
So(nt.OrgId, ShouldEqual, 2) So(nt.OrgId, ShouldEqual, 2)
So(nt.IsDefault, ShouldBeTrue) So(nt.IsDefault, ShouldBeTrue)
So(nt.Settings, ShouldResemble, map[string]interface{}{ So(nt.Settings, ShouldResemble, map[string]interface{}{
"recipient": "XXX", "token": "xoxb", "uploadImage": true, "recipient": "XXX", "token": "xoxb", "uploadImage": true, "url": "https://slack.com",
}) })
nt = nts[1] nt = nts[1]
@ -218,6 +222,13 @@ func TestNotificationAsConfig(t *testing.T) {
So(err, ShouldEqual, ErrInvalidNotifierType) So(err, ShouldEqual, ErrInvalidNotifierType)
}) })
Convey("Read incorrect properties", func() {
cfgProvifer := &configReader{log: log.New("test logger")}
_, err := cfgProvifer.readConfig(incorrect_properties)
So(err, ShouldNotBeNil)
So(err.Error(), ShouldEqual, "Alert validation error: Could not find url property in settings")
})
}) })
} }

View File

@ -7,8 +7,11 @@ alert_notifications:
recipient: "XXX" recipient: "XXX"
token: "xoxb" token: "xoxb"
uploadImage: true uploadImage: true
url: https://slack.com
- name: another-not-default-notification - name: another-not-default-notification
type: email type: email
settings:
addresses: example@example.com
org_name: Main Org. 2 org_name: Main Org. 2
is_default: false is_default: false
delete_alert_notifications: delete_alert_notifications:

View File

@ -7,16 +7,23 @@ alert_notifications:
recipient: "XXX" recipient: "XXX"
token: "xoxb" token: "xoxb"
uploadImage: true uploadImage: true
url: https://slack.com
- name: another-not-default-notification - name: another-not-default-notification
type: email type: email
settings:
addresses: example@exmaple.com
org_id: 3 org_id: 3
is_default: false is_default: false
- name: check-unset-is_default-is-false - name: check-unset-is_default-is-false
type: slack type: slack
org_id: 3 org_id: 3
settings:
url: https://slack.com
- name: Added notification with whitespaces in name - name: Added notification with whitespaces in name
type: email type: email
org_id: 3 org_id: 3
settings:
addresses: example@exmaple.com
delete_alert_notifications: delete_alert_notifications:
- name: default-slack-notification - name: default-slack-notification
org_id: 2 org_id: 2

View File

@ -1,4 +1,6 @@
alert_notifications: alert_notifications:
- name: first-default - name: first-default
type: slack type: slack
is_default: true is_default: true
settings:
url: https://slack.com

View File

@ -1,4 +1,6 @@
alert_notifications: alert_notifications:
- name: second-default - name: second-default
type: email type: email
is_default: true is_default: true
settings:
addresses: example@example.com

View File

@ -0,0 +1,9 @@
alert_notifications:
- name: slack-notification-without-url-in-settings
type: slack
org_id: 2
is_default: true
settings:
recipient: "XXX"
token: "xoxb"
uploadImage: true

View File

@ -1,5 +1,9 @@
alert_notifications: alert_notifications:
- name: channel1 - name: channel1
type: slack type: slack
settings:
url: http://slack.com
- name: channel2 - name: channel2
type: email type: email
settings:
addresses: example@example.com

View File

@ -1,5 +1,7 @@
package alert_notifications package alert_notifications
import "github.com/grafana/grafana/pkg/components/simplejson"
type notificationsAsConfig struct { type notificationsAsConfig struct {
Notifications []*notificationFromConfig `json:"alert_notifications" yaml:"alert_notifications"` Notifications []*notificationFromConfig `json:"alert_notifications" yaml:"alert_notifications"`
DeleteNotifications []*deleteNotificationConfig `json:"delete_alert_notifications" yaml:"delete_alert_notifications"` DeleteNotifications []*deleteNotificationConfig `json:"delete_alert_notifications" yaml:"delete_alert_notifications"`
@ -19,3 +21,13 @@ type notificationFromConfig struct {
IsDefault bool `json:"is_default" yaml:"is_default"` IsDefault bool `json:"is_default" yaml:"is_default"`
Settings map[string]interface{} `json:"settings" yaml:"settings"` Settings map[string]interface{} `json:"settings" yaml:"settings"`
} }
func (notification notificationFromConfig) SettingsToJson() *simplejson.Json {
settings := simplejson.New()
if len(notification.Settings) > 0 {
for k, v := range notification.Settings {
settings.Set(k, v)
}
}
return settings
}