mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Alerting: Adds support for multiple URLs in Alertmanager notifier (#24196)
* Alerting: Adds support for multiple URLs in Alertmanager notifier Adds support for multiple URLs in Alertmanager notifier following alertmanager documentation for high availability setup. Update the documentation for alertmanager notifier. Closes #24195 Co-authored-by: Diana Payton <52059945+oddlittlebird@users.noreply.github.com> Co-authored-by: bergquist <carl.bergquist@gmail.com>
This commit is contained in:
committed by
GitHub
parent
50b2f26d80
commit
3a0f2dc160
@@ -3,6 +3,7 @@ package notifiers
|
||||
import (
|
||||
"context"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
@@ -20,17 +21,20 @@ func init() {
|
||||
Factory: NewAlertmanagerNotifier,
|
||||
OptionsTemplate: `
|
||||
<h3 class="page-heading">Alertmanager settings</h3>
|
||||
<div class="gf-form">
|
||||
<span class="gf-form-label width-10">Url</span>
|
||||
<input type="text" required class="gf-form-input max-width-26" ng-model="ctrl.model.settings.url" placeholder="http://localhost:9093"></input>
|
||||
<div class="gf-form max-width-30">
|
||||
<span class="gf-form-label width-10">Url(s)</span>
|
||||
<input type="text" required class="gf-form-input max-width-30" ng-model="ctrl.model.settings.url" placeholder="http://localhost:9093"></input>
|
||||
<info-popover mode="right-absolute">
|
||||
As specified in Alertmanager documentation, do not specify a load balancer here. Enter all your Alertmanager URLs comma-separated.
|
||||
</info-popover>
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
<div class="gf-form max-width-30">
|
||||
<span class="gf-form-label width-10">Basic Auth User</span>
|
||||
<input type="text" class="gf-form-input max-width-26" ng-model="ctrl.model.settings.basicAuthUser" placeholder=""></input>
|
||||
<input type="text" class="gf-form-input max-width-30" ng-model="ctrl.model.settings.basicAuthUser" placeholder=""></input>
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
<div class="gf-form max-width-30">
|
||||
<span class="gf-form-label width-10">Basic Auth Password</span>
|
||||
<input type="text" class="gf-form-input max-width-26" ng-model="ctrl.model.settings.basicAuthPassword" placeholder=""></input>
|
||||
<input type="text" class="gf-form-input max-width-30" ng-model="ctrl.model.settings.basicAuthPassword" placeholder=""></input>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
@@ -39,10 +43,18 @@ func init() {
|
||||
|
||||
// NewAlertmanagerNotifier returns a new Alertmanager notifier
|
||||
func NewAlertmanagerNotifier(model *models.AlertNotification) (alerting.Notifier, error) {
|
||||
url := model.Settings.Get("url").MustString()
|
||||
if url == "" {
|
||||
urlString := model.Settings.Get("url").MustString()
|
||||
if urlString == "" {
|
||||
return nil, alerting.ValidationError{Reason: "Could not find url property in settings"}
|
||||
}
|
||||
|
||||
var url []string
|
||||
for _, u := range strings.Split(urlString, ",") {
|
||||
u = strings.TrimSpace(u)
|
||||
if u != "" {
|
||||
url = append(url, u)
|
||||
}
|
||||
}
|
||||
basicAuthUser := model.Settings.Get("basicAuthUser").MustString()
|
||||
basicAuthPassword := model.Settings.Get("basicAuthPassword").MustString()
|
||||
|
||||
@@ -58,7 +70,7 @@ func NewAlertmanagerNotifier(model *models.AlertNotification) (alerting.Notifier
|
||||
// AlertmanagerNotifier sends alert notifications to the alert manager
|
||||
type AlertmanagerNotifier struct {
|
||||
NotifierBase
|
||||
URL string
|
||||
URL []string
|
||||
BasicAuthUser string
|
||||
BasicAuthPassword string
|
||||
log log.Logger
|
||||
@@ -153,17 +165,19 @@ func (am *AlertmanagerNotifier) Notify(evalContext *alerting.EvalContext) error
|
||||
bodyJSON := simplejson.NewFromAny(alerts)
|
||||
body, _ := bodyJSON.MarshalJSON()
|
||||
|
||||
cmd := &models.SendWebhookSync{
|
||||
Url: am.URL + "/api/v1/alerts",
|
||||
User: am.BasicAuthUser,
|
||||
Password: am.BasicAuthPassword,
|
||||
HttpMethod: "POST",
|
||||
Body: string(body),
|
||||
}
|
||||
for _, url := range am.URL {
|
||||
cmd := &models.SendWebhookSync{
|
||||
Url: strings.TrimSuffix(url, "/") + "/api/v1/alerts",
|
||||
User: am.BasicAuthUser,
|
||||
Password: am.BasicAuthPassword,
|
||||
HttpMethod: "POST",
|
||||
Body: string(body),
|
||||
}
|
||||
|
||||
if err := bus.DispatchCtx(evalContext.Ctx, cmd); err != nil {
|
||||
am.log.Error("Failed to send alertmanager", "error", err, "alertmanager", am.Name)
|
||||
return err
|
||||
if err := bus.DispatchCtx(evalContext.Ctx, cmd); err != nil {
|
||||
am.log.Error("Failed to send alertmanager", "error", err, "alertmanager", am.Name, "url", url)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -97,7 +97,7 @@ func TestAlertmanagerNotifier(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("from settings", func() {
|
||||
json := `{ "url": "http://127.0.0.1:9093/" }`
|
||||
json := `{ "url": "http://127.0.0.1:9093/", "basicAuthUser": "user", "basicAuthPassword": "password" }`
|
||||
|
||||
settingsJSON, _ := simplejson.NewJson([]byte(json))
|
||||
model := &models.AlertNotification{
|
||||
@@ -110,7 +110,26 @@ func TestAlertmanagerNotifier(t *testing.T) {
|
||||
alertmanagerNotifier := not.(*AlertmanagerNotifier)
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
So(alertmanagerNotifier.URL, ShouldEqual, "http://127.0.0.1:9093/")
|
||||
So(alertmanagerNotifier.BasicAuthUser, ShouldEqual, "user")
|
||||
So(alertmanagerNotifier.BasicAuthPassword, ShouldEqual, "password")
|
||||
So(alertmanagerNotifier.URL, ShouldResemble, []string{"http://127.0.0.1:9093/"})
|
||||
})
|
||||
|
||||
Convey("from settings with multiple alertmanager", func() {
|
||||
json := `{ "url": "http://alertmanager1:9093,http://alertmanager2:9093" }`
|
||||
|
||||
settingsJSON, _ := simplejson.NewJson([]byte(json))
|
||||
model := &models.AlertNotification{
|
||||
Name: "alertmanager",
|
||||
Type: "alertmanager",
|
||||
Settings: settingsJSON,
|
||||
}
|
||||
|
||||
not, err := NewAlertmanagerNotifier(model)
|
||||
alertmanagerNotifier := not.(*AlertmanagerNotifier)
|
||||
|
||||
So(err, ShouldBeNil)
|
||||
So(alertmanagerNotifier.URL, ShouldResemble, []string{"http://alertmanager1:9093", "http://alertmanager2:9093"})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user