mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Alerting: Add support for image annotation in Alertmanager alerts (#50686)
This commit is contained in:
parent
6f2c0d467f
commit
c8466d285c
@ -5,14 +5,17 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/prometheus/alertmanager/template"
|
||||
"github.com/prometheus/alertmanager/types"
|
||||
"github.com/prometheus/common/model"
|
||||
|
||||
"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
|
||||
@ -60,11 +63,11 @@ func AlertmanagerFactory(fc FactoryConfig) (NotificationChannel, error) {
|
||||
Cfg: *fc.Config,
|
||||
}
|
||||
}
|
||||
return NewAlertmanagerNotifier(config, nil, fc.DecryptFunc), nil
|
||||
return NewAlertmanagerNotifier(config, fc.ImageStore, nil, fc.DecryptFunc), nil
|
||||
}
|
||||
|
||||
// NewAlertmanagerNotifier returns a new Alertmanager notifier.
|
||||
func NewAlertmanagerNotifier(config *AlertmanagerConfig, _ *template.Template, fn GetDecryptedValueFn) *AlertmanagerNotifier {
|
||||
func NewAlertmanagerNotifier(config *AlertmanagerConfig, images ImageStore, _ *template.Template, fn GetDecryptedValueFn) *AlertmanagerNotifier {
|
||||
return &AlertmanagerNotifier{
|
||||
Base: NewBase(&models.AlertNotification{
|
||||
Uid: config.UID,
|
||||
@ -72,6 +75,7 @@ func NewAlertmanagerNotifier(config *AlertmanagerConfig, _ *template.Template, f
|
||||
DisableResolveMessage: config.DisableResolveMessage,
|
||||
Settings: config.Settings,
|
||||
}),
|
||||
images: images,
|
||||
urls: config.URLs,
|
||||
basicAuthUser: config.BasicAuthUser,
|
||||
basicAuthPassword: config.BasicAuthPassword,
|
||||
@ -82,6 +86,7 @@ func NewAlertmanagerNotifier(config *AlertmanagerConfig, _ *template.Template, f
|
||||
// AlertmanagerNotifier sends alert notifications to the alert manager
|
||||
type AlertmanagerNotifier struct {
|
||||
*Base
|
||||
images ImageStore
|
||||
|
||||
urls []*url.URL
|
||||
basicAuthUser string
|
||||
@ -96,6 +101,16 @@ func (n *AlertmanagerNotifier) Notify(ctx context.Context, as ...*types.Alert) (
|
||||
return true, nil
|
||||
}
|
||||
|
||||
_ = withStoredImages(ctx, n.logger, n.images,
|
||||
func(index int, image *ngmodels.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 != nil && image.URL != "" {
|
||||
as[index].Annotations["image"] = model.LabelValue(image.URL)
|
||||
}
|
||||
return nil
|
||||
}, as...)
|
||||
|
||||
body, err := json.Marshal(as)
|
||||
if err != nil {
|
||||
return false, err
|
||||
|
@ -66,7 +66,7 @@ func TestNewAlertmanagerNotifier(t *testing.T) {
|
||||
return
|
||||
}
|
||||
require.NoError(t, err)
|
||||
sn := NewAlertmanagerNotifier(cfg, tmpl, decryptFn)
|
||||
sn := NewAlertmanagerNotifier(cfg, &UnavailableImageStore{}, tmpl, decryptFn)
|
||||
require.NotNil(t, sn)
|
||||
})
|
||||
}
|
||||
@ -75,6 +75,8 @@ func TestNewAlertmanagerNotifier(t *testing.T) {
|
||||
func TestAlertmanagerNotifier_Notify(t *testing.T) {
|
||||
tmpl := templateForTests(t)
|
||||
|
||||
images := newFakeImageStore(1)
|
||||
|
||||
externalURL, err := url.Parse("http://localhost")
|
||||
require.NoError(t, err)
|
||||
tmpl.ExternalURL = externalURL
|
||||
@ -99,8 +101,19 @@ func TestAlertmanagerNotifier_Notify(t *testing.T) {
|
||||
},
|
||||
},
|
||||
receiverName: "Alertmanager",
|
||||
},
|
||||
{
|
||||
}, {
|
||||
name: "Default config with one alert with image URL",
|
||||
settings: `{"url": "https://alertmanager.com"}`,
|
||||
alerts: []*types.Alert{
|
||||
{
|
||||
Alert: model.Alert{
|
||||
Labels: model.LabelSet{"__alert_rule_uid__": "rule uid", "alertname": "alert1"},
|
||||
Annotations: model.LabelSet{"__alertScreenshotToken__": "test-image-1"},
|
||||
},
|
||||
},
|
||||
},
|
||||
receiverName: "Alertmanager",
|
||||
}, {
|
||||
name: "Default config with one alert with empty receiver name",
|
||||
settings: `{"url": "https://alertmanager.com"}`,
|
||||
alerts: []*types.Alert{
|
||||
@ -146,7 +159,7 @@ func TestAlertmanagerNotifier_Notify(t *testing.T) {
|
||||
decryptFn := secretsService.GetDecryptedValue
|
||||
cfg, err := NewAlertmanagerConfig(m, decryptFn)
|
||||
require.NoError(t, err)
|
||||
sn := NewAlertmanagerNotifier(cfg, tmpl, decryptFn)
|
||||
sn := NewAlertmanagerNotifier(cfg, images, tmpl, decryptFn)
|
||||
var body []byte
|
||||
origSendHTTPRequest := sendHTTPRequest
|
||||
t.Cleanup(func() {
|
||||
|
@ -7,7 +7,6 @@ import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
@ -26,13 +25,6 @@ import (
|
||||
func TestSlackNotifier(t *testing.T) {
|
||||
tmpl := templateForTests(t)
|
||||
|
||||
// Create our temporary image file.
|
||||
f, err := os.CreateTemp("", "ngalert-images-example*.png")
|
||||
if err != nil {
|
||||
panic("Temp file error!")
|
||||
}
|
||||
defer func() { _ = os.Remove(f.Name()) }()
|
||||
|
||||
fakeImageStore := &fakeImageStore{
|
||||
Images: []*models.Image{
|
||||
{
|
||||
@ -42,9 +34,6 @@ func TestSlackNotifier(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
_, _ = f.Write([]byte("test image"))
|
||||
_ = f.Close()
|
||||
|
||||
externalURL, err := url.Parse("http://localhost")
|
||||
require.NoError(t, err)
|
||||
tmpl.ExternalURL = externalURL
|
||||
|
Loading…
Reference in New Issue
Block a user