Indicate whether routes are provisioned when GETting Alertmanager configuration (#47857)

* Test composition simplification from last PR

* Policies use proper API model everywhere

* Expose policy provenance in API, miss some dep injection

* Complete injection

* fix args

* Tests for provenance value

* Extract test helpers so tests are very readable

* Single source adapter struct that was copied in 3 places

* Drop redundant test

* Resolve merge conflicts on changelog
This commit is contained in:
Alexander Weaver 2022-04-22 11:57:56 -05:00 committed by GitHub
parent f915767fdc
commit 8310789ef1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 163 additions and 84 deletions

View File

@ -50,3 +50,4 @@ Scopes must have an order to ensure consistency and ease of search, this helps u
- [BUGFIX] Scheduler: Fix state manager to support OK option of `AlertRule.ExecErrState` #47670
- [ENHANCEMENT] Templates: Enable the use of classic condition values in templates #46971
- [CHANGE] Notification URL points to alert view page instead of alert edit page. #47752
- [FEATURE] Indicate whether routes are provisioned when GETting Alertmanager configuration #47857

View File

@ -2,6 +2,7 @@ package api
import (
"context"
"encoding/json"
"math/rand"
"net/http"
"testing"
@ -12,14 +13,17 @@ import (
"github.com/prometheus/client_golang/prometheus"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
acMock "github.com/grafana/grafana/pkg/services/accesscontrol/mock"
"github.com/grafana/grafana/pkg/services/featuremgmt"
apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
"github.com/grafana/grafana/pkg/services/ngalert/metrics"
ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models"
"github.com/grafana/grafana/pkg/services/ngalert/notifier"
"github.com/grafana/grafana/pkg/services/ngalert/provisioning"
"github.com/grafana/grafana/pkg/services/secrets/fakes"
secretsManager "github.com/grafana/grafana/pkg/services/secrets/manager"
"github.com/grafana/grafana/pkg/setting"
@ -208,6 +212,31 @@ func TestAlertmanagerConfig(t *testing.T) {
require.Equal(t, 202, response.Status())
})
t.Run("when objects are not provisioned", func(t *testing.T) {
t.Run("route from GET config has no provenance", func(t *testing.T) {
sut := createSut(t, nil)
rc := createRequestCtxInOrg(1)
response := sut.RouteGetAlertingConfig(rc)
body := asGettableUserConfig(t, response)
require.Equal(t, ngmodels.ProvenanceNone, body.AlertmanagerConfig.Route.Provenance)
})
})
t.Run("when objects are provisioned", func(t *testing.T) {
t.Run("route from GET config has expected provenance", func(t *testing.T) {
sut := createSut(t, nil)
rc := createRequestCtxInOrg(1)
setRouteProvenance(t, 1, sut.mam.ProvStore)
response := sut.RouteGetAlertingConfig(rc)
body := asGettableUserConfig(t, response)
require.Equal(t, ngmodels.ProvenanceAPI, body.AlertmanagerConfig.Route.Provenance)
})
})
}
func TestRouteCreateSilence(t *testing.T) {
@ -346,19 +375,16 @@ func createSut(t *testing.T, accessControl accesscontrol.AccessControl) Alertman
t.Helper()
mam := createMultiOrgAlertmanager(t)
configs := map[int64]*ngmodels.AlertConfiguration{
1: {AlertmanagerConfiguration: validConfig, OrgID: 1},
2: {AlertmanagerConfiguration: validConfig, OrgID: 2},
3: {AlertmanagerConfiguration: brokenConfig, OrgID: 3},
}
configStore := notifier.NewFakeConfigStore(t, configs)
secrets := fakes.NewFakeSecretsService()
if accessControl == nil {
accessControl = acMock.New().WithDisabled()
}
log := log.NewNopLogger()
crypto := notifier.NewCrypto(secrets, &configStore, log)
return AlertmanagerSrv{mam: mam, crypto: crypto, ac: accessControl, log: log}
return AlertmanagerSrv{
mam: mam,
crypto: mam.Crypto,
ac: accessControl,
log: log,
}
}
func createAmConfigRequest(t *testing.T) apimodels.PostableUserConfig {
@ -381,6 +407,7 @@ func createMultiOrgAlertmanager(t *testing.T) *notifier.MultiOrgAlertmanager {
}
configStore := notifier.NewFakeConfigStore(t, configs)
orgStore := notifier.NewFakeOrgStore(t, []int64{1, 2, 3})
provStore := provisioning.NewFakeProvisioningStore()
tmpDir := t.TempDir()
kvStore := notifier.NewFakeKVStore(t)
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
@ -394,9 +421,12 @@ func createMultiOrgAlertmanager(t *testing.T) *notifier.MultiOrgAlertmanager {
DefaultConfiguration: setting.GetAlertmanagerDefaultConfiguration(),
DisabledOrgs: map[int64]struct{}{5: {}},
}, // do not poll in tests.
IsFeatureToggleEnabled: func(key string) bool {
return key == featuremgmt.FlagAlertProvisioning
},
}
mam, err := notifier.NewMultiOrgAlertmanager(cfg, &configStore, &orgStore, kvStore, decryptFn, m.GetMultiOrgAlertmanagerMetrics(), nil, log.New("testlogger"), secretsService)
mam, err := notifier.NewMultiOrgAlertmanager(cfg, &configStore, &orgStore, kvStore, provStore, decryptFn, m.GetMultiOrgAlertmanagerMetrics(), nil, log.New("testlogger"), secretsService)
require.NoError(t, err)
err = mam.LoadAndSyncAlertmanagersForOrgs(context.Background())
require.NoError(t, err)
@ -460,3 +490,30 @@ func silenceGen(mutatorFuncs ...func(*apimodels.PostableSilence)) func() apimode
func withEmptyID(silence *apimodels.PostableSilence) {
silence.ID = ""
}
func createRequestCtxInOrg(org int64) *models.ReqContext {
return &models.ReqContext{
Context: &web.Context{
Req: &http.Request{},
},
SignedInUser: &models.SignedInUser{
OrgId: org,
},
}
}
// setRouteProvenance marks an org's routing tree as provisioned.
func setRouteProvenance(t *testing.T, org int64, ps provisioning.ProvisioningStore) {
t.Helper()
adp := provisioning.ProvenanceOrgAdapter{Inner: &apimodels.Route{}, OrgID: org}
err := ps.SetProvenance(context.Background(), adp, ngmodels.ProvenanceAPI)
require.NoError(t, err)
}
func asGettableUserConfig(t *testing.T, r response.Response) *apimodels.GettableUserConfig {
t.Helper()
body := &apimodels.GettableUserConfig{}
err := json.Unmarshal(r.Body(), body)
require.NoError(t, err)
return body
}

View File

@ -10,7 +10,6 @@ import (
"github.com/grafana/grafana/pkg/models"
apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
alerting_models "github.com/grafana/grafana/pkg/services/ngalert/models"
"github.com/grafana/grafana/pkg/services/ngalert/provisioning"
"github.com/grafana/grafana/pkg/services/ngalert/store"
"github.com/grafana/grafana/pkg/util"
"github.com/grafana/grafana/pkg/web"
@ -30,7 +29,7 @@ type ContactPointService interface {
}
type NotificationPolicyService interface {
GetPolicyTree(ctx context.Context, orgID int64) (provisioning.EmbeddedRoutingTree, error)
GetPolicyTree(ctx context.Context, orgID int64) (apimodels.Route, error)
UpdatePolicyTree(ctx context.Context, orgID int64, tree apimodels.Route, p alerting_models.Provenance) error
}

View File

@ -10,7 +10,6 @@ import (
"github.com/grafana/grafana/pkg/models"
apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
domain "github.com/grafana/grafana/pkg/services/ngalert/models"
"github.com/grafana/grafana/pkg/services/ngalert/provisioning"
"github.com/grafana/grafana/pkg/services/ngalert/store"
"github.com/grafana/grafana/pkg/web"
"github.com/stretchr/testify/require"
@ -120,14 +119,13 @@ func newFakeNotificationPolicyService() *fakeNotificationPolicyService {
}
}
func (f *fakeNotificationPolicyService) GetPolicyTree(ctx context.Context, orgID int64) (provisioning.EmbeddedRoutingTree, error) {
func (f *fakeNotificationPolicyService) GetPolicyTree(ctx context.Context, orgID int64) (apimodels.Route, error) {
if orgID != 1 {
return provisioning.EmbeddedRoutingTree{}, store.ErrNoAlertmanagerConfiguration
return apimodels.Route{}, store.ErrNoAlertmanagerConfiguration
}
return provisioning.EmbeddedRoutingTree{
Route: f.tree,
Provenance: f.prov,
}, nil
result := f.tree
result.Provenance = f.prov
return result, nil
}
func (f *fakeNotificationPolicyService) UpdatePolicyTree(ctx context.Context, orgID int64, tree apimodels.Route, p domain.Provenance) error {
@ -141,8 +139,8 @@ func (f *fakeNotificationPolicyService) UpdatePolicyTree(ctx context.Context, or
type fakeFailingNotificationPolicyService struct{}
func (f *fakeFailingNotificationPolicyService) GetPolicyTree(ctx context.Context, orgID int64) (provisioning.EmbeddedRoutingTree, error) {
return provisioning.EmbeddedRoutingTree{}, fmt.Errorf("something went wrong")
func (f *fakeFailingNotificationPolicyService) GetPolicyTree(ctx context.Context, orgID int64) (apimodels.Route, error) {
return apimodels.Route{}, fmt.Errorf("something went wrong")
}
func (f *fakeFailingNotificationPolicyService) UpdatePolicyTree(ctx context.Context, orgID int64, tree apimodels.Route, p domain.Provenance) error {

View File

@ -66,7 +66,7 @@ type EmbeddedContactPoint struct {
Type string `json:"type" binding:"required"`
Settings *simplejson.Json `json:"settings" binding:"required"`
DisableResolveMessage bool `json:"disableResolveMessage"`
Provenance string `json:"provanance"`
Provenance string `json:"provenance"`
}
const RedactedValue = "[REDACTED]"

View File

@ -99,7 +99,7 @@ func (ng *AlertNG) init() error {
decryptFn := ng.SecretsService.GetDecryptedValue
multiOrgMetrics := ng.Metrics.GetMultiOrgAlertmanagerMetrics()
ng.MultiOrgAlertmanager, err = notifier.NewMultiOrgAlertmanager(ng.Cfg, store, store, ng.KVStore, decryptFn, multiOrgMetrics, ng.NotificationService, log.New("ngalert.multiorg.alertmanager"), ng.SecretsService)
ng.MultiOrgAlertmanager, err = notifier.NewMultiOrgAlertmanager(ng.Cfg, store, store, ng.KVStore, store, decryptFn, multiOrgMetrics, ng.NotificationService, log.New("ngalert.multiorg.alertmanager"), ng.SecretsService)
if err != nil {
return err
}

View File

@ -5,8 +5,10 @@ import (
"errors"
"fmt"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"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/provisioning"
"github.com/grafana/grafana/pkg/services/ngalert/store"
)
@ -81,6 +83,13 @@ func (moa *MultiOrgAlertmanager) GetAlertmanagerConfiguration(ctx context.Contex
result.AlertmanagerConfig.Receivers = append(result.AlertmanagerConfig.Receivers, &gettableApiReceiver)
}
if moa.settings.IsFeatureToggleEnabled(featuremgmt.FlagAlertProvisioning) {
result.AlertmanagerConfig, err = moa.mergeProvenance(ctx, result.AlertmanagerConfig, org)
if err != nil {
return definitions.GettableUserConfig{}, err
}
}
return result, nil
}
@ -117,3 +126,18 @@ func (moa *MultiOrgAlertmanager) ApplyAlertmanagerConfiguration(ctx context.Cont
return nil
}
func (moa *MultiOrgAlertmanager) mergeProvenance(ctx context.Context, config definitions.GettableApiAlertingConfig, org int64) (definitions.GettableApiAlertingConfig, error) {
if config.Route != nil {
adp := provisioning.ProvenanceOrgAdapter{
Inner: config.Route,
OrgID: org,
}
provenance, err := moa.ProvStore.GetProvenance(ctx, adp)
if err != nil {
return definitions.GettableApiAlertingConfig{}, err
}
config.Route.Provenance = provenance
}
return config, nil
}

View File

@ -10,6 +10,7 @@ import (
"time"
"github.com/grafana/grafana/pkg/services/ngalert/notifier/channels"
"github.com/grafana/grafana/pkg/services/ngalert/provisioning"
"github.com/grafana/grafana/pkg/services/notifications"
"github.com/grafana/grafana/pkg/services/secrets"
@ -30,7 +31,8 @@ var (
)
type MultiOrgAlertmanager struct {
Crypto Crypto
Crypto Crypto
ProvStore provisioning.ProvisioningStore
alertmanagersMtx sync.RWMutex
alertmanagers map[int64]*Alertmanager
@ -53,11 +55,12 @@ type MultiOrgAlertmanager struct {
}
func NewMultiOrgAlertmanager(cfg *setting.Cfg, configStore store.AlertingStore, orgStore store.OrgStore,
kvStore kvstore.KVStore, decryptFn channels.GetDecryptedValueFn, m *metrics.MultiOrgAlertmanager,
ns notifications.Service, l log.Logger, s secrets.Service,
kvStore kvstore.KVStore, provStore provisioning.ProvisioningStore, decryptFn channels.GetDecryptedValueFn,
m *metrics.MultiOrgAlertmanager, ns notifications.Service, l log.Logger, s secrets.Service,
) (*MultiOrgAlertmanager, error) {
moa := &MultiOrgAlertmanager{
Crypto: NewCrypto(s, configStore, l),
Crypto: NewCrypto(s, configStore, l),
ProvStore: provStore,
logger: l,
settings: cfg,

View File

@ -13,6 +13,7 @@ import (
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/services/ngalert/metrics"
"github.com/grafana/grafana/pkg/services/ngalert/models"
"github.com/grafana/grafana/pkg/services/ngalert/provisioning"
"github.com/grafana/grafana/pkg/services/secrets/fakes"
secretsManager "github.com/grafana/grafana/pkg/services/secrets/manager"
"github.com/grafana/grafana/pkg/setting"
@ -32,6 +33,7 @@ func TestMultiOrgAlertmanager_SyncAlertmanagersForOrgs(t *testing.T) {
tmpDir := t.TempDir()
kvStore := NewFakeKVStore(t)
provStore := provisioning.NewFakeProvisioningStore()
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
decryptFn := secretsService.GetDecryptedValue
reg := prometheus.NewPedanticRegistry()
@ -44,7 +46,7 @@ func TestMultiOrgAlertmanager_SyncAlertmanagersForOrgs(t *testing.T) {
DisabledOrgs: map[int64]struct{}{5: {}},
}, // do not poll in tests.
}
mam, err := NewMultiOrgAlertmanager(cfg, configStore, orgStore, kvStore, decryptFn, m.GetMultiOrgAlertmanagerMetrics(), nil, log.New("testlogger"), secretsService)
mam, err := NewMultiOrgAlertmanager(cfg, configStore, orgStore, kvStore, provStore, decryptFn, m.GetMultiOrgAlertmanagerMetrics(), nil, log.New("testlogger"), secretsService)
require.NoError(t, err)
ctx := context.Background()
@ -157,6 +159,7 @@ func TestMultiOrgAlertmanager_SyncAlertmanagersForOrgsWithFailures(t *testing.T)
tmpDir := t.TempDir()
kvStore := NewFakeKVStore(t)
provStore := provisioning.NewFakeProvisioningStore()
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
decryptFn := secretsService.GetDecryptedValue
reg := prometheus.NewPedanticRegistry()
@ -168,7 +171,7 @@ func TestMultiOrgAlertmanager_SyncAlertmanagersForOrgsWithFailures(t *testing.T)
DefaultConfiguration: setting.GetAlertmanagerDefaultConfiguration(),
}, // do not poll in tests.
}
mam, err := NewMultiOrgAlertmanager(cfg, configStore, orgStore, kvStore, decryptFn, m.GetMultiOrgAlertmanagerMetrics(), nil, log.New("testlogger"), secretsService)
mam, err := NewMultiOrgAlertmanager(cfg, configStore, orgStore, kvStore, provStore, decryptFn, m.GetMultiOrgAlertmanagerMetrics(), nil, log.New("testlogger"), secretsService)
require.NoError(t, err)
ctx := context.Background()
@ -214,11 +217,12 @@ func TestMultiOrgAlertmanager_AlertmanagerFor(t *testing.T) {
UnifiedAlerting: setting.UnifiedAlertingSettings{AlertmanagerConfigPollInterval: 3 * time.Minute, DefaultConfiguration: setting.GetAlertmanagerDefaultConfiguration()}, // do not poll in tests.
}
kvStore := NewFakeKVStore(t)
provStore := provisioning.NewFakeProvisioningStore()
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
decryptFn := secretsService.GetDecryptedValue
reg := prometheus.NewPedanticRegistry()
m := metrics.NewNGAlert(reg)
mam, err := NewMultiOrgAlertmanager(cfg, configStore, orgStore, kvStore, decryptFn, m.GetMultiOrgAlertmanagerMetrics(), nil, log.New("testlogger"), secretsService)
mam, err := NewMultiOrgAlertmanager(cfg, configStore, orgStore, kvStore, provStore, decryptFn, m.GetMultiOrgAlertmanagerMetrics(), nil, log.New("testlogger"), secretsService)
require.NoError(t, err)
ctx := context.Background()

View File

@ -177,9 +177,9 @@ func (ecp *ContactPointService) CreateContactPoint(ctx context.Context, orgID in
if err != nil {
return err
}
adapter := provenanceOrgAdapter{
inner: &contactPoint,
orgID: orgID,
adapter := ProvenanceOrgAdapter{
Inner: &contactPoint,
OrgID: orgID,
}
err = ecp.provenanceStore.SetProvenance(ctx, adapter, provenance)
if err != nil {
@ -218,9 +218,9 @@ func (ecp *ContactPointService) UpdateContactPoint(ctx context.Context, orgID in
return err
}
// check that provenance is not changed in a invalid way
storedProvenance, err := ecp.provenanceStore.GetProvenance(ctx, provenanceOrgAdapter{
inner: &contactPoint,
orgID: orgID,
storedProvenance, err := ecp.provenanceStore.GetProvenance(ctx, ProvenanceOrgAdapter{
Inner: &contactPoint,
OrgID: orgID,
})
if err != nil {
return err
@ -283,9 +283,9 @@ func (ecp *ContactPointService) UpdateContactPoint(ctx context.Context, orgID in
if err != nil {
return err
}
adapter := provenanceOrgAdapter{
inner: &contactPoint,
orgID: orgID,
adapter := ProvenanceOrgAdapter{
Inner: &contactPoint,
OrgID: orgID,
}
err = ecp.provenanceStore.SetProvenance(ctx, adapter, provenance)
if err != nil {
@ -330,11 +330,11 @@ func (ecp *ContactPointService) DeleteContactPoint(ctx context.Context, orgID in
return err
}
return ecp.xact.InTransaction(ctx, func(ctx context.Context) error {
err := ecp.provenanceStore.DeleteProvenance(ctx, provenanceOrgAdapter{
inner: &apimodels.EmbeddedContactPoint{
err := ecp.provenanceStore.DeleteProvenance(ctx, ProvenanceOrgAdapter{
Inner: &apimodels.EmbeddedContactPoint{
UID: uid,
},
orgID: orgID,
OrgID: orgID,
})
if err != nil {
return err

View File

@ -178,7 +178,7 @@ func TestContactPointInUse(t *testing.T) {
func createContactPointServiceSut(secretService secrets.Service) *ContactPointService {
return &ContactPointService{
amStore: newFakeAMConfigStore(),
provenanceStore: newFakeProvisioningStore(),
provenanceStore: NewFakeProvisioningStore(),
xact: newNopTransactionManager(),
encryptionService: secretService,
log: log.NewNopLogger(),

View File

@ -25,47 +25,39 @@ func NewNotificationPolicyService(am AMConfigStore, prov ProvisioningStore, xact
}
}
// TODO: move to Swagger codegen
type EmbeddedRoutingTree struct {
definitions.Route
Provenance models.Provenance
}
func (nps *NotificationPolicyService) GetAMConfigStore() AMConfigStore {
return nps.amStore
}
func (nps *NotificationPolicyService) GetPolicyTree(ctx context.Context, orgID int64) (EmbeddedRoutingTree, error) {
func (nps *NotificationPolicyService) GetPolicyTree(ctx context.Context, orgID int64) (definitions.Route, error) {
q := models.GetLatestAlertmanagerConfigurationQuery{
OrgID: orgID,
}
err := nps.amStore.GetLatestAlertmanagerConfiguration(ctx, &q)
if err != nil {
return EmbeddedRoutingTree{}, err
return definitions.Route{}, err
}
cfg, err := DeserializeAlertmanagerConfig([]byte(q.Result.AlertmanagerConfiguration))
if err != nil {
return EmbeddedRoutingTree{}, err
return definitions.Route{}, err
}
if cfg.AlertmanagerConfig.Config.Route == nil {
return EmbeddedRoutingTree{}, fmt.Errorf("no route present in current alertmanager config")
return definitions.Route{}, fmt.Errorf("no route present in current alertmanager config")
}
adapter := provenanceOrgAdapter{
inner: cfg.AlertmanagerConfig.Route,
orgID: orgID,
adapter := ProvenanceOrgAdapter{
Inner: cfg.AlertmanagerConfig.Route,
OrgID: orgID,
}
provenance, err := nps.provenanceStore.GetProvenance(ctx, adapter)
if err != nil {
return EmbeddedRoutingTree{}, err
return definitions.Route{}, err
}
result := EmbeddedRoutingTree{
Route: *cfg.AlertmanagerConfig.Route,
Provenance: provenance,
}
result := *cfg.AlertmanagerConfig.Route
result.Provenance = provenance
return result, nil
}
@ -103,9 +95,9 @@ func (nps *NotificationPolicyService) UpdatePolicyTree(ctx context.Context, orgI
if err != nil {
return err
}
adapter := provenanceOrgAdapter{
inner: &tree,
orgID: orgID,
adapter := ProvenanceOrgAdapter{
Inner: &tree,
OrgID: orgID,
}
err = nps.provenanceStore.SetProvenance(ctx, adapter, p)
if err != nil {
@ -119,20 +111,3 @@ func (nps *NotificationPolicyService) UpdatePolicyTree(ctx context.Context, orgI
return nil
}
type provenanceOrgAdapter struct {
inner models.ProvisionableInOrg
orgID int64
}
func (a provenanceOrgAdapter) ResourceType() string {
return a.inner.ResourceType()
}
func (a provenanceOrgAdapter) ResourceID() string {
return a.inner.ResourceID()
}
func (a provenanceOrgAdapter) ResourceOrgID() int64 {
return a.orgID
}

View File

@ -75,7 +75,7 @@ func TestNotificationPolicyService(t *testing.T) {
func createNotificationPolicyServiceSut() *NotificationPolicyService {
return &NotificationPolicyService{
amStore: newFakeAMConfigStore(),
provenanceStore: newFakeProvisioningStore(),
provenanceStore: NewFakeProvisioningStore(),
xact: newNopTransactionManager(),
log: log.NewNopLogger(),
}

View File

@ -24,3 +24,20 @@ type ProvisioningStore interface {
type TransactionManager interface {
InTransaction(ctx context.Context, work func(ctx context.Context) error) error
}
type ProvenanceOrgAdapter struct {
Inner models.ProvisionableInOrg
OrgID int64
}
func (a ProvenanceOrgAdapter) ResourceType() string {
return a.Inner.ResourceType()
}
func (a ProvenanceOrgAdapter) ResourceID() string {
return a.Inner.ResourceID()
}
func (a ProvenanceOrgAdapter) ResourceOrgID() int64 {
return a.OrgID
}

View File

@ -92,7 +92,7 @@ type fakeProvisioningStore struct {
records map[int64]map[string]models.Provenance
}
func newFakeProvisioningStore() *fakeProvisioningStore {
func NewFakeProvisioningStore() *fakeProvisioningStore {
return &fakeProvisioningStore{
records: map[int64]map[string]models.Provenance{},
}

View File

@ -26,6 +26,7 @@ import (
"github.com/grafana/grafana/pkg/services/ngalert/metrics"
"github.com/grafana/grafana/pkg/services/ngalert/models"
"github.com/grafana/grafana/pkg/services/ngalert/notifier"
"github.com/grafana/grafana/pkg/services/ngalert/provisioning"
"github.com/grafana/grafana/pkg/services/ngalert/sender"
"github.com/grafana/grafana/pkg/services/ngalert/state"
"github.com/grafana/grafana/pkg/services/ngalert/store"
@ -1015,7 +1016,7 @@ func setupScheduler(t *testing.T, rs store.RuleStore, is store.InstanceStore, ac
m := metrics.NewNGAlert(registry)
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
decryptFn := secretsService.GetDecryptedValue
moa, err := notifier.NewMultiOrgAlertmanager(&setting.Cfg{}, &notifier.FakeConfigStore{}, &notifier.FakeOrgStore{}, &notifier.FakeKVStore{}, decryptFn, m.GetMultiOrgAlertmanagerMetrics(), nil, log.New("testlogger"), secretsService)
moa, err := notifier.NewMultiOrgAlertmanager(&setting.Cfg{}, &notifier.FakeConfigStore{}, &notifier.FakeOrgStore{}, &notifier.FakeKVStore{}, provisioning.NewFakeProvisioningStore(), decryptFn, m.GetMultiOrgAlertmanagerMetrics(), nil, log.New("testlogger"), secretsService)
require.NoError(t, err)
schedCfg := SchedulerCfg{