From e1aae0549e09b1ea92c5a1a5675ecfe700948152 Mon Sep 17 00:00:00 2001 From: Yuriy Tseretyan Date: Fri, 17 Sep 2021 14:12:27 -0400 Subject: [PATCH] Provide reader to alertmanager silence instead of file path (#39305) --- pkg/services/ngalert/notifier/alertmanager.go | 33 +++++++++++++++---- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/pkg/services/ngalert/notifier/alertmanager.go b/pkg/services/ngalert/notifier/alertmanager.go index d7fec832c3b..f393a01bfab 100644 --- a/pkg/services/ngalert/notifier/alertmanager.go +++ b/pkg/services/ngalert/notifier/alertmanager.go @@ -8,6 +8,7 @@ import ( "errors" "fmt" "net/url" + "os" "path/filepath" "strconv" "sync" @@ -164,12 +165,7 @@ func newAlertmanager(orgID int64, cfg *setting.Cfg, store store.AlertingStore, k c := am.peer.AddState(fmt.Sprintf("notificationlog:%d", am.OrgID), am.notificationLog, m.Registerer) am.notificationLog.SetBroadcast(c.Broadcast) - // Initialize silences - am.silences, err = silence.New(silence.Options{ - Metrics: m.Registerer, - SnapshotFile: silencesFilePath, - Retention: retentionNotificationsAndSilences, - }) + am.silences, err = newSilences(silencesFilePath, m.Registerer) if err != nil { return nil, fmt.Errorf("unable to initialize the silencing component of alerting: %w", err) } @@ -194,6 +190,31 @@ func newAlertmanager(orgID int64, cfg *setting.Cfg, store store.AlertingStore, k return am, nil } +// newSilences initializes returns *silence.Silences (from the Alertmanager) with silences taken from the file by path silencesFilePath and specific metrics registerer. +func newSilences(silencesFilePath string, registerer prometheus.Registerer) (*silence.Silences, error) { + //TODO yuriy: Replace with silencesFilePath when fix in https://github.com/prometheus/alertmanager/pull/2710 is merged. + silenceOpts := silence.Options{ + Metrics: registerer, + Retention: retentionNotificationsAndSilences, + } + + //The path is generated by the filestore. So presumably it should be safe + //nolint:gosec + silencesFileReader, err := os.Open(silencesFilePath) + if err != nil && !os.IsNotExist(err) { + return nil, err + } + + if silencesFileReader != nil { + silenceOpts.SnapshotReader = silencesFileReader + defer func(file *os.File) { + _ = file.Close() + }(silencesFileReader) + } + // Initialize silences + return silence.New(silenceOpts) +} + func (am *Alertmanager) Ready() bool { // We consider AM as ready only when the config has been // applied at least once successfully. Until then, some objects