Commit 8f0e65a1 by bergquist

renames alert_notifications -> notifiers

parent 21fff415
# # config file version # # config file version
apiVersion: 1 apiVersion: 1
# alert_notifications: # notifiers:
# - name: default-slack-temp # - name: default-slack-temp
# type: slack # type: slack
# org_name: Main Org. # org_name: Main Org.
...@@ -19,7 +19,7 @@ apiVersion: 1 ...@@ -19,7 +19,7 @@ apiVersion: 1
# is_default: false # is_default: false
# settings: # settings:
# addresses: example11111@example.com # addresses: example11111@example.com
# delete_alert_notifications: # delete_notifiers:
# - name: default-slack-temp # - name: default-slack-temp
# org_name: Main Org. # org_name: Main Org.
# uid: notifier1 # uid: notifier1
\ No newline at end of file
...@@ -234,11 +234,11 @@ By default Grafana will delete dashboards in the database if the file is removed ...@@ -234,11 +234,11 @@ By default Grafana will delete dashboards in the database if the file is removed
## Alert Notification Channels ## Alert Notification Channels
Alert Notification Channels can be provisionned by adding one or more yaml config files in the [`provisioning/alert_notifications`](/installation/configuration/#provisioning) directory. Alert Notification Channels can be provisionned by adding one or more yaml config files in the [`provisioning/notifiers`](/installation/configuration/#provisioning) directory.
Each config file can contain the following top-level fields: Each config file can contain the following top-level fields:
- `alert_notifications`, a list of alert notifications that will be added or updated during start up. If the notification channel already exists, Grafana will update it to match the configuration file. - `notifiers`, a list of alert notifications that will be added or updated during start up. If the notification channel already exists, Grafana will update it to match the configuration file.
- `delete_alert_notifications`, a list of alert notifications to be deleted before before inserting/updating those in the `alert_notifications` list. - `delete_notifiers`, a list of alert notifications to be deleted before before inserting/updating those in the `notifiers` list.
Provisionning looks up alert notifications by name, and will update any existing notification with the provided name. Provisionning looks up alert notifications by name, and will update any existing notification with the provided name.
...@@ -264,7 +264,7 @@ By default, exporting a dashboard as JSON will use a sequential identifier to re ...@@ -264,7 +264,7 @@ By default, exporting a dashboard as JSON will use a sequential identifier to re
### Example Alert Notification Channels Config File ### Example Alert Notification Channels Config File
```yaml ```yaml
alert_notifications: notifiers:
- name: notification-channel-1 - name: notification-channel-1
type: slack type: slack
uid: notifier1 uid: notifier1
...@@ -281,7 +281,7 @@ alert_notifications: ...@@ -281,7 +281,7 @@ alert_notifications:
uploadImage: true uploadImage: true
url: https://slack.com url: https://slack.com
delete_alert_notifications: delete_notifiers:
- name: notification-channel-1 - name: notification-channel-1
uid: notifier1 uid: notifier1
# either # either
......
package alert_notifications package notifiers
import ( import (
"errors" "errors"
...@@ -13,7 +13,7 @@ var ( ...@@ -13,7 +13,7 @@ var (
) )
func Provision(configDirectory string) error { func Provision(configDirectory string) error {
dc := newNotificationProvisioner(log.New("provisioning.alert_notifications")) dc := newNotificationProvisioner(log.New("provisioning.notifiers"))
return dc.applyChanges(configDirectory) return dc.applyChanges(configDirectory)
} }
...@@ -54,6 +54,7 @@ func (dc *NotificationProvisioner) deleteNotifications(notificationToDelete []*d ...@@ -54,6 +54,7 @@ func (dc *NotificationProvisioner) deleteNotifications(notificationToDelete []*d
} else if notification.OrgId < 0 { } else if notification.OrgId < 0 {
notification.OrgId = 1 notification.OrgId = 1
} }
getNotification := &models.GetAlertNotificationsWithUidQuery{Uid: notification.Uid, OrgId: notification.OrgId} getNotification := &models.GetAlertNotificationsWithUidQuery{Uid: notification.Uid, OrgId: notification.OrgId}
if err := bus.Dispatch(getNotification); err != nil { if err := bus.Dispatch(getNotification); err != nil {
...@@ -103,6 +104,7 @@ func (dc *NotificationProvisioner) mergeNotifications(notificationToMerge []*not ...@@ -103,6 +104,7 @@ func (dc *NotificationProvisioner) mergeNotifications(notificationToMerge []*not
Frequency: notification.Frequency, Frequency: notification.Frequency,
SendReminder: notification.SendReminder, SendReminder: notification.SendReminder,
} }
if err := bus.Dispatch(insertCmd); err != nil { if err := bus.Dispatch(insertCmd); err != nil {
return err return err
} }
...@@ -119,6 +121,7 @@ func (dc *NotificationProvisioner) mergeNotifications(notificationToMerge []*not ...@@ -119,6 +121,7 @@ func (dc *NotificationProvisioner) mergeNotifications(notificationToMerge []*not
Frequency: notification.Frequency, Frequency: notification.Frequency,
SendReminder: notification.SendReminder, SendReminder: notification.SendReminder,
} }
if err := bus.Dispatch(updateCmd); err != nil { if err := bus.Dispatch(updateCmd); err != nil {
return err return err
} }
......
package alert_notifications package notifiers
import ( import (
"fmt" "fmt"
...@@ -94,8 +94,8 @@ func checkOrgIdAndOrgName(notifications []*notificationsAsConfig) { ...@@ -94,8 +94,8 @@ func checkOrgIdAndOrgName(notifications []*notificationsAsConfig) {
} }
} }
} }
} }
func validateRequiredField(notifications []*notificationsAsConfig) error { func validateRequiredField(notifications []*notificationsAsConfig) error {
for i := range notifications { for i := range notifications {
var errStrings []string var errStrings []string
...@@ -106,6 +106,7 @@ func validateRequiredField(notifications []*notificationsAsConfig) error { ...@@ -106,6 +106,7 @@ func validateRequiredField(notifications []*notificationsAsConfig) error {
fmt.Sprintf("Added alert notification item %d in configuration doesn't contain required field name", index+1), fmt.Sprintf("Added alert notification item %d in configuration doesn't contain required field name", index+1),
) )
} }
if notification.Uid == "" { if notification.Uid == "" {
errStrings = append( errStrings = append(
errStrings, errStrings,
...@@ -121,6 +122,7 @@ func validateRequiredField(notifications []*notificationsAsConfig) error { ...@@ -121,6 +122,7 @@ func validateRequiredField(notifications []*notificationsAsConfig) error {
fmt.Sprintf("Deleted alert notification item %d in configuration doesn't contain required field name", index+1), fmt.Sprintf("Deleted alert notification item %d in configuration doesn't contain required field name", index+1),
) )
} }
if notification.Uid == "" { if notification.Uid == "" {
errStrings = append( errStrings = append(
errStrings, errStrings,
...@@ -128,10 +130,12 @@ func validateRequiredField(notifications []*notificationsAsConfig) error { ...@@ -128,10 +130,12 @@ func validateRequiredField(notifications []*notificationsAsConfig) error {
) )
} }
} }
if len(errStrings) != 0 { if len(errStrings) != 0 {
return fmt.Errorf(strings.Join(errStrings, "\n")) return fmt.Errorf(strings.Join(errStrings, "\n"))
} }
} }
return nil return nil
} }
...@@ -148,6 +152,7 @@ func validateNotifications(notifications []*notificationsAsConfig) error { ...@@ -148,6 +152,7 @@ func validateNotifications(notifications []*notificationsAsConfig) error {
Settings: notification.SettingsToJson(), Settings: notification.SettingsToJson(),
Type: notification.Type, Type: notification.Type,
}) })
if err != nil { if err != nil {
return err return err
} }
......
package alert_notifications package notifiers
import ( import (
"testing" "testing"
...@@ -35,11 +35,13 @@ func TestNotificationAsConfig(t *testing.T) { ...@@ -35,11 +35,13 @@ func TestNotificationAsConfig(t *testing.T) {
Name: "slack", Name: "slack",
Factory: notifiers.NewSlackNotifier, Factory: notifiers.NewSlackNotifier,
}) })
alerting.RegisterNotifier(&alerting.NotifierPlugin{ alerting.RegisterNotifier(&alerting.NotifierPlugin{
Type: "email", Type: "email",
Name: "email", Name: "email",
Factory: notifiers.NewEmailNotifier, 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")}
cfg, err := cfgProvifer.readConfig(correct_properties) cfg, err := cfgProvifer.readConfig(correct_properties)
...@@ -264,6 +266,7 @@ func TestNotificationAsConfig(t *testing.T) { ...@@ -264,6 +266,7 @@ func TestNotificationAsConfig(t *testing.T) {
So(errString, ShouldContainSubstring, "Added alert notification item 1 in configuration doesn't contain required field name") So(errString, ShouldContainSubstring, "Added alert notification item 1 in configuration doesn't contain required field name")
So(errString, ShouldContainSubstring, "Added alert notification item 2 in configuration doesn't contain required field uid") So(errString, ShouldContainSubstring, "Added alert notification item 2 in configuration doesn't contain required field uid")
}) })
Convey("Empty yaml file", func() { Convey("Empty yaml file", func() {
Convey("should have not changed repo", func() { Convey("should have not changed repo", func() {
dc := newNotificationProvisioner(logger) dc := newNotificationProvisioner(logger)
...@@ -277,11 +280,13 @@ func TestNotificationAsConfig(t *testing.T) { ...@@ -277,11 +280,13 @@ func TestNotificationAsConfig(t *testing.T) {
So(notificationsQuery.Result, ShouldBeEmpty) So(notificationsQuery.Result, ShouldBeEmpty)
}) })
}) })
Convey("Broken yaml should return error", func() { Convey("Broken yaml should return error", func() {
reader := &configReader{log: log.New("test logger")} reader := &configReader{log: log.New("test logger")}
_, err := reader.readConfig(brokenYaml) _, err := reader.readConfig(brokenYaml)
So(err, ShouldNotBeNil) So(err, ShouldNotBeNil)
}) })
Convey("Skip invalid directory", func() { Convey("Skip invalid directory", func() {
cfgProvifer := &configReader{log: log.New("test logger")} cfgProvifer := &configReader{log: log.New("test logger")}
cfg, err := cfgProvifer.readConfig(emptyFolder) cfg, err := cfgProvifer.readConfig(emptyFolder)
...@@ -290,6 +295,7 @@ func TestNotificationAsConfig(t *testing.T) { ...@@ -290,6 +295,7 @@ func TestNotificationAsConfig(t *testing.T) {
} }
So(len(cfg), ShouldEqual, 0) So(len(cfg), ShouldEqual, 0)
}) })
Convey("Unknown notifier should return error", func() { Convey("Unknown notifier should return error", func() {
cfgProvifer := &configReader{log: log.New("test logger")} cfgProvifer := &configReader{log: log.New("test logger")}
_, err := cfgProvifer.readConfig(unknownNotifier) _, err := cfgProvifer.readConfig(unknownNotifier)
...@@ -303,6 +309,5 @@ func TestNotificationAsConfig(t *testing.T) { ...@@ -303,6 +309,5 @@ func TestNotificationAsConfig(t *testing.T) {
So(err, ShouldNotBeNil) So(err, ShouldNotBeNil)
So(err.Error(), ShouldEqual, "Alert validation error: Could not find url property in settings") So(err.Error(), ShouldEqual, "Alert validation error: Could not find url property in settings")
}) })
}) })
} }
alert_notifications: notifiers:
- name: notification-channel-1 - name: notification-channel-1
type: slack type: slack
org_id: 2 org_id: 2
......
alert_notifications: notifiers:
- name: default-notification-create - name: default-notification-create
type: email type: email
uid: notifier2 uid: notifier2
...@@ -6,7 +6,7 @@ alert_notifications: ...@@ -6,7 +6,7 @@ alert_notifications:
addresses: example@example.com addresses: example@example.com
org_name: Main Org. 2 org_name: Main Org. 2
is_default: false is_default: false
delete_alert_notifications: delete_notifiers:
- name: default-notification-delete - name: default-notification-delete
org_name: Main Org. 2 org_name: Main Org. 2
uid: notifier2 uid: notifier2
\ No newline at end of file
alert_notifications: notifiers:
- name: default-slack-notification - name: default-slack-notification
type: slack type: slack
uid: notifier1 uid: notifier1
...@@ -29,7 +29,7 @@ alert_notifications: ...@@ -29,7 +29,7 @@ alert_notifications:
uid: "notifier4" uid: "notifier4"
settings: settings:
addresses: example@exmaple.com addresses: example@exmaple.com
delete_alert_notifications: delete_notifiers:
- name: default-slack-notification - name: default-slack-notification
org_id: 2 org_id: 2
uid: notifier1 uid: notifier1
......
alert_notifications: notifiers:
- name: first-default - name: first-default
type: slack type: slack
uid: notifier1 uid: notifier1
......
alert_notifications: notifiers:
- name: second-default - name: second-default
type: email type: email
uid: notifier2 uid: notifier2
......
alert_notifications: notifiers:
- name: slack-notification-without-url-in-settings - name: slack-notification-without-url-in-settings
type: slack type: slack
org_id: 2 org_id: 2
......
alert_notifications: notifiers:
- type: slack - type: slack
org_id: 2 org_id: 2
uid: no-name_added-notification uid: no-name_added-notification
...@@ -15,7 +15,7 @@ alert_notifications: ...@@ -15,7 +15,7 @@ alert_notifications:
recipient: "XXX" recipient: "XXX"
token: "xoxb" token: "xoxb"
uploadImage: true uploadImage: true
delete_alert_notifications: delete_notifiers:
- name: no-uid - name: no-uid
type: slack type: slack
org_id: 2 org_id: 2
......
alert_notifications: notifiers:
- name: unknown-notifier - name: unknown-notifier
type: nonexisting type: nonexisting
uid: notifier1 uid: notifier1
\ No newline at end of file
package alert_notifications package notifiers
import "github.com/grafana/grafana/pkg/components/simplejson" 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:"notifiers" yaml:"notifiers"`
DeleteNotifications []*deleteNotificationConfig `json:"delete_alert_notifications" yaml:"delete_alert_notifications"` DeleteNotifications []*deleteNotificationConfig `json:"delete_notifiers" yaml:"delete_notifiers"`
} }
type deleteNotificationConfig struct { type deleteNotificationConfig struct {
......
...@@ -6,7 +6,7 @@ import ( ...@@ -6,7 +6,7 @@ import (
"path" "path"
"github.com/grafana/grafana/pkg/registry" "github.com/grafana/grafana/pkg/registry"
"github.com/grafana/grafana/pkg/services/provisioning/alert_notifications" "github.com/grafana/grafana/pkg/services/provisioning/notifiers"
"github.com/grafana/grafana/pkg/services/provisioning/dashboards" "github.com/grafana/grafana/pkg/services/provisioning/dashboards"
"github.com/grafana/grafana/pkg/services/provisioning/datasources" "github.com/grafana/grafana/pkg/services/provisioning/datasources"
"github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/setting"
...@@ -26,8 +26,8 @@ func (ps *ProvisioningService) Init() error { ...@@ -26,8 +26,8 @@ func (ps *ProvisioningService) Init() error {
return fmt.Errorf("Datasource provisioning error: %v", err) return fmt.Errorf("Datasource provisioning error: %v", err)
} }
alertNotificationsPath := path.Join(ps.Cfg.ProvisioningPath, "alert_notifications") alertNotificationsPath := path.Join(ps.Cfg.ProvisioningPath, "notifiers")
if err := alert_notifications.Provision(alertNotificationsPath); err != nil { if err := notifiers.Provision(alertNotificationsPath); err != nil {
return fmt.Errorf("Alert notification provisioning error: %v", err) return fmt.Errorf("Alert notification provisioning error: %v", err)
} }
......
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