From 307e33614ee1d16cf85e6b02bf4b84b5aaa04529 Mon Sep 17 00:00:00 2001 From: Joe Blubaugh Date: Mon, 23 May 2022 22:41:29 +0800 Subject: [PATCH] Alerting: Add image_urls to OpsGenie notification details. (#49379) Adds an array of image_urls to the OpsGenie details field in a message, if image urls are available. ```json { "message": "Alert with Images!", "details": { "image_urls": ["http://www.example.com"] } } ``` --- .../ngalert/notifier/channels/opsgenie.go | 31 +++++++++++++++++-- .../notifier/channels/opsgenie_test.go | 2 +- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/pkg/services/ngalert/notifier/channels/opsgenie.go b/pkg/services/ngalert/notifier/channels/opsgenie.go index 43149270a39..2afcedac7d3 100644 --- a/pkg/services/ngalert/notifier/channels/opsgenie.go +++ b/pkg/services/ngalert/notifier/channels/opsgenie.go @@ -40,6 +40,7 @@ type OpsgenieNotifier struct { tmpl *template.Template log log.Logger ns notifications.WebhookSender + images ImageStore } type OpsgenieConfig struct { @@ -59,7 +60,7 @@ func OpsgenieFactory(fc FactoryConfig) (NotificationChannel, error) { Cfg: *fc.Config, } } - return NewOpsgenieNotifier(cfg, fc.NotificationService, fc.Template, fc.DecryptFunc), nil + return NewOpsgenieNotifier(cfg, fc.NotificationService, fc.ImageStore, fc.Template, fc.DecryptFunc), nil } func NewOpsgenieConfig(config *NotificationChannelConfig, decryptFunc GetDecryptedValueFn) (*OpsgenieConfig, error) { @@ -84,7 +85,7 @@ func NewOpsgenieConfig(config *NotificationChannelConfig, decryptFunc GetDecrypt } // NewOpsgenieNotifier is the constructor for the Opsgenie notifier -func NewOpsgenieNotifier(config *OpsgenieConfig, ns notifications.WebhookSender, t *template.Template, fn GetDecryptedValueFn) *OpsgenieNotifier { +func NewOpsgenieNotifier(config *OpsgenieConfig, ns notifications.WebhookSender, images ImageStore, t *template.Template, fn GetDecryptedValueFn) *OpsgenieNotifier { return &OpsgenieNotifier{ Base: NewBase(&models.AlertNotification{ Uid: config.UID, @@ -101,6 +102,7 @@ func NewOpsgenieNotifier(config *OpsgenieConfig, ns notifications.WebhookSender, tmpl: t, log: log.New("alerting.notifier." + config.Name), ns: ns, + images: images, } } @@ -208,6 +210,31 @@ func (on *OpsgenieNotifier) buildOpsgenieMessage(ctx context.Context, alerts mod for k, v := range lbls { details.Set(k, v) } + + images := []string{} + for i := range as { + imgToken := getTokenFromAnnotations(as[i].Annotations) + if len(imgToken) == 0 { + continue + } + + dbContext, cancel := context.WithTimeout(ctx, ImageStoreTimeout) + imgURL, err := on.images.GetURL(dbContext, imgToken) + cancel() + + if err != nil { + if !errors.Is(err, ErrImagesUnavailable) { + // Ignore errors. Don't log "ImageUnavailable", which means the storage doesn't exist. + on.log.Warn("Error reading screenshot data from ImageStore: %v", err) + } + } else if len(imgURL) != 0 { + images = append(images, imgURL) + } + } + + if len(images) != 0 { + details.Set("image_urls", images) + } } tags := make([]string, 0, len(lbls)) diff --git a/pkg/services/ngalert/notifier/channels/opsgenie_test.go b/pkg/services/ngalert/notifier/channels/opsgenie_test.go index 818f86f0ed7..c1b6179cb59 100644 --- a/pkg/services/ngalert/notifier/channels/opsgenie_test.go +++ b/pkg/services/ngalert/notifier/channels/opsgenie_test.go @@ -184,7 +184,7 @@ func TestOpsgenieNotifier(t *testing.T) { ctx := notify.WithGroupKey(context.Background(), "alertname") ctx = notify.WithGroupLabels(ctx, model.LabelSet{"alertname": ""}) - pn := NewOpsgenieNotifier(cfg, webhookSender, tmpl, decryptFn) + pn := NewOpsgenieNotifier(cfg, webhookSender, &UnavailableImageStore{}, tmpl, decryptFn) ok, err := pn.Notify(ctx, c.alerts...) if c.expMsgError != nil { require.False(t, ok)