2016-07-27 05:09:55 -05:00
|
|
|
package notifiers
|
|
|
|
|
|
|
|
import (
|
2021-07-13 07:14:04 -05:00
|
|
|
"encoding/json"
|
|
|
|
|
2016-07-27 05:09:55 -05:00
|
|
|
"github.com/grafana/grafana/pkg/bus"
|
2019-05-13 01:45:54 -05:00
|
|
|
"github.com/grafana/grafana/pkg/infra/log"
|
2019-05-14 01:15:05 -05:00
|
|
|
"github.com/grafana/grafana/pkg/models"
|
2016-07-27 05:09:55 -05:00
|
|
|
"github.com/grafana/grafana/pkg/services/alerting"
|
|
|
|
)
|
|
|
|
|
|
|
|
func init() {
|
2017-01-06 05:04:25 -06:00
|
|
|
alerting.RegisterNotifier(&alerting.NotifierPlugin{
|
|
|
|
Type: "webhook",
|
|
|
|
Name: "webhook",
|
|
|
|
Description: "Sends HTTP POST request to a URL",
|
2020-06-29 06:39:12 -05:00
|
|
|
Heading: "Webhook settings",
|
2017-01-06 05:04:25 -06:00
|
|
|
Factory: NewWebHookNotifier,
|
2020-06-29 06:39:12 -05:00
|
|
|
Options: []alerting.NotifierOption{
|
|
|
|
{
|
|
|
|
Label: "Url",
|
|
|
|
Element: alerting.ElementTypeInput,
|
|
|
|
InputType: alerting.InputTypeText,
|
|
|
|
PropertyName: "url",
|
|
|
|
Required: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Label: "Http Method",
|
|
|
|
Element: alerting.ElementTypeSelect,
|
|
|
|
SelectOptions: []alerting.SelectOption{
|
|
|
|
{
|
|
|
|
Value: "POST",
|
|
|
|
Label: "POST",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Value: "PUT",
|
|
|
|
Label: "PUT",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
PropertyName: "httpMethod",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Label: "Username",
|
|
|
|
Element: alerting.ElementTypeInput,
|
|
|
|
InputType: alerting.InputTypeText,
|
|
|
|
PropertyName: "username",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Label: "Password",
|
|
|
|
Element: alerting.ElementTypeInput,
|
|
|
|
InputType: alerting.InputTypePassword,
|
|
|
|
PropertyName: "password",
|
2020-09-09 05:46:19 -05:00
|
|
|
Secure: true,
|
2020-06-29 06:39:12 -05:00
|
|
|
},
|
|
|
|
},
|
2017-01-06 05:04:25 -06:00
|
|
|
})
|
2016-07-27 05:09:55 -05:00
|
|
|
}
|
|
|
|
|
2019-05-20 08:23:06 -05:00
|
|
|
// NewWebHookNotifier is the constructor for
|
|
|
|
// the WebHook notifier.
|
2019-05-14 01:15:05 -05:00
|
|
|
func NewWebHookNotifier(model *models.AlertNotification) (alerting.Notifier, error) {
|
2016-07-27 05:09:55 -05:00
|
|
|
url := model.Settings.Get("url").MustString()
|
|
|
|
if url == "" {
|
2016-07-27 09:29:28 -05:00
|
|
|
return nil, alerting.ValidationError{Reason: "Could not find url property in settings"}
|
2016-07-27 05:09:55 -05:00
|
|
|
}
|
|
|
|
|
2020-07-08 10:46:34 -05:00
|
|
|
password := model.DecryptedValue("password", model.Settings.Get("password").MustString())
|
|
|
|
|
2016-07-27 05:09:55 -05:00
|
|
|
return &WebhookNotifier{
|
2018-06-05 03:27:29 -05:00
|
|
|
NotifierBase: NewNotifierBase(model),
|
2019-05-20 08:23:06 -05:00
|
|
|
URL: url,
|
2020-07-08 12:13:59 -05:00
|
|
|
User: model.Settings.Get("username").MustString(),
|
2020-07-08 10:46:34 -05:00
|
|
|
Password: password,
|
2019-05-20 08:23:06 -05:00
|
|
|
HTTPMethod: model.Settings.Get("httpMethod").MustString("POST"),
|
2016-09-06 06:19:05 -05:00
|
|
|
log: log.New("alerting.notifier.webhook"),
|
2016-07-27 05:09:55 -05:00
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
2019-05-20 08:23:06 -05:00
|
|
|
// WebhookNotifier is responsible for sending
|
|
|
|
// alert notifications as webhooks.
|
2016-07-27 05:09:55 -05:00
|
|
|
type WebhookNotifier struct {
|
|
|
|
NotifierBase
|
2019-05-20 08:23:06 -05:00
|
|
|
URL string
|
2016-10-18 09:18:16 -05:00
|
|
|
User string
|
|
|
|
Password string
|
2019-05-20 08:23:06 -05:00
|
|
|
HTTPMethod string
|
2016-10-18 09:18:16 -05:00
|
|
|
log log.Logger
|
2016-07-27 05:09:55 -05:00
|
|
|
}
|
|
|
|
|
2021-07-13 07:14:04 -05:00
|
|
|
// WebhookNotifierBody is the body of webhook
|
|
|
|
// notification channel
|
|
|
|
type WebhookNotifierBody struct {
|
|
|
|
Title string `json:"title"`
|
|
|
|
RuleID int64 `json:"ruleId"`
|
|
|
|
RuleName string `json:"ruleName"`
|
|
|
|
State models.AlertStateType `json:"state"`
|
|
|
|
EvalMatches []*alerting.EvalMatch `json:"evalMatches"`
|
|
|
|
OrgID int64 `json:"orgId"`
|
|
|
|
DashboardID int64 `json:"dashboardId"`
|
|
|
|
PanelID int64 `json:"panelId"`
|
|
|
|
Tags map[string]string `json:"tags"`
|
|
|
|
RuleURL string `json:"ruleUrl,omitempty"`
|
|
|
|
ImageURL string `json:"imageUrl,omitempty"`
|
|
|
|
Message string `json:"message,omitempty"`
|
|
|
|
}
|
|
|
|
|
2019-05-20 08:23:06 -05:00
|
|
|
// Notify send alert notifications as
|
|
|
|
// webhook as http requests.
|
|
|
|
func (wn *WebhookNotifier) Notify(evalContext *alerting.EvalContext) error {
|
|
|
|
wn.log.Info("Sending webhook")
|
2016-07-27 05:09:55 -05:00
|
|
|
|
2021-07-13 07:14:04 -05:00
|
|
|
body := WebhookNotifierBody{
|
|
|
|
Title: evalContext.GetNotificationTitle(),
|
|
|
|
RuleID: evalContext.Rule.ID,
|
|
|
|
RuleName: evalContext.Rule.Name,
|
|
|
|
State: evalContext.Rule.State,
|
|
|
|
EvalMatches: evalContext.EvalMatches,
|
|
|
|
OrgID: evalContext.Rule.OrgID,
|
|
|
|
DashboardID: evalContext.Rule.DashboardID,
|
|
|
|
PanelID: evalContext.Rule.PanelID,
|
|
|
|
}
|
2016-08-22 08:11:27 -05:00
|
|
|
|
2019-08-03 10:00:40 -05:00
|
|
|
tags := make(map[string]string)
|
|
|
|
|
|
|
|
for _, tag := range evalContext.Rule.AlertRuleTags {
|
|
|
|
tags[tag.Key] = tag.Value
|
|
|
|
}
|
|
|
|
|
2021-07-13 07:14:04 -05:00
|
|
|
body.Tags = tags
|
2019-08-03 10:00:40 -05:00
|
|
|
|
2019-06-03 03:25:58 -05:00
|
|
|
ruleURL, err := evalContext.GetRuleURL()
|
2016-08-22 08:11:27 -05:00
|
|
|
if err == nil {
|
2021-07-13 07:14:04 -05:00
|
|
|
body.RuleURL = ruleURL
|
2016-08-22 08:11:27 -05:00
|
|
|
}
|
|
|
|
|
2020-03-30 17:46:01 -05:00
|
|
|
if wn.NeedsImage() && evalContext.ImagePublicURL != "" {
|
2021-07-13 07:14:04 -05:00
|
|
|
body.ImageURL = evalContext.ImagePublicURL
|
2016-08-22 08:11:27 -05:00
|
|
|
}
|
2016-07-27 05:09:55 -05:00
|
|
|
|
2016-12-02 15:24:35 -06:00
|
|
|
if evalContext.Rule.Message != "" {
|
2021-07-13 07:14:04 -05:00
|
|
|
body.Message = evalContext.Rule.Message
|
2016-12-02 15:24:35 -06:00
|
|
|
}
|
|
|
|
|
2021-07-13 07:14:04 -05:00
|
|
|
bodyJSON, _ := json.Marshal(body)
|
2016-07-27 05:09:55 -05:00
|
|
|
|
2019-05-14 01:15:05 -05:00
|
|
|
cmd := &models.SendWebhookSync{
|
2019-05-20 08:23:06 -05:00
|
|
|
Url: wn.URL,
|
|
|
|
User: wn.User,
|
|
|
|
Password: wn.Password,
|
2021-07-13 07:14:04 -05:00
|
|
|
Body: string(bodyJSON),
|
2019-05-20 08:23:06 -05:00
|
|
|
HttpMethod: wn.HTTPMethod,
|
2016-07-27 05:09:55 -05:00
|
|
|
}
|
|
|
|
|
2016-10-03 10:03:21 -05:00
|
|
|
if err := bus.DispatchCtx(evalContext.Ctx, cmd); err != nil {
|
2019-05-20 08:23:06 -05:00
|
|
|
wn.log.Error("Failed to send webhook", "error", err, "webhook", wn.Name)
|
2016-12-12 03:20:50 -06:00
|
|
|
return err
|
2016-07-27 05:09:55 -05:00
|
|
|
}
|
2016-10-03 02:38:03 -05:00
|
|
|
|
|
|
|
return nil
|
2016-07-27 05:09:55 -05:00
|
|
|
}
|