diff --git a/pkg/services/ngalert/notifier/alertmanager.go b/pkg/services/ngalert/notifier/alertmanager.go index c107de17cf5..bf2b2c7cfe9 100644 --- a/pkg/services/ngalert/notifier/alertmanager.go +++ b/pkg/services/ngalert/notifier/alertmanager.go @@ -514,7 +514,7 @@ func (am *Alertmanager) buildReceiverIntegration(r *apimodels.PostableGrafanaRec SecureSettings: secureSettings, } ) - factoryConfig, err := channels.NewFactoryConfig(cfg, NewNotificationSender(am.NotificationService), am.decryptFn, tmpl, am.Store) + factoryConfig, err := channels.NewFactoryConfig(cfg, NewNotificationSender(am.NotificationService), am.decryptFn, tmpl, newImageStore(am.Store)) if err != nil { return nil, InvalidReceiverError{ Receiver: r, diff --git a/pkg/services/ngalert/notifier/channels/alertmanager.go b/pkg/services/ngalert/notifier/channels/alertmanager.go index 9d5d32e4531..0430653a4e3 100644 --- a/pkg/services/ngalert/notifier/channels/alertmanager.go +++ b/pkg/services/ngalert/notifier/channels/alertmanager.go @@ -14,7 +14,6 @@ import ( "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/models" - ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models" ) // GetDecryptedValueFn is a function that returns the decrypted value of @@ -104,7 +103,7 @@ func (n *AlertmanagerNotifier) Notify(ctx context.Context, as ...*types.Alert) ( } _ = withStoredImages(ctx, n.logger, n.images, - func(index int, image ngmodels.Image) error { + func(index int, image Image) error { // If there is an image for this alert and the image has been uploaded // to a public URL then include it as an annotation if image.URL != "" { diff --git a/pkg/services/ngalert/notifier/channels/discord.go b/pkg/services/ngalert/notifier/channels/discord.go index 3d7fb1532e0..cf3a50c1b96 100644 --- a/pkg/services/ngalert/notifier/channels/discord.go +++ b/pkg/services/ngalert/notifier/channels/discord.go @@ -19,7 +19,6 @@ import ( "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/models" - ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models" "github.com/grafana/grafana/pkg/setting" ) @@ -193,7 +192,7 @@ func (d DiscordNotifier) constructAttachments(ctx context.Context, as []*types.A attachments := make([]discordAttachment, 0) _ = withStoredImages(ctx, d.log, d.images, - func(index int, image ngmodels.Image) error { + func(index int, image Image) error { if embedQuota < 1 { return ErrImagesDone } @@ -213,7 +212,7 @@ func (d DiscordNotifier) constructAttachments(ctx context.Context, as []*types.A base := filepath.Base(image.Path) url := fmt.Sprintf("attachment://%s", base) reader, err := openImage(image.Path) - if err != nil && !errors.Is(err, ngmodels.ErrImageNotFound) { + if err != nil && !errors.Is(err, ErrImageNotFound) { d.log.Warn("failed to retrieve image data from store", "error", err) return nil } diff --git a/pkg/services/ngalert/notifier/channels/email.go b/pkg/services/ngalert/notifier/channels/email.go index 2ff07d12cb4..56ea5534c06 100644 --- a/pkg/services/ngalert/notifier/channels/email.go +++ b/pkg/services/ngalert/notifier/channels/email.go @@ -13,7 +13,6 @@ import ( "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/models" - ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models" "github.com/grafana/grafana/pkg/util" ) @@ -110,7 +109,7 @@ func (en *EmailNotifier) Notify(ctx context.Context, alerts ...*types.Alert) (bo // Extend alerts data with images, if available. var embeddedFiles []string _ = withStoredImages(ctx, en.log, en.images, - func(index int, image ngmodels.Image) error { + func(index int, image Image) error { if len(image.URL) != 0 { data.Alerts[index].ImageURL = image.URL } else if len(image.Path) != 0 { diff --git a/pkg/services/ngalert/notifier/channels/factory.go b/pkg/services/ngalert/notifier/channels/factory.go index 5f5c08ce591..36e6ff90a84 100644 --- a/pkg/services/ngalert/notifier/channels/factory.go +++ b/pkg/services/ngalert/notifier/channels/factory.go @@ -1,13 +1,10 @@ package channels import ( - "context" "errors" "strings" "github.com/prometheus/alertmanager/template" - - "github.com/grafana/grafana/pkg/services/ngalert/models" ) type FactoryConfig struct { @@ -19,10 +16,6 @@ type FactoryConfig struct { Template *template.Template } -type ImageStore interface { - GetImage(ctx context.Context, token string) (*models.Image, error) -} - func NewFactoryConfig(config *NotificationChannelConfig, notificationService NotificationSender, decryptFunc GetDecryptedValueFn, template *template.Template, imageStore ImageStore) (FactoryConfig, error) { if config.Settings == nil { diff --git a/pkg/services/ngalert/notifier/channels/googlechat.go b/pkg/services/ngalert/notifier/channels/googlechat.go index cdc5b6b31ef..f5f2f93039a 100644 --- a/pkg/services/ngalert/notifier/channels/googlechat.go +++ b/pkg/services/ngalert/notifier/channels/googlechat.go @@ -13,7 +13,6 @@ import ( "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/models" - ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models" "github.com/grafana/grafana/pkg/setting" ) @@ -197,7 +196,7 @@ func (gcn *GoogleChatNotifier) buildScreenshotCard(ctx context.Context, alerts [ } _ = withStoredImages(ctx, gcn.log, gcn.images, - func(index int, image ngmodels.Image) error { + func(index int, image Image) error { if len(image.URL) == 0 { return nil } diff --git a/pkg/services/ngalert/notifier/channels/images.go b/pkg/services/ngalert/notifier/channels/images.go new file mode 100644 index 00000000000..ceb723a2396 --- /dev/null +++ b/pkg/services/ngalert/notifier/channels/images.go @@ -0,0 +1,26 @@ +package channels + +import ( + "context" + "errors" + "time" +) + +var ( + ErrImageNotFound = errors.New("image not found") +) + +type Image struct { + Token string + Path string + URL string + CreatedAt time.Time +} + +func (i Image) HasURL() bool { + return i.URL != "" +} + +type ImageStore interface { + GetImage(ctx context.Context, token string) (*Image, error) +} diff --git a/pkg/services/ngalert/notifier/channels/kafka.go b/pkg/services/ngalert/notifier/channels/kafka.go index bc0aff3fff2..c433ce00c1c 100644 --- a/pkg/services/ngalert/notifier/channels/kafka.go +++ b/pkg/services/ngalert/notifier/channels/kafka.go @@ -13,7 +13,6 @@ import ( "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/models" - ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models" ) // KafkaNotifier is responsible for sending @@ -161,7 +160,7 @@ func buildState(as ...*types.Alert) models.AlertStateType { func buildContextImages(ctx context.Context, l log.Logger, imageStore ImageStore, as ...*types.Alert) []interface{} { var contexts []interface{} _ = withStoredImages(ctx, l, imageStore, - func(_ int, image ngmodels.Image) error { + func(_ int, image Image) error { if image.URL != "" { imageJSON := simplejson.New() imageJSON.Set("type", "image") diff --git a/pkg/services/ngalert/notifier/channels/opsgenie.go b/pkg/services/ngalert/notifier/channels/opsgenie.go index 13b88378eaf..0a4e38a4ec2 100644 --- a/pkg/services/ngalert/notifier/channels/opsgenie.go +++ b/pkg/services/ngalert/notifier/channels/opsgenie.go @@ -17,7 +17,6 @@ import ( "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/models" - ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models" ) const ( @@ -246,7 +245,7 @@ func (on *OpsgenieNotifier) buildOpsgenieMessage(ctx context.Context, alerts mod } var images []string _ = withStoredImages(ctx, on.log, on.images, - func(_ int, image ngmodels.Image) error { + func(_ int, image Image) error { if len(image.URL) == 0 { return nil } diff --git a/pkg/services/ngalert/notifier/channels/pagerduty.go b/pkg/services/ngalert/notifier/channels/pagerduty.go index 95c1fd60d69..519be1c185c 100644 --- a/pkg/services/ngalert/notifier/channels/pagerduty.go +++ b/pkg/services/ngalert/notifier/channels/pagerduty.go @@ -15,7 +15,6 @@ import ( "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/models" - ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models" ) const ( @@ -231,7 +230,7 @@ func (pn *PagerdutyNotifier) buildPagerdutyMessage(ctx context.Context, alerts m } _ = withStoredImages(ctx, pn.log, pn.images, - func(_ int, image ngmodels.Image) error { + func(_ int, image Image) error { if len(image.URL) != 0 { msg.Images = append(msg.Images, pagerDutyImage{Src: image.URL}) } diff --git a/pkg/services/ngalert/notifier/channels/pushover.go b/pkg/services/ngalert/notifier/channels/pushover.go index 1b1819200bd..1827f7c0472 100644 --- a/pkg/services/ngalert/notifier/channels/pushover.go +++ b/pkg/services/ngalert/notifier/channels/pushover.go @@ -19,7 +19,6 @@ import ( "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/models" - ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models" ) const ( @@ -316,7 +315,7 @@ func (pn *PushoverNotifier) genPushoverBody(ctx context.Context, as ...*types.Al func (pn *PushoverNotifier) writeImageParts(ctx context.Context, w *multipart.Writer, as ...*types.Alert) { // Pushover supports at most one image attachment with a maximum size of pushoverMaxFileSize. // If the image is larger than pushoverMaxFileSize then return an error. - _ = withStoredImages(ctx, pn.log, pn.images, func(index int, image ngmodels.Image) error { + _ = withStoredImages(ctx, pn.log, pn.images, func(index int, image Image) error { f, err := os.Open(image.Path) if err != nil { return fmt.Errorf("failed to open the image: %w", err) diff --git a/pkg/services/ngalert/notifier/channels/sensugo.go b/pkg/services/ngalert/notifier/channels/sensugo.go index ac481258015..4f8b953151b 100644 --- a/pkg/services/ngalert/notifier/channels/sensugo.go +++ b/pkg/services/ngalert/notifier/channels/sensugo.go @@ -13,7 +13,6 @@ import ( "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/models" - ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models" ) type SensuGoNotifier struct { @@ -127,7 +126,7 @@ func (sn *SensuGoNotifier) Notify(ctx context.Context, as ...*types.Alert) (bool labels := make(map[string]string) _ = withStoredImages(ctx, sn.log, sn.images, - func(_ int, image ngmodels.Image) error { + func(_ int, image Image) error { // If there is an image for this alert and the image has been uploaded // to a public URL then add it to the request. We cannot add more than // one image per request. diff --git a/pkg/services/ngalert/notifier/channels/slack.go b/pkg/services/ngalert/notifier/channels/slack.go index d2745292c93..4b75dbdbef2 100644 --- a/pkg/services/ngalert/notifier/channels/slack.go +++ b/pkg/services/ngalert/notifier/channels/slack.go @@ -24,7 +24,6 @@ import ( "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/models" - ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models" "github.com/grafana/grafana/pkg/setting" ) @@ -220,7 +219,7 @@ func (sn *SlackNotifier) Notify(ctx context.Context, alerts ...*types.Alert) (bo // Do not upload images if using an incoming webhook as incoming webhooks cannot upload files if !isIncomingWebhook(sn.settings) { - if err := withStoredImages(ctx, sn.log, sn.images, func(index int, image ngmodels.Image) error { + if err := withStoredImages(ctx, sn.log, sn.images, func(index int, image Image) error { // If we have exceeded the maximum number of images for this thread_ts // then tell the recipient and stop iterating subsequent images if index >= maxImagesPerThreadTs { @@ -393,7 +392,7 @@ func (sn *SlackNotifier) createSlackMessage(ctx context.Context, alerts []*types if isIncomingWebhook(sn.settings) { // Incoming webhooks cannot upload files, instead share images via their URL - _ = withStoredImages(ctx, sn.log, sn.images, func(index int, image ngmodels.Image) error { + _ = withStoredImages(ctx, sn.log, sn.images, func(index int, image Image) error { if image.URL != "" { req.Attachments[0].ImageURL = image.URL return ErrImagesDone @@ -476,7 +475,7 @@ func (sn *SlackNotifier) sendSlackMessage(ctx context.Context, m *slackMessage) // createImageMultipart returns the mutlipart/form-data request and headers for files.upload. // It returns an error if the image does not exist or there was an error preparing the // multipart form. -func (sn *SlackNotifier) createImageMultipart(image ngmodels.Image, channel, comment, thread_ts string) (http.Header, []byte, error) { +func (sn *SlackNotifier) createImageMultipart(image Image, channel, comment, thread_ts string) (http.Header, []byte, error) { buf := bytes.Buffer{} w := multipart.NewWriter(&buf) defer func() { @@ -553,7 +552,7 @@ func (sn *SlackNotifier) sendMultipart(ctx context.Context, headers http.Header, // uploadImage shares the image to the channel names or IDs. It returns an error if the file // does not exist, or if there was an error either preparing or sending the multipart/form-data // request. -func (sn *SlackNotifier) uploadImage(ctx context.Context, image ngmodels.Image, channel, comment, thread_ts string) error { +func (sn *SlackNotifier) uploadImage(ctx context.Context, image Image, channel, comment, thread_ts string) error { sn.log.Debug("Uploadimg image", "image", image.Token) headers, data, err := sn.createImageMultipart(image, channel, comment, thread_ts) if err != nil { diff --git a/pkg/services/ngalert/notifier/channels/slack_test.go b/pkg/services/ngalert/notifier/channels/slack_test.go index 8b15177da54..e7faf34312a 100644 --- a/pkg/services/ngalert/notifier/channels/slack_test.go +++ b/pkg/services/ngalert/notifier/channels/slack_test.go @@ -21,7 +21,6 @@ import ( "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/infra/log" - "github.com/grafana/grafana/pkg/services/ngalert/models" "github.com/grafana/grafana/pkg/services/secrets/fakes" secretsManager "github.com/grafana/grafana/pkg/services/secrets/manager" "github.com/grafana/grafana/pkg/setting" @@ -416,7 +415,7 @@ func setupSlackForTests(t *testing.T, settings string) (*SlackNotifier, *slackRe }) images := &fakeImageStore{ - Images: []*models.Image{{ + Images: []*Image{{ Token: "image-on-disk", Path: f.Name(), }, { diff --git a/pkg/services/ngalert/notifier/channels/teams.go b/pkg/services/ngalert/notifier/channels/teams.go index 0292254f053..5fd8ed2e685 100644 --- a/pkg/services/ngalert/notifier/channels/teams.go +++ b/pkg/services/ngalert/notifier/channels/teams.go @@ -13,7 +13,6 @@ import ( "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/models" - ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models" ) const ( @@ -309,7 +308,7 @@ func (tn *TeamsNotifier) Notify(ctx context.Context, as ...*types.Alert) (bool, var s AdaptiveCardImageSetItem _ = withStoredImages(ctx, tn.log, tn.images, - func(_ int, image ngmodels.Image) error { + func(_ int, image Image) error { if image.URL != "" { s.AppendImage(AdaptiveCardImageItem{URL: image.URL}) } diff --git a/pkg/services/ngalert/notifier/channels/telegram.go b/pkg/services/ngalert/notifier/channels/telegram.go index b9c78dd01db..fe68845a09e 100644 --- a/pkg/services/ngalert/notifier/channels/telegram.go +++ b/pkg/services/ngalert/notifier/channels/telegram.go @@ -16,7 +16,6 @@ import ( "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/models" - ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models" ) var ( @@ -144,7 +143,7 @@ func (tn *TelegramNotifier) Notify(ctx context.Context, as ...*types.Alert) (boo } // Create the cmd to upload each image - _ = withStoredImages(ctx, tn.log, tn.images, func(index int, image ngmodels.Image) error { + _ = withStoredImages(ctx, tn.log, tn.images, func(index int, image Image) error { cmd, err = tn.newWebhookSyncCmd("sendPhoto", func(w *multipart.Writer) error { f, err := os.Open(image.Path) if err != nil { diff --git a/pkg/services/ngalert/notifier/channels/testing.go b/pkg/services/ngalert/notifier/channels/testing.go index 2a113a11a46..e8293e0f1e9 100644 --- a/pkg/services/ngalert/notifier/channels/testing.go +++ b/pkg/services/ngalert/notifier/channels/testing.go @@ -13,23 +13,22 @@ import ( "github.com/grafana/grafana/pkg/bus" "github.com/grafana/grafana/pkg/infra/tracing" "github.com/grafana/grafana/pkg/models" - ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models" "github.com/grafana/grafana/pkg/services/notifications" "github.com/grafana/grafana/pkg/setting" ) type fakeImageStore struct { - Images []*ngmodels.Image + Images []*Image } // getImage returns an image with the same token. -func (f *fakeImageStore) GetImage(_ context.Context, token string) (*ngmodels.Image, error) { +func (f *fakeImageStore) GetImage(_ context.Context, token string) (*Image, error) { for _, img := range f.Images { if img.Token == token { return img, nil } } - return nil, ngmodels.ErrImageNotFound + return nil, ErrImageNotFound } // newFakeImageStore returns an image store with N test images. @@ -37,7 +36,7 @@ func (f *fakeImageStore) GetImage(_ context.Context, token string) (*ngmodels.Im func newFakeImageStore(n int) ImageStore { s := fakeImageStore{} for i := 1; i <= n; i++ { - s.Images = append(s.Images, &ngmodels.Image{ + s.Images = append(s.Images, &Image{ Token: fmt.Sprintf("test-image-%d", i), URL: fmt.Sprintf("https://www.example.com/test-image-%d.jpg", i), CreatedAt: time.Now().UTC(), @@ -72,7 +71,7 @@ func newFakeImageStoreWithFile(t *testing.T, n int) ImageStore { t.Fatalf("failed to create test image: %s", err) } files = append(files, file) - s.Images = append(s.Images, &ngmodels.Image{ + s.Images = append(s.Images, &Image{ Token: fmt.Sprintf("test-image-%d", i), Path: file, URL: fmt.Sprintf("https://www.example.com/test-image-%d", i), diff --git a/pkg/services/ngalert/notifier/channels/threema.go b/pkg/services/ngalert/notifier/channels/threema.go index 0a96bd7c75d..2f093324fc9 100644 --- a/pkg/services/ngalert/notifier/channels/threema.go +++ b/pkg/services/ngalert/notifier/channels/threema.go @@ -14,7 +14,6 @@ import ( "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/models" - ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models" ) var ( @@ -158,7 +157,7 @@ func (tn *ThreemaNotifier) buildMessage(ctx context.Context, as ...*types.Alert) } _ = withStoredImages(ctx, tn.log, tn.images, - func(_ int, image ngmodels.Image) error { + func(_ int, image Image) error { if image.URL != "" { message += fmt.Sprintf("*Image:* %s\n", image.URL) } diff --git a/pkg/services/ngalert/notifier/channels/util.go b/pkg/services/ngalert/notifier/channels/util.go index 525fa11acb6..6e136898641 100644 --- a/pkg/services/ngalert/notifier/channels/util.go +++ b/pkg/services/ngalert/notifier/channels/util.go @@ -49,11 +49,11 @@ var ( ErrImagesUnavailable = errors.New("alert screenshots are unavailable") ) -type forEachImageFunc func(index int, image models.Image) error +type forEachImageFunc func(index int, image Image) error // getImage returns the image for the alert or an error. It returns a nil // image if the alert does not have an image token or the image does not exist. -func getImage(ctx context.Context, l log.Logger, imageStore ImageStore, alert types.Alert) (*models.Image, error) { +func getImage(ctx context.Context, l log.Logger, imageStore ImageStore, alert types.Alert) (*Image, error) { token := getTokenFromAnnotations(alert.Annotations) if token == "" { return nil, nil @@ -63,7 +63,7 @@ func getImage(ctx context.Context, l log.Logger, imageStore ImageStore, alert ty defer cancelFunc() img, err := imageStore.GetImage(ctx, token) - if errors.Is(err, models.ErrImageNotFound) || errors.Is(err, ErrImagesUnavailable) { + if errors.Is(err, ErrImageNotFound) || errors.Is(err, ErrImagesUnavailable) { return nil, nil } else if err != nil { l.Warn("failed to get image with token", "token", token, "error", err) @@ -107,7 +107,7 @@ func openImage(path string) (io.ReadCloser, error) { fp := filepath.Clean(path) _, err := os.Stat(fp) if os.IsNotExist(err) || os.IsPermission(err) { - return nil, models.ErrImageNotFound + return nil, ErrImageNotFound } f, err := os.Open(fp) @@ -128,7 +128,7 @@ func getTokenFromAnnotations(annotations model.LabelSet) string { type UnavailableImageStore struct{} // Get returns the image with the corresponding token, or ErrImageNotFound. -func (u *UnavailableImageStore) GetImage(ctx context.Context, token string) (*models.Image, error) { +func (u *UnavailableImageStore) GetImage(ctx context.Context, token string) (*Image, error) { return nil, ErrImagesUnavailable } diff --git a/pkg/services/ngalert/notifier/channels/util_test.go b/pkg/services/ngalert/notifier/channels/util_test.go index 08ae8c19c9a..547390ac947 100644 --- a/pkg/services/ngalert/notifier/channels/util_test.go +++ b/pkg/services/ngalert/notifier/channels/util_test.go @@ -29,7 +29,7 @@ func TestWithStoredImages(t *testing.T) { }, }, }} - imageStore := &fakeImageStore{Images: []*models.Image{{ + imageStore := &fakeImageStore{Images: []*Image{{ Token: "test-image-1", URL: "https://www.example.com/test-image-1.jpg", CreatedAt: time.Now().UTC(), @@ -45,7 +45,7 @@ func TestWithStoredImages(t *testing.T) { ) // should iterate all images - err = withStoredImages(ctx, log.New(ctx), imageStore, func(index int, image models.Image) error { + err = withStoredImages(ctx, log.New(ctx), imageStore, func(index int, image Image) error { i += 1 return nil }, alerts...) @@ -54,7 +54,7 @@ func TestWithStoredImages(t *testing.T) { // should iterate just the first image i = 0 - err = withStoredImages(ctx, log.New(ctx), imageStore, func(index int, image models.Image) error { + err = withStoredImages(ctx, log.New(ctx), imageStore, func(index int, image Image) error { i += 1 return ErrImagesDone }, alerts...) diff --git a/pkg/services/ngalert/notifier/channels/victorops.go b/pkg/services/ngalert/notifier/channels/victorops.go index cbcb4e78711..ace7ed59c41 100644 --- a/pkg/services/ngalert/notifier/channels/victorops.go +++ b/pkg/services/ngalert/notifier/channels/victorops.go @@ -15,7 +15,6 @@ import ( "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/models" - ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models" "github.com/grafana/grafana/pkg/setting" ) @@ -139,7 +138,7 @@ func (vn *VictoropsNotifier) Notify(ctx context.Context, as ...*types.Alert) (bo } _ = withStoredImages(ctx, vn.log, vn.images, - func(index int, image ngmodels.Image) error { + func(index int, image Image) error { if image.URL != "" { bodyJSON["image_url"] = image.URL return ErrImagesDone diff --git a/pkg/services/ngalert/notifier/channels/webex.go b/pkg/services/ngalert/notifier/channels/webex.go index 67851bc4b74..d0522b8f175 100644 --- a/pkg/services/ngalert/notifier/channels/webex.go +++ b/pkg/services/ngalert/notifier/channels/webex.go @@ -12,7 +12,6 @@ import ( "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/models" - ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models" ) const webexAPIURL = "https://webexapis.com/v1/messages" @@ -130,7 +129,7 @@ func (wn *WebexNotifier) Notify(ctx context.Context, as ...*types.Alert) (bool, } // Augment our Alert data with ImageURLs if available. - _ = withStoredImages(ctx, wn.log, wn.images, func(index int, image ngmodels.Image) error { + _ = withStoredImages(ctx, wn.log, wn.images, func(index int, image Image) error { // Cisco Webex only supports a single image per request: https://developer.webex.com/docs/basics#message-attachments if image.HasURL() { data.Alerts[index].ImageURL = image.URL diff --git a/pkg/services/ngalert/notifier/channels/webhook.go b/pkg/services/ngalert/notifier/channels/webhook.go index 65d1d32103e..76df97f0e47 100644 --- a/pkg/services/ngalert/notifier/channels/webhook.go +++ b/pkg/services/ngalert/notifier/channels/webhook.go @@ -15,7 +15,6 @@ import ( "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/models" - ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models" ) // WebhookNotifier is responsible for sending @@ -160,7 +159,7 @@ func (wn *WebhookNotifier) Notify(ctx context.Context, as ...*types.Alert) (bool // Augment our Alert data with ImageURLs if available. _ = withStoredImages(ctx, wn.log, wn.images, - func(index int, image ngmodels.Image) error { + func(index int, image Image) error { if len(image.URL) != 0 { data.Alerts[index].ImageURL = image.URL } diff --git a/pkg/services/ngalert/notifier/images.go b/pkg/services/ngalert/notifier/images.go new file mode 100644 index 00000000000..c9555e6247a --- /dev/null +++ b/pkg/services/ngalert/notifier/images.go @@ -0,0 +1,39 @@ +package notifier + +import ( + "context" + "errors" + + "github.com/grafana/grafana/pkg/services/ngalert/models" + "github.com/grafana/grafana/pkg/services/ngalert/notifier/channels" + "github.com/grafana/grafana/pkg/services/ngalert/store" +) + +type imageStore struct { + store store.ImageStore +} + +func newImageStore(store store.ImageStore) channels.ImageStore { + return &imageStore{ + store: store, + } +} + +func (i imageStore) GetImage(ctx context.Context, token string) (*channels.Image, error) { + image, err := i.store.GetImage(ctx, token) + if err != nil { + if errors.Is(err, models.ErrImageNotFound) { + err = channels.ErrImageNotFound + } + } + var result *channels.Image + if image != nil { + result = &channels.Image{ + Token: image.Token, + Path: image.Path, + URL: image.URL, + CreatedAt: image.CreatedAt, + } + } + return result, err +}