2021-03-18 20:25:11 +05:30
|
|
|
package channels
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
2021-05-19 19:58:31 +03:00
|
|
|
"net/url"
|
2021-04-22 19:31:55 +05:30
|
|
|
"path"
|
2021-03-18 20:25:11 +05:30
|
|
|
|
2021-04-15 16:01:41 +05:30
|
|
|
"github.com/prometheus/alertmanager/template"
|
|
|
|
|
"github.com/prometheus/alertmanager/types"
|
|
|
|
|
|
|
|
|
|
"github.com/grafana/grafana/pkg/bus"
|
2021-03-18 20:25:11 +05:30
|
|
|
"github.com/grafana/grafana/pkg/infra/log"
|
|
|
|
|
"github.com/grafana/grafana/pkg/models"
|
|
|
|
|
"github.com/grafana/grafana/pkg/util"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// EmailNotifier is responsible for sending
|
|
|
|
|
// alert notifications over email.
|
|
|
|
|
type EmailNotifier struct {
|
2021-10-22 10:11:06 +01:00
|
|
|
*Base
|
2021-03-18 20:25:11 +05:30
|
|
|
Addresses []string
|
|
|
|
|
SingleEmail bool
|
2021-05-17 16:05:09 +05:30
|
|
|
Message string
|
2021-03-18 20:25:11 +05:30
|
|
|
log log.Logger
|
2021-05-17 16:05:09 +05:30
|
|
|
tmpl *template.Template
|
2021-03-18 20:25:11 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// NewEmailNotifier is the constructor function
|
|
|
|
|
// for the EmailNotifier.
|
2021-05-18 13:34:47 +05:30
|
|
|
func NewEmailNotifier(model *NotificationChannelConfig, t *template.Template) (*EmailNotifier, error) {
|
2021-04-15 16:01:41 +05:30
|
|
|
if model.Settings == nil {
|
2021-11-22 11:56:18 +00:00
|
|
|
return nil, receiverInitError{Cfg: *model, Reason: "no settings supplied"}
|
2021-04-15 16:01:41 +05:30
|
|
|
}
|
|
|
|
|
|
2021-03-18 20:25:11 +05:30
|
|
|
addressesString := model.Settings.Get("addresses").MustString()
|
|
|
|
|
singleEmail := model.Settings.Get("singleEmail").MustBool(false)
|
|
|
|
|
|
|
|
|
|
if addressesString == "" {
|
2021-07-19 11:58:35 +03:00
|
|
|
return nil, receiverInitError{Reason: "could not find addresses in settings", Cfg: *model}
|
2021-03-18 20:25:11 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// split addresses with a few different ways
|
|
|
|
|
addresses := util.SplitEmails(addressesString)
|
|
|
|
|
|
|
|
|
|
return &EmailNotifier{
|
2021-10-22 10:11:06 +01:00
|
|
|
Base: NewBase(&models.AlertNotification{
|
2021-05-18 13:34:47 +05:30
|
|
|
Uid: model.UID,
|
|
|
|
|
Name: model.Name,
|
|
|
|
|
Type: model.Type,
|
|
|
|
|
DisableResolveMessage: model.DisableResolveMessage,
|
|
|
|
|
Settings: model.Settings,
|
|
|
|
|
}),
|
|
|
|
|
Addresses: addresses,
|
|
|
|
|
SingleEmail: singleEmail,
|
|
|
|
|
Message: model.Settings.Get("message").MustString(),
|
|
|
|
|
log: log.New("alerting.notifier.email"),
|
|
|
|
|
tmpl: t,
|
2021-03-18 20:25:11 +05:30
|
|
|
}, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Notify sends the alert notification.
|
2021-03-24 14:20:44 +00:00
|
|
|
func (en *EmailNotifier) Notify(ctx context.Context, as ...*types.Alert) (bool, error) {
|
2021-05-26 20:19:39 +05:30
|
|
|
var tmplErr error
|
2021-06-03 19:39:32 +05:30
|
|
|
tmpl, data := TmplText(ctx, en.tmpl, as, en.log, &tmplErr)
|
2021-03-18 20:25:11 +05:30
|
|
|
|
2021-05-17 16:05:09 +05:30
|
|
|
title := tmpl(`{{ template "default.title" . }}`)
|
2021-03-26 12:53:14 +05:30
|
|
|
|
2021-06-03 19:39:32 +05:30
|
|
|
alertPageURL := en.tmpl.ExternalURL.String()
|
|
|
|
|
ruleURL := en.tmpl.ExternalURL.String()
|
2021-05-19 19:58:31 +03:00
|
|
|
u, err := url.Parse(en.tmpl.ExternalURL.String())
|
2021-06-03 19:39:32 +05:30
|
|
|
if err == nil {
|
|
|
|
|
basePath := u.Path
|
|
|
|
|
u.Path = path.Join(basePath, "/alerting/list")
|
|
|
|
|
ruleURL = u.String()
|
|
|
|
|
u.RawQuery = "alertState=firing&view=state"
|
|
|
|
|
alertPageURL = u.String()
|
|
|
|
|
} else {
|
|
|
|
|
en.log.Debug("failed to parse external URL", "url", en.tmpl.ExternalURL.String(), "err", err.Error())
|
2021-05-19 19:58:31 +03:00
|
|
|
}
|
|
|
|
|
|
2021-03-18 20:25:11 +05:30
|
|
|
cmd := &models.SendEmailCommandSync{
|
|
|
|
|
SendEmailCommand: models.SendEmailCommand{
|
2021-03-26 12:53:14 +05:30
|
|
|
Subject: title,
|
2021-03-18 20:25:11 +05:30
|
|
|
Data: map[string]interface{}{
|
2021-03-26 12:53:14 +05:30
|
|
|
"Title": title,
|
2021-05-17 16:05:09 +05:30
|
|
|
"Message": tmpl(en.Message),
|
2021-03-18 20:25:11 +05:30
|
|
|
"Status": data.Status,
|
|
|
|
|
"Alerts": data.Alerts,
|
|
|
|
|
"GroupLabels": data.GroupLabels,
|
|
|
|
|
"CommonLabels": data.CommonLabels,
|
|
|
|
|
"CommonAnnotations": data.CommonAnnotations,
|
|
|
|
|
"ExternalURL": data.ExternalURL,
|
2021-05-19 19:58:31 +03:00
|
|
|
"RuleUrl": ruleURL,
|
|
|
|
|
"AlertPageUrl": alertPageURL,
|
2021-03-18 20:25:11 +05:30
|
|
|
},
|
|
|
|
|
To: en.Addresses,
|
|
|
|
|
SingleEmail: en.SingleEmail,
|
2021-07-19 12:31:51 +02:00
|
|
|
Template: "ng_alert_notification",
|
2021-03-18 20:25:11 +05:30
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-17 16:05:09 +05:30
|
|
|
if tmplErr != nil {
|
2021-06-03 19:39:32 +05:30
|
|
|
en.log.Debug("failed to template email message", "err", tmplErr.Error())
|
2021-05-17 16:05:09 +05:30
|
|
|
}
|
|
|
|
|
|
2021-12-28 17:36:22 +01:00
|
|
|
if err := bus.Dispatch(ctx, cmd); err != nil {
|
2021-03-24 14:20:44 +00:00
|
|
|
return false, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (en *EmailNotifier) SendResolved() bool {
|
2021-04-22 21:46:26 +05:30
|
|
|
return !en.GetDisableResolveMessage()
|
2021-03-18 20:25:11 +05:30
|
|
|
}
|