From fce03cd724eec337a5ae1c0072a118396360f2f1 Mon Sep 17 00:00:00 2001 From: Santiago Date: Mon, 1 Jul 2024 17:48:40 +0200 Subject: [PATCH] Alerting: Send static headers to the remote Alertmanager (#89846) --- pkg/services/ngalert/ngalert.go | 3 +++ pkg/services/ngalert/remote/alertmanager.go | 6 ++++++ pkg/services/ngalert/remote/alertmanager_test.go | 4 +++- .../ngalert/remote/client/alertmanager_configuration.go | 2 ++ pkg/services/ngalert/remote/client/mimir.go | 3 +++ 5 files changed, 17 insertions(+), 1 deletion(-) diff --git a/pkg/services/ngalert/ngalert.go b/pkg/services/ngalert/ngalert.go index 539cb38fd25..5fef66c558b 100644 --- a/pkg/services/ngalert/ngalert.go +++ b/pkg/services/ngalert/ngalert.go @@ -204,6 +204,7 @@ func (ng *AlertNG) init() error { PromoteConfig: true, SyncInterval: ng.Cfg.UnifiedAlerting.RemoteAlertmanager.SyncInterval, ExternalURL: ng.Cfg.AppURL, + StaticHeaders: ng.Cfg.Smtp.StaticHeaders, } remoteAM, err := createRemoteAlertmanager(cfg, ng.KVStore, ng.SecretsService.Decrypt, autogenFn, m, ng.tracer) if err != nil { @@ -239,6 +240,7 @@ func (ng *AlertNG) init() error { TenantID: ng.Cfg.UnifiedAlerting.RemoteAlertmanager.TenantID, URL: ng.Cfg.UnifiedAlerting.RemoteAlertmanager.URL, ExternalURL: ng.Cfg.AppURL, + StaticHeaders: ng.Cfg.Smtp.StaticHeaders, } remoteAM, err := createRemoteAlertmanager(cfg, ng.KVStore, ng.SecretsService.Decrypt, autogenFn, m, ng.tracer) if err != nil { @@ -276,6 +278,7 @@ func (ng *AlertNG) init() error { URL: ng.Cfg.UnifiedAlerting.RemoteAlertmanager.URL, SyncInterval: ng.Cfg.UnifiedAlerting.RemoteAlertmanager.SyncInterval, ExternalURL: ng.Cfg.AppURL, + StaticHeaders: ng.Cfg.Smtp.StaticHeaders, } remoteAM, err := createRemoteAlertmanager(cfg, ng.KVStore, ng.SecretsService.Decrypt, autogenFn, m, ng.tracer) if err != nil { diff --git a/pkg/services/ngalert/remote/alertmanager.go b/pkg/services/ngalert/remote/alertmanager.go index 819df0792ec..e57bd723696 100644 --- a/pkg/services/ngalert/remote/alertmanager.go +++ b/pkg/services/ngalert/remote/alertmanager.go @@ -80,9 +80,14 @@ type AlertmanagerConfig struct { // ExternalURL is used in notifications sent by the remote Alertmanager. ExternalURL string + // PromoteConfig is a flag that determines whether the configuration should be used in the remote Alertmanager. // The same flag is used for promoting state. PromoteConfig bool + + // StaticHeaders are used in email notifications sent by the remote Alertmanager. + StaticHeaders map[string]string + // SyncInterval determines how often we should attempt to synchronize configuration. SyncInterval time.Duration } @@ -120,6 +125,7 @@ func NewAlertmanager(cfg AlertmanagerConfig, store stateStore, decryptFn Decrypt URL: u, PromoteConfig: cfg.PromoteConfig, ExternalURL: cfg.ExternalURL, + StaticHeaders: cfg.StaticHeaders, } mc, err := remoteClient.New(mcCfg, metrics, tracer) if err != nil { diff --git a/pkg/services/ngalert/remote/alertmanager_test.go b/pkg/services/ngalert/remote/alertmanager_test.go index 3f61d163245..ec3296badbc 100644 --- a/pkg/services/ngalert/remote/alertmanager_test.go +++ b/pkg/services/ngalert/remote/alertmanager_test.go @@ -169,6 +169,7 @@ func TestApplyConfig(t *testing.T) { PromoteConfig: true, SyncInterval: 1 * time.Hour, ExternalURL: "https://test.grafana.com", + StaticHeaders: map[string]string{"Header-1": "Value-1", "Header-2": "Value-2"}, } ctx := context.Background() @@ -199,8 +200,9 @@ func TestApplyConfig(t *testing.T) { require.JSONEq(t, testGrafanaConfigWithSecret, string(amCfg)) require.True(t, configSent.Promoted) - // Grafana's URL should be sent alongside the configuration. + // Grafana's URL and static headers should be sent alongside the configuration. require.Equal(t, cfg.ExternalURL, configSent.ExternalURL) + require.Equal(t, cfg.StaticHeaders, configSent.StaticHeaders) // If we already got a 200 status code response and the sync interval hasn't elapsed, // we shouldn't send the state/configuration again. diff --git a/pkg/services/ngalert/remote/client/alertmanager_configuration.go b/pkg/services/ngalert/remote/client/alertmanager_configuration.go index 2a94b851a38..d1808819a84 100644 --- a/pkg/services/ngalert/remote/client/alertmanager_configuration.go +++ b/pkg/services/ngalert/remote/client/alertmanager_configuration.go @@ -22,6 +22,7 @@ type UserGrafanaConfig struct { Default bool `json:"default"` Promoted bool `json:"promoted"` ExternalURL string `json:"external_url"` + StaticHeaders map[string]string `json:"static_headers"` } func (mc *Mimir) ShouldPromoteConfig() bool { @@ -55,6 +56,7 @@ func (mc *Mimir) CreateGrafanaAlertmanagerConfig(ctx context.Context, cfg *apimo Default: isDefault, Promoted: mc.promoteConfig, ExternalURL: mc.externalURL, + StaticHeaders: mc.staticHeaders, }) if err != nil { return err diff --git a/pkg/services/ngalert/remote/client/mimir.go b/pkg/services/ngalert/remote/client/mimir.go index 4b58bb22b60..1bc84473074 100644 --- a/pkg/services/ngalert/remote/client/mimir.go +++ b/pkg/services/ngalert/remote/client/mimir.go @@ -41,6 +41,7 @@ type Mimir struct { metrics *metrics.RemoteAlertmanager promoteConfig bool externalURL string + staticHeaders map[string]string } type Config struct { @@ -51,6 +52,7 @@ type Config struct { Logger log.Logger PromoteConfig bool ExternalURL string + StaticHeaders map[string]string } // successResponse represents a successful response from the Mimir API. @@ -94,6 +96,7 @@ func New(cfg *Config, metrics *metrics.RemoteAlertmanager, tracer tracing.Tracer metrics: metrics, promoteConfig: cfg.PromoteConfig, externalURL: cfg.ExternalURL, + staticHeaders: cfg.StaticHeaders, }, nil }