mirror of
https://github.com/grafana/grafana.git
synced 2024-11-25 18:30:41 -06:00
Alerting: Implement ApplyConfig for remote primary mode (forked AM) (#84811)
* Alerting: Implement ApplyConfig for remote primary mode (forked AM) * add TODO for saving the config hash in other config-related methods * fix bad method receiver name (m -> am) * tests * add mutex * remove sync loop
This commit is contained in:
parent
08c24e4133
commit
a2facbecd4
@ -89,7 +89,7 @@ func TestForkedAlertmanager_ModeRemoteSecondary(t *testing.T) {
|
|||||||
internal.EXPECT().ApplyConfig(ctx, mock.Anything).Return(expErr).Once()
|
internal.EXPECT().ApplyConfig(ctx, mock.Anything).Return(expErr).Once()
|
||||||
readyCall := remote.EXPECT().Ready().Return(false).Once()
|
readyCall := remote.EXPECT().Ready().Return(false).Once()
|
||||||
remote.EXPECT().ApplyConfig(ctx, mock.Anything).Return(nil).Once().NotBefore(readyCall)
|
remote.EXPECT().ApplyConfig(ctx, mock.Anything).Return(nil).Once().NotBefore(readyCall)
|
||||||
require.Error(tt, forked.ApplyConfig(ctx, &models.AlertConfiguration{}), expErr)
|
require.ErrorIs(tt, forked.ApplyConfig(ctx, &models.AlertConfiguration{}), expErr)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -375,6 +375,28 @@ func TestForkedAlertmanager_ModeRemotePrimary(t *testing.T) {
|
|||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
expErr := errors.New("test error")
|
expErr := errors.New("test error")
|
||||||
|
|
||||||
|
t.Run("ApplyConfig", func(tt *testing.T) {
|
||||||
|
{
|
||||||
|
// If the remote Alertmanager is not ready, ApplyConfig should be called on both Alertmanagers,
|
||||||
|
// first on the remote, then on the internal.
|
||||||
|
internal, remote, forked := genTestAlertmanagers(tt, modeRemotePrimary)
|
||||||
|
remoteCall := remote.EXPECT().ApplyConfig(ctx, mock.Anything).Return(nil).Once()
|
||||||
|
internal.EXPECT().ApplyConfig(ctx, mock.Anything).Return(nil).Once().NotBefore(remoteCall)
|
||||||
|
require.NoError(tt, forked.ApplyConfig(ctx, &models.AlertConfiguration{}))
|
||||||
|
|
||||||
|
// An error in the remote Alertmanager should be returned.
|
||||||
|
_, remote, forked = genTestAlertmanagers(tt, modeRemotePrimary)
|
||||||
|
remote.EXPECT().ApplyConfig(ctx, mock.Anything).Return(expErr).Once()
|
||||||
|
require.ErrorIs(tt, forked.ApplyConfig(ctx, &models.AlertConfiguration{}), expErr)
|
||||||
|
|
||||||
|
// An error in the internal Alertmanager should not be returned.
|
||||||
|
internal, remote, forked = genTestAlertmanagers(tt, modeRemotePrimary)
|
||||||
|
remote.EXPECT().ApplyConfig(ctx, mock.Anything).Return(nil).Once()
|
||||||
|
internal.EXPECT().ApplyConfig(ctx, mock.Anything).Return(expErr).Once()
|
||||||
|
require.NoError(tt, forked.ApplyConfig(ctx, &models.AlertConfiguration{}))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
t.Run("GetStatus", func(tt *testing.T) {
|
t.Run("GetStatus", func(tt *testing.T) {
|
||||||
// We care about the status of the remote Alertmanager.
|
// We care about the status of the remote Alertmanager.
|
||||||
_, remote, forked := genTestAlertmanagers(tt, modeRemotePrimary)
|
_, remote, forked := genTestAlertmanagers(tt, modeRemotePrimary)
|
||||||
@ -626,7 +648,7 @@ func genTestAlertmanagersWithSyncInterval(t *testing.T, mode int, syncInterval t
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
return internal, remote, forked
|
return internal, remote, forked
|
||||||
}
|
}
|
||||||
return internal, remote, NewRemotePrimaryForkedAlertmanager(internal, remote)
|
return internal, remote, NewRemotePrimaryForkedAlertmanager(log.NewNopLogger(), internal, remote)
|
||||||
}
|
}
|
||||||
|
|
||||||
// errConfigStore returns an error when a method is called.
|
// errConfigStore returns an error when a method is called.
|
||||||
|
@ -2,32 +2,47 @@ package remote
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
|
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/models"
|
||||||
"github.com/grafana/grafana/pkg/services/ngalert/notifier"
|
"github.com/grafana/grafana/pkg/services/ngalert/notifier"
|
||||||
)
|
)
|
||||||
|
|
||||||
type RemotePrimaryForkedAlertmanager struct {
|
type RemotePrimaryForkedAlertmanager struct {
|
||||||
|
log log.Logger
|
||||||
|
|
||||||
internal notifier.Alertmanager
|
internal notifier.Alertmanager
|
||||||
remote notifier.Alertmanager
|
remote remoteAlertmanager
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRemotePrimaryForkedAlertmanager(internal, remote notifier.Alertmanager) *RemotePrimaryForkedAlertmanager {
|
func NewRemotePrimaryForkedAlertmanager(log log.Logger, internal notifier.Alertmanager, remote remoteAlertmanager) *RemotePrimaryForkedAlertmanager {
|
||||||
return &RemotePrimaryForkedAlertmanager{
|
return &RemotePrimaryForkedAlertmanager{
|
||||||
|
log: log,
|
||||||
internal: internal,
|
internal: internal,
|
||||||
remote: remote,
|
remote: remote,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ApplyConfig will send the configuration to the remote Alertmanager on startup.
|
||||||
func (fam *RemotePrimaryForkedAlertmanager) ApplyConfig(ctx context.Context, config *models.AlertConfiguration) error {
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: save the new configuration hash in memory.
|
||||||
func (fam *RemotePrimaryForkedAlertmanager) SaveAndApplyConfig(ctx context.Context, config *apimodels.PostableUserConfig) error {
|
func (fam *RemotePrimaryForkedAlertmanager) SaveAndApplyConfig(ctx context.Context, config *apimodels.PostableUserConfig) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: save the new configuration hash in memory.
|
||||||
func (fam *RemotePrimaryForkedAlertmanager) SaveAndApplyDefaultConfig(ctx context.Context) error {
|
func (fam *RemotePrimaryForkedAlertmanager) SaveAndApplyDefaultConfig(ctx context.Context) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user