Jelajahi Sumber

feat(alerting): basic support for creating and updating notifications

bergquist 9 tahun lalu
induk
melakukan
7f767224af

+ 17 - 4
pkg/api/alerting.go

@@ -169,20 +169,33 @@ func GetAlertNotifications(c *middleware.Context) Response {
 	return Json(200, query.Result)
 	return Json(200, query.Result)
 }
 }
 
 
-func CreateAlertNotification(c *middleware.Context, cmd *models.CreateAlertNotificationCommand) Response {
+func GetAlertNotificationById(c *middleware.Context) Response {
+	query := &models.GetAlertNotificationQuery{
+		OrgID: c.OrgId,
+		Id:    c.ParamsInt64("notificationId"),
+	}
+
+	if err := bus.Dispatch(query); err != nil {
+		return ApiError(500, "Failed to get alert notifications", err)
+	}
+
+	return Json(200, query.Result[0])
+}
+
+func CreateAlertNotification(c *middleware.Context, cmd models.CreateAlertNotificationCommand) Response {
 	cmd.OrgID = c.OrgId
 	cmd.OrgID = c.OrgId
 
 
-	if err := bus.Dispatch(cmd); err != nil {
+	if err := bus.Dispatch(&cmd); err != nil {
 		return ApiError(500, "Failed to create alert notification", err)
 		return ApiError(500, "Failed to create alert notification", err)
 	}
 	}
 
 
 	return Json(200, cmd.Result)
 	return Json(200, cmd.Result)
 }
 }
 
 
-func UpdateAlertNotification(c *middleware.Context, cmd *models.UpdateAlertNotificationCommand) Response {
+func UpdateAlertNotification(c *middleware.Context, cmd models.UpdateAlertNotificationCommand) Response {
 	cmd.OrgID = c.OrgId
 	cmd.OrgID = c.OrgId
 
 
-	if err := bus.Dispatch(cmd); err != nil {
+	if err := bus.Dispatch(&cmd); err != nil {
 		return ApiError(500, "Failed to update alert notification", err)
 		return ApiError(500, "Failed to update alert notification", err)
 	}
 	}
 
 

+ 3 - 1
pkg/api/api.go

@@ -252,9 +252,11 @@ func Register(r *macaron.Macaron) {
 			})
 			})
 
 
 			r.Get("/notifications", wrap(GetAlertNotifications))
 			r.Get("/notifications", wrap(GetAlertNotifications))
+
 			r.Group("/notification", func() {
 			r.Group("/notification", func() {
 				r.Post("/", bind(m.CreateAlertNotificationCommand{}), wrap(CreateAlertNotification))
 				r.Post("/", bind(m.CreateAlertNotificationCommand{}), wrap(CreateAlertNotification))
-				r.Put("/", bind(m.UpdateAlertNotificationCommand{}), wrap(UpdateAlertNotification))
+				r.Put("/:notificationId", bind(m.UpdateAlertNotificationCommand{}), wrap(UpdateAlertNotification))
+				r.Get("/:notificationId", wrap(GetAlertNotificationById))
 			})
 			})
 
 
 			r.Get("/changes", wrap(GetAlertChanges))
 			r.Get("/changes", wrap(GetAlertChanges))

+ 16 - 17
pkg/models/alert_notifications.go

@@ -7,31 +7,30 @@ import (
 )
 )
 
 
 type AlertNotification struct {
 type AlertNotification struct {
-	Id       int64
-	OrgId    int64
-	Name     string
-	Type     string
-	Settings *simplejson.Json
-
-	Created time.Time
-	Updated time.Time
+	Id       int64            `json:"id"`
+	OrgId    int64            `json:"-"`
+	Name     string           `json:"name"`
+	Type     string           `json:"type"`
+	Settings *simplejson.Json `json:"settings"`
+	Created  time.Time        `json:"created"`
+	Updated  time.Time        `json:"updated"`
 }
 }
 
 
 type CreateAlertNotificationCommand struct {
 type CreateAlertNotificationCommand struct {
-	Name     string
-	Type     string
-	OrgID    int64
-	Settings *simplejson.Json
+	Name     string           `json:"name"  binding:"Required"`
+	Type     string           `json:"type"  binding:"Required"`
+	OrgID    int64            `json:"-"`
+	Settings *simplejson.Json `json:"settings"`
 
 
 	Result *AlertNotification
 	Result *AlertNotification
 }
 }
 
 
 type UpdateAlertNotificationCommand struct {
 type UpdateAlertNotificationCommand struct {
-	Id       int64
-	Name     string
-	Type     string
-	OrgID    int64
-	Settings *simplejson.Json
+	Id       int64            `json:"id"  binding:"Required"`
+	Name     string           `json:"name"  binding:"Required"`
+	Type     string           `json:"type"  binding:"Required"`
+	OrgID    int64            `json:"-"`
+	Settings *simplejson.Json `json:"settings"  binding:"Required"`
 
 
 	Result *AlertNotification
 	Result *AlertNotification
 }
 }

