Alerting: Add Image URLs to Microsoft Teams notifier. (#49385)

If there are screenshot images with URLs, they will be attached to the
Microsoft teams notification in the first sections, as a slice of image
objects.
This commit is contained in:
Joe Blubaugh 2022-05-23 21:53:36 +08:00 committed by GitHub
parent 762a84153d
commit 4ea0b39db1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 39 additions and 9 deletions

View File

@ -24,6 +24,7 @@ type TeamsNotifier struct {
tmpl *template.Template
log log.Logger
ns notifications.WebhookSender
images ImageStore
}
type TeamsConfig struct {
@ -42,7 +43,7 @@ func TeamsFactory(fc FactoryConfig) (NotificationChannel, error) {
Cfg: *fc.Config,
}
}
return NewTeamsNotifier(cfg, fc.NotificationService, fc.Template), nil
return NewTeamsNotifier(cfg, fc.NotificationService, fc.ImageStore, fc.Template), nil
}
func NewTeamsConfig(config *NotificationChannelConfig) (*TeamsConfig, error) {
@ -59,8 +60,12 @@ func NewTeamsConfig(config *NotificationChannelConfig) (*TeamsConfig, error) {
}, nil
}
type teamsImage struct {
Image string `json:"image"`
}
// NewTeamsNotifier is the constructor for Teams notifier.
func NewTeamsNotifier(config *TeamsConfig, ns notifications.WebhookSender, t *template.Template) *TeamsNotifier {
func NewTeamsNotifier(config *TeamsConfig, ns notifications.WebhookSender, images ImageStore, t *template.Template) *TeamsNotifier {
return &TeamsNotifier{
Base: NewBase(&models.AlertNotification{
Uid: config.UID,
@ -75,6 +80,7 @@ func NewTeamsNotifier(config *TeamsConfig, ns notifications.WebhookSender, t *te
SectionTitle: config.SectionTitle,
log: log.New("alerting.notifier.teams"),
ns: ns,
images: images,
tmpl: t,
}
}
@ -86,7 +92,36 @@ func (tn *TeamsNotifier) Notify(ctx context.Context, as ...*types.Alert) (bool,
ruleURL := joinUrlPath(tn.tmpl.ExternalURL.String(), "/alerting/list", tn.log)
images := []teamsImage{}
for i := range as {
imgToken := getTokenFromAnnotations(as[i].Annotations)
timeoutCtx, cancel := context.WithTimeout(ctx, ImageStoreTimeout)
imgURL, err := tn.images.GetURL(timeoutCtx, imgToken)
cancel()
if err != nil {
if !errors.Is(err, ErrImagesUnavailable) {
// Ignore errors. Don't log "ImageUnavailable", which means the storage doesn't exist.
tn.log.Warn("failed to retrieve image url from store", "error", err)
}
}
if len(imgURL) > 0 {
images = append(images, teamsImage{Image: imgURL})
}
}
// Note: these template calls must remain in this order
title := tmpl(tn.Title)
sections := []map[string]interface{}{
{
"title": tmpl(tn.SectionTitle),
"text": tmpl(tn.Message),
},
}
if len(images) != 0 {
sections[0]["images"] = images
}
body := map[string]interface{}{
"@type": "MessageCard",
"@context": "http://schema.org/extensions",
@ -95,12 +130,7 @@ func (tn *TeamsNotifier) Notify(ctx context.Context, as ...*types.Alert) (bool,
"summary": title,
"title": title,
"themeColor": getAlertStatusColor(types.Alerts(as...).Status()),
"sections": []map[string]interface{}{
{
"title": tmpl(tn.SectionTitle),
"text": tmpl(tn.Message),
},
},
"sections": sections,
"potentialAction": []map[string]interface{}{
{
"@context": "http://schema.org",

View File

@ -220,7 +220,7 @@ func TestTeamsNotifier(t *testing.T) {
ctx := notify.WithGroupKey(context.Background(), "alertname")
ctx = notify.WithGroupLabels(ctx, model.LabelSet{"alertname": ""})
pn := NewTeamsNotifier(cfg, webhookSender, tmpl)
pn := NewTeamsNotifier(cfg, webhookSender, &UnavailableImageStore{}, tmpl)
ok, err := pn.Notify(ctx, c.alerts...)
if c.expMsgError != nil {
require.False(t, ok)