mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
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:
parent
f915767fdc
commit
8310789ef1
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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]"
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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
|
||||
|
@ -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(),
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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(),
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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{},
|
||||
}
|
||||
|
@ -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{}, ¬ifier.FakeConfigStore{}, ¬ifier.FakeOrgStore{}, ¬ifier.FakeKVStore{}, decryptFn, m.GetMultiOrgAlertmanagerMetrics(), nil, log.New("testlogger"), secretsService)
|
||||
moa, err := notifier.NewMultiOrgAlertmanager(&setting.Cfg{}, ¬ifier.FakeConfigStore{}, ¬ifier.FakeOrgStore{}, ¬ifier.FakeKVStore{}, provisioning.NewFakeProvisioningStore(), decryptFn, m.GetMultiOrgAlertmanagerMetrics(), nil, log.New("testlogger"), secretsService)
|
||||
require.NoError(t, err)
|
||||
|
||||
schedCfg := SchedulerCfg{
|
||||
|
Loading…
Reference in New Issue
Block a user