grafana/pkg/services/ngalert/remote/remote_primary_forked_alertmanager.go
Matthew Jacobson f79dd7c7f9
Alerting: Persist silence state immediately on Create/Delete (#84705)
* Alerting: Persist silence state immediately on Create/Delete

Persists the silence state to the kvstore immediately instead of waiting for the
 next maintenance run. This is used after Create/Delete to prevent silences from
 being lost when a new Alertmanager is started before the state has persisted.
 This can happen, for example, in a rolling deployment scenario.

* Fix test that requires real data

* Don't error if silence state persist fails, maintenance will correct
2024-04-09 13:39:34 -04:00

112 lines
4.0 KiB
Go

package remote
import (
"context"
"fmt"
alertingNotify "github.com/grafana/alerting/notify"
"github.com/grafana/grafana/pkg/infra/log"
apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
"github.com/grafana/grafana/pkg/services/ngalert/models"
"github.com/grafana/grafana/pkg/services/ngalert/notifier"
)
type RemotePrimaryForkedAlertmanager struct {
log log.Logger
internal notifier.Alertmanager
remote remoteAlertmanager
}
func NewRemotePrimaryForkedAlertmanager(log log.Logger, internal notifier.Alertmanager, remote remoteAlertmanager) *RemotePrimaryForkedAlertmanager {
return &RemotePrimaryForkedAlertmanager{
log: log,
internal: internal,
remote: remote,
}
}
// ApplyConfig will send the configuration to the remote Alertmanager on startup.
func (fam *RemotePrimaryForkedAlertmanager) ApplyConfig(ctx context.Context, config *models.AlertConfiguration) error {
if err := fam.remote.ApplyConfig(ctx, config); err != nil {
return fmt.Errorf("failed to call ApplyConfig on the remote Alertmanager: %w", err)
}
if err := fam.internal.ApplyConfig(ctx, config); err != nil {
fam.log.Error("Error applying config to the internal Alertmanager", "err", err)
}
return nil
}
// TODO: save the new configuration hash in memory.
func (fam *RemotePrimaryForkedAlertmanager) SaveAndApplyConfig(ctx context.Context, config *apimodels.PostableUserConfig) error {
return nil
}
// TODO: save the new configuration hash in memory.
func (fam *RemotePrimaryForkedAlertmanager) SaveAndApplyDefaultConfig(ctx context.Context) error {
return nil
}
func (fam *RemotePrimaryForkedAlertmanager) GetStatus() apimodels.GettableStatus {
return fam.remote.GetStatus()
}
func (fam *RemotePrimaryForkedAlertmanager) CreateSilence(ctx context.Context, silence *apimodels.PostableSilence) (string, error) {
return fam.remote.CreateSilence(ctx, silence)
}
func (fam *RemotePrimaryForkedAlertmanager) DeleteSilence(ctx context.Context, id string) error {
return fam.remote.DeleteSilence(ctx, id)
}
func (fam *RemotePrimaryForkedAlertmanager) GetSilence(ctx context.Context, id string) (apimodels.GettableSilence, error) {
return fam.remote.GetSilence(ctx, id)
}
func (fam *RemotePrimaryForkedAlertmanager) ListSilences(ctx context.Context, filter []string) (apimodels.GettableSilences, error) {
return fam.remote.ListSilences(ctx, filter)
}
func (fam *RemotePrimaryForkedAlertmanager) GetAlerts(ctx context.Context, active, silenced, inhibited bool, filter []string, receiver string) (apimodels.GettableAlerts, error) {
return fam.remote.GetAlerts(ctx, active, silenced, inhibited, filter, receiver)
}
func (fam *RemotePrimaryForkedAlertmanager) GetAlertGroups(ctx context.Context, active, silenced, inhibited bool, filter []string, receiver string) (apimodels.AlertGroups, error) {
return fam.remote.GetAlertGroups(ctx, active, silenced, inhibited, filter, receiver)
}
func (fam *RemotePrimaryForkedAlertmanager) PutAlerts(ctx context.Context, alerts apimodels.PostableAlerts) error {
return fam.remote.PutAlerts(ctx, alerts)
}
func (fam *RemotePrimaryForkedAlertmanager) GetReceivers(ctx context.Context) ([]apimodels.Receiver, error) {
return fam.remote.GetReceivers(ctx)
}
func (fam *RemotePrimaryForkedAlertmanager) TestReceivers(ctx context.Context, c apimodels.TestReceiversConfigBodyParams) (*notifier.TestReceiversResult, error) {
return fam.remote.TestReceivers(ctx, c)
}
func (fam *RemotePrimaryForkedAlertmanager) TestTemplate(ctx context.Context, c apimodels.TestTemplatesConfigBodyParams) (*notifier.TestTemplatesResults, error) {
return fam.remote.TestTemplate(ctx, c)
}
func (fam *RemotePrimaryForkedAlertmanager) SilenceState(ctx context.Context) (alertingNotify.SilenceState, error) {
return fam.remote.SilenceState(ctx)
}
func (fam *RemotePrimaryForkedAlertmanager) StopAndWait() {
fam.internal.StopAndWait()
fam.remote.StopAndWait()
}
func (fam *RemotePrimaryForkedAlertmanager) Ready() bool {
// Both Alertmanagers must be ready.
if ready := fam.remote.Ready(); !ready {
return false
}
return fam.internal.Ready()
}