grafana/pkg/services/ngalert/notifier/channels/email.go
Ganesh Vernekar 0b788b5ce8
AlertingNG: Notification channel for emails (#31768)
* Email notification channel in ngalert

Signed-off-by: Ganesh Vernekar <cs15btech11018@iith.ac.in>

* Use existing templating system

Signed-off-by: Ganesh Vernekar <cs15btech11018@iith.ac.in>

* Update template and add unit tests

Signed-off-by: Ganesh Vernekar <cs15btech11018@iith.ac.in>
2021-03-18 14:55:11 +00:00

93 lines
3.0 KiB
Go

package channels
import (
"context"
"net/url"
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
log log.Logger
externalUrl *url.URL
}
// NewEmailNotifier is the constructor function
// for the EmailNotifier.
func NewEmailNotifier(model *models.AlertNotification) (*EmailNotifier, error) {
addressesString := model.Settings.Get("addresses").MustString()
singleEmail := model.Settings.Get("singleEmail").MustBool(false)
if addressesString == "" {
return nil, alerting.ValidationError{Reason: "Could not find addresses in settings"}
}
// split addresses with a few different ways
addresses := util.SplitEmails(addressesString)
// TODO: remove this URL hack and add an actual external URL.
u, err := url.Parse("http://localhost")
if err != nil {
return nil, err
}
return &EmailNotifier{
NotifierBase: old_notifiers.NewNotifierBase(model),
Addresses: addresses,
SingleEmail: singleEmail,
log: log.New("alerting.notifier.email"),
externalUrl: u,
}, nil
}
// Notify sends the alert notification.
func (en *EmailNotifier) Notify(ctx context.Context, as ...*types.Alert) error {
// 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())
cmd := &models.SendEmailCommandSync{
SendEmailCommand: models.SendEmailCommand{
Subject: "TODO",
Data: map[string]interface{}{
"Title": "TODO",
"Subject": "TODO",
"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",
},
}
return bus.DispatchCtx(ctx, cmd)
}