Commit 7f767224 by bergquist

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

parent 00fc2e25
...@@ -169,20 +169,33 @@ func GetAlertNotifications(c *middleware.Context) Response { ...@@ -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)
} }
......
...@@ -252,9 +252,11 @@ func Register(r *macaron.Macaron) { ...@@ -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))
......
...@@ -7,31 +7,30 @@ import ( ...@@ -7,31 +7,30 @@ import (
) )
type AlertNotification struct { type AlertNotification struct {
Id int64 Id int64 `json:"id"`
OrgId int64 OrgId int64 `json:"-"`
Name string Name string `json:"name"`
Type string Type string `json:"type"`
Settings *simplejson.Json Settings *simplejson.Json `json:"settings"`
Created time.Time `json:"created"`
Created time.Time Updated time.Time `json:"updated"`
Updated time.Time
} }
type CreateAlertNotificationCommand struct { type CreateAlertNotificationCommand struct {
Name string Name string `json:"name" binding:"Required"`
Type string Type string `json:"type" binding:"Required"`
OrgID int64 OrgID int64 `json:"-"`
Settings *simplejson.Json Settings *simplejson.Json `json:"settings"`
Result *AlertNotification Result *AlertNotification
} }
type UpdateAlertNotificationCommand struct { type UpdateAlertNotificationCommand struct {
Id int64 Id int64 `json:"id" binding:"Required"`
Name string Name string `json:"name" binding:"Required"`
Type string Type string `json:"type" binding:"Required"`
OrgID int64 OrgID int64 `json:"-"`
Settings *simplejson.Json Settings *simplejson.Json `json:"settings" binding:"Required"`
Result *AlertNotification Result *AlertNotification
} }
......
...@@ -202,9 +202,21 @@ function setupAngularRoutes($routeProvider, $locationProvider) { ...@@ -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', templateUrl: 'public/app/features/alerting/partials/notifications_list.html',
controller: 'AlertNotificationsCtrl', controller: 'AlertNotificationsListCtrl',
contrllerAs: 'ctrl', 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', {
......
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';
///<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);
...@@ -5,7 +5,9 @@ import _ from 'lodash'; ...@@ -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 { ...@@ -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);
<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>
<navbar icon="fa fa-fw fa-list" title="Alerting" title-url="alerting"> <navbar icon="fa fa-fw fa-list" title="Alerting" title-url="alerting">
</navbar> </navbar>
<div class="page-container" > <div class="page-container" >
<div class="page-header"> <div class="page-header">
<h1>Alert notifications</h1> <h1>Alert notifications</h1>
</div> <button class="btn btn-success pull-right">
<i class="fa fa-plus"></i>
New Notification
</button>
</div>
<table class="grafana-options-table"> <table class="grafana-options-table">
<thead> <thead>
<th style="min-width: 200px"><strong>Name</strong></th> <th style="min-width: 200px"><strong>Name</strong></th>
<th style="width: 1%">Type</th>
<th style="width: 1%"></th>
</thead> </thead>
<tr ng-repeat="notification in ctrl.notifications"> <tr ng-repeat="notification in ctrl.notifications">
<td>
<a href="alerting/notification{{notification.id}}/edit">
{{alert.name}}
</a>
</td>
<td class="text-center"> <td class="text-center">
Name {{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> </td>
</tr> </tr>
</table> </table>
</div> </div>
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