From 48aa173f67c3c8525985532b8d3dc4a1cf44f57b Mon Sep 17 00:00:00 2001
From: bergquist 
Date: Mon, 28 Jan 2019 13:20:29 +0100
Subject: [PATCH 15/21] support both uid and id for showing/removing notifiers
---
 public/app/features/alerting/AlertTabCtrl.ts  | 21 ++++++++++++++-----
 .../features/alerting/partials/alert_tab.html |  2 +-
 2 files changed, 17 insertions(+), 6 deletions(-)
diff --git a/public/app/features/alerting/AlertTabCtrl.ts b/public/app/features/alerting/AlertTabCtrl.ts
index fe27f45e0f3..12943805c2c 100644
--- a/public/app/features/alerting/AlertTabCtrl.ts
+++ b/public/app/features/alerting/AlertTabCtrl.ts
@@ -142,7 +142,9 @@ export class AlertTabCtrl {
       isDefault: false,
       uid: model.uid
     });
-    if (!_.find(this.alert.notifications, { id: model.id})) {
+
+    // avoid duplicates using both id and uid to be backwards compatible.
+    if (!_.find(this.alert.notifications, n => n.id === model.id || n.uid === model.uid)) {
       this.alert.notifications.push({ uid: model.uid });
     }
 
@@ -152,9 +154,11 @@ export class AlertTabCtrl {
     this.addNotificationSegment.fake = true;
   }
 
-  removeNotification(deleteUid) {
-    _.remove(this.alert.notifications, { uid: deleteUid});
-    _.remove(this.alertNotifications, { uid: deleteUid});
+  removeNotification(an) {
+    // remove notifiers refeered to by id and uid to support notifiers added
+    // before and after we added support for uid
+    _.remove(this.alert.notifications, n =>  n.uid === an.uid || n.id === an.id);
+    _.remove(this.alertNotifications, n =>  n.uid === an.uid || n.id === an.id);
   }
 
   initModel() {
@@ -190,7 +194,14 @@ export class AlertTabCtrl {
     ThresholdMapper.alertToGraphThresholds(this.panel);
 
     for (const addedNotification of alert.notifications) {
-      const model = _.find(this.notifications, { id: addedNotification.id });
+      // lookup notifier type by uid
+      let model = _.find(this.notifications, { uid: addedNotification.uid });
+
+      // fallback to using id if uid is missing
+      if (!model) {
+        model = _.find(this.notifications, { id: addedNotification.id });
+      }
+
       if (model && model.isDefault === false) {
         model.iconClass = this.getNotificationIcon(model.type);
         this.alertNotifications.push(model);
diff --git a/public/app/features/alerting/partials/alert_tab.html b/public/app/features/alerting/partials/alert_tab.html
index 27518a1e44b..b99859fd847 100644
--- a/public/app/features/alerting/partials/alert_tab.html
+++ b/public/app/features/alerting/partials/alert_tab.html
@@ -135,7 +135,7 @@
         
           
              {{nc.name}} 
-            
+            
           
         
         
From 935da14f7d1ccc9d9223f5fee117ff09247f9999 Mon Sep 17 00:00:00 2001
From: bergquist 
Date: Mon, 28 Jan 2019 15:27:02 +0100
Subject: [PATCH 16/21] tab/spaces formatting
---
 pkg/services/alerting/rule_test.go | 28 ++++++++++++++--------------
 1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/pkg/services/alerting/rule_test.go b/pkg/services/alerting/rule_test.go
index 7e8af888338..f0c7ea0c9d6 100644
--- a/pkg/services/alerting/rule_test.go
+++ b/pkg/services/alerting/rule_test.go
@@ -77,13 +77,13 @@ func TestAlertRuleModel(t *testing.T) {
 					"noDataMode": "critical",
 					"enabled": true,
 					"frequency": "60s",
-			"conditions": [
-			{
-				"type": "test",
-				"prop": 123
+					"conditions": [
+						{
+							"type": "test",
+							"prop": 123
 						}
-			],
-			"notifications": [
+					],
+					"notifications": [
 						{"id": 1},
 						{"uid": "notifier2"}
 					]
@@ -123,8 +123,8 @@ func TestAlertRuleModel(t *testing.T) {
 				"noDataMode": "critical",
 				"enabled": true,
 				"frequency": "0s",
-        		"conditions": [ { "type": "test", "prop": 123 } ],
-        		"notifications": []
+				"conditions": [ { "type": "test", "prop": 123 } ],
+				"notifications": []
 			}`
 
 			alertJSON, jsonErr := simplejson.NewJson([]byte(json))
@@ -153,13 +153,13 @@ func TestAlertRuleModel(t *testing.T) {
 				"noDataMode": "critical",
 				"enabled": true,
 				"frequency": "60s",
-        "conditions": [
-          {
-            "type": "test",
-            "prop": 123
+				"conditions": [
+					{
+						"type": "test",
+						"prop": 123
 					}
-        ],
-        "notifications": [
+				],
+				"notifications": [
 					{"not_id_uid": "1134"}
 				]
 			}
From 21fff415ed6dc405435e83c8a214926f61850af9 Mon Sep 17 00:00:00 2001
From: bergquist 
Date: Mon, 28 Jan 2019 15:37:52 +0100
Subject: [PATCH 17/21] removes unnessecary db request
---
 pkg/services/alerting/extractor_test.go | 2 --
 pkg/services/alerting/rule_test.go      | 5 +----
 2 files changed, 1 insertion(+), 6 deletions(-)
diff --git a/pkg/services/alerting/extractor_test.go b/pkg/services/alerting/extractor_test.go
index 66adf951269..9c689fec921 100644
--- a/pkg/services/alerting/extractor_test.go
+++ b/pkg/services/alerting/extractor_test.go
@@ -200,8 +200,6 @@ func TestAlertRuleExtraction(t *testing.T) {
 
 		Convey("Alert notifications are in DB", func() {
 			sqlstore.InitTestDB(t)
-			err := sqlstore.CreateOrg(&m.CreateOrgCommand{Name: "Main Org."})
-			So(err, ShouldBeNil)
 			firstNotification := m.CreateAlertNotificationCommand{Uid: "notifier1", OrgId: 1, Name: "1"}
 			err = sqlstore.CreateAlertNotificationCommand(&firstNotification)
 			So(err, ShouldBeNil)
diff --git a/pkg/services/alerting/rule_test.go b/pkg/services/alerting/rule_test.go
index f0c7ea0c9d6..f4172a57e74 100644
--- a/pkg/services/alerting/rule_test.go
+++ b/pkg/services/alerting/rule_test.go
@@ -59,10 +59,8 @@ func TestAlertRuleModel(t *testing.T) {
 		})
 
 		Convey("can construct alert rule model", func() {
-			err := sqlstore.CreateOrg(&m.CreateOrgCommand{Name: "Main Org."})
-			So(err, ShouldBeNil)
 			firstNotification := m.CreateAlertNotificationCommand{OrgId: 1, Name: "1"}
-			err = sqlstore.CreateAlertNotificationCommand(&firstNotification)
+			err := sqlstore.CreateAlertNotificationCommand(&firstNotification)
 			So(err, ShouldBeNil)
 			secondNotification := m.CreateAlertNotificationCommand{Uid: "notifier2", OrgId: 1, Name: "2"}
 			err = sqlstore.CreateAlertNotificationCommand(&secondNotification)
@@ -182,6 +180,5 @@ func TestAlertRuleModel(t *testing.T) {
 			So(err, ShouldNotBeNil)
 			So(err.Error(), ShouldEqual, "Alert validation error: Neither id nor uid is specified, type assertion to string failed AlertId: 1 PanelId: 1 DashboardId: 1")
 		})
-
 	})
 }
From 8f0e65a150f71e187aaf8d51dd7d4d99b54b8897 Mon Sep 17 00:00:00 2001
From: bergquist 
Date: Mon, 28 Jan 2019 20:39:09 +0100
Subject: [PATCH 18/21] renames alert_notifications -> notifiers
---
 .../{alert_notifications => notifiers}/sample.yaml     |  4 ++--
 docs/sources/administration/provisioning.md            | 10 +++++-----
 .../alert_notifications.go                             |  7 +++++--
 .../config_reader.go                                   |  9 +++++++--
 .../config_reader_test.go                              |  9 +++++++--
 .../test-configs/broken-yaml/broken.yaml               |  2 +-
 .../test-configs/broken-yaml/not.yaml.text             |  0
 .../correct-properties-with-orgName.yaml               |  4 ++--
 .../correct-properties/correct-properties.yaml         |  4 ++--
 .../test-configs/double-default/default-1.yml          |  2 +-
 .../test-configs/double-default/default-2.yaml         |  2 +-
 .../test-configs/empty/empty.yaml                      |  0
 .../test-configs/empty_folder/.gitignore               |  0
 .../incorrect-settings/incorrect-settings.yaml         |  2 +-
 .../no-required-fields/no-required-fields.yaml         |  4 ++--
 .../two-notifications/two-notifications.yaml           |  2 +-
 .../test-configs/unknown-notifier/notification.yaml    |  2 +-
 .../{alert_notifications => notifiers}/types.go        |  6 +++---
 pkg/services/provisioning/provisioning.go              |  6 +++---
 19 files changed, 44 insertions(+), 31 deletions(-)
 rename conf/provisioning/{alert_notifications => notifiers}/sample.yaml (87%)
 rename pkg/services/provisioning/{alert_notifications => notifiers}/alert_notifications.go (98%)
 rename pkg/services/provisioning/{alert_notifications => notifiers}/config_reader.go (99%)
 rename pkg/services/provisioning/{alert_notifications => notifiers}/config_reader_test.go (99%)
 rename pkg/services/provisioning/{alert_notifications => notifiers}/test-configs/broken-yaml/broken.yaml (76%)
 rename pkg/services/provisioning/{alert_notifications => notifiers}/test-configs/broken-yaml/not.yaml.text (100%)
 rename pkg/services/provisioning/{alert_notifications => notifiers}/test-configs/correct-properties-with-orgName/correct-properties-with-orgName.yaml (78%)
 rename pkg/services/provisioning/{alert_notifications => notifiers}/test-configs/correct-properties/correct-properties.yaml (93%)
 rename pkg/services/provisioning/{alert_notifications => notifiers}/test-configs/double-default/default-1.yml (65%)
 rename pkg/services/provisioning/{alert_notifications => notifiers}/test-configs/double-default/default-2.yaml (62%)
 rename pkg/services/provisioning/{alert_notifications => notifiers}/test-configs/empty/empty.yaml (100%)
 rename pkg/services/provisioning/{alert_notifications => notifiers}/test-configs/empty_folder/.gitignore (100%)
 rename pkg/services/provisioning/{alert_notifications => notifiers}/test-configs/incorrect-settings/incorrect-settings.yaml (80%)
 rename pkg/services/provisioning/{alert_notifications => notifiers}/test-configs/no-required-fields/no-required-fields.yaml (92%)
 rename pkg/services/provisioning/{alert_notifications => notifiers}/test-configs/two-notifications/two-notifications.yaml (90%)
 rename pkg/services/provisioning/{alert_notifications => notifiers}/test-configs/unknown-notifier/notification.yaml (55%)
 rename pkg/services/provisioning/{alert_notifications => notifiers}/types.go (84%)
diff --git a/conf/provisioning/alert_notifications/sample.yaml b/conf/provisioning/notifiers/sample.yaml
similarity index 87%
rename from conf/provisioning/alert_notifications/sample.yaml
rename to conf/provisioning/notifiers/sample.yaml
index d08df2545e9..7d909839412 100644
--- a/conf/provisioning/alert_notifications/sample.yaml
+++ b/conf/provisioning/notifiers/sample.yaml
@@ -1,7 +1,7 @@
 # # config file version
 apiVersion: 1
 
-# alert_notifications:
+# notifiers:
 #   - name: default-slack-temp
 #     type: slack
 #     org_name: Main Org.
@@ -19,7 +19,7 @@ apiVersion: 1
 #     is_default: false  
 #     settings:
 #       addresses: example11111@example.com
-# delete_alert_notifications:
+# delete_notifiers:
 #   - name: default-slack-temp
 #     org_name: Main Org.
 #     uid: notifier1
\ No newline at end of file
diff --git a/docs/sources/administration/provisioning.md b/docs/sources/administration/provisioning.md
index 9d3fd9385d4..3c94cb79f21 100644
--- a/docs/sources/administration/provisioning.md
+++ b/docs/sources/administration/provisioning.md
@@ -234,11 +234,11 @@ By default Grafana will delete dashboards in the database if the file is removed
 
 ## 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:
-- `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.
-- `delete_alert_notifications`, a list of alert notifications to be deleted before before inserting/updating those in the `alert_notifications` list.
+- `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_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.
 
@@ -264,7 +264,7 @@ By default, exporting a dashboard as JSON will use a sequential identifier to re
 ### Example Alert Notification Channels Config File
 
 ```yaml
-alert_notifications:
+notifiers:
   - name: notification-channel-1
     type: slack
     uid: notifier1
@@ -281,7 +281,7 @@ alert_notifications:
       uploadImage: true
       url: https://slack.com
 
-delete_alert_notifications:
+delete_notifiers:
   - name: notification-channel-1
     uid: notifier1
     # either
diff --git a/pkg/services/provisioning/alert_notifications/alert_notifications.go b/pkg/services/provisioning/notifiers/alert_notifications.go
similarity index 98%
rename from pkg/services/provisioning/alert_notifications/alert_notifications.go
rename to pkg/services/provisioning/notifiers/alert_notifications.go
index 0f155dda4a8..514f11379c8 100644
--- a/pkg/services/provisioning/alert_notifications/alert_notifications.go
+++ b/pkg/services/provisioning/notifiers/alert_notifications.go
@@ -1,4 +1,4 @@
-package alert_notifications
+package notifiers
 
 import (
 	"errors"
@@ -13,7 +13,7 @@ var (
 )
 
 func Provision(configDirectory string) error {
-	dc := newNotificationProvisioner(log.New("provisioning.alert_notifications"))
+	dc := newNotificationProvisioner(log.New("provisioning.notifiers"))
 	return dc.applyChanges(configDirectory)
 }
 
@@ -54,6 +54,7 @@ func (dc *NotificationProvisioner) deleteNotifications(notificationToDelete []*d
 		} else if notification.OrgId < 0 {
 			notification.OrgId = 1
 		}
+
 		getNotification := &models.GetAlertNotificationsWithUidQuery{Uid: notification.Uid, OrgId: notification.OrgId}
 
 		if err := bus.Dispatch(getNotification); err != nil {
@@ -103,6 +104,7 @@ func (dc *NotificationProvisioner) mergeNotifications(notificationToMerge []*not
 				Frequency:             notification.Frequency,
 				SendReminder:          notification.SendReminder,
 			}
+
 			if err := bus.Dispatch(insertCmd); err != nil {
 				return err
 			}
@@ -119,6 +121,7 @@ func (dc *NotificationProvisioner) mergeNotifications(notificationToMerge []*not
 				Frequency:             notification.Frequency,
 				SendReminder:          notification.SendReminder,
 			}
+
 			if err := bus.Dispatch(updateCmd); err != nil {
 				return err
 			}
diff --git a/pkg/services/provisioning/alert_notifications/config_reader.go b/pkg/services/provisioning/notifiers/config_reader.go
similarity index 99%
rename from pkg/services/provisioning/alert_notifications/config_reader.go
rename to pkg/services/provisioning/notifiers/config_reader.go
index 56bfdab2f19..e712e8e3eff 100644
--- a/pkg/services/provisioning/alert_notifications/config_reader.go
+++ b/pkg/services/provisioning/notifiers/config_reader.go
@@ -1,4 +1,4 @@
-package alert_notifications
+package notifiers
 
 import (
 	"fmt"
@@ -94,8 +94,8 @@ func checkOrgIdAndOrgName(notifications []*notificationsAsConfig) {
 			}
 		}
 	}
-
 }
+
 func validateRequiredField(notifications []*notificationsAsConfig) error {
 	for i := range notifications {
 		var errStrings []string
@@ -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),
 				)
 			}
+
 			if notification.Uid == "" {
 				errStrings = append(
 					errStrings,
@@ -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),
 				)
 			}
+
 			if notification.Uid == "" {
 				errStrings = append(
 					errStrings,
@@ -128,10 +130,12 @@ func validateRequiredField(notifications []*notificationsAsConfig) error {
 				)
 			}
 		}
+
 		if len(errStrings) != 0 {
 			return fmt.Errorf(strings.Join(errStrings, "\n"))
 		}
 	}
+
 	return nil
 }
 
@@ -148,6 +152,7 @@ func validateNotifications(notifications []*notificationsAsConfig) error {
 				Settings: notification.SettingsToJson(),
 				Type:     notification.Type,
 			})
+
 			if err != nil {
 				return err
 			}
diff --git a/pkg/services/provisioning/alert_notifications/config_reader_test.go b/pkg/services/provisioning/notifiers/config_reader_test.go
similarity index 99%
rename from pkg/services/provisioning/alert_notifications/config_reader_test.go
rename to pkg/services/provisioning/notifiers/config_reader_test.go
index d66dded8407..18074d7614e 100644
--- a/pkg/services/provisioning/alert_notifications/config_reader_test.go
+++ b/pkg/services/provisioning/notifiers/config_reader_test.go
@@ -1,4 +1,4 @@
-package alert_notifications
+package notifiers
 
 import (
 	"testing"
@@ -35,11 +35,13 @@ func TestNotificationAsConfig(t *testing.T) {
 			Name:    "slack",
 			Factory: notifiers.NewSlackNotifier,
 		})
+
 		alerting.RegisterNotifier(&alerting.NotifierPlugin{
 			Type:    "email",
 			Name:    "email",
 			Factory: notifiers.NewEmailNotifier,
 		})
+
 		Convey("Can read correct properties", func() {
 			cfgProvifer := &configReader{log: log.New("test logger")}
 			cfg, err := cfgProvifer.readConfig(correct_properties)
@@ -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 2 in configuration doesn't contain required field uid")
 		})
+
 		Convey("Empty yaml file", func() {
 			Convey("should have not changed repo", func() {
 				dc := newNotificationProvisioner(logger)
@@ -277,11 +280,13 @@ func TestNotificationAsConfig(t *testing.T) {
 				So(notificationsQuery.Result, ShouldBeEmpty)
 			})
 		})
+
 		Convey("Broken yaml should return error", func() {
 			reader := &configReader{log: log.New("test logger")}
 			_, err := reader.readConfig(brokenYaml)
 			So(err, ShouldNotBeNil)
 		})
+
 		Convey("Skip invalid directory", func() {
 			cfgProvifer := &configReader{log: log.New("test logger")}
 			cfg, err := cfgProvifer.readConfig(emptyFolder)
@@ -290,6 +295,7 @@ func TestNotificationAsConfig(t *testing.T) {
 			}
 			So(len(cfg), ShouldEqual, 0)
 		})
+
 		Convey("Unknown notifier should return error", func() {
 			cfgProvifer := &configReader{log: log.New("test logger")}
 			_, err := cfgProvifer.readConfig(unknownNotifier)
@@ -303,6 +309,5 @@ func TestNotificationAsConfig(t *testing.T) {
 			So(err, ShouldNotBeNil)
 			So(err.Error(), ShouldEqual, "Alert validation error: Could not find url property in settings")
 		})
-
 	})
 }
diff --git a/pkg/services/provisioning/alert_notifications/test-configs/broken-yaml/broken.yaml b/pkg/services/provisioning/notifiers/test-configs/broken-yaml/broken.yaml
similarity index 76%
rename from pkg/services/provisioning/alert_notifications/test-configs/broken-yaml/broken.yaml
rename to pkg/services/provisioning/notifiers/test-configs/broken-yaml/broken.yaml
index e7c38d22f2c..72f2fbdbf63 100644
--- a/pkg/services/provisioning/alert_notifications/test-configs/broken-yaml/broken.yaml
+++ b/pkg/services/provisioning/notifiers/test-configs/broken-yaml/broken.yaml
@@ -1,4 +1,4 @@
-alert_notifications:
+notifiers:
   - name: notification-channel-1
      type: slack
     org_id: 2
diff --git a/pkg/services/provisioning/alert_notifications/test-configs/broken-yaml/not.yaml.text b/pkg/services/provisioning/notifiers/test-configs/broken-yaml/not.yaml.text
similarity index 100%
rename from pkg/services/provisioning/alert_notifications/test-configs/broken-yaml/not.yaml.text
rename to pkg/services/provisioning/notifiers/test-configs/broken-yaml/not.yaml.text
diff --git a/pkg/services/provisioning/alert_notifications/test-configs/correct-properties-with-orgName/correct-properties-with-orgName.yaml b/pkg/services/provisioning/notifiers/test-configs/correct-properties-with-orgName/correct-properties-with-orgName.yaml
similarity index 78%
rename from pkg/services/provisioning/alert_notifications/test-configs/correct-properties-with-orgName/correct-properties-with-orgName.yaml
rename to pkg/services/provisioning/notifiers/test-configs/correct-properties-with-orgName/correct-properties-with-orgName.yaml
index 214396982ea..25c4536d1f3 100644
--- a/pkg/services/provisioning/alert_notifications/test-configs/correct-properties-with-orgName/correct-properties-with-orgName.yaml
+++ b/pkg/services/provisioning/notifiers/test-configs/correct-properties-with-orgName/correct-properties-with-orgName.yaml
@@ -1,4 +1,4 @@
-alert_notifications:
+notifiers:
   - name: default-notification-create
     type: email
     uid: notifier2
@@ -6,7 +6,7 @@ alert_notifications:
       addresses: example@example.com
     org_name: Main Org. 2
     is_default: false  
-delete_alert_notifications:
+delete_notifiers:
   - name: default-notification-delete
     org_name: Main Org. 2
     uid: notifier2
\ No newline at end of file
diff --git a/pkg/services/provisioning/alert_notifications/test-configs/correct-properties/correct-properties.yaml b/pkg/services/provisioning/notifiers/test-configs/correct-properties/correct-properties.yaml
similarity index 93%
rename from pkg/services/provisioning/alert_notifications/test-configs/correct-properties/correct-properties.yaml
rename to pkg/services/provisioning/notifiers/test-configs/correct-properties/correct-properties.yaml
index 4f4cd171852..af0736f35a4 100644
--- a/pkg/services/provisioning/alert_notifications/test-configs/correct-properties/correct-properties.yaml
+++ b/pkg/services/provisioning/notifiers/test-configs/correct-properties/correct-properties.yaml
@@ -1,4 +1,4 @@
-alert_notifications:
+notifiers:
   - name: default-slack-notification
     type: slack
     uid: notifier1
@@ -29,7 +29,7 @@ alert_notifications:
     uid: "notifier4"
     settings:
       addresses: example@exmaple.com
-delete_alert_notifications:
+delete_notifiers:
   - name: default-slack-notification
     org_id: 2
     uid: notifier1
diff --git a/pkg/services/provisioning/alert_notifications/test-configs/double-default/default-1.yml b/pkg/services/provisioning/notifiers/test-configs/double-default/default-1.yml
similarity index 65%
rename from pkg/services/provisioning/alert_notifications/test-configs/double-default/default-1.yml
rename to pkg/services/provisioning/notifiers/test-configs/double-default/default-1.yml
index d3ae32c5ae7..d9d2fe66081 100644
--- a/pkg/services/provisioning/alert_notifications/test-configs/double-default/default-1.yml
+++ b/pkg/services/provisioning/notifiers/test-configs/double-default/default-1.yml
@@ -1,4 +1,4 @@
-alert_notifications:
+notifiers:
   - name: first-default
     type: slack
     uid: notifier1
diff --git a/pkg/services/provisioning/alert_notifications/test-configs/double-default/default-2.yaml b/pkg/services/provisioning/notifiers/test-configs/double-default/default-2.yaml
similarity index 62%
rename from pkg/services/provisioning/alert_notifications/test-configs/double-default/default-2.yaml
rename to pkg/services/provisioning/notifiers/test-configs/double-default/default-2.yaml
index 3c2e8953f6b..878f8b48aa5 100644
--- a/pkg/services/provisioning/alert_notifications/test-configs/double-default/default-2.yaml
+++ b/pkg/services/provisioning/notifiers/test-configs/double-default/default-2.yaml
@@ -1,4 +1,4 @@
-alert_notifications:
+notifiers:
   - name: second-default
     type: email
     uid: notifier2
diff --git a/pkg/services/provisioning/alert_notifications/test-configs/empty/empty.yaml b/pkg/services/provisioning/notifiers/test-configs/empty/empty.yaml
similarity index 100%
rename from pkg/services/provisioning/alert_notifications/test-configs/empty/empty.yaml
rename to pkg/services/provisioning/notifiers/test-configs/empty/empty.yaml
diff --git a/pkg/services/provisioning/alert_notifications/test-configs/empty_folder/.gitignore b/pkg/services/provisioning/notifiers/test-configs/empty_folder/.gitignore
similarity index 100%
rename from pkg/services/provisioning/alert_notifications/test-configs/empty_folder/.gitignore
rename to pkg/services/provisioning/notifiers/test-configs/empty_folder/.gitignore
diff --git a/pkg/services/provisioning/alert_notifications/test-configs/incorrect-settings/incorrect-settings.yaml b/pkg/services/provisioning/notifiers/test-configs/incorrect-settings/incorrect-settings.yaml
similarity index 80%
rename from pkg/services/provisioning/alert_notifications/test-configs/incorrect-settings/incorrect-settings.yaml
rename to pkg/services/provisioning/notifiers/test-configs/incorrect-settings/incorrect-settings.yaml
index 2d720d9d2d9..b7ecfbdf012 100644
--- a/pkg/services/provisioning/alert_notifications/test-configs/incorrect-settings/incorrect-settings.yaml
+++ b/pkg/services/provisioning/notifiers/test-configs/incorrect-settings/incorrect-settings.yaml
@@ -1,4 +1,4 @@
-alert_notifications:
+notifiers:
   - name: slack-notification-without-url-in-settings
     type: slack
     org_id: 2
diff --git a/pkg/services/provisioning/alert_notifications/test-configs/no-required-fields/no-required-fields.yaml b/pkg/services/provisioning/notifiers/test-configs/no-required-fields/no-required-fields.yaml
similarity index 92%
rename from pkg/services/provisioning/alert_notifications/test-configs/no-required-fields/no-required-fields.yaml
rename to pkg/services/provisioning/notifiers/test-configs/no-required-fields/no-required-fields.yaml
index 582abefe14d..55ff545525e 100644
--- a/pkg/services/provisioning/alert_notifications/test-configs/no-required-fields/no-required-fields.yaml
+++ b/pkg/services/provisioning/notifiers/test-configs/no-required-fields/no-required-fields.yaml
@@ -1,4 +1,4 @@
-alert_notifications:
+notifiers:
   - type: slack
     org_id: 2
     uid: no-name_added-notification
@@ -15,7 +15,7 @@ alert_notifications:
       recipient: "XXX"
       token: "xoxb"
       uploadImage: true
-delete_alert_notifications:
+delete_notifiers:
   - name: no-uid 
     type: slack
     org_id: 2    
diff --git a/pkg/services/provisioning/alert_notifications/test-configs/two-notifications/two-notifications.yaml b/pkg/services/provisioning/notifiers/test-configs/two-notifications/two-notifications.yaml
similarity index 90%
rename from pkg/services/provisioning/alert_notifications/test-configs/two-notifications/two-notifications.yaml
rename to pkg/services/provisioning/notifiers/test-configs/two-notifications/two-notifications.yaml
index 23fff0aff23..aeeb718e6de 100644
--- a/pkg/services/provisioning/alert_notifications/test-configs/two-notifications/two-notifications.yaml
+++ b/pkg/services/provisioning/notifiers/test-configs/two-notifications/two-notifications.yaml
@@ -1,4 +1,4 @@
-alert_notifications:  
+notifiers:  
   - name: channel1
     type: email
     uid: notifier1
diff --git a/pkg/services/provisioning/alert_notifications/test-configs/unknown-notifier/notification.yaml b/pkg/services/provisioning/notifiers/test-configs/unknown-notifier/notification.yaml
similarity index 55%
rename from pkg/services/provisioning/alert_notifications/test-configs/unknown-notifier/notification.yaml
rename to pkg/services/provisioning/notifiers/test-configs/unknown-notifier/notification.yaml
index e46db7b8b6e..ca0d3fa3c75 100644
--- a/pkg/services/provisioning/alert_notifications/test-configs/unknown-notifier/notification.yaml
+++ b/pkg/services/provisioning/notifiers/test-configs/unknown-notifier/notification.yaml
@@ -1,4 +1,4 @@
-alert_notifications:
+notifiers:
   - name: unknown-notifier
     type: nonexisting
     uid: notifier1
\ No newline at end of file
diff --git a/pkg/services/provisioning/alert_notifications/types.go b/pkg/services/provisioning/notifiers/types.go
similarity index 84%
rename from pkg/services/provisioning/alert_notifications/types.go
rename to pkg/services/provisioning/notifiers/types.go
index d3a858ae956..f788da79c79 100644
--- a/pkg/services/provisioning/alert_notifications/types.go
+++ b/pkg/services/provisioning/notifiers/types.go
@@ -1,10 +1,10 @@
-package alert_notifications
+package notifiers
 
 import "github.com/grafana/grafana/pkg/components/simplejson"
 
 type notificationsAsConfig struct {
-	Notifications       []*notificationFromConfig   `json:"alert_notifications" yaml:"alert_notifications"`
-	DeleteNotifications []*deleteNotificationConfig `json:"delete_alert_notifications" yaml:"delete_alert_notifications"`
+	Notifications       []*notificationFromConfig   `json:"notifiers" yaml:"notifiers"`
+	DeleteNotifications []*deleteNotificationConfig `json:"delete_notifiers" yaml:"delete_notifiers"`
 }
 
 type deleteNotificationConfig struct {
diff --git a/pkg/services/provisioning/provisioning.go b/pkg/services/provisioning/provisioning.go
index fdecd03a3da..eb19cb2c5e8 100644
--- a/pkg/services/provisioning/provisioning.go
+++ b/pkg/services/provisioning/provisioning.go
@@ -6,7 +6,7 @@ import (
 	"path"
 
 	"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/datasources"
 	"github.com/grafana/grafana/pkg/setting"
@@ -26,8 +26,8 @@ func (ps *ProvisioningService) Init() error {
 		return fmt.Errorf("Datasource provisioning error: %v", err)
 	}
 
-	alertNotificationsPath := path.Join(ps.Cfg.ProvisioningPath, "alert_notifications")
-	if err := alert_notifications.Provision(alertNotificationsPath); err != nil {
+	alertNotificationsPath := path.Join(ps.Cfg.ProvisioningPath, "notifiers")
+	if err := notifiers.Provision(alertNotificationsPath); err != nil {
 		return fmt.Errorf("Alert notification provisioning error: %v", err)
 	}
 
From 809019d4eeaf490dd905e601d2171c89a0b056d9 Mon Sep 17 00:00:00 2001
From: bergquist 
Date: Mon, 28 Jan 2019 20:43:53 +0100
Subject: [PATCH 19/21] moves test files into testdata folder
---
 .../notifiers/config_reader_test.go           | 24 +++++++++----------
 .../test-configs/broken-yaml/broken.yaml      |  0
 .../test-configs/broken-yaml/not.yaml.text    |  0
 .../correct-properties-with-orgName.yaml      |  0
 .../correct-properties.yaml                   |  0
 .../test-configs/double-default/default-1.yml |  0
 .../double-default/default-2.yaml             |  0
 .../test-configs/empty/empty.yaml             |  0
 .../test-configs/empty_folder/.gitignore      |  0
 .../incorrect-settings.yaml                   |  0
 .../no-required-fields.yaml                   |  0
 .../two-notifications/two-notifications.yaml  |  0
 .../unknown-notifier/notification.yaml        |  0
 13 files changed, 12 insertions(+), 12 deletions(-)
 rename pkg/services/provisioning/notifiers/{ => testdata}/test-configs/broken-yaml/broken.yaml (100%)
 rename pkg/services/provisioning/notifiers/{ => testdata}/test-configs/broken-yaml/not.yaml.text (100%)
 rename pkg/services/provisioning/notifiers/{ => testdata}/test-configs/correct-properties-with-orgName/correct-properties-with-orgName.yaml (100%)
 rename pkg/services/provisioning/notifiers/{ => testdata}/test-configs/correct-properties/correct-properties.yaml (100%)
 rename pkg/services/provisioning/notifiers/{ => testdata}/test-configs/double-default/default-1.yml (100%)
 rename pkg/services/provisioning/notifiers/{ => testdata}/test-configs/double-default/default-2.yaml (100%)
 rename pkg/services/provisioning/notifiers/{ => testdata}/test-configs/empty/empty.yaml (100%)
 rename pkg/services/provisioning/notifiers/{ => testdata}/test-configs/empty_folder/.gitignore (100%)
 rename pkg/services/provisioning/notifiers/{ => testdata}/test-configs/incorrect-settings/incorrect-settings.yaml (100%)
 rename pkg/services/provisioning/notifiers/{ => testdata}/test-configs/no-required-fields/no-required-fields.yaml (100%)
 rename pkg/services/provisioning/notifiers/{ => testdata}/test-configs/two-notifications/two-notifications.yaml (100%)
 rename pkg/services/provisioning/notifiers/{ => testdata}/test-configs/unknown-notifier/notification.yaml (100%)
diff --git a/pkg/services/provisioning/notifiers/config_reader_test.go b/pkg/services/provisioning/notifiers/config_reader_test.go
index 18074d7614e..87645ee7d31 100644
--- a/pkg/services/provisioning/notifiers/config_reader_test.go
+++ b/pkg/services/provisioning/notifiers/config_reader_test.go
@@ -12,21 +12,21 @@ import (
 )
 
 var (
-	logger = log.New("fake.log")
-
-	correct_properties              = "./test-configs/correct-properties"
-	incorrect_settings              = "./test-configs/incorrect-settings"
-	no_required_fields              = "./test-configs/no-required-fields"
-	correct_properties_with_orgName = "./test-configs/correct-properties-with-orgName"
-	brokenYaml                      = "./test-configs/broken-yaml"
-	doubleNotificationsConfig       = "./test-configs/double-default"
-	emptyFolder                     = "./test-configs/empty_folder"
-	emptyFile                       = "./test-configs/empty"
-	twoNotificationsConfig          = "./test-configs/two-notifications"
-	unknownNotifier                 = "./test-configs/unknown-notifier"
+	correct_properties              = "./testdata/test-configs/correct-properties"
+	incorrect_settings              = "./testdata/test-configs/incorrect-settings"
+	no_required_fields              = "./testdata/test-configs/no-required-fields"
+	correct_properties_with_orgName = "./testdata/test-configs/correct-properties-with-orgName"
+	brokenYaml                      = "./testdata/test-configs/broken-yaml"
+	doubleNotificationsConfig       = "./testdata/test-configs/double-default"
+	emptyFolder                     = "./testdata/test-configs/empty_folder"
+	emptyFile                       = "./testdata/test-configs/empty"
+	twoNotificationsConfig          = "./testdata/test-configs/two-notifications"
+	unknownNotifier                 = "./testdata/test-configs/unknown-notifier"
 )
 
 func TestNotificationAsConfig(t *testing.T) {
+	logger := log.New("fake.log")
+
 	Convey("Testing notification as configuration", t, func() {
 		sqlstore.InitTestDB(t)
 
diff --git a/pkg/services/provisioning/notifiers/test-configs/broken-yaml/broken.yaml b/pkg/services/provisioning/notifiers/testdata/test-configs/broken-yaml/broken.yaml
similarity index 100%
rename from pkg/services/provisioning/notifiers/test-configs/broken-yaml/broken.yaml
rename to pkg/services/provisioning/notifiers/testdata/test-configs/broken-yaml/broken.yaml
diff --git a/pkg/services/provisioning/notifiers/test-configs/broken-yaml/not.yaml.text b/pkg/services/provisioning/notifiers/testdata/test-configs/broken-yaml/not.yaml.text
similarity index 100%
rename from pkg/services/provisioning/notifiers/test-configs/broken-yaml/not.yaml.text
rename to pkg/services/provisioning/notifiers/testdata/test-configs/broken-yaml/not.yaml.text
diff --git a/pkg/services/provisioning/notifiers/test-configs/correct-properties-with-orgName/correct-properties-with-orgName.yaml b/pkg/services/provisioning/notifiers/testdata/test-configs/correct-properties-with-orgName/correct-properties-with-orgName.yaml
similarity index 100%
rename from pkg/services/provisioning/notifiers/test-configs/correct-properties-with-orgName/correct-properties-with-orgName.yaml
rename to pkg/services/provisioning/notifiers/testdata/test-configs/correct-properties-with-orgName/correct-properties-with-orgName.yaml
diff --git a/pkg/services/provisioning/notifiers/test-configs/correct-properties/correct-properties.yaml b/pkg/services/provisioning/notifiers/testdata/test-configs/correct-properties/correct-properties.yaml
similarity index 100%
rename from pkg/services/provisioning/notifiers/test-configs/correct-properties/correct-properties.yaml
rename to pkg/services/provisioning/notifiers/testdata/test-configs/correct-properties/correct-properties.yaml
diff --git a/pkg/services/provisioning/notifiers/test-configs/double-default/default-1.yml b/pkg/services/provisioning/notifiers/testdata/test-configs/double-default/default-1.yml
similarity index 100%
rename from pkg/services/provisioning/notifiers/test-configs/double-default/default-1.yml
rename to pkg/services/provisioning/notifiers/testdata/test-configs/double-default/default-1.yml
diff --git a/pkg/services/provisioning/notifiers/test-configs/double-default/default-2.yaml b/pkg/services/provisioning/notifiers/testdata/test-configs/double-default/default-2.yaml
similarity index 100%
rename from pkg/services/provisioning/notifiers/test-configs/double-default/default-2.yaml
rename to pkg/services/provisioning/notifiers/testdata/test-configs/double-default/default-2.yaml
diff --git a/pkg/services/provisioning/notifiers/test-configs/empty/empty.yaml b/pkg/services/provisioning/notifiers/testdata/test-configs/empty/empty.yaml
similarity index 100%
rename from pkg/services/provisioning/notifiers/test-configs/empty/empty.yaml
rename to pkg/services/provisioning/notifiers/testdata/test-configs/empty/empty.yaml
diff --git a/pkg/services/provisioning/notifiers/test-configs/empty_folder/.gitignore b/pkg/services/provisioning/notifiers/testdata/test-configs/empty_folder/.gitignore
similarity index 100%
rename from pkg/services/provisioning/notifiers/test-configs/empty_folder/.gitignore
rename to pkg/services/provisioning/notifiers/testdata/test-configs/empty_folder/.gitignore
diff --git a/pkg/services/provisioning/notifiers/test-configs/incorrect-settings/incorrect-settings.yaml b/pkg/services/provisioning/notifiers/testdata/test-configs/incorrect-settings/incorrect-settings.yaml
similarity index 100%
rename from pkg/services/provisioning/notifiers/test-configs/incorrect-settings/incorrect-settings.yaml
rename to pkg/services/provisioning/notifiers/testdata/test-configs/incorrect-settings/incorrect-settings.yaml
diff --git a/pkg/services/provisioning/notifiers/test-configs/no-required-fields/no-required-fields.yaml b/pkg/services/provisioning/notifiers/testdata/test-configs/no-required-fields/no-required-fields.yaml
similarity index 100%
rename from pkg/services/provisioning/notifiers/test-configs/no-required-fields/no-required-fields.yaml
rename to pkg/services/provisioning/notifiers/testdata/test-configs/no-required-fields/no-required-fields.yaml
diff --git a/pkg/services/provisioning/notifiers/test-configs/two-notifications/two-notifications.yaml b/pkg/services/provisioning/notifiers/testdata/test-configs/two-notifications/two-notifications.yaml
similarity index 100%
rename from pkg/services/provisioning/notifiers/test-configs/two-notifications/two-notifications.yaml
rename to pkg/services/provisioning/notifiers/testdata/test-configs/two-notifications/two-notifications.yaml
diff --git a/pkg/services/provisioning/notifiers/test-configs/unknown-notifier/notification.yaml b/pkg/services/provisioning/notifiers/testdata/test-configs/unknown-notifier/notification.yaml
similarity index 100%
rename from pkg/services/provisioning/notifiers/test-configs/unknown-notifier/notification.yaml
rename to pkg/services/provisioning/notifiers/testdata/test-configs/unknown-notifier/notification.yaml
From 7c93335d28d6ad3c6e06d6340ef51cf7d52f5ff3 Mon Sep 17 00:00:00 2001
From: bergquist 
Date: Mon, 28 Jan 2019 21:04:08 +0100
Subject: [PATCH 20/21] gofmt issue
---
 pkg/services/provisioning/provisioning.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pkg/services/provisioning/provisioning.go b/pkg/services/provisioning/provisioning.go
index eb19cb2c5e8..45f0972b885 100644
--- a/pkg/services/provisioning/provisioning.go
+++ b/pkg/services/provisioning/provisioning.go
@@ -6,9 +6,9 @@ import (
 	"path"
 
 	"github.com/grafana/grafana/pkg/registry"
-	"github.com/grafana/grafana/pkg/services/provisioning/notifiers"
 	"github.com/grafana/grafana/pkg/services/provisioning/dashboards"
 	"github.com/grafana/grafana/pkg/services/provisioning/datasources"
+	"github.com/grafana/grafana/pkg/services/provisioning/notifiers"
 	"github.com/grafana/grafana/pkg/setting"
 )
 
From e218cc7637e78f8ebb5767a3051517824f9730ab Mon Sep 17 00:00:00 2001
From: bergquist 
Date: Mon, 28 Jan 2019 22:03:16 +0100
Subject: [PATCH 21/21] docs: updates docs to refer to using uid
---
 docs/sources/administration/provisioning.md   | 6 +++---
 pkg/services/sqlstore/alert_notification.go   | 2 ++
 pkg/services/sqlstore/migrations/alert_mig.go | 3 +++
 3 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/docs/sources/administration/provisioning.md b/docs/sources/administration/provisioning.md
index 3c94cb79f21..cce25e4cf2b 100644
--- a/docs/sources/administration/provisioning.md
+++ b/docs/sources/administration/provisioning.md
@@ -234,15 +234,15 @@ By default Grafana will delete dashboards in the database if the file is removed
 
 ## Alert Notification Channels
 
-Alert Notification Channels can be provisionned by adding one or more yaml config files in the [`provisioning/notifiers`](/installation/configuration/#provisioning) directory.
+Alert Notification Channels can be provisioned 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:
 - `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_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.
+Provisioning looks up alert notifications by uid, and will update any existing notification with the provided uid.
 
-By default, exporting a dashboard as JSON will use a sequential identifier to refer to alert notifications. The field `name` can be optionally specified to specify a string identifier for the alert name.
+By default, exporting a dashboard as JSON will use a sequential identifier to refer to alert notifications. The field `uid` can be optionally specified to specify a string identifier for the alert name.
 
 ```json
 {
diff --git a/pkg/services/sqlstore/alert_notification.go b/pkg/services/sqlstore/alert_notification.go
index 9231c896cf1..efb5f621392 100644
--- a/pkg/services/sqlstore/alert_notification.go
+++ b/pkg/services/sqlstore/alert_notification.go
@@ -281,10 +281,12 @@ func generateNewAlertNotificationUid(sess *DBSession, orgId int64) (string, erro
 		if err != nil {
 			return "", err
 		}
+
 		if !exists {
 			return uid, nil
 		}
 	}
+
 	return "", m.ErrAlertNotificationFailedGenerateUniqueUid
 }
 
diff --git a/pkg/services/sqlstore/migrations/alert_mig.go b/pkg/services/sqlstore/migrations/alert_mig.go
index 2ed9732687a..84014bd386f 100644
--- a/pkg/services/sqlstore/migrations/alert_mig.go
+++ b/pkg/services/sqlstore/migrations/alert_mig.go
@@ -141,13 +141,16 @@ func addAlertMigrations(mg *Migrator) {
 	mg.AddMigration("Add column uid in alert_notification", NewAddColumnMigration(alert_notification, &Column{
 		Name: "uid", Type: DB_NVarchar, Length: 40, Nullable: true,
 	}))
+
 	mg.AddMigration("Update uid column values in alert_notification", new(RawSqlMigration).
 		Sqlite("UPDATE alert_notification SET uid=printf('%09d',id) WHERE uid IS NULL;").
 		Postgres("UPDATE alert_notification SET uid=lpad('' || id,9,'0') WHERE uid IS NULL;").
 		Mysql("UPDATE alert_notification SET uid=lpad(id,9,'0') WHERE uid IS NULL;"))
+
 	mg.AddMigration("Add unique index alert_notification_org_id_uid", NewAddIndexMigration(alert_notification, &Index{
 		Cols: []string{"org_id", "uid"}, Type: UniqueIndex,
 	}))
+
 	mg.AddMigration("Remove unique index org_id_name", NewDropIndexMigration(alert_notification, &Index{
 		Cols: []string{"org_id", "name"}, Type: UniqueIndex,
 	}))