Alerting: Add additional customisation to ngalert MS Teams notifier (#46372)

Makes the Title and Section Title of the Teams message customisable.
Closes #46366
This commit is contained in:
cianooooo 2022-04-27 18:03:15 +01:00 committed by GitHub
parent ebfb70dc12
commit e8f4b58a8b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 51 additions and 22 deletions

View File

@ -562,6 +562,21 @@ func GetAvailableNotifiers() []*alerting.NotifierPlugin {
PropertyName: "url", PropertyName: "url",
Required: true, Required: true,
}, },
{
Label: "Title",
Element: alerting.ElementTypeInput,
InputType: alerting.InputTypeText,
Description: "Templated title of the Teams message.",
PropertyName: "title",
Placeholder: `{{ template "default.title" . }}`,
},
{
Label: "Section Title",
Element: alerting.ElementTypeInput,
InputType: alerting.InputTypeText,
Description: "Section title for the Teams message. Leave blank for none.",
PropertyName: "sectiontitle",
},
{ // New in 8.0. { // New in 8.0.
Label: "Message", Label: "Message",
Element: alerting.ElementTypeTextArea, Element: alerting.ElementTypeTextArea,

View File

@ -19,6 +19,8 @@ type TeamsNotifier struct {
*Base *Base
URL string URL string
Message string Message string
Title string
SectionTitle string
tmpl *template.Template tmpl *template.Template
log log.Logger log log.Logger
ns notifications.WebhookSender ns notifications.WebhookSender
@ -28,6 +30,8 @@ type TeamsConfig struct {
*NotificationChannelConfig *NotificationChannelConfig
URL string URL string
Message string Message string
Title string
SectionTitle string
} }
func TeamsFactory(fc FactoryConfig) (NotificationChannel, error) { func TeamsFactory(fc FactoryConfig) (NotificationChannel, error) {
@ -50,6 +54,8 @@ func NewTeamsConfig(config *NotificationChannelConfig) (*TeamsConfig, error) {
NotificationChannelConfig: config, NotificationChannelConfig: config,
URL: URL, URL: URL,
Message: config.Settings.Get("message").MustString(`{{ template "teams.default.message" .}}`), Message: config.Settings.Get("message").MustString(`{{ template "teams.default.message" .}}`),
Title: config.Settings.Get("title").MustString(DefaultMessageTitleEmbed),
SectionTitle: config.Settings.Get("sectiontitle").MustString(""),
}, nil }, nil
} }
@ -65,6 +71,8 @@ func NewTeamsNotifier(config *TeamsConfig, ns notifications.WebhookSender, t *te
}), }),
URL: config.URL, URL: config.URL,
Message: config.Message, Message: config.Message,
Title: config.Title,
SectionTitle: config.SectionTitle,
log: log.New("alerting.notifier.teams"), log: log.New("alerting.notifier.teams"),
ns: ns, ns: ns,
tmpl: t, tmpl: t,
@ -78,7 +86,7 @@ func (tn *TeamsNotifier) Notify(ctx context.Context, as ...*types.Alert) (bool,
ruleURL := joinUrlPath(tn.tmpl.ExternalURL.String(), "/alerting/list", tn.log) ruleURL := joinUrlPath(tn.tmpl.ExternalURL.String(), "/alerting/list", tn.log)
title := tmpl(DefaultMessageTitleEmbed) title := tmpl(tn.Title)
body := map[string]interface{}{ body := map[string]interface{}{
"@type": "MessageCard", "@type": "MessageCard",
"@context": "http://schema.org/extensions", "@context": "http://schema.org/extensions",
@ -89,7 +97,7 @@ func (tn *TeamsNotifier) Notify(ctx context.Context, as ...*types.Alert) (bool,
"themeColor": getAlertStatusColor(types.Alerts(as...).Status()), "themeColor": getAlertStatusColor(types.Alerts(as...).Status()),
"sections": []map[string]interface{}{ "sections": []map[string]interface{}{
{ {
"title": "Details", "title": tmpl(tn.SectionTitle),
"text": tmpl(tn.Message), "text": tmpl(tn.Message),
}, },
}, },

View File

@ -48,7 +48,7 @@ func TestTeamsNotifier(t *testing.T) {
"themeColor": "#D63232", "themeColor": "#D63232",
"sections": []map[string]interface{}{ "sections": []map[string]interface{}{
{ {
"title": "Details", "title": "",
"text": "**Firing**\n\nValue: [no value]\nLabels:\n - alertname = alert1\n - lbl1 = val1\nAnnotations:\n - ann1 = annv1\nSilence: http://localhost/alerting/silence/new?alertmanager=grafana&matcher=alertname%3Dalert1&matcher=lbl1%3Dval1\nDashboard: http://localhost/d/abcd\nPanel: http://localhost/d/abcd?viewPanel=efgh\n", "text": "**Firing**\n\nValue: [no value]\nLabels:\n - alertname = alert1\n - lbl1 = val1\nAnnotations:\n - ann1 = annv1\nSilence: http://localhost/alerting/silence/new?alertmanager=grafana&matcher=alertname%3Dalert1&matcher=lbl1%3Dval1\nDashboard: http://localhost/d/abcd\nPanel: http://localhost/d/abcd?viewPanel=efgh\n",
}, },
}, },
@ -66,6 +66,8 @@ func TestTeamsNotifier(t *testing.T) {
name: "Custom config with multiple alerts", name: "Custom config with multiple alerts",
settings: `{ settings: `{
"url": "http://localhost", "url": "http://localhost",
"title": "{{ .CommonLabels.alertname }}",
"sectiontitle": "Details",
"message": "{{ len .Alerts.Firing }} alerts are firing, {{ len .Alerts.Resolved }} are resolved" "message": "{{ len .Alerts.Firing }} alerts are firing, {{ len .Alerts.Resolved }} are resolved"
}`, }`,
alerts: []*types.Alert{ alerts: []*types.Alert{
@ -84,8 +86,8 @@ func TestTeamsNotifier(t *testing.T) {
expMsg: map[string]interface{}{ expMsg: map[string]interface{}{
"@type": "MessageCard", "@type": "MessageCard",
"@context": "http://schema.org/extensions", "@context": "http://schema.org/extensions",
"summary": "[FIRING:2] ", "summary": "alert1",
"title": "[FIRING:2] ", "title": "alert1",
"themeColor": "#D63232", "themeColor": "#D63232",
"sections": []map[string]interface{}{ "sections": []map[string]interface{}{
{ {
@ -107,6 +109,8 @@ func TestTeamsNotifier(t *testing.T) {
name: "Missing field in template", name: "Missing field in template",
settings: `{ settings: `{
"url": "http://localhost", "url": "http://localhost",
"title": "{{ .CommonLabels.alertname }}",
"sectiontitle": "Details",
"message": "I'm a custom template {{ .NotAField }} bad template" "message": "I'm a custom template {{ .NotAField }} bad template"
}`, }`,
alerts: []*types.Alert{ alerts: []*types.Alert{
@ -125,8 +129,8 @@ func TestTeamsNotifier(t *testing.T) {
expMsg: map[string]interface{}{ expMsg: map[string]interface{}{
"@type": "MessageCard", "@type": "MessageCard",
"@context": "http://schema.org/extensions", "@context": "http://schema.org/extensions",
"summary": "[FIRING:2] ", "summary": "alert1",
"title": "[FIRING:2] ", "title": "alert1",
"themeColor": "#D63232", "themeColor": "#D63232",
"sections": []map[string]interface{}{ "sections": []map[string]interface{}{
{ {
@ -148,6 +152,8 @@ func TestTeamsNotifier(t *testing.T) {
name: "Invalid template", name: "Invalid template",
settings: `{ settings: `{
"url": "http://localhost", "url": "http://localhost",
"title": "{{ .CommonLabels.alertname }}",
"sectiontitle": "Details",
"message": "I'm a custom template {{ {.NotAField }} bad template" "message": "I'm a custom template {{ {.NotAField }} bad template"
}`, }`,
alerts: []*types.Alert{ alerts: []*types.Alert{
@ -166,8 +172,8 @@ func TestTeamsNotifier(t *testing.T) {
expMsg: map[string]interface{}{ expMsg: map[string]interface{}{
"@type": "MessageCard", "@type": "MessageCard",
"@context": "http://schema.org/extensions", "@context": "http://schema.org/extensions",
"summary": "[FIRING:2] ", "summary": "alert1",
"title": "[FIRING:2] ", "title": "alert1",
"themeColor": "#D63232", "themeColor": "#D63232",
"sections": []map[string]interface{}{ "sections": []map[string]interface{}{
{ {

View File

@ -2226,7 +2226,7 @@ var expNonEmailNotifications = map[string][]string{
"sections": [ "sections": [
{ {
"text": "**Firing**\n\nValue: [ var='A' labels={} value=1 ]\nLabels:\n - alertname = TeamsAlert\nAnnotations:\nSource: http://localhost:3000/alerting/grafana/UID_TeamsAlert/view\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matcher=alertname%3DTeamsAlert\n", "text": "**Firing**\n\nValue: [ var='A' labels={} value=1 ]\nLabels:\n - alertname = TeamsAlert\nAnnotations:\nSource: http://localhost:3000/alerting/grafana/UID_TeamsAlert/view\nSilence: http://localhost:3000/alerting/silence/new?alertmanager=grafana&matcher=alertname%3DTeamsAlert\n",
"title": "Details" "title": ""
} }
], ],
"summary": "[FIRING:1] TeamsAlert ", "summary": "[FIRING:1] TeamsAlert ",