Alerting: Refactor encryption and receiver handling for improved clarity (#115959)

* refactor: change GetReceiver to get by UID

to avoid conversions of name to uid back an forth

* refactor: consolidate all encrypt\decrypt functions

* move error from temporary location
This commit is contained in:
Yuri Tseretyan
2026-01-09 13:43:36 -05:00
committed by GitHub
parent 909ed02218
commit e4ba1c1a6d
9 changed files with 100 additions and 163 deletions
@@ -17,7 +17,6 @@ import (
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
alertingac "github.com/grafana/grafana/pkg/services/ngalert/accesscontrol"
ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models"
"github.com/grafana/grafana/pkg/services/ngalert/notifier/legacy_storage"
)
var (
@@ -25,7 +24,7 @@ var (
)
type ReceiverService interface {
GetReceiver(ctx context.Context, q ngmodels.GetReceiverQuery, user identity.Requester) (*ngmodels.Receiver, error)
GetReceiver(ctx context.Context, uid string, decrypt bool, user identity.Requester) (*ngmodels.Receiver, error)
GetReceivers(ctx context.Context, q ngmodels.GetReceiversQuery, user identity.Requester) ([]*ngmodels.Receiver, error)
CreateReceiver(ctx context.Context, r *ngmodels.Receiver, orgID int64, user identity.Requester) (*ngmodels.Receiver, error)
UpdateReceiver(ctx context.Context, r *ngmodels.Receiver, storedSecureFields map[string][]string, orgID int64, user identity.Requester) (*ngmodels.Receiver, error)
@@ -116,22 +115,12 @@ func (s *legacyStorage) Get(ctx context.Context, uid string, _ *metav1.GetOption
return nil, err
}
name, err := legacy_storage.UidToName(uid)
if err != nil {
return nil, apierrors.NewNotFound(ResourceInfo.GroupResource(), uid)
}
q := ngmodels.GetReceiverQuery{
OrgID: info.OrgID,
Name: name,
Decrypt: false,
}
user, err := identity.GetRequester(ctx)
if err != nil {
return nil, err
}
r, err := s.service.GetReceiver(ctx, q, user)
r, err := s.service.GetReceiver(ctx, uid, false, user)
if err != nil {
return nil, err
}
-7
View File
@@ -16,13 +16,6 @@ import (
"github.com/grafana/alerting/receivers/schema"
)
// GetReceiverQuery represents a query for a single receiver.
type GetReceiverQuery struct {
OrgID int64
Name string
Decrypt bool
}
// GetReceiversQuery represents a query for receiver groups.
type GetReceiversQuery struct {
OrgID int64
+26
View File
@@ -378,3 +378,29 @@ func EncryptedReceivers(receivers []*definitions.PostableApiReceiver, encryptFn
}
return encrypted, nil
}
// DecryptIntegrationSettings returns a function to decrypt integration settings.
func DecryptIntegrationSettings(ctx context.Context, ss secretService) models.DecryptFn {
return func(value string) (string, error) {
decoded, err := base64.StdEncoding.DecodeString(value)
if err != nil {
return "", err
}
decrypted, err := ss.Decrypt(ctx, decoded)
if err != nil {
return "", err
}
return string(decrypted), nil
}
}
// EncryptIntegrationSettings returns a function to encrypt integration settings.
func EncryptIntegrationSettings(ctx context.Context, ss secretService) models.EncryptFn {
return func(payload string) (string, error) {
encrypted, err := ss.Encrypt(ctx, []byte(payload), secrets.WithoutScope())
if err != nil {
return "", err
}
return base64.StdEncoding.EncodeToString(encrypted), nil
}
}
+29 -1
View File
@@ -1,9 +1,37 @@
package notifier
import "github.com/grafana/grafana/pkg/apimachinery/errutil"
import (
"errors"
"slices"
"github.com/grafana/alerting/receivers/schema"
"github.com/grafana/grafana/pkg/apimachinery/errutil"
)
// WithPublicError sets the public message of an errutil error to the error message.
func WithPublicError(err errutil.Error) error {
err.PublicMessage = err.Error()
return err
}
// If provided error is errutil.Error it appends fields that caused the error to public payload
func makeProtectedFieldsAuthzError(err error, diff map[string][]schema.IntegrationFieldPath) error {
var authzErr errutil.Error
if !errors.As(err, &authzErr) {
return err
}
if authzErr.PublicPayload == nil {
authzErr.PublicPayload = map[string]interface{}{}
}
fields := make(map[string][]string, len(diff))
for field, paths := range diff {
fields[field] = make([]string, len(paths))
for i, path := range paths {
fields[field][i] = path.String()
}
slices.Sort(fields[field])
}
authzErr.PublicPayload["changed_protected_fields"] = fields
return authzErr
}
+16 -30
View File
@@ -2,7 +2,6 @@ package notifier
import (
"context"
"encoding/base64"
"errors"
"fmt"
"strings"
@@ -133,30 +132,33 @@ func (rs *ReceiverService) loadProvenances(ctx context.Context, orgID int64) (ma
return rs.provisioningStore.GetProvenances(ctx, orgID, (&models.Integration{}).ResourceType())
}
// GetReceiver returns a receiver by name.
// GetReceiver returns a receiver by its UID.
// The receiver's secure settings are decrypted if requested and the user has access to do so.
func (rs *ReceiverService) GetReceiver(ctx context.Context, q models.GetReceiverQuery, user identity.Requester) (*models.Receiver, error) {
func (rs *ReceiverService) GetReceiver(ctx context.Context, uid string, decrypt bool, user identity.Requester) (*models.Receiver, error) {
if user == nil {
return nil, errors.New("user is required")
}
ctx, span := rs.tracer.Start(ctx, "alerting.receivers.get", trace.WithAttributes(
attribute.Int64("query_org_id", q.OrgID),
attribute.String("query_name", q.Name),
attribute.Bool("query_decrypt", q.Decrypt),
attribute.Int64("query_org_id", user.GetOrgID()),
attribute.String("query_uid", uid),
attribute.Bool("query_decrypt", decrypt),
))
defer span.End()
revision, err := rs.cfgStore.Get(ctx, q.OrgID)
revision, err := rs.cfgStore.Get(ctx, user.GetOrgID())
if err != nil {
return nil, err
}
prov, err := rs.loadProvenances(ctx, q.OrgID)
prov, err := rs.loadProvenances(ctx, user.GetOrgID())
if err != nil {
return nil, err
}
rcv, err := revision.GetReceiver(legacy_storage.NameToUid(q.Name), prov)
rcv, err := revision.GetReceiver(uid, prov)
if err != nil {
if errors.Is(err, legacy_storage.ErrReceiverNotFound) && rs.includeImported {
imported := rs.getImportedReceivers(ctx, span, []string{legacy_storage.NameToUid(q.Name)}, revision)
imported := rs.getImportedReceivers(ctx, span, []string{uid}, revision)
if len(imported) > 0 {
rcv = imported[0]
}
@@ -171,14 +173,14 @@ func (rs *ReceiverService) GetReceiver(ctx context.Context, q models.GetReceiver
))
auth := rs.authz.AuthorizeReadDecrypted
if !q.Decrypt {
if !decrypt {
auth = rs.authz.AuthorizeRead
}
if err := auth(ctx, user, rcv); err != nil {
return nil, err
}
if q.Decrypt {
if decrypt {
err := rcv.Decrypt(rs.decryptor(ctx))
if err != nil {
rs.log.FromContext(ctx).Warn("Failed to decrypt secure settings", "name", rcv.Name, "error", err)
@@ -684,28 +686,12 @@ func (rs *ReceiverService) deleteProvenances(ctx context.Context, orgID int64, i
// decryptor returns a models.DecryptFn that decrypts a secure setting. If decryption fails, the fallback value is used.
func (rs *ReceiverService) decryptor(ctx context.Context) models.DecryptFn {
return func(value string) (string, error) {
decoded, err := base64.StdEncoding.DecodeString(value)
if err != nil {
return "", err
}
decrypted, err := rs.encryptionService.Decrypt(ctx, decoded)
if err != nil {
return "", err
}
return string(decrypted), nil
}
return DecryptIntegrationSettings(ctx, rs.encryptionService)
}
// encryptor creates an encrypt function that delegates to secrets.Service and returns the base64 encoded result.
func (rs *ReceiverService) encryptor(ctx context.Context) models.EncryptFn {
return func(payload string) (string, error) {
s, err := rs.encryptionService.Encrypt(ctx, []byte(payload), secrets.WithoutScope())
if err != nil {
return "", err
}
return base64.StdEncoding.EncodeToString(s), nil
}
return EncryptIntegrationSettings(ctx, rs.encryptionService)
}
// checkOptimisticConcurrency checks if the existing receiver's version matches the desired version.
@@ -1,30 +0,0 @@
package notifier
import (
"errors"
"slices"
"github.com/grafana/alerting/receivers/schema"
"github.com/grafana/grafana/pkg/apimachinery/errutil"
)
func makeProtectedFieldsAuthzError(err error, diff map[string][]schema.IntegrationFieldPath) error {
var authzErr errutil.Error
if !errors.As(err, &authzErr) {
return err
}
if authzErr.PublicPayload == nil {
authzErr.PublicPayload = map[string]interface{}{}
}
fields := make(map[string][]string, len(diff))
for field, paths := range diff {
fields[field] = make([]string, len(paths))
for i, path := range paths {
fields[field][i] = path.String()
}
slices.Sort(fields[field])
}
authzErr.PublicPayload["changed_protected_fields"] = fields
return authzErr
}
@@ -50,7 +50,7 @@ func TestIntegrationReceiverService_GetReceiver(t *testing.T) {
t.Run("service gets receiver from AM config", func(t *testing.T) {
sut := createReceiverServiceSut(t, secretsService)
recv, err := sut.GetReceiver(context.Background(), singleQ(1, "slack receiver"), redactedUser)
recv, err := sut.GetReceiver(context.Background(), legacy_storage.NameToUid("slack receiver"), false, redactedUser)
require.NoError(t, err)
require.Equal(t, "slack receiver", recv.Name)
require.Len(t, recv.Integrations, 1)
@@ -60,7 +60,7 @@ func TestIntegrationReceiverService_GetReceiver(t *testing.T) {
t.Run("service returns error when receiver does not exist", func(t *testing.T) {
sut := createReceiverServiceSut(t, secretsService)
_, err := sut.GetReceiver(context.Background(), singleQ(1, "receiver1"), redactedUser)
_, err := sut.GetReceiver(context.Background(), legacy_storage.NameToUid("receiver1"), false, redactedUser)
require.ErrorIs(t, err, legacy_storage.ErrReceiverNotFound)
})
@@ -68,7 +68,7 @@ func TestIntegrationReceiverService_GetReceiver(t *testing.T) {
t.Run("gets imported receivers", func(t *testing.T) {
sut := createReceiverServiceSut(t, secretsService, withImportedIncluded)
recv, err := sut.GetReceiver(context.Background(), singleQ(1, "receiver1"), redactedUser)
recv, err := sut.GetReceiver(context.Background(), legacy_storage.NameToUid("receiver1"), false, redactedUser)
require.NoError(t, err)
assert.Equal(t, models.ResourceOriginImported, recv.Origin)
assert.Equal(t, "receiver1", recv.Name)
@@ -81,9 +81,9 @@ func TestIntegrationReceiverService_GetReceiver(t *testing.T) {
t.Run("falls to only Grafana if cannot read imported receivers", func(t *testing.T) {
sut := createReceiverServiceSut(t, secretsService, withImportedIncluded, withInvalidExtraConfig)
_, err := sut.GetReceiver(context.Background(), singleQ(1, "receiver1"), redactedUser)
_, err := sut.GetReceiver(context.Background(), legacy_storage.NameToUid("receiver1"), false, redactedUser)
require.ErrorIs(t, err, legacy_storage.ErrReceiverNotFound)
_, err = sut.GetReceiver(context.Background(), singleQ(1, "slack receiver"), redactedUser)
_, err = sut.GetReceiver(context.Background(), legacy_storage.NameToUid("slack receiver"), false, redactedUser)
require.NoError(t, err)
})
})
@@ -187,12 +187,6 @@ func TestIntegrationReceiverService_DecryptRedact(t *testing.T) {
user: readUser,
err: "[alerting.unauthorized] user is not authorized to read any decrypted receiver",
},
{
name: "service returns error if user is nil and decrypt is true",
decrypt: true,
user: nil,
err: "[alerting.unauthorized] user is not authorized to read any decrypted receiver",
},
{
name: "service decrypts receivers with permission",
decrypt: true,
@@ -224,18 +218,16 @@ func TestIntegrationReceiverService_DecryptRedact(t *testing.T) {
},
}
for _, o := range origin {
for _, method := range getMethods {
t.Run(fmt.Sprintf("%s %s", tc.name, method), func(t *testing.T) {
for _, method := range getMethods {
t.Run(fmt.Sprintf("%s %s", tc.name, method), func(t *testing.T) {
for _, o := range origin {
t.Run(fmt.Sprintf("%s %s (%s)", tc.name, method, o.origin), func(t *testing.T) {
sut := createReceiverServiceSut(t, secretsService, o.opts...)
var res *models.Receiver
var err error
if method == "single" {
q := singleQ(1, o.receiver)
q.Decrypt = tc.decrypt
res, err = sut.GetReceiver(context.Background(), q, tc.user)
res, err = sut.GetReceiver(context.Background(), legacy_storage.NameToUid(o.receiver), tc.decrypt, tc.user)
} else {
q := multiQ(1, o.receiver)
q.Decrypt = tc.decrypt
@@ -267,8 +259,8 @@ func TestIntegrationReceiverService_DecryptRedact(t *testing.T) {
require.NotEqual(t, o.decryptedSettingValue, res.Integrations[0].SecureSettings[o.secureSettingKey])
}
})
})
}
}
})
}
}
}
@@ -412,8 +404,7 @@ func TestReceiverService_Delete(t *testing.T) {
// Ensure receiver saved to store is correct.
name, err := legacy_storage.UidToName(tc.deleteUID)
require.NoError(t, err)
q := models.GetReceiverQuery{OrgID: tc.user.GetOrgID(), Name: name}
_, err = sut.GetReceiver(context.Background(), q, writer)
_, err = sut.GetReceiver(context.Background(), legacy_storage.NameToUid(name), false, writer)
assert.ErrorIs(t, err, legacy_storage.ErrReceiverNotFound)
provenances, err := sut.provisioningStore.GetProvenances(context.Background(), tc.user.GetOrgID(), (&definitions.EmbeddedContactPoint{}).ResourceType())
@@ -626,8 +617,7 @@ func TestReceiverService_Create(t *testing.T) {
assert.Equal(t, tc.expectedCreate, *created)
// Ensure receiver saved to store is correct.
q := models.GetReceiverQuery{OrgID: tc.user.GetOrgID(), Name: tc.receiver.Name, Decrypt: true}
stored, err := sut.GetReceiver(context.Background(), q, decryptUser)
stored, err := sut.GetReceiver(context.Background(), legacy_storage.NameToUid(tc.receiver.Name), true, decryptUser)
require.NoError(t, err)
decrypted := models.CopyReceiverWith(tc.expectedCreate, models.ReceiverMuts.Decrypted(models.Base64Decrypt))
decrypted.Version = tc.expectedCreate.Version // Version is calculated before decryption.
@@ -931,8 +921,7 @@ func TestReceiverService_Update(t *testing.T) {
assert.Equal(t, tc.expectedUpdate, *updated)
// Ensure receiver saved to store is correct.
q := models.GetReceiverQuery{OrgID: tc.user.GetOrgID(), Name: tc.receiver.Name, Decrypt: true}
stored, err := sut.GetReceiver(context.Background(), q, decryptUser)
stored, err := sut.GetReceiver(context.Background(), legacy_storage.NameToUid(tc.receiver.Name), true, decryptUser)
require.NoError(t, err)
decrypted := models.CopyReceiverWith(tc.expectedUpdate, models.ReceiverMuts.Decrypted(models.Base64Decrypt))
decrypted.Version = tc.expectedUpdate.Version // Version is calculated before decryption.
@@ -1054,7 +1043,7 @@ func TestReceiverService_UpdateReceiverName(t *testing.T) {
sut.ruleNotificationsStore = ruleStore
newReceiverName = "receiver1"
actual, err := sut.GetReceiver(context.Background(), models.GetReceiverQuery{OrgID: writer.GetOrgID(), Name: newReceiverName}, writer)
actual, err := sut.GetReceiver(context.Background(), legacy_storage.NameToUid(newReceiverName), false, writer)
require.NoError(t, err)
require.Equal(t, models.ResourceOriginImported, actual.Origin)
require.Equal(t, newReceiverName, actual.Name)
@@ -1067,7 +1056,7 @@ func TestReceiverService_UpdateReceiverName(t *testing.T) {
require.NotEqual(t, actual, recv)
require.Equal(t, models.ResourceOriginGrafana, recv.Origin)
actual, err = sut.GetReceiver(context.Background(), models.GetReceiverQuery{OrgID: writer.GetOrgID(), Name: newReceiverName}, writer)
actual, err = sut.GetReceiver(context.Background(), legacy_storage.NameToUid(newReceiverName), false, writer)
require.NoError(t, err)
require.Equal(t, recv.Name, actual.Name)
})
@@ -1185,7 +1174,7 @@ func TestReceiverServiceAC_Read(t *testing.T) {
return false
}
for _, recv := range allReceivers() {
response, err := sut.GetReceiver(context.Background(), singleQ(orgId, recv.Name), usr)
response, err := sut.GetReceiver(context.Background(), legacy_storage.NameToUid(recv.Name), false, usr)
if isVisible(recv.UID) {
require.NoErrorf(t, err, "receiver '%s' should be visible, but isn't", recv.Name)
assert.NotNil(t, response)
@@ -1207,7 +1196,7 @@ func TestReceiverServiceAC_Read(t *testing.T) {
}
sut.authz = ac.NewReceiverAccess[*models.Receiver](acimpl.ProvideAccessControl(featuremgmt.WithFeatures()), true)
for _, recv := range allReceivers() {
response, err := sut.GetReceiver(context.Background(), singleQ(orgId, recv.Name), usr)
response, err := sut.GetReceiver(context.Background(), legacy_storage.NameToUid(recv.Name), false, usr)
if isVisibleInProvisioning(recv.UID) {
require.NoErrorf(t, err, "receiver '%s' should be visible, but isn't", recv.Name)
assert.NotNil(t, response)
@@ -1766,7 +1755,7 @@ func TestReceiverService_AccessControlMetadata(t *testing.T) {
},
}}
r, err := sut.GetReceiver(context.Background(), models.GetReceiverQuery{OrgID: 1, Name: "receiver1"}, admin)
r, err := sut.GetReceiver(context.Background(), legacy_storage.NameToUid("receiver1"), false, admin)
require.NoError(t, err)
t.Run("should override metadata for imported receivers", func(t *testing.T) {
@@ -1842,13 +1831,6 @@ func createEncryptedConfig(t *testing.T, secretService secretService, extraConfi
return string(bytes)
}
func singleQ(orgID int64, name string) models.GetReceiverQuery {
return models.GetReceiverQuery{
OrgID: orgID,
Name: name,
}
}
func multiQ(orgID int64, names ...string) models.GetReceiversQuery {
return models.GetReceiversQuery{
OrgID: orgID,
+4 -16
View File
@@ -40,6 +40,7 @@ import (
"github.com/grafana/grafana/pkg/services/ngalert/notifier"
remoteClient "github.com/grafana/grafana/pkg/services/ngalert/remote/client"
"github.com/grafana/grafana/pkg/services/ngalert/sender"
"github.com/grafana/grafana/pkg/services/secrets"
"github.com/grafana/grafana/pkg/util/cmputil"
)
@@ -57,6 +58,7 @@ func NoopAutogenFn(_ context.Context, _ log.Logger, _ int64, _ *apimodels.Postab
}
type Crypto interface {
Encrypt(ctx context.Context, payload []byte, opt secrets.EncryptionOptions) ([]byte, error)
Decrypt(ctx context.Context, payload []byte) ([]byte, error)
DecryptExtraConfigs(ctx context.Context, config *apimodels.PostableUserConfig) error
}
@@ -289,20 +291,6 @@ func (am *Alertmanager) isDefaultConfiguration(configHash string) bool {
return configHash == am.defaultConfigHash
}
func decrypter(ctx context.Context, crypto Crypto) models.DecryptFn {
return func(value string) (string, error) {
decoded, err := base64.StdEncoding.DecodeString(value)
if err != nil {
return "", err
}
decrypted, err := crypto.Decrypt(ctx, decoded)
if err != nil {
return "", err
}
return string(decrypted), nil
}
}
// buildConfiguration takes a raw Alertmanager configuration and returns a config that the remote Alertmanager can use.
// It parses the initial configuration, adds auto-generated routes, decrypts receivers, and merges the extra configs.
func (am *Alertmanager) buildConfiguration(ctx context.Context, raw []byte, createdAtEpoch int64, autogenInvalidReceiverAction notifier.InvalidReceiversAction) (remoteClient.UserGrafanaConfig, error) {
@@ -317,7 +305,7 @@ func (am *Alertmanager) buildConfiguration(ctx context.Context, raw []byte, crea
}
// Decrypt the receivers in the configuration.
decryptedReceivers, err := notifier.DecryptedReceivers(c.AlertmanagerConfig.Receivers, decrypter(ctx, am.crypto))
decryptedReceivers, err := notifier.DecryptedReceivers(c.AlertmanagerConfig.Receivers, notifier.DecryptIntegrationSettings(ctx, am.crypto))
if err != nil {
return remoteClient.UserGrafanaConfig{}, fmt.Errorf("unable to decrypt receivers: %w", err)
}
@@ -619,7 +607,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 := notifier.DecryptedReceivers(c.Receivers, decrypter(ctx, am.crypto))
decryptedReceivers, err := notifier.DecryptedReceivers(c.Receivers, notifier.DecryptIntegrationSettings(ctx, am.crypto))
if err != nil {
return nil, 0, fmt.Errorf("failed to decrypt receivers: %w", err)
}
@@ -43,7 +43,6 @@ import (
"github.com/grafana/grafana/pkg/services/ngalert/notifier"
"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"
"github.com/grafana/grafana/pkg/services/secrets/database"
"github.com/grafana/grafana/pkg/services/secrets/fakes"
secretsManager "github.com/grafana/grafana/pkg/services/secrets/manager"
@@ -298,13 +297,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 := 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
}
return base64.StdEncoding.EncodeToString(encrypted), nil
})
encryptedReceivers, err := notifier.EncryptedReceivers(c.AlertmanagerConfig.Receivers, notifier.EncryptIntegrationSettings(context.Background(), secretsService))
c.AlertmanagerConfig.Receivers = encryptedReceivers
require.NoError(t, err)
@@ -462,13 +455,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 := 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
}
return base64.StdEncoding.EncodeToString(encrypted), nil
})
encryptedReceivers, err := notifier.EncryptedReceivers(inputCfg.AlertmanagerConfig.Receivers, notifier.EncryptIntegrationSettings(context.Background(), secretsService))
inputCfg.AlertmanagerConfig.Receivers = encryptedReceivers
require.NoError(t, err)
testGrafanaConfigWithEncryptedSecret, err := json.Marshal(inputCfg)
@@ -663,13 +650,7 @@ func Test_TestReceiversDecryptsSecureSettings(t *testing.T) {
var inputCfg apimodels.PostableUserConfig
require.NoError(t, json.Unmarshal([]byte(testGrafanaConfigWithSecret), &inputCfg))
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
}
return base64.StdEncoding.EncodeToString(encrypted), nil
})
encryptedReceivers, err := notifier.EncryptedReceivers(inputCfg.AlertmanagerConfig.Receivers, notifier.EncryptIntegrationSettings(context.Background(), secretsService))
inputCfg.AlertmanagerConfig.Receivers = encryptedReceivers
require.NoError(t, err)
@@ -1037,13 +1018,7 @@ func TestIntegrationRemoteAlertmanagerConfiguration(t *testing.T) {
{
postableCfg, err := notifier.Load([]byte(testGrafanaConfigWithSecret))
require.NoError(t, err)
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
}
return base64.StdEncoding.EncodeToString(encrypted), nil
})
encryptedReceivers, err := notifier.EncryptedReceivers(postableCfg.AlertmanagerConfig.Receivers, notifier.EncryptIntegrationSettings(context.Background(), secretsService))
postableCfg.AlertmanagerConfig.Receivers = encryptedReceivers
require.NoError(t, err)