Ver Fonte

Alerting: Notification channel http api enhancements (#16219)

Now returns uid in response to get notification channel by id.
Adds GET/PUT/DELETE support for notification channel by uid, 
  /api/alert-notifications/uid/:uid.
Break apart alerting and alert notification http api docs in two 
  pages and update documentation to make it up to date
  with current implementation.

Fixes #16012
Marcus Efraimsson há 6 anos atrás
pai
commit
2ae63e70c0

+ 7 - 3
docs/sources/http_api/admin.md

@@ -319,7 +319,7 @@ Only works with Basic Authentication (username and password). See [introduction]
 
 **Example Request**:
 
-```json
+```http
 POST /api/admin/pause-all-alerts HTTP/1.1
 Accept: application/json
 Content-Type: application/json
@@ -335,11 +335,15 @@ JSON Body schema:
 
 **Example Response**:
 
-```json
+```http
 HTTP/1.1 200
 Content-Type: application/json
 
-{"state": "new state", "message": "alerts pause/un paused", "alertsAffected": 100}
+{
+  "state":   "Paused",
+  "message": "alert paused",
+  "alertsAffected": 1
+}
 ```
 
 ## Auth tokens for User

+ 5 - 191
docs/sources/http_api/alerting.md

@@ -1,7 +1,7 @@
 +++
 title = "Alerting HTTP API "
-description = "Grafana Alerting HTTP API"
-keywords = ["grafana", "http", "documentation", "api", "alerting"]
+description = "Grafana Alerts HTTP API"
+keywords = ["grafana", "http", "documentation", "api", "alerting", "alerts"]
 aliases = ["/http_api/alerting/"]
 type = "docs"
 [menu.docs]
@@ -9,14 +9,11 @@ name = "Alerting"
 parent = "http_api"
 +++
 
-
 # Alerting API
 
 You can use the Alerting API to get information about alerts and their states but this API cannot be used to modify the alert.
 To create new alerts or modify them you need to update the dashboard json that contains the alerts.
 
-This API can also be used to create, update and delete alert notifications.
-
 ## Get alerts
 
 `GET /api/alerts/`
@@ -69,7 +66,7 @@ Content-Type: application/json
 ]
 ```
 
-## Get one alert
+## Get alert by id
 
 `GET /api/alerts/:id`
 
@@ -120,7 +117,7 @@ Content-Type: application/json
 If data from one server triggers the alert first and, before that server is seen leaving alerting state,
 a second server also enters a state that would trigger the alert, the second server will not be visible in "evalMatches" data.
 
-## Pause alert
+## Pause alert by id
 
 `POST /api/alerts/:id/pause`
 
@@ -158,187 +155,4 @@ Content-Type: application/json
 
 ## Pause all alerts
 
-`POST /api/admin/pause-all-alerts`
-
-Only works with Basic Authentication (username and password). See [introduction](http://docs.grafana.org/http_api/admin/#admin-api) for an explanation.
-
-**Example Request**:
-
-```http
-POST /api/admin/pause-all-alerts HTTP/1.1
-Accept: application/json
-Content-Type: application/json
-
-{
-  "paused": true
-}
-```
-
-JSON Body Schema:
-
-- **paused** – Can be `true` or `false`. True to pause an alert. False to unpause an alert.
-
-**Example Response**:
-
-```http
-HTTP/1.1 200
-Content-Type: application/json
-
-{
-  "state":   "Paused",
-  "message": "alert paused",
-  "alertsAffected": 1
-}
-```
-
-## Get alert notifications
-
-`GET /api/alert-notifications`
-
-**Example Request**:
-
-```http
-GET /api/alert-notifications HTTP/1.1
-Accept: application/json
-Content-Type: application/json
-Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
-```
-
-
-**Example Response**:
-
-```http
-HTTP/1.1 200
-Content-Type: application/json
-
-[
-  {
-    "id": 1,
-    "name": "Team A",
-    "type": "email",
-    "isDefault": false,
-    "sendReminder": false,
-    "settings": {
-      "addresses": "carl@grafana.com;dev@grafana.com"
-    },
-    "created": "2018-04-23T14:44:09+02:00",
-    "updated": "2018-08-20T15:47:49+02:00"
-  }
-]
-
-```
-
-## Create alert notification
-
-You can find the full list of [supported notifiers](/alerting/notifications/#all-supported-notifier) at the alert notifiers page.
-
-`POST /api/alert-notifications`
-
-**Example Request**:
-
-```http
-POST /api/alert-notifications HTTP/1.1
-Accept: application/json
-Content-Type: application/json
-Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
-
-{
-  "name": "new alert notification",  //Required
-  "type":  "email", //Required
-  "isDefault": false,
-  "sendReminder": false,
-  "settings": {
-    "addresses": "carl@grafana.com;dev@grafana.com"
-  }
-}
-```
-
-**Example Response**:
-
-```http
-HTTP/1.1 200
-Content-Type: application/json
-
-{
-  "id": 1,
-  "name": "new alert notification",
-  "type": "email",
-  "isDefault": false,
-  "sendReminder": false,
-  "settings": {
-    "addresses": "carl@grafana.com;dev@grafana.com"
-  },
-  "created": "2018-04-23T14:44:09+02:00",
-  "updated": "2018-08-20T15:47:49+02:00"
-}
-```
-
-## Update alert notification
-
-`PUT /api/alert-notifications/:id`
-
-**Example Request**:
-
-```http
-PUT /api/alert-notifications/1 HTTP/1.1
-Accept: application/json
-Content-Type: application/json
-Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
-
-{
-  "id": 1,
-  "name": "new alert notification",  //Required
-  "type":  "email", //Required
-  "isDefault": false,
-  "sendReminder": true,
-  "frequency": "15m",
-  "settings": {
-    "addresses": "carl@grafana.com;dev@grafana.com"
-  }
-}
-```
-
-**Example Response**:
-
-```http
-HTTP/1.1 200
-Content-Type: application/json
-
-{
-  "id": 1,
-  "name": "new alert notification",
-  "type": "email",
-  "isDefault": false,
-  "sendReminder": true,
-  "frequency": "15m",
-  "settings": {
-    "addresses": "carl@grafana.com;dev@grafana.com"
-  },
-  "created": "2017-01-01 12:34",
-  "updated": "2017-01-01 12:34"
-}
-```
-
-## Delete alert notification
-
-`DELETE /api/alert-notifications/:id`
-
-**Example Request**:
-
-```http
-DELETE /api/alert-notifications/1 HTTP/1.1
-Accept: application/json
-Content-Type: application/json
-Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
-```
-
-**Example Response**:
-
-```http
-HTTP/1.1 200
-Content-Type: application/json
-
-{
-  "message": "Notification deleted"
-}
-```
+See [Admin API]({{< relref "http_api/admin.md#pause-all-alerts" >}}).

+ 369 - 0
docs/sources/http_api/alerting_notification_channels.md

@@ -0,0 +1,369 @@
++++
+title = "Alerting Notification Channels HTTP API "
+description = "Grafana Alerting Notification Channel HTTP API"
+keywords = ["grafana", "http", "documentation", "api", "alerting", "alerts", "notifications"]
+aliases = []
+type = "docs"
+[menu.docs]
+name = "Alerting Notification Channels"
+parent = "http_api"
++++
+
+# Alerting Notification Channels API
+
+## Identifier (id) vs unique identifier (uid)
+
+The identifier (id) of a notification channel is an auto-incrementing numeric value and is only unique per Grafana install.
+
+The unique identifier (uid) of a notification channel can be used for uniquely identify a notification channel between
+multiple Grafana installs. It's automatically generated if not provided when creating a notification channel. The uid
+allows having consistent URL's for accessing notification channels and when syncing notification channels between multiple
+Grafana installs, see [alert notification channel provisioning](/administration/provisioning/#alert-notification-channels)
+for more information.
+
+The uid can have a maximum length of 40 characters.
+
+## Get all notification channels
+
+Returns all notification channels that the authenticated user has permission to view.
+
+`GET /api/alert-notifications`
+
+**Example Request**:
+
+```http
+GET /api/alert-notifications HTTP/1.1
+Accept: application/json
+Content-Type: application/json
+Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
+```
+
+**Example Response**:
+
+```http
+HTTP/1.1 200
+Content-Type: application/json
+
+[
+  {
+    "id": 1,
+    "uid": "team-a-email-notifier",
+    "name": "Team A",
+    "type": "email",
+    "isDefault": false,
+    "sendReminder": false,
+    "disableResolveMessage": false,
+    "settings": {
+      "addresses": "carl@grafana.com;dev@grafana.com"
+    },
+    "created": "2018-04-23T14:44:09+02:00",
+    "updated": "2018-08-20T15:47:49+02:00"
+  }
+]
+
+```
+
+## Get notification channel by uid
+
+`GET /api/alert-notifications/uid/:uid`
+
+Will return the notification channel given the notification channel uid.
+
+**Example Request**:
+
+```http
+GET /api/alert-notifications/uid/team-a-email-notifier HTTP/1.1
+Accept: application/json
+Content-Type: application/json
+Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
+```
+
+**Example Response**:
+
+```http
+HTTP/1.1 200
+Content-Type: application/json
+
+{
+  "id": 1,
+  "uid": "team-a-email-notifier",
+  "name": "Team A",
+  "type": "email",
+  "isDefault": false,
+  "sendReminder": false,
+  "disableResolveMessage": false,
+  "settings": {
+    "addresses": "carl@grafana.com;dev@grafana.com"
+  },
+  "created": "2018-04-23T14:44:09+02:00",
+  "updated": "2018-08-20T15:47:49+02:00"
+}
+```
+
+## Get notification channel by id
+
+`GET /api/alert-notifications/:id`
+
+Will return the notification channel given the notification channel id.
+
+**Example Request**:
+
+```http
+GET /api/alert-notifications/1 HTTP/1.1
+Accept: application/json
+Content-Type: application/json
+Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
+```
+
+**Example Response**:
+
+```http
+HTTP/1.1 200
+Content-Type: application/json
+
+{
+  "id": 1,
+  "uid": "team-a-email-notifier",
+  "name": "Team A",
+  "type": "email",
+  "isDefault": false,
+  "sendReminder": false,
+  "disableResolveMessage": false,
+  "settings": {
+    "addresses": "carl@grafana.com;dev@grafana.com"
+  },
+  "created": "2018-04-23T14:44:09+02:00",
+  "updated": "2018-08-20T15:47:49+02:00"
+}
+```
+
+## Create notification channel
+
+You can find the full list of [supported notifiers](/alerting/notifications/#all-supported-notifier) at the alert notifiers page.
+
+`POST /api/alert-notifications`
+
+**Example Request**:
+
+```http
+POST /api/alert-notifications HTTP/1.1
+Accept: application/json
+Content-Type: application/json
+Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
+
+{
+  "name": "new alert notification",  //Required
+  "type":  "email", //Required
+  "isDefault": false,
+  "sendReminder": false,
+  "settings": {
+    "addresses": "carl@grafana.com;dev@grafana.com"
+  }
+}
+```
+
+**Example Response**:
+
+```http
+HTTP/1.1 200
+Content-Type: application/json
+
+{
+  "id": 1,
+  "uid": "cIBgcSjkk",
+  "name": "new alert notification",
+  "type": "email",
+  "isDefault": false,
+  "sendReminder": false,
+  "settings": {
+    "addresses": "carl@grafana.com;dev@grafana.com"
+  },
+  "created": "2018-04-23T14:44:09+02:00",
+  "updated": "2018-08-20T15:47:49+02:00"
+}
+```
+
+## Update notification channel by uid
+
+`PUT /api/alert-notifications/uid/:uid`
+
+Updates an existing notification channel identified by uid.
+
+**Example Request**:
+
+```http
+PUT /api/alert-notifications/uid/cIBgcSjkk HTTP/1.1
+Accept: application/json
+Content-Type: application/json
+Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
+
+{
+  "name": "new alert notification",  //Required
+  "type":  "email", //Required
+  "isDefault": false,
+  "sendReminder": true,
+  "frequency": "15m",
+  "settings": {
+    "addresses": "carl@grafana.com;dev@grafana.com"
+  }
+}
+```
+
+**Example Response**:
+
+```http
+HTTP/1.1 200
+Content-Type: application/json
+
+{
+  "id": 1,
+  "uid": "cIBgcSjkk",
+  "name": "new alert notification",
+  "type": "email",
+  "isDefault": false,
+  "sendReminder": true,
+  "frequency": "15m",
+  "settings": {
+    "addresses": "carl@grafana.com;dev@grafana.com"
+  },
+  "created": "2017-01-01 12:34",
+  "updated": "2017-01-01 12:34"
+}
+```
+
+## Update notification channel by id
+
+`PUT /api/alert-notifications/:id`
+
+Updates an existing notification channel identified by id.
+
+**Example Request**:
+
+```http
+PUT /api/alert-notifications/1 HTTP/1.1
+Accept: application/json
+Content-Type: application/json
+Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
+
+{
+  "id": 1,
+  "uid": "cIBgcSjkk",
+  "name": "new alert notification",  //Required
+  "type":  "email", //Required
+  "isDefault": false,
+  "sendReminder": true,
+  "frequency": "15m",
+  "settings": {
+    "addresses": "carl@grafana.com;dev@grafana.com"
+  }
+}
+```
+
+**Example Response**:
+
+```http
+HTTP/1.1 200
+Content-Type: application/json
+
+{
+  "id": 1,
+  "uid": "cIBgcSjkk",
+  "name": "new alert notification",
+  "type": "email",
+  "isDefault": false,
+  "sendReminder": true,
+  "frequency": "15m",
+  "settings": {
+    "addresses": "carl@grafana.com;dev@grafana.com"
+  },
+  "created": "2017-01-01 12:34",
+  "updated": "2017-01-01 12:34"
+}
+```
+
+## Delete alert notification by uid
+
+`DELETE /api/alert-notifications/uid/:uid`
+
+Deletes an existing notification channel identified by uid.
+
+**Example Request**:
+
+```http
+DELETE /api/alert-notifications/uid/team-a-email-notifier HTTP/1.1
+Accept: application/json
+Content-Type: application/json
+Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
+```
+
+**Example Response**:
+
+```http
+HTTP/1.1 200
+Content-Type: application/json
+
+{
+  "message": "Notification deleted"
+}
+```
+
+## Delete alert notification by id
+
+`DELETE /api/alert-notifications/:id`
+
+Deletes an existing notification channel identified by id.
+
+**Example Request**:
+
+```http
+DELETE /api/alert-notifications/1 HTTP/1.1
+Accept: application/json
+Content-Type: application/json
+Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
+```
+
+**Example Response**:
+
+```http
+HTTP/1.1 200
+Content-Type: application/json
+
+{
+  "message": "Notification deleted"
+}
+```
+
+## Test notification channel
+
+Sends a test notification message for the given notification channel type and settings.
+You can find the full list of [supported notifiers](/alerting/notifications/#all-supported-notifier) at the alert notifiers page.
+
+`POST /api/alert-notifications/test`
+
+**Example Request**:
+
+```http
+POST /api/alert-notifications/test HTTP/1.1
+Accept: application/json
+Content-Type: application/json
+Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
+
+{
+  "type":  "email",
+  "settings": {
+    "addresses": "carl@grafana.com;dev@grafana.com"
+  }
+}
+```
+
+**Example Response**:
+
+```http
+HTTP/1.1 200
+Content-Type: application/json
+
+{
+  "message": "Test notification sent"
+}
+```
+

+ 1 - 0
docs/sources/http_api/index.md

@@ -30,6 +30,7 @@ dashboards, creating users and updating data sources.
 * [Snapshot API]({{< relref "http_api/snapshot.md" >}})
 * [Annotations API]({{< relref "http_api/annotations.md" >}})
 * [Alerting API]({{< relref "http_api/alerting.md" >}})
+* [Alert Notification Channels API]({{< relref "http_api/alert_notification_channels.md" >}})
 * [User API]({{< relref "http_api/user.md" >}})
 * [Team API]({{< relref "http_api/team.md" >}})
 * [Admin API]({{< relref "http_api/admin.md" >}})

+ 49 - 0
pkg/api/alerting.go

@@ -208,6 +208,31 @@ func GetAlertNotificationByID(c *m.ReqContext) Response {
 		Id:    c.ParamsInt64("notificationId"),
 	}
 
+	if query.Id == 0 {
+		return Error(404, "Alert notification not found", nil)
+	}
+
+	if err := bus.Dispatch(query); err != nil {
+		return Error(500, "Failed to get alert notifications", err)
+	}
+
+	if query.Result == nil {
+		return Error(404, "Alert notification not found", nil)
+	}
+
+	return JSON(200, dtos.NewAlertNotification(query.Result))
+}
+
+func GetAlertNotificationByUID(c *m.ReqContext) Response {
+	query := &m.GetAlertNotificationsWithUidQuery{
+		OrgId: c.OrgId,
+		Uid:   c.Params("uid"),
+	}
+
+	if query.Uid == "" {
+		return Error(404, "Alert notification not found", nil)
+	}
+
 	if err := bus.Dispatch(query); err != nil {
 		return Error(500, "Failed to get alert notifications", err)
 	}
@@ -239,6 +264,17 @@ func UpdateAlertNotification(c *m.ReqContext, cmd m.UpdateAlertNotificationComma
 	return JSON(200, dtos.NewAlertNotification(cmd.Result))
 }
 
+func UpdateAlertNotificationByUID(c *m.ReqContext, cmd m.UpdateAlertNotificationWithUidCommand) Response {
+	cmd.OrgId = c.OrgId
+	cmd.Uid = c.Params("uid")
+
+	if err := bus.Dispatch(&cmd); err != nil {
+		return Error(500, "Failed to update alert notification", err)
+	}
+
+	return JSON(200, dtos.NewAlertNotification(cmd.Result))
+}
+
 func DeleteAlertNotification(c *m.ReqContext) Response {
 	cmd := m.DeleteAlertNotificationCommand{
 		OrgId: c.OrgId,
@@ -252,6 +288,19 @@ func DeleteAlertNotification(c *m.ReqContext) Response {
 	return Success("Notification deleted")
 }
 
+func DeleteAlertNotificationByUID(c *m.ReqContext) Response {
+	cmd := m.DeleteAlertNotificationWithUidCommand{
+		OrgId: c.OrgId,
+		Uid:   c.Params("uid"),
+	}
+
+	if err := bus.Dispatch(&cmd); err != nil {
+		return Error(500, "Failed to delete alert notification", err)
+	}
+
+	return Success("Notification deleted")
+}
+
 //POST /api/alert-notifications/test
 func NotificationTest(c *m.ReqContext, dto dtos.NotificationTestCommand) Response {
 	cmd := &alerting.NotificationTestCommand{

+ 3 - 0
pkg/api/api.go

@@ -350,6 +350,9 @@ func (hs *HTTPServer) registerRoutes() {
 			alertNotifications.Put("/:notificationId", bind(m.UpdateAlertNotificationCommand{}), Wrap(UpdateAlertNotification))
 			alertNotifications.Get("/:notificationId", Wrap(GetAlertNotificationByID))
 			alertNotifications.Delete("/:notificationId", Wrap(DeleteAlertNotification))
+			alertNotifications.Get("/uid/:uid", Wrap(GetAlertNotificationByUID))
+			alertNotifications.Put("/uid/:uid", bind(m.UpdateAlertNotificationWithUidCommand{}), Wrap(UpdateAlertNotificationByUID))
+			alertNotifications.Delete("/uid/:uid", Wrap(DeleteAlertNotificationByUID))
 		}, reqEditorRole)
 
 		apiRoute.Get("/annotations", Wrap(GetAnnotations))

+ 8 - 8
pkg/models/alert_notifications.go

@@ -67,14 +67,14 @@ type UpdateAlertNotificationCommand struct {
 }
 
 type UpdateAlertNotificationWithUidCommand struct {
-	Uid                   string
-	Name                  string
-	Type                  string
-	SendReminder          bool
-	DisableResolveMessage bool
-	Frequency             string
-	IsDefault             bool
-	Settings              *simplejson.Json
+	Uid                   string           `json:"-"`
+	Name                  string           `json:"name"  binding:"Required"`
+	Type                  string           `json:"type"  binding:"Required"`
+	SendReminder          bool             `json:"sendReminder"`
+	DisableResolveMessage bool             `json:"disableResolveMessage"`
+	Frequency             string           `json:"frequency"`
+	IsDefault             bool             `json:"isDefault"`
+	Settings              *simplejson.Json `json:"settings"  binding:"Required"`
 
 	OrgId  int64
 	Result *AlertNotification

+ 1 - 0
pkg/services/sqlstore/alert_notification.go

@@ -130,6 +130,7 @@ func getAlertNotificationInternal(query *m.GetAlertNotificationsQuery, sess *DBS
 
 	sql.WriteString(`SELECT
 										alert_notification.id,
+										alert_notification.uid,
 										alert_notification.org_id,
 										alert_notification.name,
 										alert_notification.type,