mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Alerting: Templated URLs for webhook type contact points (#57296)
* templated URLs for webhooks * clear tmplErr before using tmpl() again
This commit is contained in:
@@ -178,6 +178,7 @@ func (wn *WebhookNotifier) Notify(ctx context.Context, as ...*types.Alert) (bool
|
|||||||
|
|
||||||
if tmplErr != nil {
|
if tmplErr != nil {
|
||||||
wn.log.Warn("failed to template webhook message", "err", tmplErr.Error())
|
wn.log.Warn("failed to template webhook message", "err", tmplErr.Error())
|
||||||
|
tmplErr = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
body, err := json.Marshal(msg)
|
body, err := json.Marshal(msg)
|
||||||
@@ -190,8 +191,13 @@ func (wn *WebhookNotifier) Notify(ctx context.Context, as ...*types.Alert) (bool
|
|||||||
headers["Authorization"] = fmt.Sprintf("%s %s", wn.settings.AuthorizationScheme, wn.settings.AuthorizationCredentials)
|
headers["Authorization"] = fmt.Sprintf("%s %s", wn.settings.AuthorizationScheme, wn.settings.AuthorizationCredentials)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parsedURL := tmpl(wn.settings.URL)
|
||||||
|
if tmplErr != nil {
|
||||||
|
return false, tmplErr
|
||||||
|
}
|
||||||
|
|
||||||
cmd := &models.SendWebhookSync{
|
cmd := &models.SendWebhookSync{
|
||||||
Url: wn.settings.URL,
|
Url: parsedURL,
|
||||||
User: wn.settings.User,
|
User: wn.settings.User,
|
||||||
Password: wn.settings.Password,
|
Password: wn.settings.Password,
|
||||||
Body: string(body),
|
Body: string(body),
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package channels
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@@ -175,6 +176,73 @@ func TestWebhookNotifier(t *testing.T) {
|
|||||||
expMsgError: nil,
|
expMsgError: nil,
|
||||||
expHeaders: map[string]string{},
|
expHeaders: map[string]string{},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "Default config, template variables in URL",
|
||||||
|
settings: `{"url": "http://localhost/test?numAlerts={{len .Alerts}}&status={{.Status}}"}`,
|
||||||
|
alerts: []*types.Alert{
|
||||||
|
{
|
||||||
|
Alert: model.Alert{
|
||||||
|
Labels: model.LabelSet{"alertname": "alert1", "lbl1": "val1"},
|
||||||
|
Annotations: model.LabelSet{"ann1": "annv1"},
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
Alert: model.Alert{
|
||||||
|
Labels: model.LabelSet{"alertname": "alert1", "lbl1": "val2"},
|
||||||
|
Annotations: model.LabelSet{"ann1": "annv2"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expUrl: "http://localhost/test?numAlerts=2&status=firing",
|
||||||
|
expHttpMethod: "POST",
|
||||||
|
expMsg: &WebhookMessage{
|
||||||
|
ExtendedData: &ExtendedData{
|
||||||
|
Receiver: "my_receiver",
|
||||||
|
Status: "firing",
|
||||||
|
Alerts: ExtendedAlerts{
|
||||||
|
{
|
||||||
|
Status: "firing",
|
||||||
|
Labels: template.KV{
|
||||||
|
"alertname": "alert1",
|
||||||
|
"lbl1": "val1",
|
||||||
|
},
|
||||||
|
Annotations: template.KV{
|
||||||
|
"ann1": "annv1",
|
||||||
|
},
|
||||||
|
Fingerprint: "fac0861a85de433a",
|
||||||
|
SilenceURL: "http://localhost/alerting/silence/new?alertmanager=grafana&matcher=alertname%3Dalert1&matcher=lbl1%3Dval1",
|
||||||
|
}, {
|
||||||
|
Status: "firing",
|
||||||
|
Labels: template.KV{
|
||||||
|
"alertname": "alert1",
|
||||||
|
"lbl1": "val2",
|
||||||
|
},
|
||||||
|
Annotations: template.KV{
|
||||||
|
"ann1": "annv2",
|
||||||
|
},
|
||||||
|
Fingerprint: "fab6861a85d5eeb5",
|
||||||
|
SilenceURL: "http://localhost/alerting/silence/new?alertmanager=grafana&matcher=alertname%3Dalert1&matcher=lbl1%3Dval2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
GroupLabels: template.KV{
|
||||||
|
"alertname": "",
|
||||||
|
},
|
||||||
|
CommonLabels: template.KV{
|
||||||
|
"alertname": "alert1",
|
||||||
|
},
|
||||||
|
CommonAnnotations: template.KV{},
|
||||||
|
ExternalURL: "http://localhost",
|
||||||
|
},
|
||||||
|
Version: "1",
|
||||||
|
GroupKey: "alertname",
|
||||||
|
TruncatedAlerts: 0,
|
||||||
|
Title: "[FIRING:2] ",
|
||||||
|
State: "alerting",
|
||||||
|
Message: "**Firing**\n\nValue: [no value]\nLabels:\n - alertname = alert1\n - lbl1 = val1\nAnnotations:\n - ann1 = annv1\nSilence: http://localhost/alerting/silence/new?alertmanager=grafana&matcher=alertname%3Dalert1&matcher=lbl1%3Dval1\n\nValue: [no value]\nLabels:\n - alertname = alert1\n - lbl1 = val2\nAnnotations:\n - ann1 = annv2\nSilence: http://localhost/alerting/silence/new?alertmanager=grafana&matcher=alertname%3Dalert1&matcher=lbl1%3Dval2\n",
|
||||||
|
OrgID: orgID,
|
||||||
|
},
|
||||||
|
expMsgError: nil,
|
||||||
|
expHeaders: map[string]string{},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "with Authorization set",
|
name: "with Authorization set",
|
||||||
settings: `{
|
settings: `{
|
||||||
@@ -234,6 +302,19 @@ func TestWebhookNotifier(t *testing.T) {
|
|||||||
expHttpMethod: "POST",
|
expHttpMethod: "POST",
|
||||||
expHeaders: map[string]string{"Authorization": "Bearer mysecret"},
|
expHeaders: map[string]string{"Authorization": "Bearer mysecret"},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "bad template in url",
|
||||||
|
settings: `{"url": "http://localhost/test1?numAlerts={{len Alerts}}"}`,
|
||||||
|
alerts: []*types.Alert{
|
||||||
|
{
|
||||||
|
Alert: model.Alert{
|
||||||
|
Labels: model.LabelSet{"alertname": "alert1", "lbl1": "val1"},
|
||||||
|
Annotations: model.LabelSet{"ann1": "annv1", "__dashboardUid__": "abcd", "__panelId__": "efgh"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expMsgError: fmt.Errorf("template: :1: function \"Alerts\" not defined"),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "with both HTTP basic auth and Authorization Header set",
|
name: "with both HTTP basic auth and Authorization Header set",
|
||||||
settings: `{
|
settings: `{
|
||||||
|
|||||||
Reference in New Issue
Block a user