mirror of
https://github.com/grafana/grafana.git
synced 2025-02-11 08:05:43 -06:00
Add context.Context to AlertingStore (#45069)
This commit is contained in:
parent
069f772c6f
commit
4e3a72fc2a
@ -32,8 +32,8 @@ type Scheduler interface {
|
||||
|
||||
type Alertmanager interface {
|
||||
// Configuration
|
||||
SaveAndApplyConfig(config *apimodels.PostableUserConfig) error
|
||||
SaveAndApplyDefaultConfig() error
|
||||
SaveAndApplyConfig(ctx context.Context, config *apimodels.PostableUserConfig) error
|
||||
SaveAndApplyDefaultConfig(ctx context.Context) error
|
||||
GetStatus() apimodels.GettableStatus
|
||||
|
||||
// Silences
|
||||
@ -51,7 +51,7 @@ type Alertmanager interface {
|
||||
}
|
||||
|
||||
type AlertingStore interface {
|
||||
GetLatestAlertmanagerConfiguration(query *models.GetLatestAlertmanagerConfigurationQuery) error
|
||||
GetLatestAlertmanagerConfiguration(ctx context.Context, query *models.GetLatestAlertmanagerConfigurationQuery) error
|
||||
}
|
||||
|
||||
// API handlers.
|
||||
|
@ -42,10 +42,10 @@ func (e UnknownReceiverError) Error() string {
|
||||
return fmt.Sprintf("unknown receiver: %s", e.UID)
|
||||
}
|
||||
|
||||
func (srv AlertmanagerSrv) loadSecureSettings(orgId int64, receivers []*apimodels.PostableApiReceiver) error {
|
||||
func (srv AlertmanagerSrv) loadSecureSettings(ctx context.Context, orgId int64, receivers []*apimodels.PostableApiReceiver) error {
|
||||
// Get the last known working configuration
|
||||
query := ngmodels.GetLatestAlertmanagerConfigurationQuery{OrgID: orgId}
|
||||
if err := srv.store.GetLatestAlertmanagerConfiguration(&query); err != nil {
|
||||
if err := srv.store.GetLatestAlertmanagerConfiguration(ctx, &query); err != nil {
|
||||
// If we don't have a configuration there's nothing for us to know and we should just continue saving the new one
|
||||
if !errors.Is(err, store.ErrNoAlertmanagerConfiguration) {
|
||||
return fmt.Errorf("failed to get latest configuration: %w", err)
|
||||
@ -159,7 +159,7 @@ func (srv AlertmanagerSrv) RouteDeleteAlertingConfig(c *models.ReqContext) respo
|
||||
return errResp
|
||||
}
|
||||
|
||||
if err := am.SaveAndApplyDefaultConfig(); err != nil {
|
||||
if err := am.SaveAndApplyDefaultConfig(c.Req.Context()); err != nil {
|
||||
srv.log.Error("unable to save and apply default alertmanager configuration", "err", err)
|
||||
return ErrResp(http.StatusInternalServerError, err, "failed to save and apply default Alertmanager configuration")
|
||||
}
|
||||
@ -193,7 +193,7 @@ func (srv AlertmanagerSrv) RouteGetAlertingConfig(c *models.ReqContext) response
|
||||
}
|
||||
|
||||
query := ngmodels.GetLatestAlertmanagerConfigurationQuery{OrgID: c.OrgId}
|
||||
if err := srv.store.GetLatestAlertmanagerConfiguration(&query); err != nil {
|
||||
if err := srv.store.GetLatestAlertmanagerConfiguration(c.Req.Context(), &query); err != nil {
|
||||
if errors.Is(err, store.ErrNoAlertmanagerConfiguration) {
|
||||
return ErrResp(http.StatusNotFound, err, "")
|
||||
}
|
||||
@ -340,14 +340,14 @@ func (srv AlertmanagerSrv) RoutePostAlertingConfig(c *models.ReqContext, body ap
|
||||
|
||||
// Get the last known working configuration
|
||||
query := ngmodels.GetLatestAlertmanagerConfigurationQuery{OrgID: c.OrgId}
|
||||
if err := srv.store.GetLatestAlertmanagerConfiguration(&query); err != nil {
|
||||
if err := srv.store.GetLatestAlertmanagerConfiguration(c.Req.Context(), &query); err != nil {
|
||||
// If we don't have a configuration there's nothing for us to know and we should just continue saving the new one
|
||||
if !errors.Is(err, store.ErrNoAlertmanagerConfiguration) {
|
||||
return ErrResp(http.StatusInternalServerError, err, "failed to get latest configuration")
|
||||
}
|
||||
}
|
||||
|
||||
if err := srv.loadSecureSettings(c.OrgId, body.AlertmanagerConfig.Receivers); err != nil {
|
||||
if err := srv.loadSecureSettings(c.Req.Context(), c.OrgId, body.AlertmanagerConfig.Receivers); err != nil {
|
||||
var unknownReceiverError UnknownReceiverError
|
||||
if errors.As(err, &unknownReceiverError) {
|
||||
return ErrResp(http.StatusBadRequest, err, "")
|
||||
@ -367,7 +367,7 @@ func (srv AlertmanagerSrv) RoutePostAlertingConfig(c *models.ReqContext, body ap
|
||||
}
|
||||
}
|
||||
|
||||
if err := am.SaveAndApplyConfig(&body); err != nil {
|
||||
if err := am.SaveAndApplyConfig(c.Req.Context(), &body); err != nil {
|
||||
srv.log.Error("unable to save and apply alertmanager configuration", "err", err)
|
||||
return ErrResp(http.StatusBadRequest, err, "failed to save and apply Alertmanager configuration")
|
||||
}
|
||||
@ -384,7 +384,7 @@ func (srv AlertmanagerSrv) RoutePostTestReceivers(c *models.ReqContext, body api
|
||||
return accessForbiddenResp()
|
||||
}
|
||||
|
||||
if err := srv.loadSecureSettings(c.OrgId, body.Receivers); err != nil {
|
||||
if err := srv.loadSecureSettings(c.Req.Context(), c.OrgId, body.Receivers); err != nil {
|
||||
var unknownReceiverError UnknownReceiverError
|
||||
if errors.As(err, &unknownReceiverError) {
|
||||
return ErrResp(http.StatusBadRequest, err, "")
|
||||
|
@ -17,6 +17,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/secrets/fakes"
|
||||
secretsManager "github.com/grafana/grafana/pkg/services/secrets/manager"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/web"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
@ -155,6 +156,9 @@ func TestAlertmanagerConfig(t *testing.T) {
|
||||
|
||||
t.Run("assert 404 Not Found when applying config to nonexistent org", func(t *testing.T) {
|
||||
rc := models.ReqContext{
|
||||
Context: &web.Context{
|
||||
Req: &http.Request{},
|
||||
},
|
||||
SignedInUser: &models.SignedInUser{
|
||||
OrgRole: models.ROLE_EDITOR,
|
||||
OrgId: 12,
|
||||
@ -170,6 +174,9 @@ func TestAlertmanagerConfig(t *testing.T) {
|
||||
|
||||
t.Run("assert 403 Forbidden when applying config while not Editor", func(t *testing.T) {
|
||||
rc := models.ReqContext{
|
||||
Context: &web.Context{
|
||||
Req: &http.Request{},
|
||||
},
|
||||
SignedInUser: &models.SignedInUser{
|
||||
OrgRole: models.ROLE_VIEWER,
|
||||
OrgId: 1,
|
||||
@ -185,6 +192,9 @@ func TestAlertmanagerConfig(t *testing.T) {
|
||||
|
||||
t.Run("assert 202 when config successfully applied", func(t *testing.T) {
|
||||
rc := models.ReqContext{
|
||||
Context: &web.Context{
|
||||
Req: &http.Request{},
|
||||
},
|
||||
SignedInUser: &models.SignedInUser{
|
||||
OrgRole: models.ROLE_EDITOR,
|
||||
OrgId: 1,
|
||||
@ -200,6 +210,9 @@ func TestAlertmanagerConfig(t *testing.T) {
|
||||
t.Run("assert 202 when alertmanager to configure is not ready", func(t *testing.T) {
|
||||
sut := createSut(t)
|
||||
rc := models.ReqContext{
|
||||
Context: &web.Context{
|
||||
Req: &http.Request{},
|
||||
},
|
||||
SignedInUser: &models.SignedInUser{
|
||||
OrgRole: models.ROLE_EDITOR,
|
||||
OrgId: 3, // Org 3 was initialized with broken config.
|
||||
|
@ -1,6 +1,7 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/models"
|
||||
@ -23,7 +24,7 @@ func (f FakeAlertingStore) Setup(orgID int64) {
|
||||
f.orgsWithConfig[orgID] = true
|
||||
}
|
||||
|
||||
func (f FakeAlertingStore) GetLatestAlertmanagerConfiguration(query *models.GetLatestAlertmanagerConfigurationQuery) error {
|
||||
func (f FakeAlertingStore) GetLatestAlertmanagerConfiguration(_ context.Context, query *models.GetLatestAlertmanagerConfigurationQuery) error {
|
||||
if _, ok := f.orgsWithConfig[query.OrgID]; ok {
|
||||
return nil
|
||||
}
|
||||
|
@ -232,7 +232,7 @@ func (am *Alertmanager) StopAndWait() {
|
||||
|
||||
// SaveAndApplyDefaultConfig saves the default configuration the database and applies the configuration to the Alertmanager.
|
||||
// It rollbacks the save if we fail to apply the configuration.
|
||||
func (am *Alertmanager) SaveAndApplyDefaultConfig() error {
|
||||
func (am *Alertmanager) SaveAndApplyDefaultConfig(ctx context.Context) error {
|
||||
am.reloadConfigMtx.Lock()
|
||||
defer am.reloadConfigMtx.Unlock()
|
||||
|
||||
@ -248,7 +248,7 @@ func (am *Alertmanager) SaveAndApplyDefaultConfig() error {
|
||||
return err
|
||||
}
|
||||
|
||||
err = am.Store.SaveAlertmanagerConfigurationWithCallback(cmd, func() error {
|
||||
err = am.Store.SaveAlertmanagerConfigurationWithCallback(ctx, cmd, func() error {
|
||||
if err := am.applyConfig(cfg, []byte(am.Settings.UnifiedAlerting.DefaultConfiguration)); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -263,7 +263,7 @@ func (am *Alertmanager) SaveAndApplyDefaultConfig() error {
|
||||
|
||||
// SaveAndApplyConfig saves the configuration the database and applies the configuration to the Alertmanager.
|
||||
// It rollbacks the save if we fail to apply the configuration.
|
||||
func (am *Alertmanager) SaveAndApplyConfig(cfg *apimodels.PostableUserConfig) error {
|
||||
func (am *Alertmanager) SaveAndApplyConfig(ctx context.Context, cfg *apimodels.PostableUserConfig) error {
|
||||
rawConfig, err := json.Marshal(&cfg)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to serialize to the Alertmanager configuration: %w", err)
|
||||
@ -278,7 +278,7 @@ func (am *Alertmanager) SaveAndApplyConfig(cfg *apimodels.PostableUserConfig) er
|
||||
OrgID: am.orgID,
|
||||
}
|
||||
|
||||
err = am.Store.SaveAlertmanagerConfigurationWithCallback(cmd, func() error {
|
||||
err = am.Store.SaveAlertmanagerConfigurationWithCallback(ctx, cmd, func() error {
|
||||
if err := am.applyConfig(cfg, rawConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -188,7 +188,7 @@ func (moa *MultiOrgAlertmanager) SyncAlertmanagersForOrgs(ctx context.Context, o
|
||||
// This means that the configuration is gone but the organization, as well as the Alertmanager, exists.
|
||||
moa.logger.Warn("Alertmanager exists for org but the configuration is gone. Applying the default configuration", "org", orgID)
|
||||
}
|
||||
err := alertmanager.SaveAndApplyDefaultConfig()
|
||||
err := alertmanager.SaveAndApplyDefaultConfig(ctx)
|
||||
if err != nil {
|
||||
moa.logger.Error("failed to apply the default Alertmanager configuration", "org", orgID)
|
||||
continue
|
||||
|
@ -31,7 +31,7 @@ func (f *FakeConfigStore) GetAllLatestAlertmanagerConfiguration(context.Context)
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (f *FakeConfigStore) GetLatestAlertmanagerConfiguration(query *models.GetLatestAlertmanagerConfigurationQuery) error {
|
||||
func (f *FakeConfigStore) GetLatestAlertmanagerConfiguration(_ context.Context, query *models.GetLatestAlertmanagerConfigurationQuery) error {
|
||||
var ok bool
|
||||
query.Result, ok = f.configs[query.OrgID]
|
||||
if !ok {
|
||||
@ -41,7 +41,7 @@ func (f *FakeConfigStore) GetLatestAlertmanagerConfiguration(query *models.GetLa
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FakeConfigStore) SaveAlertmanagerConfiguration(cmd *models.SaveAlertmanagerConfigurationCmd) error {
|
||||
func (f *FakeConfigStore) SaveAlertmanagerConfiguration(_ context.Context, cmd *models.SaveAlertmanagerConfigurationCmd) error {
|
||||
f.configs[cmd.OrgID] = &models.AlertConfiguration{
|
||||
AlertmanagerConfiguration: cmd.AlertmanagerConfiguration,
|
||||
OrgID: cmd.OrgID,
|
||||
@ -52,7 +52,7 @@ func (f *FakeConfigStore) SaveAlertmanagerConfiguration(cmd *models.SaveAlertman
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FakeConfigStore) SaveAlertmanagerConfigurationWithCallback(cmd *models.SaveAlertmanagerConfigurationCmd, callback store.SaveCallback) error {
|
||||
func (f *FakeConfigStore) SaveAlertmanagerConfigurationWithCallback(_ context.Context, cmd *models.SaveAlertmanagerConfigurationCmd, callback store.SaveCallback) error {
|
||||
f.configs[cmd.OrgID] = &models.AlertConfiguration{
|
||||
AlertmanagerConfiguration: cmd.AlertmanagerConfiguration,
|
||||
OrgID: cmd.OrgID,
|
||||
|
@ -17,8 +17,8 @@ var (
|
||||
|
||||
// GetLatestAlertmanagerConfiguration returns the lastest version of the alertmanager configuration.
|
||||
// It returns ErrNoAlertmanagerConfiguration if no configuration is found.
|
||||
func (st *DBstore) GetLatestAlertmanagerConfiguration(query *models.GetLatestAlertmanagerConfigurationQuery) error {
|
||||
return st.SQLStore.WithDbSession(context.Background(), func(sess *sqlstore.DBSession) error {
|
||||
func (st *DBstore) GetLatestAlertmanagerConfiguration(ctx context.Context, query *models.GetLatestAlertmanagerConfigurationQuery) error {
|
||||
return st.SQLStore.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
||||
c := &models.AlertConfiguration{}
|
||||
// The ID is already an auto incremental column, using the ID as an order should guarantee the latest.
|
||||
ok, err := sess.Desc("id").Where("org_id = ?", query.OrgID).Limit(1).Get(c)
|
||||
@ -52,16 +52,16 @@ func (st *DBstore) GetAllLatestAlertmanagerConfiguration(ctx context.Context) ([
|
||||
}
|
||||
|
||||
// SaveAlertmanagerConfiguration creates an alertmanager configuration.
|
||||
func (st DBstore) SaveAlertmanagerConfiguration(cmd *models.SaveAlertmanagerConfigurationCmd) error {
|
||||
return st.SaveAlertmanagerConfigurationWithCallback(cmd, func() error { return nil })
|
||||
func (st DBstore) SaveAlertmanagerConfiguration(ctx context.Context, cmd *models.SaveAlertmanagerConfigurationCmd) error {
|
||||
return st.SaveAlertmanagerConfigurationWithCallback(ctx, cmd, func() error { return nil })
|
||||
}
|
||||
|
||||
type SaveCallback func() error
|
||||
|
||||
// SaveAlertmanagerConfigurationWithCallback creates an alertmanager configuration version and then executes a callback.
|
||||
// If the callback results in error it rolls back the transaction.
|
||||
func (st DBstore) SaveAlertmanagerConfigurationWithCallback(cmd *models.SaveAlertmanagerConfigurationCmd, callback SaveCallback) error {
|
||||
return st.SQLStore.WithTransactionalDbSession(context.Background(), func(sess *sqlstore.DBSession) error {
|
||||
func (st DBstore) SaveAlertmanagerConfigurationWithCallback(ctx context.Context, cmd *models.SaveAlertmanagerConfigurationCmd, callback SaveCallback) error {
|
||||
return st.SQLStore.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
||||
config := models.AlertConfiguration{
|
||||
AlertmanagerConfiguration: cmd.AlertmanagerConfiguration,
|
||||
ConfigurationVersion: cmd.ConfigurationVersion,
|
||||
|
@ -17,10 +17,10 @@ const AlertDefinitionMaxTitleLength = 190
|
||||
|
||||
// AlertingStore is the database interface used by the Alertmanager service.
|
||||
type AlertingStore interface {
|
||||
GetLatestAlertmanagerConfiguration(*models.GetLatestAlertmanagerConfigurationQuery) error
|
||||
GetLatestAlertmanagerConfiguration(ctx context.Context, query *models.GetLatestAlertmanagerConfigurationQuery) error
|
||||
GetAllLatestAlertmanagerConfiguration(ctx context.Context) ([]*models.AlertConfiguration, error)
|
||||
SaveAlertmanagerConfiguration(*models.SaveAlertmanagerConfigurationCmd) error
|
||||
SaveAlertmanagerConfigurationWithCallback(*models.SaveAlertmanagerConfigurationCmd, SaveCallback) error
|
||||
SaveAlertmanagerConfiguration(ctx context.Context, cmd *models.SaveAlertmanagerConfigurationCmd) error
|
||||
SaveAlertmanagerConfigurationWithCallback(ctx context.Context, cmd *models.SaveAlertmanagerConfigurationCmd, callback SaveCallback) error
|
||||
}
|
||||
|
||||
// DBstore stores the alert definitions and instances in the database.
|
||||
|
Loading…
Reference in New Issue
Block a user