Alerting: Refactoring ConfigRevision methods (#111192)

* make validateReceiver private

* make functions and type alias private

* move EncryptedReceivers and DecryptedReceivers to notifier package

to reduce exposure of definitions package via legacy_storage

* return receivers with Grafana origin after create\update

* add tests for ConfigRevision methods
This commit is contained in:
Yuri Tseretyan
2025-09-19 09:46:35 -04:00
committed by GitHub
parent a5517d72ee
commit f166968357
5 changed files with 552 additions and 69 deletions
+48
View File
@@ -10,7 +10,9 @@ import (
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
"github.com/grafana/grafana/pkg/services/ngalert/models"
"github.com/grafana/grafana/pkg/services/ngalert/notifier/channels_config"
"github.com/grafana/grafana/pkg/services/ngalert/notifier/legacy_storage"
"github.com/grafana/grafana/pkg/services/ngalert/store"
"github.com/grafana/grafana/pkg/services/secrets"
)
@@ -302,3 +304,49 @@ func (c *ExtraConfigsCrypto) DecryptExtraConfigs(ctx context.Context, config *de
return nil
}
func DecryptedReceivers(receivers []*definitions.PostableApiReceiver, decryptFn models.DecryptFn) ([]*definitions.PostableApiReceiver, error) {
decrypted := make([]*definitions.PostableApiReceiver, len(receivers))
for i, r := range receivers {
// We don't care about the provenance here, so we pass ProvenanceNone.
rcv, err := legacy_storage.PostableApiReceiverToReceiver(r, models.ProvenanceNone, models.ResourceOriginGrafana)
if err != nil {
return nil, err
}
err = rcv.Decrypt(decryptFn)
if err != nil {
return nil, fmt.Errorf("failed to decrypt receiver %q: %w", rcv.Name, err)
}
postable, err := legacy_storage.ReceiverToPostableApiReceiver(rcv)
if err != nil {
return nil, fmt.Errorf("failed to convert Receiver %q to APIReceiver: %w", rcv.Name, err)
}
decrypted[i] = postable
}
return decrypted, nil
}
func EncryptedReceivers(receivers []*definitions.PostableApiReceiver, encryptFn models.EncryptFn) ([]*definitions.PostableApiReceiver, error) {
encrypted := make([]*definitions.PostableApiReceiver, len(receivers))
for i, r := range receivers {
// We don't care about the provenance here, so we pass ProvenanceNone.
rcv, err := legacy_storage.PostableApiReceiverToReceiver(r, models.ProvenanceNone, models.ResourceOriginGrafana)
if err != nil {
return nil, err
}
err = rcv.Encrypt(encryptFn)
if err != nil {
return nil, fmt.Errorf("failed to decrypt receiver %q: %w", rcv.Name, err)
}
postable, err := legacy_storage.ReceiverToPostableApiReceiver(rcv)
if err != nil {
return nil, fmt.Errorf("failed to convert Receiver %q to APIReceiver: %w", rcv.Name, err)
}
encrypted[i] = postable
}
return encrypted, nil
}
@@ -11,7 +11,7 @@ import (
"github.com/grafana/grafana/pkg/util"
)
type Provenances map[string]models.Provenance
type provenances = map[string]models.Provenance
func (rev *ConfigRevision) DeleteReceiver(uid string) {
// Remove the receiver from the configuration.
@@ -39,11 +39,11 @@ func (rev *ConfigRevision) CreateReceiver(receiver *models.Receiver) (*models.Re
rev.Config.AlertmanagerConfig.Receivers = append(rev.Config.AlertmanagerConfig.Receivers, postable)
if err := rev.ValidateReceiver(postable); err != nil {
if err := rev.validateReceiver(postable); err != nil {
return nil, err
}
return PostableApiReceiverToReceiver(postable, receiver.Provenance, receiver.Origin)
return PostableApiReceiverToReceiver(postable, receiver.Provenance, models.ResourceOriginGrafana)
}
func (rev *ConfigRevision) UpdateReceiver(receiver *models.Receiver) (*models.Receiver, error) {
@@ -65,11 +65,11 @@ func (rev *ConfigRevision) UpdateReceiver(receiver *models.Receiver) (*models.Re
rev.Config.AlertmanagerConfig.Receivers[existingIdx] = newReceiver
if err := rev.ValidateReceiver(newReceiver); err != nil {
if err := rev.validateReceiver(newReceiver); err != nil {
return nil, err
}
return PostableApiReceiverToReceiver(newReceiver, receiver.Provenance, receiver.Origin)
return PostableApiReceiverToReceiver(newReceiver, receiver.Provenance, models.ResourceOriginGrafana)
}
// ReceiverNameUsedByRoutes checks if a receiver name is used in any routes.
@@ -84,7 +84,7 @@ func (rev *ConfigRevision) ReceiverUseByName() map[string]int {
return m
}
func (rev *ConfigRevision) GetReceiver(uid string, prov Provenances) (*models.Receiver, error) {
func (rev *ConfigRevision) GetReceiver(uid string, prov provenances) (*models.Receiver, error) {
for _, r := range rev.Config.AlertmanagerConfig.Receivers {
if NameToUid(r.GetName()) != uid {
continue
@@ -98,7 +98,7 @@ func (rev *ConfigRevision) GetReceiver(uid string, prov Provenances) (*models.Re
return nil, ErrReceiverNotFound.Errorf("")
}
func (rev *ConfigRevision) GetReceivers(uids []string, prov Provenances) ([]*models.Receiver, error) {
func (rev *ConfigRevision) GetReceivers(uids []string, prov provenances) ([]*models.Receiver, error) {
capacity := len(uids)
if capacity == 0 {
capacity = len(rev.Config.AlertmanagerConfig.Receivers)
@@ -127,60 +127,14 @@ func (rev *ConfigRevision) GetReceiversNames() map[string]struct{} {
return result
}
func DecryptedReceivers(receivers []*definitions.PostableApiReceiver, decryptFn models.DecryptFn) ([]*definitions.PostableApiReceiver, error) {
decrypted := make([]*definitions.PostableApiReceiver, len(receivers))
for i, r := range receivers {
// We don't care about the provenance here, so we pass ProvenanceNone.
rcv, err := PostableApiReceiverToReceiver(r, models.ProvenanceNone, models.ResourceOriginGrafana)
if err != nil {
return nil, err
}
err = rcv.Decrypt(decryptFn)
if err != nil {
return nil, fmt.Errorf("failed to decrypt receiver %q: %w", rcv.Name, err)
}
postable, err := ReceiverToPostableApiReceiver(rcv)
if err != nil {
return nil, fmt.Errorf("failed to convert Receiver %q to APIReceiver: %w", rcv.Name, err)
}
decrypted[i] = postable
}
return decrypted, nil
}
func EncryptedReceivers(receivers []*definitions.PostableApiReceiver, encryptFn models.EncryptFn) ([]*definitions.PostableApiReceiver, error) {
encrypted := make([]*definitions.PostableApiReceiver, len(receivers))
for i, r := range receivers {
// We don't care about the provenance here, so we pass ProvenanceNone.
rcv, err := PostableApiReceiverToReceiver(r, models.ProvenanceNone, models.ResourceOriginGrafana)
if err != nil {
return nil, err
}
err = rcv.Encrypt(encryptFn)
if err != nil {
return nil, fmt.Errorf("failed to decrypt receiver %q: %w", rcv.Name, err)
}
postable, err := ReceiverToPostableApiReceiver(rcv)
if err != nil {
return nil, fmt.Errorf("failed to convert Receiver %q to APIReceiver: %w", rcv.Name, err)
}
encrypted[i] = postable
}
return encrypted, nil
}
// RenameReceiverInRoutes renames all references to a receiver in routes. Returns number of routes that were updated
func (rev *ConfigRevision) RenameReceiverInRoutes(oldName, newName string) int {
return RenameReceiverInRoute(oldName, newName, rev.Config.AlertmanagerConfig.Route)
return renameReceiverInRoute(oldName, newName, rev.Config.AlertmanagerConfig.Route)
}
// ValidateReceiver checks if the given receiver conflicts in name or integration UID with existing receivers.
// validateReceiver checks if the given receiver conflicts in name or integration UID with existing receivers.
// We only check the receiver being modified to prevent existing issues from other receivers being reported.
func (rev *ConfigRevision) ValidateReceiver(p *definitions.PostableApiReceiver) error {
func (rev *ConfigRevision) validateReceiver(p *definitions.PostableApiReceiver) error {
uids := make(map[string]struct{}, len(rev.Config.AlertmanagerConfig.Receivers))
for _, integrations := range p.GrafanaManagedReceivers {
if _, exists := uids[integrations.UID]; exists {
@@ -207,7 +161,7 @@ func (rev *ConfigRevision) ValidateReceiver(p *definitions.PostableApiReceiver)
return nil
}
func RenameReceiverInRoute(oldName, newName string, routes ...*definitions.Route) int {
func renameReceiverInRoute(oldName, newName string, routes ...*definitions.Route) int {
if len(routes) == 0 {
return 0
}
@@ -217,7 +171,7 @@ func RenameReceiverInRoute(oldName, newName string, routes ...*definitions.Route
route.Receiver = newName
updated++
}
updated += RenameReceiverInRoute(oldName, newName, route.Routes...)
updated += renameReceiverInRoute(oldName, newName, route.Routes...)
}
return updated
}
@@ -1,11 +1,20 @@
package legacy_storage
import (
"encoding/json"
"slices"
"strings"
"testing"
"github.com/grafana/alerting/definition"
"github.com/grafana/alerting/notify"
"github.com/prometheus/alertmanager/config"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
"github.com/grafana/grafana/pkg/services/ngalert/models"
"github.com/grafana/grafana/pkg/util"
)
func TestReceiverInUse(t *testing.T) {
@@ -38,3 +47,477 @@ func TestReceiverInUse(t *testing.T) {
})
require.False(t, result)
}
func TestDeleteReceiver(t *testing.T) {
testCases := []struct {
name string
receiverUID string
assert func(t *testing.T, rev *ConfigRevision)
}{
{
name: "should remove receiver if exists",
receiverUID: NameToUid("receiver1"),
assert: func(t *testing.T, rev *ConfigRevision) {
require.False(t, slices.ContainsFunc(rev.Config.AlertmanagerConfig.Receivers, func(receiver *definition.PostableApiReceiver) bool {
return receiver.Name == "receiver1"
}))
},
},
{
name: "should do nothing if receiver does not exist",
receiverUID: NameToUid("not-existing"),
assert: func(t *testing.T, rev *ConfigRevision) {
require.Equal(t, getConfigRevisionForTest(), rev)
},
},
{
name: "should remove all receivers with the same name",
receiverUID: NameToUid("dupe-receiver"),
assert: func(t *testing.T, rev *ConfigRevision) {
require.False(t, slices.ContainsFunc(rev.Config.AlertmanagerConfig.Receivers, func(receiver *definition.PostableApiReceiver) bool {
return receiver.Name == "dupe-receiver"
}))
},
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
rev := getConfigRevisionForTest()
rev.DeleteReceiver(tc.receiverUID)
tc.assert(t, rev)
})
}
}
func TestCreateReceiver(t *testing.T) {
rawCfg := notify.AllKnownConfigsForTesting["webhook"]
cfgSchema, err := models.IntegrationConfigFromType(rawCfg.NotifierType, util.Pointer("v1"))
require.NoError(t, err)
settings := map[string]any{}
require.NoError(t, json.Unmarshal([]byte(rawCfg.Config), &settings))
testCases := []struct {
name string
receiver *models.Receiver
expectedError error
assertResponse func(t *testing.T, rev *ConfigRevision, receiver *models.Receiver)
}{
{
name: "should error if receiver already exists by UID",
receiver: &models.Receiver{
UID: NameToUid("receiver1"),
Name: "New receiver name",
},
expectedError: ErrReceiverExists,
},
{
name: "should error if receiver already exists by name",
receiver: &models.Receiver{
UID: "some-uid",
Name: "receiver1",
},
expectedError: ErrReceiverInvalid,
},
{
name: "should fail if integration UID is not valid",
receiver: &models.Receiver{
UID: "some-uid",
Name: "receiver",
Integrations: []*models.Integration{
{
UID: strings.Repeat("*", 256),
Config: cfgSchema,
Settings: settings,
},
},
},
expectedError: ErrReceiverInvalid,
},
{
name: "should fail if integration UID already exists",
receiver: &models.Receiver{
UID: "some-uid",
Name: "receiver",
Integrations: []*models.Integration{
{
UID: "integration-uid-1",
Config: cfgSchema,
Settings: settings,
},
},
},
expectedError: ErrReceiverInvalid,
},
{
name: "should add the receiver to configuration and set integrations UID",
receiver: &models.Receiver{
UID: "some-uid",
Name: "receiver2",
Provenance: "test",
Integrations: []*models.Integration{
{
Config: cfgSchema,
Settings: settings,
},
},
},
expectedError: nil,
assertResponse: func(t *testing.T, rev *ConfigRevision, receiver *models.Receiver) {
t.Helper()
idx := slices.IndexFunc(rev.Config.AlertmanagerConfig.Receivers, func(r *definition.PostableApiReceiver) bool {
return r.Name == "receiver2"
})
assert.Greaterf(t, idx, -1, "receiver was not added to the configuration")
postable := rev.Config.AlertmanagerConfig.Receivers[idx]
require.Len(t, postable.GrafanaManagedReceivers, 1)
require.Equal(t, receiver.Name, postable.Name)
require.NotEmpty(t, postable.GrafanaManagedReceivers[0].UID)
require.JSONEq(t, string(postable.GrafanaManagedReceivers[0].Settings), rawCfg.Config)
assert.Equal(t, models.ResourceOriginGrafana, receiver.Origin)
assert.Equal(t, NameToUid("receiver2"), receiver.UID)
assert.Equal(t, postable.GrafanaManagedReceivers[0].UID, receiver.Integrations[0].UID)
assert.EqualValues(t, "test", receiver.Provenance)
},
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
rev := getConfigRevisionForTest()
recv, err := rev.CreateReceiver(tc.receiver)
if tc.expectedError != nil {
require.ErrorIs(t, err, tc.expectedError)
return
}
require.NoError(t, err)
tc.assertResponse(t, rev, recv)
})
}
}
func TestUpdateReceiver(t *testing.T) {
rawCfg := notify.AllKnownConfigsForTesting["webhook"]
cfgSchema, err := models.IntegrationConfigFromType(rawCfg.NotifierType, util.Pointer("v1"))
require.NoError(t, err)
settings := map[string]any{}
require.NoError(t, json.Unmarshal([]byte(rawCfg.Config), &settings))
testCases := []struct {
name string
receiver *models.Receiver
expectedError error
assertResponse func(t *testing.T, rev *ConfigRevision, receiver *models.Receiver)
}{
{
name: "should error if receiver does not exists by UID",
receiver: &models.Receiver{
UID: NameToUid("receiver2"),
Name: "receiver1",
},
expectedError: ErrReceiverNotFound,
},
{
name: "should fail if integration UID is not valid",
receiver: &models.Receiver{
UID: NameToUid("receiver1"),
Name: "receiver1",
Integrations: []*models.Integration{
{
UID: strings.Repeat("*", 256),
Config: cfgSchema,
Settings: settings,
},
},
},
expectedError: ErrReceiverInvalid,
},
{
name: "should fail if integration UID already exists",
receiver: &models.Receiver{
UID: NameToUid("receiver1"),
Name: "receiver1",
Integrations: []*models.Integration{
{
UID: "integration-uid-2",
Config: cfgSchema,
Settings: settings,
},
},
},
expectedError: ErrReceiverInvalid,
},
{
name: "should update the existing receiver",
receiver: &models.Receiver{
UID: NameToUid("receiver1"),
Name: "receiver-new",
Provenance: "test",
Integrations: []*models.Integration{
{
Config: cfgSchema,
Settings: settings,
},
},
},
expectedError: nil,
assertResponse: func(t *testing.T, rev *ConfigRevision, receiver *models.Receiver) {
t.Helper()
idx := slices.IndexFunc(rev.Config.AlertmanagerConfig.Receivers, func(r *definition.PostableApiReceiver) bool {
return r.Name == "receiver-new"
})
assert.Greaterf(t, idx, -1, "receiver was not found to the configuration")
old := getConfigRevisionForTest().Config.AlertmanagerConfig.Receivers[idx]
require.Equalf(t, old.Name, "receiver1", "the receiver should be updated in place")
postable := rev.Config.AlertmanagerConfig.Receivers[idx]
require.Len(t, postable.GrafanaManagedReceivers, 1)
require.Equal(t, receiver.Name, postable.Name)
require.NotEmpty(t, postable.GrafanaManagedReceivers[0].UID)
require.JSONEq(t, string(postable.GrafanaManagedReceivers[0].Settings), rawCfg.Config)
assert.Equal(t, postable.GrafanaManagedReceivers[0].UID, receiver.Integrations[0].UID)
assert.Equal(t, NameToUid("receiver-new"), receiver.UID)
assert.EqualValues(t, "test", receiver.Provenance)
},
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
rev := getConfigRevisionForTest()
recv, err := rev.UpdateReceiver(tc.receiver)
if tc.expectedError != nil {
require.ErrorIs(t, err, tc.expectedError)
return
}
require.NoError(t, err)
tc.assertResponse(t, rev, recv)
})
}
}
func TestGetReceiver(t *testing.T) {
rawCfg := notify.AllKnownConfigsForTesting["webhook"]
cfgSchema, err := models.IntegrationConfigFromType(rawCfg.NotifierType, util.Pointer("v1"))
require.NoError(t, err)
settings := map[string]any{}
require.NoError(t, json.Unmarshal([]byte(rawCfg.Config), &settings))
t.Run("should return ErrReceiverNotFound if receiver does not exists", func(t *testing.T) {
rev := getConfigRevisionForTest()
_, err := rev.GetReceiver("not-found", nil)
require.ErrorIs(t, err, ErrReceiverNotFound)
})
t.Run("should return receiver if exists", func(t *testing.T) {
prov := provenances{
"integration-uid-1": "test",
}
expected := &models.Receiver{
UID: NameToUid("receiver1"),
Name: "receiver1",
Provenance: models.Provenance("test"),
Origin: models.ResourceOriginGrafana,
Version: "6e2fb0f572bc90f7",
Integrations: []*models.Integration{
{
UID: "integration-uid-1",
Config: cfgSchema,
Settings: settings,
SecureSettings: make(map[string]string),
},
},
}
rev := getConfigRevisionForTest()
result, err := rev.GetReceiver(NameToUid("receiver1"), prov)
require.NoError(t, err)
require.Equal(t, expected, result)
})
}
func TestGetReceivers(t *testing.T) {
rev := getConfigRevisionForTest()
t.Run("should return all receivers with correct provenance", func(t *testing.T) {
prov := provenances{
"integration-uid-1": "test",
"integration-uid-2": "some",
}
receivers, err := rev.GetReceivers(nil, prov)
require.NoError(t, err)
require.Len(t, receivers, len(rev.Config.AlertmanagerConfig.Receivers))
for _, r := range receivers {
assert.Equalf(t, NameToUid(r.Name), r.UID, "receiver UID should be function of receiver name")
assert.Equal(t, r.Origin, models.ResourceOriginGrafana)
if r.Name == "receiver1" {
assert.EqualValues(t, "test", r.Provenance)
} else if r.Name == "dupe-receiver" && r.Integrations[0].UID == "integration-uid-2" {
assert.EqualValues(t, "some", r.Provenance)
} else {
assert.Empty(t, r.Provenance)
}
}
})
t.Run("should filter by uids", func(t *testing.T) {
receivers, err := rev.GetReceivers([]string{"not-found-1", "not-found-2"}, nil)
require.NoError(t, err)
require.Empty(t, receivers)
receivers, err = rev.GetReceivers([]string{NameToUid("receiver1")}, nil)
require.NoError(t, err)
require.Len(t, receivers, 1)
expected, err := rev.GetReceiver(NameToUid("receiver1"), nil)
require.NoError(t, err)
require.Equal(t, expected, receivers[0])
})
}
func TestReceiverNameUsedByRoutes(t *testing.T) {
testCases := []struct {
name string
receiverName string
expectedResult bool
}{
{
name: "should return true if receiver is used by routes",
receiverName: "receiver1",
expectedResult: true,
},
{
name: "should return false if receiver is not used by routes",
receiverName: "receiver2",
expectedResult: false,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
rev := getConfigRevisionForTest()
result := rev.ReceiverNameUsedByRoutes(tc.receiverName)
require.Equal(t, tc.expectedResult, result)
})
}
}
func TestReceiverUseByName(t *testing.T) {
rev := getConfigRevisionForTest()
rev.Config.AlertmanagerConfig.Route.Routes = append(rev.Config.AlertmanagerConfig.Route.Routes,
&definitions.Route{
Routes: []*definitions.Route{
{
Receiver: "receiver1",
},
{
Receiver: "dupe-receiver",
},
{
Receiver: "some-missing-receiver",
},
},
})
expected := map[string]int{
"": 1, // some routes do not have receiver set
"receiver1": 2,
"dupe-receiver": 1,
"some-missing-receiver": 1,
}
require.Equal(t, expected, rev.ReceiverUseByName())
}
func TestRenameReceiverInRoutes(t *testing.T) {
rev := getConfigRevisionForTest()
rev.Config.AlertmanagerConfig.Route.Routes = append(rev.Config.AlertmanagerConfig.Route.Routes, &definitions.Route{
Receiver: "receiver1",
Routes: []*definitions.Route{
{
Receiver: "receiver1",
Routes: []*definitions.Route{
{
Receiver: "missing-receiver",
},
},
},
{
Receiver: "dupe-receiver",
Routes: []*definitions.Route{
{
Receiver: "receiver1",
},
},
},
},
})
t.Run("should do nothing if receiver is not used by routes ", func(t *testing.T) {
result := rev.RenameReceiverInRoutes("not-found", "found")
require.Zero(t, result)
expected := map[string]int{
"receiver1": 4,
"missing-receiver": 1,
"dupe-receiver": 1,
}
require.Equal(t, expected, rev.ReceiverUseByName())
})
t.Run("should rename all references", func(t *testing.T) {
result := rev.RenameReceiverInRoutes("receiver1", "found")
require.Equal(t, result, 4)
expected := map[string]int{
"found": 4,
"missing-receiver": 1,
"dupe-receiver": 1,
}
require.Equal(t, expected, rev.ReceiverUseByName())
})
}
func getConfigRevisionForTest() *ConfigRevision {
return &ConfigRevision{
Config: &definitions.PostableUserConfig{
AlertmanagerConfig: definitions.PostableApiAlertingConfig{
Config: definitions.Config{
Route: &definitions.Route{Receiver: "receiver1"},
},
Receivers: []*definition.PostableApiReceiver{
{
Receiver: config.Receiver{
Name: "receiver1",
},
PostableGrafanaReceivers: definition.PostableGrafanaReceivers{
GrafanaManagedReceivers: []*definition.PostableGrafanaReceiver{
{
UID: "integration-uid-1",
Type: "webhook",
Settings: definitions.RawMessage(notify.AllKnownConfigsForTesting["webhook"].Config),
},
},
},
},
{
Receiver: config.Receiver{Name: "dupe-receiver"},
PostableGrafanaReceivers: definition.PostableGrafanaReceivers{
GrafanaManagedReceivers: []*definition.PostableGrafanaReceiver{
{
UID: "integration-uid-2",
Type: "webhook",
Settings: definitions.RawMessage(notify.AllKnownConfigsForTesting["webhook"].Config),
},
},
},
},
{
Receiver: config.Receiver{Name: "dupe-receiver"},
PostableGrafanaReceivers: definition.PostableGrafanaReceivers{
GrafanaManagedReceivers: []*definition.PostableGrafanaReceiver{
{
UID: "integration-uid-3",
Type: "email",
Settings: definitions.RawMessage(notify.AllKnownConfigsForTesting["email"].Config),
},
},
},
},
},
},
},
}
}
+2 -3
View File
@@ -36,7 +36,6 @@ import (
"github.com/grafana/grafana/pkg/services/ngalert/metrics"
"github.com/grafana/grafana/pkg/services/ngalert/models"
"github.com/grafana/grafana/pkg/services/ngalert/notifier"
"github.com/grafana/grafana/pkg/services/ngalert/notifier/legacy_storage"
remoteClient "github.com/grafana/grafana/pkg/services/ngalert/remote/client"
"github.com/grafana/grafana/pkg/services/ngalert/sender"
"github.com/grafana/grafana/pkg/util/cmputil"
@@ -315,7 +314,7 @@ func (am *Alertmanager) buildConfiguration(ctx context.Context, raw []byte, crea
}
// Decrypt the receivers in the configuration.
decryptedReceivers, err := legacy_storage.DecryptedReceivers(c.AlertmanagerConfig.Receivers, decrypter(ctx, am.crypto))
decryptedReceivers, err := notifier.DecryptedReceivers(c.AlertmanagerConfig.Receivers, decrypter(ctx, am.crypto))
if err != nil {
return remoteClient.UserGrafanaConfig{}, fmt.Errorf("unable to decrypt receivers: %w", err)
}
@@ -605,7 +604,7 @@ func (am *Alertmanager) GetReceivers(ctx context.Context) ([]apimodels.Receiver,
}
func (am *Alertmanager) TestReceivers(ctx context.Context, c apimodels.TestReceiversConfigBodyParams) (*alertingNotify.TestReceiversResult, int, error) {
decryptedReceivers, err := legacy_storage.DecryptedReceivers(c.Receivers, decrypter(ctx, am.crypto))
decryptedReceivers, err := notifier.DecryptedReceivers(c.Receivers, decrypter(ctx, am.crypto))
if err != nil {
return nil, 0, fmt.Errorf("failed to decrypt receivers: %w", err)
}
@@ -41,7 +41,6 @@ import (
"github.com/grafana/grafana/pkg/services/ngalert/metrics"
ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models"
"github.com/grafana/grafana/pkg/services/ngalert/notifier"
"github.com/grafana/grafana/pkg/services/ngalert/notifier/legacy_storage"
"github.com/grafana/grafana/pkg/services/ngalert/remote/client"
ngfakes "github.com/grafana/grafana/pkg/services/ngalert/tests/fakes"
"github.com/grafana/grafana/pkg/services/secrets"
@@ -152,7 +151,7 @@ func TestGetRemoteState(t *testing.T) {
// getOkHandler allows us to specify a full state the test server is going to respond with.
getOkHandler := func(state string) http.HandlerFunc {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
require.Equal(t, tenantID, r.Header.Get(client.MimirTenantHeader))
require.Equal(t, "true", r.Header.Get(client.RemoteAlertmanagerHeader))
@@ -164,7 +163,7 @@ func TestGetRemoteState(t *testing.T) {
}
w.Header().Add("content-type", "application/json")
require.NoError(t, json.NewEncoder(w).Encode(res))
})
}
}
// errorHandler makes the test server return a 500 status code and a non-JSON response.
@@ -302,7 +301,7 @@ func TestIntegrationApplyConfig(t *testing.T) {
var c apimodels.PostableUserConfig
require.NoError(t, json.Unmarshal([]byte(testGrafanaConfigWithSecret), &c))
secretsService := secretsManager.SetupTestService(t, database.ProvideSecretsStore(db.InitTestDB(t)))
encryptedReceivers, err := legacy_storage.EncryptedReceivers(c.AlertmanagerConfig.Receivers, func(payload string) (string, error) {
encryptedReceivers, err := notifier.EncryptedReceivers(c.AlertmanagerConfig.Receivers, func(payload string) (string, error) {
encrypted, err := secretsService.Encrypt(context.Background(), []byte(payload), secrets.WithoutScope())
if err != nil {
return "", err
@@ -381,7 +380,7 @@ func TestIntegrationApplyConfig(t *testing.T) {
// should result in us sending the configuration but not the state.
am.syncInterval = 0
config = &ngmodels.AlertConfiguration{
AlertmanagerConfiguration: string(testGrafanaConfig),
AlertmanagerConfiguration: testGrafanaConfig,
}
require.NoError(t, am.ApplyConfig(ctx, config))
require.Equal(t, 2, configSyncs)
@@ -467,7 +466,7 @@ func TestCompareAndSendConfiguration(t *testing.T) {
// Create a config with correctly encrypted and encoded secrets.
var inputCfg apimodels.PostableUserConfig
require.NoError(t, json.Unmarshal([]byte(testGrafanaConfigWithSecret), &inputCfg))
encryptedReceivers, err := legacy_storage.EncryptedReceivers(inputCfg.AlertmanagerConfig.Receivers, func(payload string) (string, error) {
encryptedReceivers, err := notifier.EncryptedReceivers(inputCfg.AlertmanagerConfig.Receivers, func(payload string) (string, error) {
encrypted, err := secretsService.Encrypt(context.Background(), []byte(payload), secrets.WithoutScope())
if err != nil {
return "", err
@@ -669,7 +668,7 @@ func Test_TestReceiversDecryptsSecureSettings(t *testing.T) {
var inputCfg apimodels.PostableUserConfig
require.NoError(t, json.Unmarshal([]byte(testGrafanaConfigWithSecret), &inputCfg))
encryptedReceivers, err := legacy_storage.EncryptedReceivers(inputCfg.AlertmanagerConfig.Receivers, func(payload string) (string, error) {
encryptedReceivers, err := notifier.EncryptedReceivers(inputCfg.AlertmanagerConfig.Receivers, func(payload string) (string, error) {
encrypted, err := secretsService.Encrypt(context.Background(), []byte(payload), secrets.WithoutScope())
if err != nil {
return "", err
@@ -1045,7 +1044,7 @@ func TestIntegrationRemoteAlertmanagerConfiguration(t *testing.T) {
{
postableCfg, err := notifier.Load([]byte(testGrafanaConfigWithSecret))
require.NoError(t, err)
encryptedReceivers, err := legacy_storage.EncryptedReceivers(postableCfg.AlertmanagerConfig.Receivers, func(payload string) (string, error) {
encryptedReceivers, err := notifier.EncryptedReceivers(postableCfg.AlertmanagerConfig.Receivers, func(payload string) (string, error) {
encrypted, err := secretsService.Encrypt(context.Background(), []byte(payload), secrets.WithoutScope())
if err != nil {
return "", err