Alerting: Decrypt secure settings when testing receivers in the remote Alertmanager (#93864)

* Alerting: Decrypt secure settings when testing receivers in the remote Alertmanager

* go work sync

* make update-workspace

* point to latest main in grafana/alerting

* unit test

* import definitions only once
This commit is contained in:
Santiago
2024-09-30 13:28:30 -03:00
committed by GitHub
parent fcbaf188c2
commit 80611b381c
6 changed files with 78 additions and 17 deletions
@@ -2,7 +2,6 @@ package definitions
import (
"context"
"encoding/base64"
"encoding/json"
"fmt"
"time"
@@ -680,19 +679,11 @@ func (c *PostableUserConfig) Decrypt(decryptFn func(payload []byte) ([]byte, err
// Iterate through receivers and decrypt secure settings.
for _, rcv := range newCfg.AlertmanagerConfig.Receivers {
for _, gmr := range rcv.PostableGrafanaReceivers.GrafanaManagedReceivers {
for k, v := range gmr.SecureSettings {
decoded, err := base64.StdEncoding.DecodeString(v)
if err != nil {
return PostableUserConfig{}, fmt.Errorf("failed to decode value for key '%s': %w", k, err)
}
decrypted, err := decryptFn(decoded)
if err != nil {
return PostableUserConfig{}, fmt.Errorf("failed to decrypt value for key '%s': %w", k, err)
}
gmr.SecureSettings[k] = string(decrypted)
decrypted, err := gmr.DecryptSecureSettings(decryptFn)
if err != nil {
return PostableUserConfig{}, err
}
gmr.SecureSettings = decrypted
}
}
return *newCfg, nil
+10 -1
View File
@@ -527,17 +527,26 @@ func (am *Alertmanager) GetReceivers(ctx context.Context) ([]apimodels.Receiver,
}
func (am *Alertmanager) TestReceivers(ctx context.Context, c apimodels.TestReceiversConfigBodyParams) (*alertingNotify.TestReceiversResult, int, error) {
fn := func(payload []byte) ([]byte, error) {
return am.decrypt(ctx, payload)
}
receivers := make([]*alertingNotify.APIReceiver, 0, len(c.Receivers))
for _, r := range c.Receivers {
integrations := make([]*alertingNotify.GrafanaIntegrationConfig, 0, len(r.GrafanaManagedReceivers))
for _, gr := range r.PostableGrafanaReceivers.GrafanaManagedReceivers {
decrypted, err := gr.DecryptSecureSettings(fn)
if err != nil {
return nil, 0, err
}
integrations = append(integrations, &alertingNotify.GrafanaIntegrationConfig{
UID: gr.UID,
Name: gr.Name,
Type: gr.Type,
DisableResolveMessage: gr.DisableResolveMessage,
Settings: json.RawMessage(gr.Settings),
SecureSettings: gr.SecureSettings,
SecureSettings: decrypted,
})
}
receivers = append(receivers, &alertingNotify.APIReceiver{
@@ -335,6 +335,65 @@ func TestCompareAndSendConfiguration(t *testing.T) {
}
}
func Test_TestReceiversDecryptsSecureSettings(t *testing.T) {
const testKey = "test-key"
const testValue = "test-value"
decryptFn := func(_ context.Context, payload []byte) ([]byte, error) {
if string(payload) == testValue {
return []byte(testValue), nil
}
return nil, errTest
}
var got apimodels.TestReceiversConfigBodyParams
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Add("Content-Type", "application/json")
require.NoError(t, json.NewDecoder(r.Body).Decode(&got))
require.NoError(t, r.Body.Close())
_, err := w.Write([]byte(`{"status": "success"}`))
require.NoError(t, err)
}))
fstore := notifier.NewFileStore(1, ngfakes.NewFakeKVStore(t))
m := metrics.NewRemoteAlertmanagerMetrics(prometheus.NewRegistry())
cfg := AlertmanagerConfig{
OrgID: 1,
TenantID: "test",
URL: server.URL,
DefaultConfig: defaultGrafanaConfig,
}
am, err := NewAlertmanager(cfg,
fstore,
decryptFn,
NoopAutogenFn,
m,
tracing.InitializeTracerForTest(),
)
require.NoError(t, err)
params := apimodels.TestReceiversConfigBodyParams{
Alert: &apimodels.TestReceiversConfigAlertParams{},
Receivers: []*definition.PostableApiReceiver{
{
PostableGrafanaReceivers: apimodels.PostableGrafanaReceivers{
GrafanaManagedReceivers: []*apimodels.PostableGrafanaReceiver{
{
SecureSettings: map[string]string{
testKey: base64.StdEncoding.EncodeToString([]byte(testValue)),
},
},
},
},
},
},
}
_, _, err = am.TestReceivers(context.Background(), params)
require.NoError(t, err)
require.Equal(t, map[string]string{testKey: testValue}, got.Receivers[0].PostableGrafanaReceivers.GrafanaManagedReceivers[0].SecureSettings)
}
func Test_isDefaultConfiguration(t *testing.T) {
parsedDefaultConfig, _ := notifier.Load([]byte(defaultGrafanaConfig))
parsedTestConfig, _ := notifier.Load([]byte(testGrafanaConfig))