Alerting: Refactor provisioning tests/fakes (#81205)
* Fix up test Alertmanager config JSON * Move fake AM config and provisioning stores to fakes package
This commit is contained in:
@@ -663,7 +663,7 @@ func createMultiOrgAlertmanager(t *testing.T) *notifier.MultiOrgAlertmanager {
|
|||||||
}
|
}
|
||||||
configStore := notifier.NewFakeConfigStore(t, configs)
|
configStore := notifier.NewFakeConfigStore(t, configs)
|
||||||
orgStore := notifier.NewFakeOrgStore(t, []int64{1, 2, 3})
|
orgStore := notifier.NewFakeOrgStore(t, []int64{1, 2, 3})
|
||||||
provStore := provisioning.NewFakeProvisioningStore()
|
provStore := ngfakes.NewFakeProvisioningStore()
|
||||||
tmpDir := t.TempDir()
|
tmpDir := t.TempDir()
|
||||||
kvStore := ngfakes.NewFakeKVStore(t)
|
kvStore := ngfakes.NewFakeKVStore(t)
|
||||||
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
|
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ func TestRouteDeleteAlertRules(t *testing.T) {
|
|||||||
})
|
})
|
||||||
t.Run("delete only non-provisioned groups that user is authorized", func(t *testing.T) {
|
t.Run("delete only non-provisioned groups that user is authorized", func(t *testing.T) {
|
||||||
ruleStore := initFakeRuleStore(t)
|
ruleStore := initFakeRuleStore(t)
|
||||||
provisioningStore := provisioning.NewFakeProvisioningStore()
|
provisioningStore := fakes.NewFakeProvisioningStore()
|
||||||
|
|
||||||
authorizedRulesInFolder := models.GenerateAlertRulesSmallNonEmpty(models.AlertRuleGen(withOrgID(orgID), withNamespace(folder), withGroup("authz_"+util.GenerateShortUID())))
|
authorizedRulesInFolder := models.GenerateAlertRulesSmallNonEmpty(models.AlertRuleGen(withOrgID(orgID), withNamespace(folder), withGroup("authz_"+util.GenerateShortUID())))
|
||||||
|
|
||||||
@@ -109,7 +109,7 @@ func TestRouteDeleteAlertRules(t *testing.T) {
|
|||||||
})
|
})
|
||||||
t.Run("return 400 if all rules user can access are provisioned", func(t *testing.T) {
|
t.Run("return 400 if all rules user can access are provisioned", func(t *testing.T) {
|
||||||
ruleStore := initFakeRuleStore(t)
|
ruleStore := initFakeRuleStore(t)
|
||||||
provisioningStore := provisioning.NewFakeProvisioningStore()
|
provisioningStore := fakes.NewFakeProvisioningStore()
|
||||||
|
|
||||||
provisionedRulesInFolder := models.GenerateAlertRulesSmallNonEmpty(models.AlertRuleGen(withOrgID(orgID), withNamespace(folder), withGroup(util.GenerateShortUID())))
|
provisionedRulesInFolder := models.GenerateAlertRulesSmallNonEmpty(models.AlertRuleGen(withOrgID(orgID), withNamespace(folder), withGroup(util.GenerateShortUID())))
|
||||||
err := provisioningStore.SetProvenance(context.Background(), provisionedRulesInFolder[0], orgID, models.ProvenanceAPI)
|
err := provisioningStore.SetProvenance(context.Background(), provisionedRulesInFolder[0], orgID, models.ProvenanceAPI)
|
||||||
@@ -158,7 +158,7 @@ func TestRouteDeleteAlertRules(t *testing.T) {
|
|||||||
})
|
})
|
||||||
t.Run("return 400 if group is provisioned", func(t *testing.T) {
|
t.Run("return 400 if group is provisioned", func(t *testing.T) {
|
||||||
ruleStore := initFakeRuleStore(t)
|
ruleStore := initFakeRuleStore(t)
|
||||||
provisioningStore := provisioning.NewFakeProvisioningStore()
|
provisioningStore := fakes.NewFakeProvisioningStore()
|
||||||
|
|
||||||
provisionedRulesInFolder := models.GenerateAlertRulesSmallNonEmpty(models.AlertRuleGen(withOrgID(orgID), withNamespace(folder), withGroup(groupName)))
|
provisionedRulesInFolder := models.GenerateAlertRulesSmallNonEmpty(models.AlertRuleGen(withOrgID(orgID), withNamespace(folder), withGroup(groupName)))
|
||||||
err := provisioningStore.SetProvenance(context.Background(), provisionedRulesInFolder[0], orgID, models.ProvenanceAPI)
|
err := provisioningStore.SetProvenance(context.Background(), provisionedRulesInFolder[0], orgID, models.ProvenanceAPI)
|
||||||
@@ -598,7 +598,7 @@ func createService(store *fakes.RuleStore) *RulerSrv {
|
|||||||
xactManager: store,
|
xactManager: store,
|
||||||
store: store,
|
store: store,
|
||||||
QuotaService: nil,
|
QuotaService: nil,
|
||||||
provenanceStore: provisioning.NewFakeProvisioningStore(),
|
provenanceStore: fakes.NewFakeProvisioningStore(),
|
||||||
log: log.New("test"),
|
log: log.New("test"),
|
||||||
cfg: &setting.UnifiedAlertingSettings{
|
cfg: &setting.UnifiedAlertingSettings{
|
||||||
BaseInterval: 10 * time.Second,
|
BaseInterval: 10 * time.Second,
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/services/ngalert/metrics"
|
"github.com/grafana/grafana/pkg/services/ngalert/metrics"
|
||||||
"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"
|
||||||
"github.com/grafana/grafana/pkg/services/ngalert/provisioning"
|
|
||||||
"github.com/grafana/grafana/pkg/services/ngalert/remote"
|
"github.com/grafana/grafana/pkg/services/ngalert/remote"
|
||||||
remoteClient "github.com/grafana/grafana/pkg/services/ngalert/remote/client"
|
remoteClient "github.com/grafana/grafana/pkg/services/ngalert/remote/client"
|
||||||
ngfakes "github.com/grafana/grafana/pkg/services/ngalert/tests/fakes"
|
ngfakes "github.com/grafana/grafana/pkg/services/ngalert/tests/fakes"
|
||||||
@@ -93,7 +92,7 @@ func TestMultiorgAlertmanager_RemoteSecondaryMode(t *testing.T) {
|
|||||||
configStore,
|
configStore,
|
||||||
notifier.NewFakeOrgStore(t, []int64{1}),
|
notifier.NewFakeOrgStore(t, []int64{1}),
|
||||||
kvStore,
|
kvStore,
|
||||||
provisioning.NewFakeProvisioningStore(),
|
ngfakes.NewFakeProvisioningStore(),
|
||||||
secretsService.GetDecryptedValue,
|
secretsService.GetDecryptedValue,
|
||||||
m.GetMultiOrgAlertmanagerMetrics(),
|
m.GetMultiOrgAlertmanagerMetrics(),
|
||||||
nil,
|
nil,
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
"github.com/grafana/grafana/pkg/services/ngalert/metrics"
|
"github.com/grafana/grafana/pkg/services/ngalert/metrics"
|
||||||
"github.com/grafana/grafana/pkg/services/ngalert/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/services/ngalert/store"
|
||||||
ngfakes "github.com/grafana/grafana/pkg/services/ngalert/tests/fakes"
|
ngfakes "github.com/grafana/grafana/pkg/services/ngalert/tests/fakes"
|
||||||
"github.com/grafana/grafana/pkg/services/secrets/fakes"
|
"github.com/grafana/grafana/pkg/services/secrets/fakes"
|
||||||
@@ -33,7 +32,7 @@ func TestMultiOrgAlertmanager_SyncAlertmanagersForOrgs(t *testing.T) {
|
|||||||
|
|
||||||
tmpDir := t.TempDir()
|
tmpDir := t.TempDir()
|
||||||
kvStore := ngfakes.NewFakeKVStore(t)
|
kvStore := ngfakes.NewFakeKVStore(t)
|
||||||
provStore := provisioning.NewFakeProvisioningStore()
|
provStore := ngfakes.NewFakeProvisioningStore()
|
||||||
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
|
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
|
||||||
decryptFn := secretsService.GetDecryptedValue
|
decryptFn := secretsService.GetDecryptedValue
|
||||||
reg := prometheus.NewPedanticRegistry()
|
reg := prometheus.NewPedanticRegistry()
|
||||||
@@ -167,7 +166,7 @@ func TestMultiOrgAlertmanager_SyncAlertmanagersForOrgsWithFailures(t *testing.T)
|
|||||||
|
|
||||||
tmpDir := t.TempDir()
|
tmpDir := t.TempDir()
|
||||||
kvStore := ngfakes.NewFakeKVStore(t)
|
kvStore := ngfakes.NewFakeKVStore(t)
|
||||||
provStore := provisioning.NewFakeProvisioningStore()
|
provStore := ngfakes.NewFakeProvisioningStore()
|
||||||
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
|
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
|
||||||
decryptFn := secretsService.GetDecryptedValue
|
decryptFn := secretsService.GetDecryptedValue
|
||||||
reg := prometheus.NewPedanticRegistry()
|
reg := prometheus.NewPedanticRegistry()
|
||||||
@@ -261,7 +260,7 @@ func TestMultiOrgAlertmanager_AlertmanagerFor(t *testing.T) {
|
|||||||
UnifiedAlerting: setting.UnifiedAlertingSettings{AlertmanagerConfigPollInterval: 3 * time.Minute, DefaultConfiguration: setting.GetAlertmanagerDefaultConfiguration()}, // do not poll in tests.
|
UnifiedAlerting: setting.UnifiedAlertingSettings{AlertmanagerConfigPollInterval: 3 * time.Minute, DefaultConfiguration: setting.GetAlertmanagerDefaultConfiguration()}, // do not poll in tests.
|
||||||
}
|
}
|
||||||
kvStore := ngfakes.NewFakeKVStore(t)
|
kvStore := ngfakes.NewFakeKVStore(t)
|
||||||
provStore := provisioning.NewFakeProvisioningStore()
|
provStore := ngfakes.NewFakeProvisioningStore()
|
||||||
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
|
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
|
||||||
decryptFn := secretsService.GetDecryptedValue
|
decryptFn := secretsService.GetDecryptedValue
|
||||||
reg := prometheus.NewPedanticRegistry()
|
reg := prometheus.NewPedanticRegistry()
|
||||||
@@ -313,7 +312,7 @@ func TestMultiOrgAlertmanager_ActivateHistoricalConfiguration(t *testing.T) {
|
|||||||
UnifiedAlerting: setting.UnifiedAlertingSettings{AlertmanagerConfigPollInterval: 3 * time.Minute, DefaultConfiguration: defaultConfig}, // do not poll in tests.
|
UnifiedAlerting: setting.UnifiedAlertingSettings{AlertmanagerConfigPollInterval: 3 * time.Minute, DefaultConfiguration: defaultConfig}, // do not poll in tests.
|
||||||
}
|
}
|
||||||
kvStore := ngfakes.NewFakeKVStore(t)
|
kvStore := ngfakes.NewFakeKVStore(t)
|
||||||
provStore := provisioning.NewFakeProvisioningStore()
|
provStore := ngfakes.NewFakeProvisioningStore()
|
||||||
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
|
secretsService := secretsManager.SetupTestService(t, fakes.NewFakeSecretsStore())
|
||||||
decryptFn := secretsService.GetDecryptedValue
|
decryptFn := secretsService.GetDecryptedValue
|
||||||
reg := prometheus.NewPedanticRegistry()
|
reg := prometheus.NewPedanticRegistry()
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
|
"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"
|
||||||
|
"github.com/grafana/grafana/pkg/services/ngalert/tests/fakes"
|
||||||
"github.com/grafana/grafana/pkg/services/secrets"
|
"github.com/grafana/grafana/pkg/services/secrets"
|
||||||
"github.com/grafana/grafana/pkg/services/secrets/database"
|
"github.com/grafana/grafana/pkg/services/secrets/database"
|
||||||
"github.com/grafana/grafana/pkg/services/secrets/manager"
|
"github.com/grafana/grafana/pkg/services/secrets/manager"
|
||||||
@@ -36,21 +37,15 @@ func TestContactPointService(t *testing.T) {
|
|||||||
cps, err := sut.GetContactPoints(context.Background(), cpsQuery(1), nil)
|
cps, err := sut.GetContactPoints(context.Background(), cpsQuery(1), nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
require.Len(t, cps, 1)
|
require.Len(t, cps, 2)
|
||||||
require.Equal(t, "slack receiver", cps[0].Name)
|
require.Equal(t, "grafana-default-email", cps[0].Name)
|
||||||
|
require.Equal(t, "slack receiver", cps[1].Name)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("service filters contact points by name", func(t *testing.T) {
|
t.Run("service filters contact points by name", func(t *testing.T) {
|
||||||
sut := createContactPointServiceSut(t, secretsService)
|
sut := createContactPointServiceSut(t, secretsService)
|
||||||
newCp := createTestContactPoint()
|
|
||||||
_, err := sut.CreateContactPoint(context.Background(), 1, newCp, models.ProvenanceAPI)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
q := ContactPointQuery{
|
cps, err := sut.GetContactPoints(context.Background(), cpsQueryWithName(1, "slack receiver"), nil)
|
||||||
OrgID: 1,
|
|
||||||
Name: "slack receiver",
|
|
||||||
}
|
|
||||||
cps, err := sut.GetContactPoints(context.Background(), q, nil)
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
require.Len(t, cps, 1)
|
require.Len(t, cps, 1)
|
||||||
@@ -66,9 +61,9 @@ func TestContactPointService(t *testing.T) {
|
|||||||
|
|
||||||
cps, err := sut.GetContactPoints(context.Background(), cpsQuery(1), nil)
|
cps, err := sut.GetContactPoints(context.Background(), cpsQuery(1), nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Len(t, cps, 2)
|
require.Len(t, cps, 3)
|
||||||
require.Equal(t, "test-contact-point", cps[1].Name)
|
require.Equal(t, "test-contact-point", cps[2].Name)
|
||||||
require.Equal(t, "slack", cps[1].Type)
|
require.Equal(t, "slack", cps[2].Type)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("it's possible to use a custom uid", func(t *testing.T) {
|
t.Run("it's possible to use a custom uid", func(t *testing.T) {
|
||||||
@@ -80,10 +75,10 @@ func TestContactPointService(t *testing.T) {
|
|||||||
_, err := sut.CreateContactPoint(context.Background(), 1, newCp, models.ProvenanceAPI)
|
_, err := sut.CreateContactPoint(context.Background(), 1, newCp, models.ProvenanceAPI)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
cps, err := sut.GetContactPoints(context.Background(), cpsQuery(1), nil)
|
cps, err := sut.GetContactPoints(context.Background(), cpsQueryWithName(1, newCp.Name), nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Len(t, cps, 2)
|
require.Len(t, cps, 1)
|
||||||
require.Equal(t, customUID, cps[1].UID)
|
require.Equal(t, customUID, cps[0].UID)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("it's not possible to use invalid UID", func(t *testing.T) {
|
t.Run("it's not possible to use invalid UID", func(t *testing.T) {
|
||||||
@@ -216,19 +211,19 @@ func TestContactPointService(t *testing.T) {
|
|||||||
newCp, err := sut.CreateContactPoint(context.Background(), 1, newCp, test.from)
|
newCp, err := sut.CreateContactPoint(context.Background(), 1, newCp, test.from)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
cps, err := sut.GetContactPoints(context.Background(), cpsQuery(1), nil)
|
cps, err := sut.GetContactPoints(context.Background(), cpsQueryWithName(1, newCp.Name), nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, newCp.UID, cps[1].UID)
|
require.Equal(t, newCp.UID, cps[0].UID)
|
||||||
require.Equal(t, test.from, models.Provenance(cps[1].Provenance))
|
require.Equal(t, test.from, models.Provenance(cps[0].Provenance))
|
||||||
|
|
||||||
err = sut.UpdateContactPoint(context.Background(), 1, newCp, test.to)
|
err = sut.UpdateContactPoint(context.Background(), 1, newCp, test.to)
|
||||||
if test.errNil {
|
if test.errNil {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
cps, err = sut.GetContactPoints(context.Background(), cpsQuery(1), nil)
|
cps, err = sut.GetContactPoints(context.Background(), cpsQueryWithName(1, newCp.Name), nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, newCp.UID, cps[1].UID)
|
require.Equal(t, newCp.UID, cps[0].UID)
|
||||||
require.Equal(t, test.to, models.Provenance(cps[1].Provenance))
|
require.Equal(t, test.to, models.Provenance(cps[0].Provenance))
|
||||||
} else {
|
} else {
|
||||||
require.Error(t, err, fmt.Sprintf("cannot change provenance from '%s' to '%s'", test.from, test.to))
|
require.Error(t, err, fmt.Sprintf("cannot change provenance from '%s' to '%s'", test.from, test.to))
|
||||||
}
|
}
|
||||||
@@ -246,8 +241,8 @@ func TestContactPointService(t *testing.T) {
|
|||||||
_, err = sut.CreateContactPoint(context.Background(), 1, newCp, models.ProvenanceAPI)
|
_, err = sut.CreateContactPoint(context.Background(), 1, newCp, models.ProvenanceAPI)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
fake := sut.configStore.store.(*fakeAMConfigStore)
|
fake := sut.configStore.store.(*fakes.FakeAlertmanagerConfigStore)
|
||||||
intercepted := fake.lastSaveCommand
|
intercepted := fake.LastSaveCommand
|
||||||
require.Equal(t, expectedConcurrencyToken, intercepted.FetchedConfigurationHash)
|
require.Equal(t, expectedConcurrencyToken, intercepted.FetchedConfigurationHash)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -262,9 +257,9 @@ func TestContactPointServiceDecryptRedact(t *testing.T) {
|
|||||||
cps, err := sut.GetContactPoints(context.Background(), cpsQuery(1), nil)
|
cps, err := sut.GetContactPoints(context.Background(), cpsQuery(1), nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
require.Len(t, cps, 1)
|
require.Len(t, cps, 2)
|
||||||
require.Equal(t, "slack receiver", cps[0].Name)
|
require.Equal(t, "slack receiver", cps[1].Name)
|
||||||
require.Equal(t, definitions.RedactedValue, cps[0].Settings.Get("url").MustString())
|
require.Equal(t, definitions.RedactedValue, cps[1].Settings.Get("url").MustString())
|
||||||
})
|
})
|
||||||
t.Run("GetContactPoints errors when Decrypt = true and user does not have permissions", func(t *testing.T) {
|
t.Run("GetContactPoints errors when Decrypt = true and user does not have permissions", func(t *testing.T) {
|
||||||
sut := createContactPointServiceSut(t, secretsService)
|
sut := createContactPointServiceSut(t, secretsService)
|
||||||
@@ -289,7 +284,8 @@ func TestContactPointServiceDecryptRedact(t *testing.T) {
|
|||||||
sut := createContactPointServiceSut(t, secretsService)
|
sut := createContactPointServiceSut(t, secretsService)
|
||||||
sut.ac = ac
|
sut.ac = ac
|
||||||
|
|
||||||
q := cpsQuery(1)
|
expectedName := "slack receiver"
|
||||||
|
q := cpsQueryWithName(1, expectedName)
|
||||||
q.Decrypt = true
|
q.Decrypt = true
|
||||||
cps, err := sut.GetContactPoints(context.Background(), q, &user.SignedInUser{OrgID: 1, Permissions: map[int64]map[string][]string{
|
cps, err := sut.GetContactPoints(context.Background(), q, &user.SignedInUser{OrgID: 1, Permissions: map[int64]map[string][]string{
|
||||||
1: {
|
1: {
|
||||||
@@ -299,7 +295,7 @@ func TestContactPointServiceDecryptRedact(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
require.Len(t, cps, 1)
|
require.Len(t, cps, 1)
|
||||||
require.Equal(t, "slack receiver", cps[0].Name)
|
require.Equal(t, expectedName, cps[0].Name)
|
||||||
require.Equal(t, "secure url", cps[0].Settings.Get("url").MustString())
|
require.Equal(t, "secure url", cps[0].Settings.Get("url").MustString())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -349,8 +345,8 @@ func createContactPointServiceSut(t *testing.T, secretService secrets.Service) *
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
return &ContactPointService{
|
return &ContactPointService{
|
||||||
configStore: &alertmanagerConfigStoreImpl{store: newFakeAMConfigStore(string(raw))},
|
configStore: &alertmanagerConfigStoreImpl{store: fakes.NewFakeAlertmanagerConfigStore(string(raw))},
|
||||||
provenanceStore: NewFakeProvisioningStore(),
|
provenanceStore: fakes.NewFakeProvisioningStore(),
|
||||||
xact: newNopTransactionManager(),
|
xact: newNopTransactionManager(),
|
||||||
encryptionService: secretService,
|
encryptionService: secretService,
|
||||||
log: log.NewNopLogger(),
|
log: log.NewNopLogger(),
|
||||||
@@ -373,6 +369,13 @@ func cpsQuery(orgID int64) ContactPointQuery {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func cpsQueryWithName(orgID int64, name string) ContactPointQuery {
|
||||||
|
return ContactPointQuery{
|
||||||
|
OrgID: orgID,
|
||||||
|
Name: name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestStitchReceivers(t *testing.T) {
|
func TestStitchReceivers(t *testing.T) {
|
||||||
type testCase struct {
|
type testCase struct {
|
||||||
name string
|
name string
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
"github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
|
"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/tests/fakes"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -44,7 +45,7 @@ func TestNotificationPolicyService(t *testing.T) {
|
|||||||
Return(nil)
|
Return(nil)
|
||||||
newRoute := createTestRoutingTree()
|
newRoute := createTestRoutingTree()
|
||||||
newRoute.Routes = append(newRoute.Routes, &definitions.Route{
|
newRoute.Routes = append(newRoute.Routes, &definitions.Route{
|
||||||
Receiver: "a new receiver",
|
Receiver: "slack receiver",
|
||||||
MuteTimeIntervals: []string{"not-existing"},
|
MuteTimeIntervals: []string{"not-existing"},
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -70,7 +71,7 @@ func TestNotificationPolicyService(t *testing.T) {
|
|||||||
Return(nil)
|
Return(nil)
|
||||||
newRoute := createTestRoutingTree()
|
newRoute := createTestRoutingTree()
|
||||||
newRoute.Routes = append(newRoute.Routes, &definitions.Route{
|
newRoute.Routes = append(newRoute.Routes, &definitions.Route{
|
||||||
Receiver: "a new receiver",
|
Receiver: "slack receiver",
|
||||||
MuteTimeIntervals: []string{"existing"},
|
MuteTimeIntervals: []string{"existing"},
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -88,7 +89,7 @@ func TestNotificationPolicyService(t *testing.T) {
|
|||||||
|
|
||||||
updated, err := sut.GetPolicyTree(context.Background(), 1)
|
updated, err := sut.GetPolicyTree(context.Background(), 1)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, "a new receiver", updated.Receiver)
|
require.Equal(t, "slack receiver", updated.Receiver)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("not existing receiver reference will error", func(t *testing.T) {
|
t.Run("not existing receiver reference will error", func(t *testing.T) {
|
||||||
@@ -153,8 +154,8 @@ func TestNotificationPolicyService(t *testing.T) {
|
|||||||
err = sut.UpdatePolicyTree(context.Background(), 1, newRoute, models.ProvenanceAPI)
|
err = sut.UpdatePolicyTree(context.Background(), 1, newRoute, models.ProvenanceAPI)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
fake := sut.GetAMConfigStore().(*fakeAMConfigStore)
|
fake := sut.GetAMConfigStore().(*fakes.FakeAlertmanagerConfigStore)
|
||||||
intercepted := fake.lastSaveCommand
|
intercepted := fake.LastSaveCommand
|
||||||
require.Equal(t, expectedConcurrencyToken, intercepted.FetchedConfigurationHash)
|
require.Equal(t, expectedConcurrencyToken, intercepted.FetchedConfigurationHash)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -186,12 +187,12 @@ func TestNotificationPolicyService(t *testing.T) {
|
|||||||
sut.configStore.store = &MockAMConfigStore{}
|
sut.configStore.store = &MockAMConfigStore{}
|
||||||
cfg := createTestAlertingConfig()
|
cfg := createTestAlertingConfig()
|
||||||
cfg.AlertmanagerConfig.Route = &definitions.Route{
|
cfg.AlertmanagerConfig.Route = &definitions.Route{
|
||||||
Receiver: "a new receiver",
|
Receiver: "slack receiver",
|
||||||
}
|
}
|
||||||
cfg.AlertmanagerConfig.Receivers = []*definitions.PostableApiReceiver{
|
cfg.AlertmanagerConfig.Receivers = []*definitions.PostableApiReceiver{
|
||||||
{
|
{
|
||||||
Receiver: config.Receiver{
|
Receiver: config.Receiver{
|
||||||
Name: "a new receiver",
|
Name: "slack receiver",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// No default receiver! Only our custom one.
|
// No default receiver! Only our custom one.
|
||||||
@@ -216,8 +217,8 @@ func TestNotificationPolicyService(t *testing.T) {
|
|||||||
|
|
||||||
func createNotificationPolicyServiceSut() *NotificationPolicyService {
|
func createNotificationPolicyServiceSut() *NotificationPolicyService {
|
||||||
return &NotificationPolicyService{
|
return &NotificationPolicyService{
|
||||||
configStore: &alertmanagerConfigStoreImpl{store: newFakeAMConfigStore(defaultAlertmanagerConfigJSON)},
|
configStore: &alertmanagerConfigStoreImpl{store: fakes.NewFakeAlertmanagerConfigStore(defaultAlertmanagerConfigJSON)},
|
||||||
provenanceStore: NewFakeProvisioningStore(),
|
provenanceStore: fakes.NewFakeProvisioningStore(),
|
||||||
xact: newNopTransactionManager(),
|
xact: newNopTransactionManager(),
|
||||||
log: log.NewNopLogger(),
|
log: log.NewNopLogger(),
|
||||||
settings: setting.UnifiedAlertingSettings{
|
settings: setting.UnifiedAlertingSettings{
|
||||||
@@ -228,7 +229,7 @@ func createNotificationPolicyServiceSut() *NotificationPolicyService {
|
|||||||
|
|
||||||
func createTestRoutingTree() definitions.Route {
|
func createTestRoutingTree() definitions.Route {
|
||||||
return definitions.Route{
|
return definitions.Route{
|
||||||
Receiver: "a new receiver",
|
Receiver: "slack receiver",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,7 +239,7 @@ func createTestAlertingConfig() *definitions.PostableUserConfig {
|
|||||||
&definitions.PostableApiReceiver{
|
&definitions.PostableApiReceiver{
|
||||||
Receiver: config.Receiver{
|
Receiver: config.Receiver{
|
||||||
// default one from createTestRoutingTree()
|
// default one from createTestRoutingTree()
|
||||||
Name: "a new receiver",
|
Name: "slack receiver",
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
cfg.AlertmanagerConfig.Receivers = append(cfg.AlertmanagerConfig.Receivers,
|
cfg.AlertmanagerConfig.Receivers = append(cfg.AlertmanagerConfig.Receivers,
|
||||||
|
|||||||
@@ -2,9 +2,6 @@ package provisioning
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/md5"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
@@ -31,8 +28,8 @@ const defaultAlertmanagerConfigJSON = `
|
|||||||
"receivers": [{
|
"receivers": [{
|
||||||
"name": "grafana-default-email",
|
"name": "grafana-default-email",
|
||||||
"grafana_managed_receiver_configs": [{
|
"grafana_managed_receiver_configs": [{
|
||||||
"uid": "",
|
"uid": "UID1",
|
||||||
"name": "email receiver",
|
"name": "grafana-default-email",
|
||||||
"type": "email",
|
"type": "email",
|
||||||
"disableResolveMessage": false,
|
"disableResolveMessage": false,
|
||||||
"settings": {
|
"settings": {
|
||||||
@@ -41,9 +38,9 @@ const defaultAlertmanagerConfigJSON = `
|
|||||||
"secureFields": {}
|
"secureFields": {}
|
||||||
}]
|
}]
|
||||||
}, {
|
}, {
|
||||||
"name": "a new receiver",
|
"name": "slack receiver",
|
||||||
"grafana_managed_receiver_configs": [{
|
"grafana_managed_receiver_configs": [{
|
||||||
"uid": "",
|
"uid": "UID2",
|
||||||
"name": "slack receiver",
|
"name": "slack receiver",
|
||||||
"type": "slack",
|
"type": "slack",
|
||||||
"disableResolveMessage": false,
|
"disableResolveMessage": false,
|
||||||
@@ -55,88 +52,6 @@ const defaultAlertmanagerConfigJSON = `
|
|||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
type fakeAMConfigStore struct {
|
|
||||||
config models.AlertConfiguration
|
|
||||||
lastSaveCommand *models.SaveAlertmanagerConfigurationCmd
|
|
||||||
}
|
|
||||||
|
|
||||||
func newFakeAMConfigStore(config string) *fakeAMConfigStore {
|
|
||||||
return &fakeAMConfigStore{
|
|
||||||
config: models.AlertConfiguration{
|
|
||||||
AlertmanagerConfiguration: config,
|
|
||||||
ConfigurationVersion: "v1",
|
|
||||||
Default: true,
|
|
||||||
OrgID: 1,
|
|
||||||
},
|
|
||||||
lastSaveCommand: nil,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *fakeAMConfigStore) GetLatestAlertmanagerConfiguration(ctx context.Context, orgID int64) (*models.AlertConfiguration, error) {
|
|
||||||
result := &f.config
|
|
||||||
result.OrgID = orgID
|
|
||||||
result.ConfigurationHash = fmt.Sprintf("%x", md5.Sum([]byte(f.config.AlertmanagerConfiguration)))
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *fakeAMConfigStore) UpdateAlertmanagerConfiguration(ctx context.Context, cmd *models.SaveAlertmanagerConfigurationCmd) error {
|
|
||||||
f.config = models.AlertConfiguration{
|
|
||||||
AlertmanagerConfiguration: cmd.AlertmanagerConfiguration,
|
|
||||||
ConfigurationVersion: cmd.ConfigurationVersion,
|
|
||||||
Default: cmd.Default,
|
|
||||||
OrgID: cmd.OrgID,
|
|
||||||
}
|
|
||||||
f.lastSaveCommand = cmd
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type fakeProvisioningStore struct {
|
|
||||||
records map[int64]map[string]models.Provenance
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewFakeProvisioningStore() *fakeProvisioningStore {
|
|
||||||
return &fakeProvisioningStore{
|
|
||||||
records: map[int64]map[string]models.Provenance{},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *fakeProvisioningStore) GetProvenance(ctx context.Context, o models.Provisionable, org int64) (models.Provenance, error) {
|
|
||||||
if val, ok := f.records[org]; ok {
|
|
||||||
if prov, ok := val[o.ResourceID()+o.ResourceType()]; ok {
|
|
||||||
return prov, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return models.ProvenanceNone, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *fakeProvisioningStore) GetProvenances(ctx context.Context, orgID int64, resourceType string) (map[string]models.Provenance, error) {
|
|
||||||
results := make(map[string]models.Provenance)
|
|
||||||
if val, ok := f.records[orgID]; ok {
|
|
||||||
for k, v := range val {
|
|
||||||
if strings.HasSuffix(k, resourceType) {
|
|
||||||
results[strings.TrimSuffix(k, resourceType)] = v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return results, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *fakeProvisioningStore) SetProvenance(ctx context.Context, o models.Provisionable, org int64, p models.Provenance) error {
|
|
||||||
if _, ok := f.records[org]; !ok {
|
|
||||||
f.records[org] = map[string]models.Provenance{}
|
|
||||||
}
|
|
||||||
_ = f.DeleteProvenance(ctx, o, org) // delete old entries first
|
|
||||||
f.records[org][o.ResourceID()+o.ResourceType()] = p
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *fakeProvisioningStore) DeleteProvenance(ctx context.Context, o models.Provisionable, org int64) error {
|
|
||||||
if val, ok := f.records[org]; ok {
|
|
||||||
delete(val, o.ResourceID()+o.ResourceType())
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type NopTransactionManager struct{}
|
type NopTransactionManager struct{}
|
||||||
|
|
||||||
func newNopTransactionManager() *NopTransactionManager {
|
func newNopTransactionManager() *NopTransactionManager {
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/services/ngalert/metrics"
|
"github.com/grafana/grafana/pkg/services/ngalert/metrics"
|
||||||
"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"
|
||||||
"github.com/grafana/grafana/pkg/services/ngalert/provisioning"
|
|
||||||
"github.com/grafana/grafana/pkg/services/ngalert/store"
|
"github.com/grafana/grafana/pkg/services/ngalert/store"
|
||||||
"github.com/grafana/grafana/pkg/services/ngalert/tests/fakes"
|
"github.com/grafana/grafana/pkg/services/ngalert/tests/fakes"
|
||||||
fake_secrets "github.com/grafana/grafana/pkg/services/secrets/fakes"
|
fake_secrets "github.com/grafana/grafana/pkg/services/secrets/fakes"
|
||||||
@@ -411,7 +410,7 @@ func createMultiOrgAlertmanager(t *testing.T, orgs []int64) *notifier.MultiOrgAl
|
|||||||
m := metrics.NewNGAlert(registry)
|
m := metrics.NewNGAlert(registry)
|
||||||
secretsService := secretsManager.SetupTestService(t, fake_secrets.NewFakeSecretsStore())
|
secretsService := secretsManager.SetupTestService(t, fake_secrets.NewFakeSecretsStore())
|
||||||
decryptFn := secretsService.GetDecryptedValue
|
decryptFn := secretsService.GetDecryptedValue
|
||||||
moa, err := notifier.NewMultiOrgAlertmanager(cfg, cfgStore, orgStore, kvStore, provisioning.NewFakeProvisioningStore(), decryptFn, m.GetMultiOrgAlertmanagerMetrics(), nil, log.New("testlogger"), secretsService)
|
moa, err := notifier.NewMultiOrgAlertmanager(cfg, cfgStore, orgStore, kvStore, fakes.NewFakeProvisioningStore(), decryptFn, m.GetMultiOrgAlertmanagerMetrics(), nil, log.New("testlogger"), secretsService)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NoError(t, moa.LoadAndSyncAlertmanagersForOrgs(context.Background()))
|
require.NoError(t, moa.LoadAndSyncAlertmanagersForOrgs(context.Background()))
|
||||||
require.Eventually(t, func() bool {
|
require.Eventually(t, func() bool {
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package fakes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"crypto/md5"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/services/ngalert/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FakeAlertmanagerConfigStore struct {
|
||||||
|
Config models.AlertConfiguration
|
||||||
|
LastSaveCommand *models.SaveAlertmanagerConfigurationCmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFakeAlertmanagerConfigStore(config string) *FakeAlertmanagerConfigStore {
|
||||||
|
return &FakeAlertmanagerConfigStore{
|
||||||
|
Config: models.AlertConfiguration{
|
||||||
|
AlertmanagerConfiguration: config,
|
||||||
|
ConfigurationVersion: "v1",
|
||||||
|
Default: true,
|
||||||
|
OrgID: 1,
|
||||||
|
},
|
||||||
|
LastSaveCommand: nil,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FakeAlertmanagerConfigStore) GetLatestAlertmanagerConfiguration(ctx context.Context, orgID int64) (*models.AlertConfiguration, error) {
|
||||||
|
result := &f.Config
|
||||||
|
result.OrgID = orgID
|
||||||
|
result.ConfigurationHash = fmt.Sprintf("%x", md5.Sum([]byte(f.Config.AlertmanagerConfiguration)))
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FakeAlertmanagerConfigStore) UpdateAlertmanagerConfiguration(ctx context.Context, cmd *models.SaveAlertmanagerConfigurationCmd) error {
|
||||||
|
f.Config = models.AlertConfiguration{
|
||||||
|
AlertmanagerConfiguration: cmd.AlertmanagerConfiguration,
|
||||||
|
ConfigurationVersion: cmd.ConfigurationVersion,
|
||||||
|
Default: cmd.Default,
|
||||||
|
OrgID: cmd.OrgID,
|
||||||
|
}
|
||||||
|
f.LastSaveCommand = cmd
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
package fakes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/services/ngalert/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FakeProvisioningStore struct {
|
||||||
|
Records map[int64]map[string]models.Provenance
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFakeProvisioningStore() *FakeProvisioningStore {
|
||||||
|
return &FakeProvisioningStore{
|
||||||
|
Records: map[int64]map[string]models.Provenance{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FakeProvisioningStore) GetProvenance(ctx context.Context, o models.Provisionable, org int64) (models.Provenance, error) {
|
||||||
|
if val, ok := f.Records[org]; ok {
|
||||||
|
if prov, ok := val[o.ResourceID()+o.ResourceType()]; ok {
|
||||||
|
return prov, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return models.ProvenanceNone, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FakeProvisioningStore) GetProvenances(ctx context.Context, orgID int64, resourceType string) (map[string]models.Provenance, error) {
|
||||||
|
results := make(map[string]models.Provenance)
|
||||||
|
if val, ok := f.Records[orgID]; ok {
|
||||||
|
for k, v := range val {
|
||||||
|
if strings.HasSuffix(k, resourceType) {
|
||||||
|
results[strings.TrimSuffix(k, resourceType)] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FakeProvisioningStore) SetProvenance(ctx context.Context, o models.Provisionable, org int64, p models.Provenance) error {
|
||||||
|
if _, ok := f.Records[org]; !ok {
|
||||||
|
f.Records[org] = map[string]models.Provenance{}
|
||||||
|
}
|
||||||
|
_ = f.DeleteProvenance(ctx, o, org) // delete old entries first
|
||||||
|
f.Records[org][o.ResourceID()+o.ResourceType()] = p
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FakeProvisioningStore) DeleteProvenance(ctx context.Context, o models.Provisionable, org int64) error {
|
||||||
|
if val, ok := f.Records[org]; ok {
|
||||||
|
delete(val, o.ResourceID()+o.ResourceType())
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user