+ 15 - 3
public/app/core/routes/routes.ts

@@ -202,9 +202,21 @@ function setupAngularRoutes($routeProvider, $locationProvider) {
     resolve: loadAlertingBundle,
     resolve: loadAlertingBundle,
   })
   })
   .when('/alerting/notifications', {
   .when('/alerting/notifications', {
-    templateUrl: 'public/app/features/alerting/partials/alert_notifications.html',
-    controller: 'AlertNotificationsCtrl',
-    contrllerAs: 'ctrl',
+    templateUrl: 'public/app/features/alerting/partials/notifications_list.html',
+    controller: 'AlertNotificationsListCtrl',
+    controllerAs: 'ctrl',
+    resolve: loadAlertingBundle,
+  })
+  .when('/alerting/notification/new', {
+    templateUrl: 'public/app/features/alerting/partials/notification_edit.html',
+    controller: 'AlertNotificationEditCtrl',
+    controllerAs: 'ctrl',
+    resolve: loadAlertingBundle,
+  })
+  .when('/alerting/notification/:notificationId/edit', {
+    templateUrl: 'public/app/features/alerting/partials/notification_edit.html',
+    controller: 'AlertNotificationEditCtrl',
+    controllerAs: 'ctrl',
     resolve: loadAlertingBundle,
     resolve: loadAlertingBundle,
   })
   })
   .when('/alerting/:alertId/states', {
   .when('/alerting/:alertId/states', {

+ 2 - 1
public/app/features/alerting/all.ts

@@ -1,4 +1,5 @@
 import './alerts_ctrl';
 import './alerts_ctrl';
 import './alert_log_ctrl';
 import './alert_log_ctrl';
-import './alert_notifications_ctrl';
+import './notifications_list_ctrl';
+import './notification_edit_ctrl';
 
 

+ 49 - 0
public/app/features/alerting/notification_edit_ctrl.ts

@@ -0,0 +1,49 @@
+///<reference path="../../headers/common.d.ts" />
+
+import angular from 'angular';
+import _ from 'lodash';
+import coreModule from '../../core/core_module';
+import config from 'app/core/config';
+
+export class AlertNotificationEditCtrl {
+
+  notification: any;
+
+  /** @ngInject */
+  constructor(private $routeParams, private backendSrv) {
+    if ($routeParams.notificationId) {
+      this.loadNotification($routeParams.notificationId);
+    }
+  }
+
+  loadNotification(notificationId) {
+    this.backendSrv.get(`/api/alerts/notification/${notificationId}`).then(result => {
+      console.log(result);
+      this.notification = result;
+    });
+  }
+
+  isNew() {
+    return this.notification === undefined || this.notification.id === undefined;
+  }
+
+  save() {
+    if (this.notification.id) {
+      console.log('this.notification: ', this.notification);
+      this.backendSrv.put(`/api/alerts/notification/${this.notification.id}`, this.notification)
+        .then(result => {
+          this.notification = result;
+          console.log('updated notification', result);
+        });
+    } else {
+      this.backendSrv.post(`/api/alerts/notification`, this.notification)
+        .then(result => {
+          this.notification = result;
+          console.log('created new notification', result);
+        });
+    }
+  }
+}
+
+coreModule.controller('AlertNotificationEditCtrl', AlertNotificationEditCtrl);
+

+ 7 - 2
public/app/features/alerting/alert_notifications_ctrl.ts → public/app/features/alerting/notifications_list_ctrl.ts

@@ -5,7 +5,9 @@ import _ from 'lodash';
 import coreModule from '../../core/core_module';
 import coreModule from '../../core/core_module';
 import config from 'app/core/config';
 import config from 'app/core/config';
 
 
-export class AlertNotificationsCtrl {
+export class AlertNotificationsListCtrl {
+
+  notifications: any;
 
 
   /** @ngInject */
   /** @ngInject */
   constructor(private backendSrv) {
   constructor(private backendSrv) {
@@ -13,8 +15,11 @@ export class AlertNotificationsCtrl {
   }
   }
 
 
   loadNotifications() {
   loadNotifications() {
+    this.backendSrv.get(`/api/alerts/notifications`).then(result => {
+      this.notifications = result;
+    });
   }
   }
 }
 }
 
 
-coreModule.controller('AlertNotificationsCtrl', AlertNotificationsCtrl);
+coreModule.controller('AlertNotificationsListCtrl', AlertNotificationsListCtrl);
 
 

+ 0 - 20
public/app/features/alerting/partials/alert_notifications.html

@@ -1,20 +0,0 @@
-
-<navbar icon="fa fa-fw fa-list" title="Alerting" title-url="alerting">
-</navbar>
-
-<div class="page-container" >
-	<div class="page-header">
-		<h1>Alert notifications</h1>
-	</div>
-
-	<table class="grafana-options-table">
-		<thead>
-			<th style="min-width: 200px"><strong>Name</strong></th>
-		</thead>
-		<tr ng-repeat="notification in ctrl.notifications">
-			<td class="text-center">
-				Name
-			</td>
-		</tr>
-	</table>
-</div>

+ 51 - 0
public/app/features/alerting/partials/notification_edit.html

@@ -0,0 +1,51 @@
+<navbar icon="fa fa-fw fa-list" title="Alerting" title-url="alerting">
+</navbar>
+
+<div class="page-container" >
+	<div class="page-header">
+		<h1>Alert notification</h1>
+  </div>
+
+	<div class="gf-form-group section">
+		<div class="gf-form">
+			<span class="gf-form-label width-8">Name</span>
+			<input type="text" class="gf-form-input max-width-12" ng-model="ctrl.notification.name"></input>
+		</div>
+		<div class="gf-form">
+			<span class="gf-form-label width-8">Type</span>
+			<div class="gf-form-select-wrapper width-12">
+				<select class="gf-form-input"
+					ng-model="ctrl.notification.type"
+					ng-options="t for t in ['webhook', 'email']"
+					ng-change="ctrl.typeChanged(notification, $index)">
+				</select>
+			</div>
+		</div>
+	</div>
+	<div class="gf-form-group section" ng-show="ctrl.notification.type === 'webhook'">
+		<div class="gf-form">
+			<span class="gf-form-label width-6">Url</span>
+			<input type="text" class="gf-form-input max-width-26" ng-model="ctrl.notification.settings.url"></input>
+		</div>
+		<div class="gf-form-inline">
+			<div class="gf-form">
+				<span class="gf-form-label width-6">Username</span>
+				<input type="text" class="gf-form-input max-width-10" ng-model="ctrl.notification.settings.username"></input>
+			</div>
+			<div class="gf-form">
+				<span class="gf-form-label width-6">Password</span>
+				<input type="text" class="gf-form-input max-width-10" ng-model="ctrl.notification.settings.password"></input>
+			</div>
+		</div>
+	</div>
+	<div class="gf-form-group section" ng-show="ctrl.notification.type === 'email'">
+		<div class="gf-form">
+			<span class="gf-form-label width-8">To</span>
+			<input type="text" class="gf-form-input max-width-26" ng-model="ctrl.notification.settings.to">
+		</div>
+	</div>
+
+  <div class="gf-form-button-group">
+    <button ng-click="ctrl.save()" class="btn btn-success">Save</button>
+  </div>
+</div>

+ 37 - 0
public/app/features/alerting/partials/notifications_list.html

@@ -0,0 +1,37 @@
+<navbar icon="fa fa-fw fa-list" title="Alerting" title-url="alerting">
+</navbar>
+
+<div class="page-container" >
+	<div class="page-header">
+		<h1>Alert notifications</h1>
+    <button class="btn btn-success pull-right">
+      <i class="fa fa-plus"></i>
+      New Notification
+    </button>
+  </div>
+
+	<table class="grafana-options-table">
+		<thead>
+			<th style="min-width: 200px"><strong>Name</strong></th>
+			<th style="width: 1%">Type</th>
+			<th style="width: 1%"></th>
+		</thead>
+		<tr ng-repeat="notification in ctrl.notifications">
+			<td>
+				<a href="alerting/notification{{notification.id}}/edit">
+					{{alert.name}}
+				</a>
+			</td>
+			<td class="text-center">
+				{{notification.type}}
+			</td>
+			<td class="text-center">
+				<a href="alerting/notification/{{notification.id}}/edit" class="btn btn-inverse btn-small">
+					<i class="fa fa-edit"></i>
+					edit
+				</a>
+			</td>
+		</tr>
+	</table>
+
+</div>