Alerting: Add templated subject config to email notifier (#49742)

* Add subject templating to email notifier

* Fix linting
This commit is contained in:
Matthew Jacobson
2022-05-30 11:55:34 -04:00
committed by GitHub
parent d82eb5902d
commit d92625125b
3 changed files with 37 additions and 5 deletions

View File

@@ -190,6 +190,14 @@ func GetAvailableNotifiers() []*alerting.NotifierPlugin {
Element: alerting.ElementTypeTextArea, Element: alerting.ElementTypeTextArea,
PropertyName: "message", PropertyName: "message",
}, },
{ // New in 9.0.
Label: "Subject",
Element: alerting.ElementTypeInput,
InputType: alerting.InputTypeText,
Description: "Templated subject of the email",
PropertyName: "subject",
Placeholder: `{{ template "default.title" . }}`,
},
}, },
}, },
{ {

View File

@@ -24,6 +24,7 @@ type EmailNotifier struct {
Addresses []string Addresses []string
SingleEmail bool SingleEmail bool
Message string Message string
Subject string
log log.Logger log log.Logger
ns notifications.EmailSender ns notifications.EmailSender
images ImageStore images ImageStore
@@ -35,6 +36,7 @@ type EmailConfig struct {
SingleEmail bool SingleEmail bool
Addresses []string Addresses []string
Message string Message string
Subject string
} }
func EmailFactory(fc FactoryConfig) (NotificationChannel, error) { func EmailFactory(fc FactoryConfig) (NotificationChannel, error) {
@@ -59,6 +61,7 @@ func NewEmailConfig(config *NotificationChannelConfig) (*EmailConfig, error) {
NotificationChannelConfig: config, NotificationChannelConfig: config,
SingleEmail: config.Settings.Get("singleEmail").MustBool(false), SingleEmail: config.Settings.Get("singleEmail").MustBool(false),
Message: config.Settings.Get("message").MustString(), Message: config.Settings.Get("message").MustString(),
Subject: config.Settings.Get("subject").MustString(DefaultMessageTitleEmbed),
Addresses: addresses, Addresses: addresses,
}, nil }, nil
} }
@@ -77,6 +80,7 @@ func NewEmailNotifier(config *EmailConfig, ns notifications.EmailSender, images
Addresses: config.Addresses, Addresses: config.Addresses,
SingleEmail: config.SingleEmail, SingleEmail: config.SingleEmail,
Message: config.Message, Message: config.Message,
Subject: config.Subject,
log: log.New("alerting.notifier.email"), log: log.New("alerting.notifier.email"),
ns: ns, ns: ns,
images: images, images: images,
@@ -89,7 +93,7 @@ func (en *EmailNotifier) Notify(ctx context.Context, as ...*types.Alert) (bool,
var tmplErr error var tmplErr error
tmpl, data := TmplText(ctx, en.tmpl, as, en.log, &tmplErr) tmpl, data := TmplText(ctx, en.tmpl, as, en.log, &tmplErr)
title := tmpl(DefaultMessageTitleEmbed) subject := tmpl(en.Subject)
alertPageURL := en.tmpl.ExternalURL.String() alertPageURL := en.tmpl.ExternalURL.String()
ruleURL := en.tmpl.ExternalURL.String() ruleURL := en.tmpl.ExternalURL.String()
@@ -106,9 +110,9 @@ func (en *EmailNotifier) Notify(ctx context.Context, as ...*types.Alert) (bool,
cmd := &models.SendEmailCommandSync{ cmd := &models.SendEmailCommandSync{
SendEmailCommand: models.SendEmailCommand{ SendEmailCommand: models.SendEmailCommand{
Subject: title, Subject: subject,
Data: map[string]interface{}{ Data: map[string]interface{}{
"Title": title, "Title": subject,
"Message": tmpl(en.Message), "Message": tmpl(en.Message),
"Status": data.Status, "Status": data.Status,
"Alerts": data.Alerts, "Alerts": data.Alerts,

View File

@@ -117,6 +117,7 @@ func TestEmailNotifierIntegration(t *testing.T) {
name string name string
alerts []*types.Alert alerts []*types.Alert
messageTmpl string messageTmpl string
subjectTmpl string
expSubject string expSubject string
expSnippets []string expSnippets []string
}{ }{
@@ -220,11 +221,25 @@ func TestEmailNotifierIntegration(t *testing.T) {
"<li>Firing: AlwaysFiring at warning </li>", "<li>Firing: AlwaysFiring at warning </li>",
}, },
}, },
{
name: "single alert with templated subject",
alerts: []*types.Alert{
{
Alert: model.Alert{
Labels: model.LabelSet{"alertname": "AlwaysFiring", "severity": "warning"},
Annotations: model.LabelSet{"runbook_url": "http://fix.me", "__dashboardUid__": "abc", "__panelId__": "5"},
},
},
},
subjectTmpl: `This notification is {{ .Status }}!`,
expSubject: "This notification is firing!",
expSnippets: []string{},
},
} }
for _, c := range cases { for _, c := range cases {
t.Run(c.name, func(t *testing.T) { t.Run(c.name, func(t *testing.T) {
emailNotifier := createSut(t, c.messageTmpl, emailTmpl, ns) emailNotifier := createSut(t, c.messageTmpl, c.subjectTmpl, emailTmpl, ns)
ok, err := emailNotifier.Notify(context.Background(), c.alerts...) ok, err := emailNotifier.Notify(context.Background(), c.alerts...)
require.NoError(t, err) require.NoError(t, err)
@@ -271,7 +286,7 @@ func createCoreEmailService(t *testing.T) *notifications.NotificationService {
return ns return ns
} }
func createSut(t *testing.T, messageTmpl string, emailTmpl *template.Template, ns notifications.EmailSender) *EmailNotifier { func createSut(t *testing.T, messageTmpl string, subjectTmpl string, emailTmpl *template.Template, ns notifications.EmailSender) *EmailNotifier {
t.Helper() t.Helper()
json := `{ json := `{
@@ -282,6 +297,11 @@ func createSut(t *testing.T, messageTmpl string, emailTmpl *template.Template, n
if messageTmpl != "" { if messageTmpl != "" {
settingsJSON.Set("message", messageTmpl) settingsJSON.Set("message", messageTmpl)
} }
if subjectTmpl != "" {
settingsJSON.Set("subject", subjectTmpl)
}
require.NoError(t, err) require.NoError(t, err)
cfg, err := NewEmailConfig(&NotificationChannelConfig{ cfg, err := NewEmailConfig(&NotificationChannelConfig{
Name: "ops", Name: "ops",