2021-03-18 20:25:11 +05:30
|
|
|
package channels
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
2021-03-26 12:53:14 +05:30
|
|
|
"fmt"
|
2021-03-18 20:25:11 +05:30
|
|
|
"net/url"
|
2021-03-26 12:53:14 +05:30
|
|
|
"strings"
|
2021-03-18 20:25:11 +05:30
|
|
|
|
|
|
|
|
gokit_log "github.com/go-kit/kit/log"
|
|
|
|
|
"github.com/grafana/grafana/pkg/infra/log"
|
|
|
|
|
"github.com/grafana/grafana/pkg/models"
|
|
|
|
|
"github.com/grafana/grafana/pkg/services/alerting"
|
|
|
|
|
old_notifiers "github.com/grafana/grafana/pkg/services/alerting/notifiers"
|
|
|
|
|
"github.com/grafana/grafana/pkg/util"
|
|
|
|
|
|
|
|
|
|
"github.com/grafana/grafana/pkg/bus"
|
|
|
|
|
"github.com/prometheus/alertmanager/notify"
|
|
|
|
|
"github.com/prometheus/alertmanager/template"
|
|
|
|
|
"github.com/prometheus/alertmanager/types"
|
|
|
|
|
"github.com/prometheus/common/model"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// EmailNotifier is responsible for sending
|
|
|
|
|
// alert notifications over email.
|
|
|
|
|
type EmailNotifier struct {
|
|
|
|
|
old_notifiers.NotifierBase
|
|
|
|
|
Addresses []string
|
|
|
|
|
SingleEmail bool
|
2021-04-08 22:51:09 +05:30
|
|
|
AutoResolve bool
|
2021-03-18 20:25:11 +05:30
|
|
|
log log.Logger
|
|
|
|
|
externalUrl *url.URL
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// NewEmailNotifier is the constructor function
|
|
|
|
|
// for the EmailNotifier.
|
2021-04-08 22:51:09 +05:30
|
|
|
func NewEmailNotifier(model *models.AlertNotification, externalUrl *url.URL) (*EmailNotifier, error) {
|
2021-03-18 20:25:11 +05:30
|
|
|
addressesString := model.Settings.Get("addresses").MustString()
|
|
|
|
|
singleEmail := model.Settings.Get("singleEmail").MustBool(false)
|
2021-04-08 22:51:09 +05:30
|
|
|
autoResolve := model.Settings.Get("autoResolve").MustBool(true)
|
2021-03-18 20:25:11 +05:30
|
|
|
|
|
|
|
|
if addressesString == "" {
|
|
|
|
|
return nil, alerting.ValidationError{Reason: "Could not find addresses in settings"}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// split addresses with a few different ways
|
|
|
|
|
addresses := util.SplitEmails(addressesString)
|
|
|
|
|
|
|
|
|
|
return &EmailNotifier{
|
|
|
|
|
NotifierBase: old_notifiers.NewNotifierBase(model),
|
|
|
|
|
Addresses: addresses,
|
|
|
|
|
SingleEmail: singleEmail,
|
2021-04-08 22:51:09 +05:30
|
|
|
AutoResolve: autoResolve,
|
2021-03-18 20:25:11 +05:30
|
|
|
log: log.New("alerting.notifier.email"),
|
2021-04-08 22:51:09 +05:30
|
|
|
externalUrl: externalUrl,
|
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-03-18 20:25:11 +05:30
|
|
|
// TODO(codesome): make sure the receiver name is added in the ctx before calling this.
|
|
|
|
|
ctx = notify.WithReceiverName(ctx, "email-notification-channel") // Dummy.
|
|
|
|
|
// TODO(codesome): make sure the group labels is added in the ctx before calling this.
|
|
|
|
|
ctx = notify.WithGroupLabels(ctx, model.LabelSet{}) // Dummy.
|
|
|
|
|
|
|
|
|
|
// We only need ExternalURL from this template object. This hack should go away with https://github.com/prometheus/alertmanager/pull/2508.
|
|
|
|
|
data := notify.GetTemplateData(ctx, &template.Template{ExternalURL: en.externalUrl}, as, gokit_log.NewNopLogger())
|
|
|
|
|
|
2021-03-26 12:53:14 +05:30
|
|
|
title := getTitleFromTemplateData(data)
|
|
|
|
|
|
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-03-18 20:25:11 +05:30
|
|
|
"Receiver": data.Receiver,
|
|
|
|
|
"Status": data.Status,
|
|
|
|
|
"Alerts": data.Alerts,
|
|
|
|
|
"GroupLabels": data.GroupLabels,
|
|
|
|
|
"CommonLabels": data.CommonLabels,
|
|
|
|
|
"CommonAnnotations": data.CommonAnnotations,
|
|
|
|
|
"ExternalURL": data.ExternalURL,
|
|
|
|
|
"RuleUrl": "TODO",
|
|
|
|
|
"AlertPageUrl": "TODO",
|
|
|
|
|
},
|
|
|
|
|
To: en.Addresses,
|
|
|
|
|
SingleEmail: en.SingleEmail,
|
|
|
|
|
Template: "ng_alert_notification.html",
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-24 14:20:44 +00:00
|
|
|
if err := bus.DispatchCtx(ctx, cmd); err != nil {
|
|
|
|
|
return false, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true, nil
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-26 12:53:14 +05:30
|
|
|
func getTitleFromTemplateData(data *template.Data) string {
|
|
|
|
|
title := "[" + data.Status
|
|
|
|
|
if data.Status == string(model.AlertFiring) {
|
|
|
|
|
title += fmt.Sprintf(":%d", len(data.Alerts.Firing()))
|
|
|
|
|
}
|
2021-04-07 14:52:48 +05:30
|
|
|
title += "] " + strings.Join(data.GroupLabels.SortedPairs().Values(), " ") + " "
|
2021-03-26 12:53:14 +05:30
|
|
|
if len(data.CommonLabels) > len(data.GroupLabels) {
|
|
|
|
|
title += "(" + strings.Join(data.CommonLabels.Remove(data.GroupLabels.Names()).Values(), " ") + ")"
|
|
|
|
|
}
|
|
|
|
|
return title
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-24 14:20:44 +00:00
|
|
|
func (en *EmailNotifier) SendResolved() bool {
|
2021-04-08 22:51:09 +05:30
|
|
|
return en.AutoResolve
|
2021-03-18 20:25:11 +05:30
|
|
|
}
|