mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
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:
parent
762a84153d
commit
4ea0b39db1
@ -24,6 +24,7 @@ type TeamsNotifier struct {
|
|||||||
tmpl *template.Template
|
tmpl *template.Template
|
||||||
log log.Logger
|
log log.Logger
|
||||||
ns notifications.WebhookSender
|
ns notifications.WebhookSender
|
||||||
|
images ImageStore
|
||||||
}
|
}
|
||||||
|
|
||||||
type TeamsConfig struct {
|
type TeamsConfig struct {
|
||||||
@ -42,7 +43,7 @@ func TeamsFactory(fc FactoryConfig) (NotificationChannel, error) {
|
|||||||
Cfg: *fc.Config,
|
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) {
|
func NewTeamsConfig(config *NotificationChannelConfig) (*TeamsConfig, error) {
|
||||||
@ -59,8 +60,12 @@ func NewTeamsConfig(config *NotificationChannelConfig) (*TeamsConfig, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type teamsImage struct {
|
||||||
|
Image string `json:"image"`
|
||||||
|
}
|
||||||
|
|
||||||
// NewTeamsNotifier is the constructor for Teams notifier.
|
// 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{
|
return &TeamsNotifier{
|
||||||
Base: NewBase(&models.AlertNotification{
|
Base: NewBase(&models.AlertNotification{
|
||||||
Uid: config.UID,
|
Uid: config.UID,
|
||||||
@ -75,6 +80,7 @@ func NewTeamsNotifier(config *TeamsConfig, ns notifications.WebhookSender, t *te
|
|||||||
SectionTitle: config.SectionTitle,
|
SectionTitle: config.SectionTitle,
|
||||||
log: log.New("alerting.notifier.teams"),
|
log: log.New("alerting.notifier.teams"),
|
||||||
ns: ns,
|
ns: ns,
|
||||||
|
images: images,
|
||||||
tmpl: t,
|
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)
|
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)
|
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{}{
|
body := map[string]interface{}{
|
||||||
"@type": "MessageCard",
|
"@type": "MessageCard",
|
||||||
"@context": "http://schema.org/extensions",
|
"@context": "http://schema.org/extensions",
|
||||||
@ -95,12 +130,7 @@ func (tn *TeamsNotifier) Notify(ctx context.Context, as ...*types.Alert) (bool,
|
|||||||
"summary": title,
|
"summary": title,
|
||||||
"title": title,
|
"title": title,
|
||||||
"themeColor": getAlertStatusColor(types.Alerts(as...).Status()),
|
"themeColor": getAlertStatusColor(types.Alerts(as...).Status()),
|
||||||
"sections": []map[string]interface{}{
|
"sections": sections,
|
||||||
{
|
|
||||||
"title": tmpl(tn.SectionTitle),
|
|
||||||
"text": tmpl(tn.Message),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"potentialAction": []map[string]interface{}{
|
"potentialAction": []map[string]interface{}{
|
||||||
{
|
{
|
||||||
"@context": "http://schema.org",
|
"@context": "http://schema.org",
|
||||||
|
@ -220,7 +220,7 @@ func TestTeamsNotifier(t *testing.T) {
|
|||||||
|
|
||||||
ctx := notify.WithGroupKey(context.Background(), "alertname")
|
ctx := notify.WithGroupKey(context.Background(), "alertname")
|
||||||
ctx = notify.WithGroupLabels(ctx, model.LabelSet{"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...)
|
ok, err := pn.Notify(ctx, c.alerts...)
|
||||||
if c.expMsgError != nil {
|
if c.expMsgError != nil {
|
||||||
require.False(t, ok)
|
require.False(t, ok)
|
||||||
|
Loading…
Reference in New Issue
Block a user