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:
@@ -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
|
||||
|
||||
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user