Alerting: Upload images to Slack via files.upload (#59163)

This commit makes a number of changes to how images work in Slack
notifications.

It adds support for uploading images to Slack via the files.upload
API when the contact point has a token. Images are no longer linked
via a URL if a token is present.

Each image uploaded to Slack is posted as a reply to the original
notification. Up to maxImagesPerThreadTs images can be posted as
replies before a final message is sent with:

  There are no images than can be shown here. To see the panels for
  all firing and resolved alerts please check Grafana

Incoming Webhooks cannot upload files via files.upload and so webhooks
require the image to be uploaded to cloud storage and linked via URL.
This commit is contained in:
George Robinson
2022-12-02 09:41:24 +00:00
committed by GitHub
parent 311e1e56f2
commit ec1d93c8ab
3 changed files with 816 additions and 393 deletions

View File

@@ -707,6 +707,10 @@ func TestNotificationChannels(t *testing.T) {
amConfig := getAlertmanagerConfig(mockChannel.server.Addr)
mockEmail := &mockEmailHandler{}
// Set up responses
mockChannel.responses["slack_recv1"] = `{"ok": true}`
mockChannel.responses["slack_recvX"] = `{"ok": true}`
// Overriding some URLs to send to the mock channel.
os, opa, ot, opu, ogb, ol, oth := channels.SlackAPIEndpoint, channels.PagerdutyEventAPIURL,
channels.TelegramAPIURL, channels.PushoverEndpoint, channels.GetBoundary,
@@ -990,6 +994,7 @@ type mockNotificationChannel struct {
server *http.Server
receivedNotifications map[string][]string
responses map[string]string
notificationErrorCount int
notificationsMtx sync.RWMutex
}
@@ -1007,6 +1012,7 @@ func newMockNotificationChannel(t *testing.T, grafanaListedAddr string) *mockNot
Addr: listener.Addr().String(),
},
receivedNotifications: make(map[string][]string),
responses: make(map[string]string),
t: t,
}
@@ -1036,6 +1042,7 @@ func (nc *mockNotificationChannel) ServeHTTP(res http.ResponseWriter, req *http.
nc.receivedNotifications[key] = append(nc.receivedNotifications[key], body)
res.WriteHeader(http.StatusOK)
fmt.Fprint(res, nc.responses[paths[0]])
}
func (nc *mockNotificationChannel) totalNotifications() int {
@@ -2635,7 +2642,7 @@ var expNonEmailNotifications = map[string][]string{
// expNotificationErrors maps a receiver name with its expected error string.
var expNotificationErrors = map[string]string{
"slack_failed_recv": "request to Slack API failed with status code 500",
"slack_failed_recv": "failed to send Slack message: unexpected 5xx status code: 500",
}
// expInactiveReceivers is a set of receivers expected to be unused.