mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Use org service instead of sqlstore (#56407)
* Use org service instead of sqlstore * Remove methods from sqlstore * Remove commented out code * Fix lint * Fix lint 2
This commit is contained in:
parent
b0cb02568a
commit
ef651daed2
@ -9,6 +9,7 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||
"github.com/grafana/grafana/pkg/services/user"
|
||||
@ -438,9 +439,8 @@ func TestIntegrationStore_GetResourcePermissions(t *testing.T) {
|
||||
|
||||
func seedResourcePermissions(t *testing.T, store *store, sql *sqlstore.SQLStore, actions []string, resource, resourceID, resourceAttribute string, numUsers int) {
|
||||
t.Helper()
|
||||
var org *models.Org
|
||||
for i := 0; i < numUsers; i++ {
|
||||
org, _ := sql.GetOrgByName("test")
|
||||
|
||||
if org == nil {
|
||||
addedOrg, err := sql.CreateOrgWithMember("test", int64(i))
|
||||
require.NoError(t, err)
|
||||
|
@ -170,6 +170,63 @@ func TestIntegrationOrgDataAccess(t *testing.T) {
|
||||
assert.Equal(t, int64(1), result.ID)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("Testing Account DB Access", func(t *testing.T) {
|
||||
sqlStore := sqlstore.InitTestDB(t)
|
||||
|
||||
t.Run("Given we have organizations, we can query them by IDs", func(t *testing.T) {
|
||||
var err error
|
||||
var cmd *models.CreateOrgCommand
|
||||
ids := []int64{}
|
||||
|
||||
for i := 1; i < 4; i++ {
|
||||
cmd = &models.CreateOrgCommand{Name: fmt.Sprint("Org #", i)}
|
||||
err = sqlStore.CreateOrg(context.Background(), cmd)
|
||||
require.NoError(t, err)
|
||||
|
||||
ids = append(ids, cmd.Result.Id)
|
||||
}
|
||||
|
||||
query := &org.SearchOrgsQuery{IDs: ids}
|
||||
queryResult, err := orgStore.Search(context.Background(), query)
|
||||
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, len(queryResult), 3)
|
||||
})
|
||||
|
||||
t.Run("Given we have organizations, we can limit and paginate search", func(t *testing.T) {
|
||||
sqlStore = sqlstore.InitTestDB(t)
|
||||
for i := 1; i < 4; i++ {
|
||||
cmd := &models.CreateOrgCommand{Name: fmt.Sprint("Org #", i)}
|
||||
err := sqlStore.CreateOrg(context.Background(), cmd)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
t.Run("Should be able to search with defaults", func(t *testing.T) {
|
||||
query := &org.SearchOrgsQuery{}
|
||||
queryResult, err := orgStore.Search(context.Background(), query)
|
||||
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, len(queryResult), 3)
|
||||
})
|
||||
|
||||
t.Run("Should be able to limit search", func(t *testing.T) {
|
||||
query := &org.SearchOrgsQuery{Limit: 1}
|
||||
queryResult, err := orgStore.Search(context.Background(), query)
|
||||
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, len(queryResult), 1)
|
||||
})
|
||||
|
||||
t.Run("Should be able to limit and paginate search", func(t *testing.T) {
|
||||
query := &org.SearchOrgsQuery{Limit: 2, Page: 1}
|
||||
queryResult, err := orgStore.Search(context.Background(), query)
|
||||
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, len(queryResult), 1)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestIntegrationOrgUserDataAccess(t *testing.T) {
|
||||
|
@ -9,14 +9,15 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/services/org"
|
||||
"github.com/grafana/grafana/pkg/services/provisioning/utils"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
type configReader struct {
|
||||
path string
|
||||
log log.Logger
|
||||
orgStore utils.OrgStore
|
||||
path string
|
||||
log log.Logger
|
||||
orgService org.Service
|
||||
}
|
||||
|
||||
func (cr *configReader) parseConfigs(file fs.DirEntry) ([]*config, error) {
|
||||
@ -94,7 +95,7 @@ func (cr *configReader) readConfig(ctx context.Context) ([]*config, error) {
|
||||
dashboard.OrgID = 1
|
||||
}
|
||||
|
||||
if err := utils.CheckOrgExists(ctx, cr.orgStore, dashboard.OrgID); err != nil {
|
||||
if err := utils.CheckOrgExists(ctx, cr.orgService, dashboard.OrgID); err != nil {
|
||||
return nil, fmt.Errorf("failed to provision dashboards with %q reader: %w", dashboard.Name, err)
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/org/orgtest"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||
)
|
||||
|
||||
@ -26,12 +27,15 @@ func TestDashboardsAsConfig(t *testing.T) {
|
||||
t.Run("Dashboards as configuration", func(t *testing.T) {
|
||||
logger := log.New("test-logger")
|
||||
store := sqlstore.InitTestDB(t)
|
||||
orgFake := orgtest.NewOrgServiceFake()
|
||||
|
||||
t.Run("Should fail if orgs don't exist in the database", func(t *testing.T) {
|
||||
cfgProvider := configReader{path: appliedDefaults, log: logger, orgStore: store}
|
||||
orgFake.ExpectedError = models.ErrOrgNotFound
|
||||
cfgProvider := configReader{path: appliedDefaults, log: logger, orgService: orgFake}
|
||||
_, err := cfgProvider.readConfig(context.Background())
|
||||
require.Error(t, err)
|
||||
assert.True(t, errors.Is(err, models.ErrOrgNotFound))
|
||||
orgFake.ExpectedError = nil
|
||||
})
|
||||
|
||||
for i := 1; i <= 2; i++ {
|
||||
@ -41,7 +45,7 @@ func TestDashboardsAsConfig(t *testing.T) {
|
||||
}
|
||||
|
||||
t.Run("default values should be applied", func(t *testing.T) {
|
||||
cfgProvider := configReader{path: appliedDefaults, log: logger, orgStore: store}
|
||||
cfgProvider := configReader{path: appliedDefaults, log: logger, orgService: orgFake}
|
||||
cfg, err := cfgProvider.readConfig(context.Background())
|
||||
require.NoError(t, err)
|
||||
|
||||
@ -52,7 +56,7 @@ func TestDashboardsAsConfig(t *testing.T) {
|
||||
|
||||
t.Run("Can read config file version 1 format", func(t *testing.T) {
|
||||
_ = os.Setenv("TEST_VAR", "general")
|
||||
cfgProvider := configReader{path: simpleDashboardConfig, log: logger, orgStore: store}
|
||||
cfgProvider := configReader{path: simpleDashboardConfig, log: logger, orgService: orgFake}
|
||||
cfg, err := cfgProvider.readConfig(context.Background())
|
||||
_ = os.Unsetenv("TEST_VAR")
|
||||
require.NoError(t, err)
|
||||
@ -61,7 +65,7 @@ func TestDashboardsAsConfig(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("Can read config file in version 0 format", func(t *testing.T) {
|
||||
cfgProvider := configReader{path: oldVersion, log: logger, orgStore: store}
|
||||
cfgProvider := configReader{path: oldVersion, log: logger, orgService: orgFake}
|
||||
cfg, err := cfgProvider.readConfig(context.Background())
|
||||
require.NoError(t, err)
|
||||
|
||||
@ -69,7 +73,7 @@ func TestDashboardsAsConfig(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("Should skip invalid path", func(t *testing.T) {
|
||||
cfgProvider := configReader{path: "/invalid-directory", log: logger, orgStore: store}
|
||||
cfgProvider := configReader{path: "/invalid-directory", log: logger, orgService: orgFake}
|
||||
cfg, err := cfgProvider.readConfig(context.Background())
|
||||
if err != nil {
|
||||
t.Fatalf("readConfig return an error %v", err)
|
||||
@ -79,7 +83,7 @@ func TestDashboardsAsConfig(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("Should skip broken config files", func(t *testing.T) {
|
||||
cfgProvider := configReader{path: brokenConfigs, log: logger, orgStore: store}
|
||||
cfgProvider := configReader{path: brokenConfigs, log: logger, orgService: orgFake}
|
||||
cfg, err := cfgProvider.readConfig(context.Background())
|
||||
if err != nil {
|
||||
t.Fatalf("readConfig return an error %v", err)
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
"github.com/grafana/grafana/pkg/services/org"
|
||||
"github.com/grafana/grafana/pkg/services/provisioning/utils"
|
||||
)
|
||||
|
||||
@ -23,7 +24,7 @@ type DashboardProvisioner interface {
|
||||
}
|
||||
|
||||
// DashboardProvisionerFactory creates DashboardProvisioners based on input
|
||||
type DashboardProvisionerFactory func(context.Context, string, dashboards.DashboardProvisioningService, utils.OrgStore, utils.DashboardStore) (DashboardProvisioner, error)
|
||||
type DashboardProvisionerFactory func(context.Context, string, dashboards.DashboardProvisioningService, org.Service, utils.DashboardStore) (DashboardProvisioner, error)
|
||||
|
||||
// Provisioner is responsible for syncing dashboard from disk to Grafana's database.
|
||||
type Provisioner struct {
|
||||
@ -39,9 +40,9 @@ func (provider *Provisioner) HasDashboardSources() bool {
|
||||
}
|
||||
|
||||
// New returns a new DashboardProvisioner
|
||||
func New(ctx context.Context, configDirectory string, provisioner dashboards.DashboardProvisioningService, orgStore utils.OrgStore, dashboardStore utils.DashboardStore) (DashboardProvisioner, error) {
|
||||
func New(ctx context.Context, configDirectory string, provisioner dashboards.DashboardProvisioningService, orgService org.Service, dashboardStore utils.DashboardStore) (DashboardProvisioner, error) {
|
||||
logger := log.New("provisioning.dashboard")
|
||||
cfgReader := &configReader{path: configDirectory, log: logger, orgStore: orgStore}
|
||||
cfgReader := &configReader{path: configDirectory, log: logger, orgService: orgService}
|
||||
configs, err := cfgReader.readConfig(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%v: %w", "Failed to read dashboards config", err)
|
||||
|
@ -12,12 +12,13 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/services/datasources"
|
||||
"github.com/grafana/grafana/pkg/services/org"
|
||||
"github.com/grafana/grafana/pkg/services/provisioning/utils"
|
||||
)
|
||||
|
||||
type configReader struct {
|
||||
log log.Logger
|
||||
orgStore utils.OrgStore
|
||||
log log.Logger
|
||||
orgService org.Service
|
||||
}
|
||||
|
||||
func (cr *configReader) readConfig(ctx context.Context, path string) ([]*configs, error) {
|
||||
@ -130,7 +131,7 @@ func (cr *configReader) validateDefaultUniqueness(ctx context.Context, datasourc
|
||||
}
|
||||
|
||||
func (cr *configReader) validateAccessAndOrgID(ctx context.Context, ds *upsertDataSourceFromConfig) error {
|
||||
if err := utils.CheckOrgExists(ctx, cr.orgStore, ds.OrgID); err != nil {
|
||||
if err := utils.CheckOrgExists(ctx, cr.orgService, ds.OrgID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -8,9 +8,10 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/correlations"
|
||||
"github.com/grafana/grafana/pkg/services/datasources"
|
||||
"github.com/grafana/grafana/pkg/services/org"
|
||||
"github.com/grafana/grafana/pkg/services/org/orgtest"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
)
|
||||
|
||||
@ -34,9 +35,9 @@ var (
|
||||
func TestDatasourceAsConfig(t *testing.T) {
|
||||
t.Run("when some values missing should apply default on insert", func(t *testing.T) {
|
||||
store := &spyStore{}
|
||||
orgStore := &mockOrgStore{ExpectedOrg: &models.Org{Id: 1}}
|
||||
orgFake := &orgtest.FakeOrgService{ExpectedOrg: &org.Org{ID: 1}}
|
||||
correlationsStore := &mockCorrelationsStore{}
|
||||
dc := newDatasourceProvisioner(logger, store, correlationsStore, orgStore)
|
||||
dc := newDatasourceProvisioner(logger, store, correlationsStore, orgFake)
|
||||
err := dc.applyChanges(context.Background(), withoutDefaults)
|
||||
if err != nil {
|
||||
t.Fatalf("applyChanges return an error %v", err)
|
||||
@ -53,9 +54,9 @@ func TestDatasourceAsConfig(t *testing.T) {
|
||||
store := &spyStore{
|
||||
items: []*datasources.DataSource{{Name: "My datasource name", OrgId: 1, Id: 1, Uid: util.GenerateShortUID()}},
|
||||
}
|
||||
orgStore := &mockOrgStore{}
|
||||
orgFake := &orgtest.FakeOrgService{}
|
||||
correlationsStore := &mockCorrelationsStore{}
|
||||
dc := newDatasourceProvisioner(logger, store, correlationsStore, orgStore)
|
||||
dc := newDatasourceProvisioner(logger, store, correlationsStore, orgFake)
|
||||
err := dc.applyChanges(context.Background(), withoutDefaults)
|
||||
if err != nil {
|
||||
t.Fatalf("applyChanges return an error %v", err)
|
||||
@ -69,9 +70,9 @@ func TestDatasourceAsConfig(t *testing.T) {
|
||||
|
||||
t.Run("no datasource in database", func(t *testing.T) {
|
||||
store := &spyStore{}
|
||||
orgStore := &mockOrgStore{}
|
||||
orgFake := &orgtest.FakeOrgService{}
|
||||
correlationsStore := &mockCorrelationsStore{}
|
||||
dc := newDatasourceProvisioner(logger, store, correlationsStore, orgStore)
|
||||
dc := newDatasourceProvisioner(logger, store, correlationsStore, orgFake)
|
||||
err := dc.applyChanges(context.Background(), twoDatasourcesConfig)
|
||||
if err != nil {
|
||||
t.Fatalf("applyChanges return an error %v", err)
|
||||
@ -84,9 +85,9 @@ func TestDatasourceAsConfig(t *testing.T) {
|
||||
|
||||
t.Run("One datasource in database with same name should update one datasource", func(t *testing.T) {
|
||||
store := &spyStore{items: []*datasources.DataSource{{Name: "Graphite", OrgId: 1, Id: 1}}}
|
||||
orgStore := &mockOrgStore{}
|
||||
orgFake := &orgtest.FakeOrgService{}
|
||||
correlationsStore := &mockCorrelationsStore{}
|
||||
dc := newDatasourceProvisioner(logger, store, correlationsStore, orgStore)
|
||||
dc := newDatasourceProvisioner(logger, store, correlationsStore, orgFake)
|
||||
err := dc.applyChanges(context.Background(), twoDatasourcesConfig)
|
||||
if err != nil {
|
||||
t.Fatalf("applyChanges return an error %v", err)
|
||||
@ -99,18 +100,18 @@ func TestDatasourceAsConfig(t *testing.T) {
|
||||
|
||||
t.Run("Two datasources with is_default should raise error", func(t *testing.T) {
|
||||
store := &spyStore{}
|
||||
orgStore := &mockOrgStore{}
|
||||
orgFake := &orgtest.FakeOrgService{}
|
||||
correlationsStore := &mockCorrelationsStore{}
|
||||
dc := newDatasourceProvisioner(logger, store, correlationsStore, orgStore)
|
||||
dc := newDatasourceProvisioner(logger, store, correlationsStore, orgFake)
|
||||
err := dc.applyChanges(context.Background(), doubleDatasourcesConfig)
|
||||
require.Equal(t, err, ErrInvalidConfigToManyDefault)
|
||||
})
|
||||
|
||||
t.Run("Multiple datasources in different organizations with isDefault in each organization should not raise error", func(t *testing.T) {
|
||||
store := &spyStore{}
|
||||
orgStore := &mockOrgStore{}
|
||||
orgFake := &orgtest.FakeOrgService{}
|
||||
correlationsStore := &mockCorrelationsStore{}
|
||||
dc := newDatasourceProvisioner(logger, store, correlationsStore, orgStore)
|
||||
dc := newDatasourceProvisioner(logger, store, correlationsStore, orgFake)
|
||||
err := dc.applyChanges(context.Background(), multipleOrgsWithDefault)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, len(store.inserted), 4)
|
||||
@ -122,9 +123,9 @@ func TestDatasourceAsConfig(t *testing.T) {
|
||||
|
||||
t.Run("Remove one datasource should have removed old datasource", func(t *testing.T) {
|
||||
store := &spyStore{}
|
||||
orgStore := &mockOrgStore{}
|
||||
orgFake := &orgtest.FakeOrgService{}
|
||||
correlationsStore := &mockCorrelationsStore{}
|
||||
dc := newDatasourceProvisioner(logger, store, correlationsStore, orgStore)
|
||||
dc := newDatasourceProvisioner(logger, store, correlationsStore, orgFake)
|
||||
err := dc.applyChanges(context.Background(), deleteOneDatasource)
|
||||
if err != nil {
|
||||
t.Fatalf("applyChanges return an error %v", err)
|
||||
@ -139,9 +140,9 @@ func TestDatasourceAsConfig(t *testing.T) {
|
||||
|
||||
t.Run("Two configured datasource and purge others", func(t *testing.T) {
|
||||
store := &spyStore{items: []*datasources.DataSource{{Name: "old-graphite", OrgId: 1, Id: 1}, {Name: "old-graphite2", OrgId: 1, Id: 2}}}
|
||||
orgStore := &mockOrgStore{}
|
||||
orgFake := &orgtest.FakeOrgService{}
|
||||
correlationsStore := &mockCorrelationsStore{}
|
||||
dc := newDatasourceProvisioner(logger, store, correlationsStore, orgStore)
|
||||
dc := newDatasourceProvisioner(logger, store, correlationsStore, orgFake)
|
||||
err := dc.applyChanges(context.Background(), twoDatasourcesConfigPurgeOthers)
|
||||
if err != nil {
|
||||
t.Fatalf("applyChanges return an error %v", err)
|
||||
@ -154,9 +155,9 @@ func TestDatasourceAsConfig(t *testing.T) {
|
||||
|
||||
t.Run("Two configured datasource and purge others = false", func(t *testing.T) {
|
||||
store := &spyStore{items: []*datasources.DataSource{{Name: "Graphite", OrgId: 1, Id: 1}, {Name: "old-graphite2", OrgId: 1, Id: 2}}}
|
||||
orgStore := &mockOrgStore{}
|
||||
orgFake := &orgtest.FakeOrgService{}
|
||||
correlationsStore := &mockCorrelationsStore{}
|
||||
dc := newDatasourceProvisioner(logger, store, correlationsStore, orgStore)
|
||||
dc := newDatasourceProvisioner(logger, store, correlationsStore, orgFake)
|
||||
err := dc.applyChanges(context.Background(), twoDatasourcesConfig)
|
||||
if err != nil {
|
||||
t.Fatalf("applyChanges return an error %v", err)
|
||||
@ -174,14 +175,14 @@ func TestDatasourceAsConfig(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("invalid access should warn about invalid value and return 'proxy'", func(t *testing.T) {
|
||||
reader := &configReader{log: logger, orgStore: &mockOrgStore{}}
|
||||
reader := &configReader{log: logger, orgService: &orgtest.FakeOrgService{}}
|
||||
configs, err := reader.readConfig(context.Background(), invalidAccess)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, configs[0].Datasources[0].Access, datasources.DS_ACCESS_PROXY)
|
||||
})
|
||||
|
||||
t.Run("skip invalid directory", func(t *testing.T) {
|
||||
cfgProvider := &configReader{log: log.New("test logger"), orgStore: &mockOrgStore{}}
|
||||
cfgProvider := &configReader{log: log.New("test logger"), orgService: &orgtest.FakeOrgService{}}
|
||||
cfg, err := cfgProvider.readConfig(context.Background(), "./invalid-directory")
|
||||
if err != nil {
|
||||
t.Fatalf("readConfig return an error %v", err)
|
||||
@ -192,7 +193,7 @@ func TestDatasourceAsConfig(t *testing.T) {
|
||||
|
||||
t.Run("can read all properties from version 1", func(t *testing.T) {
|
||||
_ = os.Setenv("TEST_VAR", "name")
|
||||
cfgProvider := &configReader{log: log.New("test logger"), orgStore: &mockOrgStore{}}
|
||||
cfgProvider := &configReader{log: log.New("test logger"), orgService: &orgtest.FakeOrgService{}}
|
||||
cfg, err := cfgProvider.readConfig(context.Background(), allProperties)
|
||||
_ = os.Unsetenv("TEST_VAR")
|
||||
if err != nil {
|
||||
@ -221,7 +222,7 @@ func TestDatasourceAsConfig(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("can read all properties from version 0", func(t *testing.T) {
|
||||
cfgProvider := &configReader{log: log.New("test logger"), orgStore: &mockOrgStore{}}
|
||||
cfgProvider := &configReader{log: log.New("test logger"), orgService: &orgtest.FakeOrgService{}}
|
||||
cfg, err := cfgProvider.readConfig(context.Background(), versionZero)
|
||||
if err != nil {
|
||||
t.Fatalf("readConfig return an error %v", err)
|
||||
@ -240,9 +241,9 @@ func TestDatasourceAsConfig(t *testing.T) {
|
||||
t.Run("Correlations", func(t *testing.T) {
|
||||
t.Run("Creates two correlations", func(t *testing.T) {
|
||||
store := &spyStore{}
|
||||
orgStore := &mockOrgStore{}
|
||||
orgFake := &orgtest.FakeOrgService{}
|
||||
correlationsStore := &mockCorrelationsStore{}
|
||||
dc := newDatasourceProvisioner(logger, store, correlationsStore, orgStore)
|
||||
dc := newDatasourceProvisioner(logger, store, correlationsStore, orgFake)
|
||||
err := dc.applyChanges(context.Background(), oneDatasourceWithTwoCorrelations)
|
||||
if err != nil {
|
||||
t.Fatalf("applyChanges return an error %v", err)
|
||||
@ -255,9 +256,9 @@ func TestDatasourceAsConfig(t *testing.T) {
|
||||
|
||||
t.Run("Updating existing datasource deletes existing correlations and creates two", func(t *testing.T) {
|
||||
store := &spyStore{items: []*datasources.DataSource{{Name: "Graphite", OrgId: 1, Id: 1}}}
|
||||
orgStore := &mockOrgStore{}
|
||||
orgFake := &orgtest.FakeOrgService{}
|
||||
correlationsStore := &mockCorrelationsStore{}
|
||||
dc := newDatasourceProvisioner(logger, store, correlationsStore, orgStore)
|
||||
dc := newDatasourceProvisioner(logger, store, correlationsStore, orgFake)
|
||||
err := dc.applyChanges(context.Background(), oneDatasourceWithTwoCorrelations)
|
||||
if err != nil {
|
||||
t.Fatalf("applyChanges return an error %v", err)
|
||||
@ -270,10 +271,10 @@ func TestDatasourceAsConfig(t *testing.T) {
|
||||
|
||||
t.Run("Deleting datasource deletes existing correlations", func(t *testing.T) {
|
||||
store := &spyStore{items: []*datasources.DataSource{{Name: "old-data-source", OrgId: 1, Id: 1, Uid: "some-uid"}}}
|
||||
orgStore := &mockOrgStore{}
|
||||
orgFake := &orgtest.FakeOrgService{}
|
||||
targetUid := "target-uid"
|
||||
correlationsStore := &mockCorrelationsStore{items: []correlations.Correlation{{UID: "some-uid", SourceUID: "some-uid", TargetUID: &targetUid}}}
|
||||
dc := newDatasourceProvisioner(logger, store, correlationsStore, orgStore)
|
||||
dc := newDatasourceProvisioner(logger, store, correlationsStore, orgFake)
|
||||
err := dc.applyChanges(context.Background(), deleteOneDatasource)
|
||||
if err != nil {
|
||||
t.Fatalf("applyChanges return an error %v", err)
|
||||
@ -337,13 +338,6 @@ func validateDatasourceV1(t *testing.T, dsCfg *configs) {
|
||||
}}, ds.Correlations)
|
||||
}
|
||||
|
||||
type mockOrgStore struct{ ExpectedOrg *models.Org }
|
||||
|
||||
func (m *mockOrgStore) GetOrgById(c context.Context, cmd *models.GetOrgByIdQuery) error {
|
||||
cmd.Result = m.ExpectedOrg
|
||||
return nil
|
||||
}
|
||||
|
||||
type mockCorrelationsStore struct {
|
||||
created []correlations.CreateCorrelationCommand
|
||||
deletedBySourceUID []correlations.DeleteCorrelationsBySourceUIDCommand
|
||||
|
@ -10,7 +10,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/services/correlations"
|
||||
"github.com/grafana/grafana/pkg/services/datasources"
|
||||
"github.com/grafana/grafana/pkg/services/provisioning/utils"
|
||||
"github.com/grafana/grafana/pkg/services/org"
|
||||
)
|
||||
|
||||
type Store interface {
|
||||
@ -34,8 +34,8 @@ var (
|
||||
|
||||
// Provision scans a directory for provisioning config files
|
||||
// and provisions the datasource in those files.
|
||||
func Provision(ctx context.Context, configDirectory string, store Store, correlationsStore CorrelationsStore, orgStore utils.OrgStore) error {
|
||||
dc := newDatasourceProvisioner(log.New("provisioning.datasources"), store, correlationsStore, orgStore)
|
||||
func Provision(ctx context.Context, configDirectory string, store Store, correlationsStore CorrelationsStore, orgService org.Service) error {
|
||||
dc := newDatasourceProvisioner(log.New("provisioning.datasources"), store, correlationsStore, orgService)
|
||||
return dc.applyChanges(ctx, configDirectory)
|
||||
}
|
||||
|
||||
@ -48,10 +48,10 @@ type DatasourceProvisioner struct {
|
||||
correlationsStore CorrelationsStore
|
||||
}
|
||||
|
||||
func newDatasourceProvisioner(log log.Logger, store Store, correlationsStore CorrelationsStore, orgStore utils.OrgStore) DatasourceProvisioner {
|
||||
func newDatasourceProvisioner(log log.Logger, store Store, correlationsStore CorrelationsStore, orgService org.Service) DatasourceProvisioner {
|
||||
return DatasourceProvisioner{
|
||||
log: log,
|
||||
cfgProvider: &configReader{log: log, orgStore: orgStore},
|
||||
cfgProvider: &configReader{log: log, orgService: orgService},
|
||||
store: store,
|
||||
correlationsStore: correlationsStore,
|
||||
}
|
||||
|
@ -24,14 +24,10 @@ type Manager interface {
|
||||
GetAlertNotificationsWithUidToSend(ctx context.Context, query *models.GetAlertNotificationsWithUidToSendQuery) error
|
||||
UpdateAlertNotificationWithUid(ctx context.Context, cmd *models.UpdateAlertNotificationWithUidCommand) error
|
||||
}
|
||||
type SQLStore interface {
|
||||
GetOrgById(c context.Context, cmd *models.GetOrgByIdQuery) error
|
||||
GetOrgByNameHandler(ctx context.Context, query *models.GetOrgByNameQuery) error
|
||||
}
|
||||
|
||||
// Provision alert notifiers
|
||||
func Provision(ctx context.Context, configDirectory string, alertingService Manager, orgService org.Service, sqlstore SQLStore, encryptionService encryption.Internal, notificationService *notifications.NotificationService) error {
|
||||
dc := newNotificationProvisioner(orgService, sqlstore, alertingService, encryptionService, notificationService, log.New("provisioning.notifiers"))
|
||||
func Provision(ctx context.Context, configDirectory string, alertingService Manager, orgService org.Service, encryptionService encryption.Internal, notificationService *notifications.NotificationService) error {
|
||||
dc := newNotificationProvisioner(orgService, alertingService, encryptionService, notificationService, log.New("provisioning.notifiers"))
|
||||
return dc.applyChanges(ctx, configDirectory)
|
||||
}
|
||||
|
||||
@ -40,11 +36,10 @@ type NotificationProvisioner struct {
|
||||
log log.Logger
|
||||
cfgProvider *configReader
|
||||
alertingManager Manager
|
||||
sqlstore SQLStore
|
||||
orgService org.Service
|
||||
}
|
||||
|
||||
func newNotificationProvisioner(orgService org.Service, store SQLStore, alertingManager Manager, encryptionService encryption.Internal, notifiationService *notifications.NotificationService, log log.Logger) NotificationProvisioner {
|
||||
func newNotificationProvisioner(orgService org.Service, alertingManager Manager, encryptionService encryption.Internal, notifiationService *notifications.NotificationService, log log.Logger) NotificationProvisioner {
|
||||
return NotificationProvisioner{
|
||||
log: log,
|
||||
alertingManager: alertingManager,
|
||||
@ -52,9 +47,8 @@ func newNotificationProvisioner(orgService org.Service, store SQLStore, alerting
|
||||
encryptionService: encryptionService,
|
||||
notificationService: notifiationService,
|
||||
log: log,
|
||||
orgStore: store,
|
||||
orgService: orgService,
|
||||
},
|
||||
sqlstore: store,
|
||||
orgService: orgService,
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/alerting"
|
||||
"github.com/grafana/grafana/pkg/services/encryption"
|
||||
"github.com/grafana/grafana/pkg/services/notifications"
|
||||
"github.com/grafana/grafana/pkg/services/org"
|
||||
"github.com/grafana/grafana/pkg/services/provisioning/utils"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"gopkg.in/yaml.v2"
|
||||
@ -21,7 +22,7 @@ import (
|
||||
type configReader struct {
|
||||
encryptionService encryption.Internal
|
||||
notificationService *notifications.NotificationService
|
||||
orgStore utils.OrgStore
|
||||
orgService org.Service
|
||||
log log.Logger
|
||||
}
|
||||
|
||||
@ -94,7 +95,7 @@ func (cr *configReader) checkOrgIDAndOrgName(ctx context.Context, notifications
|
||||
notification.OrgID = 0
|
||||
}
|
||||
} else {
|
||||
if err := utils.CheckOrgExists(ctx, cr.orgStore, notification.OrgID); err != nil {
|
||||
if err := utils.CheckOrgExists(ctx, cr.orgService, notification.OrgID); err != nil {
|
||||
return fmt.Errorf("failed to provision %q notification: %w", notification.Name, err)
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ var (
|
||||
|
||||
func TestNotificationAsConfig(t *testing.T) {
|
||||
var sqlStore *sqlstore.SQLStore
|
||||
var orgFake org.Service
|
||||
var ns *alerting.AlertNotificationService
|
||||
logger := log.New("fake.log")
|
||||
orgService := orgtest.NewOrgServiceFake()
|
||||
@ -44,6 +45,7 @@ func TestNotificationAsConfig(t *testing.T) {
|
||||
t.Run("Testing notification as configuration", func(t *testing.T) {
|
||||
setup := func() {
|
||||
sqlStore = sqlstore.InitTestDB(t)
|
||||
orgFake = orgtest.NewOrgServiceFake()
|
||||
nm := ¬ifications.NotificationService{}
|
||||
ns = alerting.ProvideService(sqlStore, encryptionService, nm)
|
||||
|
||||
@ -70,7 +72,7 @@ func TestNotificationAsConfig(t *testing.T) {
|
||||
setup()
|
||||
_ = os.Setenv("TEST_VAR", "default")
|
||||
cfgProvider := &configReader{
|
||||
orgStore: sqlStore,
|
||||
orgService: orgFake,
|
||||
encryptionService: encryptionService,
|
||||
log: log.New("test logger"),
|
||||
}
|
||||
@ -150,7 +152,7 @@ func TestNotificationAsConfig(t *testing.T) {
|
||||
setup()
|
||||
fakeAlertNotification := &fakeAlertNotification{}
|
||||
fakeAlertNotification.ExpectedAlertNotification = &models.AlertNotification{OrgId: 1}
|
||||
dc := newNotificationProvisioner(orgService, sqlStore, fakeAlertNotification, encryptionService, nil, logger)
|
||||
dc := newNotificationProvisioner(orgService, fakeAlertNotification, encryptionService, nil, logger)
|
||||
|
||||
err := dc.applyChanges(context.Background(), twoNotificationsConfig)
|
||||
if err != nil {
|
||||
@ -176,7 +178,7 @@ func TestNotificationAsConfig(t *testing.T) {
|
||||
require.Equal(t, len(notificationsQuery.Result), 1)
|
||||
|
||||
t.Run("should update one notification", func(t *testing.T) {
|
||||
dc := newNotificationProvisioner(orgService, sqlStore, &fakeAlertNotification{}, encryptionService, nil, logger)
|
||||
dc := newNotificationProvisioner(orgService, &fakeAlertNotification{}, encryptionService, nil, logger)
|
||||
err = dc.applyChanges(context.Background(), twoNotificationsConfig)
|
||||
if err != nil {
|
||||
t.Fatalf("applyChanges return an error %v", err)
|
||||
@ -186,7 +188,7 @@ func TestNotificationAsConfig(t *testing.T) {
|
||||
|
||||
t.Run("Two notifications with is_default", func(t *testing.T) {
|
||||
setup()
|
||||
dc := newNotificationProvisioner(orgService, sqlStore, &fakeAlertNotification{}, encryptionService, nil, logger)
|
||||
dc := newNotificationProvisioner(orgService, &fakeAlertNotification{}, encryptionService, nil, logger)
|
||||
err := dc.applyChanges(context.Background(), doubleNotificationsConfig)
|
||||
t.Run("should both be inserted", func(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
@ -221,7 +223,7 @@ func TestNotificationAsConfig(t *testing.T) {
|
||||
require.Equal(t, len(notificationsQuery.Result), 2)
|
||||
|
||||
t.Run("should have two new notifications", func(t *testing.T) {
|
||||
dc := newNotificationProvisioner(orgService, sqlStore, &fakeAlertNotification{}, encryptionService, nil, logger)
|
||||
dc := newNotificationProvisioner(orgService, &fakeAlertNotification{}, encryptionService, nil, logger)
|
||||
err := dc.applyChanges(context.Background(), twoNotificationsConfig)
|
||||
if err != nil {
|
||||
t.Fatalf("applyChanges return an error %v", err)
|
||||
@ -233,25 +235,16 @@ func TestNotificationAsConfig(t *testing.T) {
|
||||
t.Run("Can read correct properties with orgName instead of orgId", func(t *testing.T) {
|
||||
setup()
|
||||
|
||||
existingOrg1 := models.GetOrgByNameQuery{Name: "Main Org. 1"}
|
||||
err := sqlStore.GetOrgByNameHandler(context.Background(), &existingOrg1)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, existingOrg1.Result)
|
||||
existingOrg2 := models.GetOrgByNameQuery{Name: "Main Org. 2"}
|
||||
err = sqlStore.GetOrgByNameHandler(context.Background(), &existingOrg2)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, existingOrg2.Result)
|
||||
|
||||
existingNotificationCmd := models.CreateAlertNotificationCommand{
|
||||
Name: "default-notification-delete",
|
||||
OrgId: existingOrg2.Result.Id,
|
||||
OrgId: 1,
|
||||
Uid: "notifier2",
|
||||
Type: "slack",
|
||||
}
|
||||
err = ns.SQLStore.CreateAlertNotificationCommand(context.Background(), &existingNotificationCmd)
|
||||
err := ns.SQLStore.CreateAlertNotificationCommand(context.Background(), &existingNotificationCmd)
|
||||
require.NoError(t, err)
|
||||
|
||||
dc := newNotificationProvisioner(orgService, sqlStore, &fakeAlertNotification{}, encryptionService, nil, logger)
|
||||
dc := newNotificationProvisioner(orgService, &fakeAlertNotification{}, encryptionService, nil, logger)
|
||||
err = dc.applyChanges(context.Background(), correctPropertiesWithOrgName)
|
||||
if err != nil {
|
||||
t.Fatalf("applyChanges return an error %v", err)
|
||||
@ -260,7 +253,7 @@ func TestNotificationAsConfig(t *testing.T) {
|
||||
|
||||
t.Run("Config doesn't contain required field", func(t *testing.T) {
|
||||
setup()
|
||||
dc := newNotificationProvisioner(orgService, sqlStore, &fakeAlertNotification{}, encryptionService, nil, logger)
|
||||
dc := newNotificationProvisioner(orgService, &fakeAlertNotification{}, encryptionService, nil, logger)
|
||||
err := dc.applyChanges(context.Background(), noRequiredFields)
|
||||
require.NotNil(t, err)
|
||||
|
||||
@ -274,7 +267,7 @@ func TestNotificationAsConfig(t *testing.T) {
|
||||
t.Run("Empty yaml file", func(t *testing.T) {
|
||||
t.Run("should have not changed repo", func(t *testing.T) {
|
||||
setup()
|
||||
dc := newNotificationProvisioner(orgService, sqlStore, &fakeAlertNotification{}, encryptionService, nil, logger)
|
||||
dc := newNotificationProvisioner(orgService, &fakeAlertNotification{}, encryptionService, nil, logger)
|
||||
err := dc.applyChanges(context.Background(), emptyFile)
|
||||
if err != nil {
|
||||
t.Fatalf("applyChanges return an error %v", err)
|
||||
@ -288,7 +281,7 @@ func TestNotificationAsConfig(t *testing.T) {
|
||||
|
||||
t.Run("Broken yaml should return error", func(t *testing.T) {
|
||||
reader := &configReader{
|
||||
orgStore: sqlStore,
|
||||
orgService: orgFake,
|
||||
encryptionService: encryptionService,
|
||||
log: log.New("test logger"),
|
||||
}
|
||||
@ -299,7 +292,7 @@ func TestNotificationAsConfig(t *testing.T) {
|
||||
|
||||
t.Run("Skip invalid directory", func(t *testing.T) {
|
||||
cfgProvider := &configReader{
|
||||
orgStore: sqlStore,
|
||||
orgService: orgFake,
|
||||
encryptionService: encryptionService,
|
||||
log: log.New("test logger"),
|
||||
}
|
||||
@ -313,7 +306,7 @@ func TestNotificationAsConfig(t *testing.T) {
|
||||
|
||||
t.Run("Unknown notifier should return error", func(t *testing.T) {
|
||||
cfgProvider := &configReader{
|
||||
orgStore: sqlStore,
|
||||
orgService: orgFake,
|
||||
encryptionService: encryptionService,
|
||||
log: log.New("test logger"),
|
||||
}
|
||||
@ -324,7 +317,7 @@ func TestNotificationAsConfig(t *testing.T) {
|
||||
|
||||
t.Run("Read incorrect properties", func(t *testing.T) {
|
||||
cfgProvider := &configReader{
|
||||
orgStore: sqlStore,
|
||||
orgService: orgFake,
|
||||
encryptionService: encryptionService,
|
||||
log: log.New("test logger"),
|
||||
}
|
||||
|
@ -26,7 +26,6 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/provisioning/datasources"
|
||||
"github.com/grafana/grafana/pkg/services/provisioning/notifiers"
|
||||
"github.com/grafana/grafana/pkg/services/provisioning/plugins"
|
||||
"github.com/grafana/grafana/pkg/services/provisioning/utils"
|
||||
"github.com/grafana/grafana/pkg/services/quota"
|
||||
"github.com/grafana/grafana/pkg/services/searchV2"
|
||||
"github.com/grafana/grafana/pkg/services/secrets"
|
||||
@ -107,8 +106,8 @@ func NewProvisioningServiceImpl() *ProvisioningServiceImpl {
|
||||
// Used for testing purposes
|
||||
func newProvisioningServiceImpl(
|
||||
newDashboardProvisioner dashboards.DashboardProvisionerFactory,
|
||||
provisionNotifiers func(context.Context, string, notifiers.Manager, org.Service, notifiers.SQLStore, encryption.Internal, *notifications.NotificationService) error,
|
||||
provisionDatasources func(context.Context, string, datasources.Store, datasources.CorrelationsStore, utils.OrgStore) error,
|
||||
provisionNotifiers func(context.Context, string, notifiers.Manager, org.Service, encryption.Internal, *notifications.NotificationService) error,
|
||||
provisionDatasources func(context.Context, string, datasources.Store, datasources.CorrelationsStore, org.Service) error,
|
||||
provisionPlugins func(context.Context, string, plugifaces.Store, pluginsettings.Service, org.Service) error,
|
||||
) *ProvisioningServiceImpl {
|
||||
return &ProvisioningServiceImpl{
|
||||
@ -132,8 +131,8 @@ type ProvisioningServiceImpl struct {
|
||||
pollingCtxCancel context.CancelFunc
|
||||
newDashboardProvisioner dashboards.DashboardProvisionerFactory
|
||||
dashboardProvisioner dashboards.DashboardProvisioner
|
||||
provisionNotifiers func(context.Context, string, notifiers.Manager, org.Service, notifiers.SQLStore, encryption.Internal, *notifications.NotificationService) error
|
||||
provisionDatasources func(context.Context, string, datasources.Store, datasources.CorrelationsStore, utils.OrgStore) error
|
||||
provisionNotifiers func(context.Context, string, notifiers.Manager, org.Service, encryption.Internal, *notifications.NotificationService) error
|
||||
provisionDatasources func(context.Context, string, datasources.Store, datasources.CorrelationsStore, org.Service) error
|
||||
provisionPlugins func(context.Context, string, plugifaces.Store, pluginsettings.Service, org.Service) error
|
||||
provisionAlerting func(context.Context, prov_alerting.ProvisionerConfig) error
|
||||
mutex sync.Mutex
|
||||
@ -206,7 +205,7 @@ func (ps *ProvisioningServiceImpl) Run(ctx context.Context) error {
|
||||
|
||||
func (ps *ProvisioningServiceImpl) ProvisionDatasources(ctx context.Context) error {
|
||||
datasourcePath := filepath.Join(ps.Cfg.ProvisioningPath, "datasources")
|
||||
if err := ps.provisionDatasources(ctx, datasourcePath, ps.datasourceService, ps.correlationsService, ps.SQLStore); err != nil {
|
||||
if err := ps.provisionDatasources(ctx, datasourcePath, ps.datasourceService, ps.correlationsService, ps.orgService); err != nil {
|
||||
err = fmt.Errorf("%v: %w", "Datasource provisioning error", err)
|
||||
ps.log.Error("Failed to provision data sources", "error", err)
|
||||
return err
|
||||
@ -226,7 +225,7 @@ func (ps *ProvisioningServiceImpl) ProvisionPlugins(ctx context.Context) error {
|
||||
|
||||
func (ps *ProvisioningServiceImpl) ProvisionNotifications(ctx context.Context) error {
|
||||
alertNotificationsPath := filepath.Join(ps.Cfg.ProvisioningPath, "notifiers")
|
||||
if err := ps.provisionNotifiers(ctx, alertNotificationsPath, ps.alertingService, ps.orgService, ps.SQLStore, ps.EncryptionService, ps.NotificationService); err != nil {
|
||||
if err := ps.provisionNotifiers(ctx, alertNotificationsPath, ps.alertingService, ps.orgService, ps.EncryptionService, ps.NotificationService); err != nil {
|
||||
err = fmt.Errorf("%v: %w", "Alert notification provisioning error", err)
|
||||
ps.log.Error("Failed to provision alert notifications", "error", err)
|
||||
return err
|
||||
@ -236,7 +235,7 @@ func (ps *ProvisioningServiceImpl) ProvisionNotifications(ctx context.Context) e
|
||||
|
||||
func (ps *ProvisioningServiceImpl) ProvisionDashboards(ctx context.Context) error {
|
||||
dashboardPath := filepath.Join(ps.Cfg.ProvisioningPath, "dashboards")
|
||||
dashProvisioner, err := ps.newDashboardProvisioner(ctx, dashboardPath, ps.dashboardProvisioningService, ps.SQLStore, ps.dashboardService)
|
||||
dashProvisioner, err := ps.newDashboardProvisioner(ctx, dashboardPath, ps.dashboardProvisioningService, ps.orgService, ps.dashboardService)
|
||||
if err != nil {
|
||||
return fmt.Errorf("%v: %w", "Failed to create provisioner", err)
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
"time"
|
||||
|
||||
dashboardstore "github.com/grafana/grafana/pkg/services/dashboards"
|
||||
"github.com/grafana/grafana/pkg/services/org"
|
||||
"github.com/grafana/grafana/pkg/services/provisioning/dashboards"
|
||||
"github.com/grafana/grafana/pkg/services/provisioning/utils"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
@ -93,7 +94,7 @@ func setup() *serviceTestStruct {
|
||||
}
|
||||
|
||||
serviceTest.service = newProvisioningServiceImpl(
|
||||
func(context.Context, string, dashboardstore.DashboardProvisioningService, utils.OrgStore, utils.DashboardStore) (dashboards.DashboardProvisioner, error) {
|
||||
func(context.Context, string, dashboardstore.DashboardProvisioningService, org.Service, utils.DashboardStore) (dashboards.DashboardProvisioner, error) {
|
||||
return serviceTest.mock, nil
|
||||
},
|
||||
nil,
|
||||
|
@ -6,19 +6,17 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/org"
|
||||
)
|
||||
|
||||
type OrgStore interface {
|
||||
GetOrgById(context.Context, *models.GetOrgByIdQuery) error
|
||||
}
|
||||
|
||||
type DashboardStore interface {
|
||||
GetDashboard(context.Context, *models.GetDashboardQuery) error
|
||||
}
|
||||
|
||||
func CheckOrgExists(ctx context.Context, store OrgStore, orgID int64) error {
|
||||
query := models.GetOrgByIdQuery{Id: orgID}
|
||||
if err := store.GetOrgById(ctx, &query); err != nil {
|
||||
func CheckOrgExists(ctx context.Context, orgService org.Service, orgID int64) error {
|
||||
query := org.GetOrgByIdQuery{ID: orgID}
|
||||
_, err := orgService.GetByID(ctx, &query)
|
||||
if err != nil {
|
||||
if errors.Is(err, models.ErrOrgNotFound) {
|
||||
return err
|
||||
}
|
||||
|
@ -13,7 +13,6 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/registry"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
@ -123,14 +122,14 @@ func (s *StandardSearchService) IsDisabled() bool {
|
||||
}
|
||||
|
||||
func (s *StandardSearchService) Run(ctx context.Context) error {
|
||||
orgQuery := &models.SearchOrgsQuery{}
|
||||
err := s.sql.SearchOrgs(ctx, orgQuery)
|
||||
orgQuery := &org.SearchOrgsQuery{}
|
||||
result, err := s.orgService.Search(ctx, orgQuery)
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't get org list: %w", err)
|
||||
}
|
||||
orgIDs := make([]int64, 0, len(orgQuery.Result))
|
||||
for _, org := range orgQuery.Result {
|
||||
orgIDs = append(orgIDs, org.Id)
|
||||
orgIDs := make([]int64, 0, len(result))
|
||||
for _, org := range result {
|
||||
orgIDs = append(orgIDs, org.ID)
|
||||
}
|
||||
return s.dashboardIndex.run(ctx, orgIDs, s.reIndexCh)
|
||||
}
|
||||
|
@ -14,79 +14,6 @@ import (
|
||||
// MainOrgName is the name of the main organization.
|
||||
const MainOrgName = "Main Org."
|
||||
|
||||
func (ss *SQLStore) SearchOrgs(ctx context.Context, query *models.SearchOrgsQuery) error {
|
||||
return ss.WithDbSession(ctx, func(dbSession *DBSession) error {
|
||||
query.Result = make([]*models.OrgDTO, 0)
|
||||
sess := dbSession.Table("org")
|
||||
if query.Query != "" {
|
||||
sess.Where("name LIKE ?", query.Query+"%")
|
||||
}
|
||||
if query.Name != "" {
|
||||
sess.Where("name=?", query.Name)
|
||||
}
|
||||
|
||||
if len(query.Ids) > 0 {
|
||||
sess.In("id", query.Ids)
|
||||
}
|
||||
|
||||
if query.Limit > 0 {
|
||||
sess.Limit(query.Limit, query.Limit*query.Page)
|
||||
}
|
||||
|
||||
sess.Cols("id", "name")
|
||||
err := sess.Find(&query.Result)
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
func (ss *SQLStore) GetOrgById(ctx context.Context, query *models.GetOrgByIdQuery) error {
|
||||
return ss.WithDbSession(ctx, func(dbSession *DBSession) error {
|
||||
var org models.Org
|
||||
exists, err := dbSession.ID(query.Id).Get(&org)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !exists {
|
||||
return models.ErrOrgNotFound
|
||||
}
|
||||
|
||||
query.Result = &org
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (ss *SQLStore) GetOrgByNameHandler(ctx context.Context, query *models.GetOrgByNameQuery) error {
|
||||
return ss.WithDbSession(ctx, func(dbSession *DBSession) error {
|
||||
var org models.Org
|
||||
exists, err := dbSession.Where("name=?", query.Name).Get(&org)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !exists {
|
||||
return models.ErrOrgNotFound
|
||||
}
|
||||
|
||||
query.Result = &org
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// GetOrgByName gets an organization by name.
|
||||
func (ss *SQLStore) GetOrgByName(name string) (*models.Org, error) {
|
||||
var org models.Org
|
||||
exists, err := ss.engine.Where("name=?", name).Get(&org)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exists {
|
||||
return nil, models.ErrOrgNotFound
|
||||
}
|
||||
|
||||
return &org, nil
|
||||
}
|
||||
|
||||
func isOrgNameTaken(name string, existingId int64, sess *DBSession) (bool, error) {
|
||||
// check if org name is taken
|
||||
var org models.Org
|
||||
|
@ -24,59 +24,6 @@ func TestIntegrationAccountDataAccess(t *testing.T) {
|
||||
t.Run("Testing Account DB Access", func(t *testing.T) {
|
||||
sqlStore := InitTestDB(t)
|
||||
|
||||
t.Run("Given we have organizations, we can query them by IDs", func(t *testing.T) {
|
||||
var err error
|
||||
var cmd *models.CreateOrgCommand
|
||||
ids := []int64{}
|
||||
|
||||
for i := 1; i < 4; i++ {
|
||||
cmd = &models.CreateOrgCommand{Name: fmt.Sprint("Org #", i)}
|
||||
err = sqlStore.CreateOrg(context.Background(), cmd)
|
||||
require.NoError(t, err)
|
||||
|
||||
ids = append(ids, cmd.Result.Id)
|
||||
}
|
||||
|
||||
query := &models.SearchOrgsQuery{Ids: ids}
|
||||
err = sqlStore.SearchOrgs(context.Background(), query)
|
||||
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, len(query.Result), 3)
|
||||
})
|
||||
|
||||
t.Run("Given we have organizations, we can limit and paginate search", func(t *testing.T) {
|
||||
sqlStore = InitTestDB(t)
|
||||
for i := 1; i < 4; i++ {
|
||||
cmd := &models.CreateOrgCommand{Name: fmt.Sprint("Org #", i)}
|
||||
err := sqlStore.CreateOrg(context.Background(), cmd)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
t.Run("Should be able to search with defaults", func(t *testing.T) {
|
||||
query := &models.SearchOrgsQuery{}
|
||||
err := sqlStore.SearchOrgs(context.Background(), query)
|
||||
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, len(query.Result), 3)
|
||||
})
|
||||
|
||||
t.Run("Should be able to limit search", func(t *testing.T) {
|
||||
query := &models.SearchOrgsQuery{Limit: 1}
|
||||
err := sqlStore.SearchOrgs(context.Background(), query)
|
||||
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, len(query.Result), 1)
|
||||
})
|
||||
|
||||
t.Run("Should be able to limit and paginate search", func(t *testing.T) {
|
||||
query := &models.SearchOrgsQuery{Limit: 2, Page: 1}
|
||||
err := sqlStore.SearchOrgs(context.Background(), query)
|
||||
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, len(query.Result), 1)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("Given single org mode", func(t *testing.T) {
|
||||
sqlStore.Cfg.AutoAssignOrg = true
|
||||
sqlStore.Cfg.AutoAssignOrgId = 1
|
||||
|
@ -80,39 +80,27 @@ func populateDB(t *testing.T, sqlStore *SQLStore) {
|
||||
users[i] = *user
|
||||
}
|
||||
|
||||
// get 1st user's organisation
|
||||
getOrgByIdQuery := &models.GetOrgByIdQuery{Id: users[0].OrgID}
|
||||
err := sqlStore.GetOrgById(context.Background(), getOrgByIdQuery)
|
||||
require.NoError(t, err)
|
||||
orga := getOrgByIdQuery.Result
|
||||
|
||||
// add 2nd user as editor
|
||||
cmd := &models.AddOrgUserCommand{
|
||||
OrgId: orga.Id,
|
||||
OrgId: users[0].OrgID,
|
||||
UserId: users[1].ID,
|
||||
Role: org.RoleEditor,
|
||||
}
|
||||
err = sqlStore.AddOrgUser(context.Background(), cmd)
|
||||
err := sqlStore.AddOrgUser(context.Background(), cmd)
|
||||
require.NoError(t, err)
|
||||
|
||||
// add 3rd user as viewer
|
||||
cmd = &models.AddOrgUserCommand{
|
||||
OrgId: orga.Id,
|
||||
OrgId: users[0].OrgID,
|
||||
UserId: users[2].ID,
|
||||
Role: org.RoleViewer,
|
||||
}
|
||||
err = sqlStore.AddOrgUser(context.Background(), cmd)
|
||||
require.NoError(t, err)
|
||||
|
||||
// get 2nd user's organisation
|
||||
getOrgByIdQuery = &models.GetOrgByIdQuery{Id: users[1].OrgID}
|
||||
err = sqlStore.GetOrgById(context.Background(), getOrgByIdQuery)
|
||||
require.NoError(t, err)
|
||||
orga = getOrgByIdQuery.Result
|
||||
|
||||
// add 1st user as admin
|
||||
cmd = &models.AddOrgUserCommand{
|
||||
OrgId: orga.Id,
|
||||
OrgId: users[1].OrgID,
|
||||
UserId: users[0].ID,
|
||||
Role: org.RoleAdmin,
|
||||
}
|
||||
|
@ -18,9 +18,6 @@ type Store interface {
|
||||
GetDialect() migrator.Dialect
|
||||
GetDBType() core.DbType
|
||||
GetSystemStats(ctx context.Context, query *models.GetSystemStatsQuery) error
|
||||
GetOrgByName(name string) (*models.Org, error)
|
||||
GetOrgById(context.Context, *models.GetOrgByIdQuery) error
|
||||
GetOrgByNameHandler(ctx context.Context, query *models.GetOrgByNameQuery) error
|
||||
CreateUser(ctx context.Context, cmd user.CreateUserCommand) (*user.User, error)
|
||||
GetUserProfile(ctx context.Context, query *models.GetUserProfileQuery) error
|
||||
GetSignedInUser(ctx context.Context, query *models.GetSignedInUserQuery) error
|
||||
@ -40,6 +37,5 @@ type Store interface {
|
||||
Reset() error
|
||||
Quote(value string) string
|
||||
GetDBHealthQuery(ctx context.Context, query *models.GetDBHealthQuery) error
|
||||
SearchOrgs(ctx context.Context, query *models.SearchOrgsQuery) error
|
||||
GetSqlxSession() *session.SessionDB
|
||||
}
|
||||
|
@ -82,13 +82,9 @@ func SetUpDatabase(t *testing.T, grafDir string) *sqlstore.SQLStore {
|
||||
sqlStore := sqlstore.InitTestDB(t, sqlstore.InitTestDBOpt{
|
||||
EnsureDefaultOrgAndUser: true,
|
||||
})
|
||||
// We need the main org, since it's used for anonymous access
|
||||
org, err := sqlStore.GetOrgByName(sqlstore.MainOrgName)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, org)
|
||||
|
||||
// Make sure changes are synced with other goroutines
|
||||
err = sqlStore.Sync()
|
||||
err := sqlStore.Sync()
|
||||
require.NoError(t, err)
|
||||
|
||||
return sqlStore
|
||||
|
Loading…
Reference in New Issue
Block a user