diff --git a/pkg/services/ngalert/notifier/channels/webhook.go b/pkg/services/ngalert/notifier/channels/webhook.go index fc4e38350d9..f23d430512d 100644 --- a/pkg/services/ngalert/notifier/channels/webhook.go +++ b/pkg/services/ngalert/notifier/channels/webhook.go @@ -178,6 +178,7 @@ func (wn *WebhookNotifier) Notify(ctx context.Context, as ...*types.Alert) (bool if tmplErr != nil { wn.log.Warn("failed to template webhook message", "err", tmplErr.Error()) + tmplErr = nil } 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) } + parsedURL := tmpl(wn.settings.URL) + if tmplErr != nil { + return false, tmplErr + } + cmd := &models.SendWebhookSync{ - Url: wn.settings.URL, + Url: parsedURL, User: wn.settings.User, Password: wn.settings.Password, Body: string(body), diff --git a/pkg/services/ngalert/notifier/channels/webhook_test.go b/pkg/services/ngalert/notifier/channels/webhook_test.go index 53b9213158a..7ad2b2a9879 100644 --- a/pkg/services/ngalert/notifier/channels/webhook_test.go +++ b/pkg/services/ngalert/notifier/channels/webhook_test.go @@ -3,6 +3,7 @@ package channels import ( "context" "encoding/json" + "fmt" "net/url" "testing" @@ -175,6 +176,73 @@ func TestWebhookNotifier(t *testing.T) { expMsgError: nil, 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", settings: `{ @@ -234,6 +302,19 @@ func TestWebhookNotifier(t *testing.T) { expHttpMethod: "POST", 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", settings: `{