Chore: Add context to org (#40685)

* Add context to org

* Rebase

* Fix rebase
This commit is contained in:
idafurjes
2021-11-03 11:31:56 +01:00
committed by GitHub
parent 91da1bbb79
commit 47f6bb3583
24 changed files with 120 additions and 112 deletions
@@ -1,6 +1,7 @@
package dashboards
import (
"context"
"fmt"
"io/ioutil"
"os"
@@ -62,7 +63,7 @@ func (cr *configReader) parseConfigs(file os.FileInfo) ([]*config, error) {
return []*config{}, nil
}
func (cr *configReader) readConfig() ([]*config, error) {
func (cr *configReader) readConfig(ctx context.Context) ([]*config, error) {
var dashboards []*config
files, err := ioutil.ReadDir(cr.path)
@@ -92,7 +93,7 @@ func (cr *configReader) readConfig() ([]*config, error) {
dashboard.OrgID = 1
}
if err := utils.CheckOrgExists(dashboard.OrgID); err != nil {
if err := utils.CheckOrgExists(ctx, dashboard.OrgID); err != nil {
return nil, fmt.Errorf("failed to provision dashboards with %q reader: %w", dashboard.Name, err)
}
@@ -1,6 +1,7 @@
package dashboards
import (
"context"
"errors"
"fmt"
"os"
@@ -28,20 +29,20 @@ func TestDashboardsAsConfig(t *testing.T) {
t.Run("Should fail if orgs don't exist in the database", func(t *testing.T) {
cfgProvider := configReader{path: appliedDefaults, log: logger}
_, err := cfgProvider.readConfig()
_, err := cfgProvider.readConfig(context.Background())
require.Error(t, err)
assert.True(t, errors.Is(err, models.ErrOrgNotFound))
})
for i := 1; i <= 2; i++ {
orgCommand := models.CreateOrgCommand{Name: fmt.Sprintf("Main Org. %v", i)}
err := sqlstore.CreateOrg(&orgCommand)
err := sqlstore.CreateOrg(context.Background(), &orgCommand)
require.NoError(t, err)
}
t.Run("default values should be applied", func(t *testing.T) {
cfgProvider := configReader{path: appliedDefaults, log: logger}
cfg, err := cfgProvider.readConfig()
cfg, err := cfgProvider.readConfig(context.Background())
require.NoError(t, err)
require.Equal(t, "file", cfg[0].Type)
@@ -52,7 +53,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}
cfg, err := cfgProvider.readConfig()
cfg, err := cfgProvider.readConfig(context.Background())
_ = os.Unsetenv("TEST_VAR")
require.NoError(t, err)
@@ -61,7 +62,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}
cfg, err := cfgProvider.readConfig()
cfg, err := cfgProvider.readConfig(context.Background())
require.NoError(t, err)
validateDashboardAsConfig(t, cfg)
@@ -69,7 +70,7 @@ func TestDashboardsAsConfig(t *testing.T) {
t.Run("Should skip invalid path", func(t *testing.T) {
cfgProvider := configReader{path: "/invalid-directory", log: logger}
cfg, err := cfgProvider.readConfig()
cfg, err := cfgProvider.readConfig(context.Background())
if err != nil {
t.Fatalf("readConfig return an error %v", err)
}
@@ -79,7 +80,7 @@ func TestDashboardsAsConfig(t *testing.T) {
t.Run("Should skip broken config files", func(t *testing.T) {
cfgProvider := configReader{path: brokenConfigs, log: logger}
cfg, err := cfgProvider.readConfig()
cfg, err := cfgProvider.readConfig(context.Background())
if err != nil {
t.Fatalf("readConfig return an error %v", err)
}
@@ -23,7 +23,7 @@ type DashboardProvisioner interface {
}
// DashboardProvisionerFactory creates DashboardProvisioners based on input
type DashboardProvisionerFactory func(string, dashboards.Store) (DashboardProvisioner, error)
type DashboardProvisionerFactory func(context.Context, string, dashboards.Store) (DashboardProvisioner, error)
// Provisioner is responsible for syncing dashboard from disk to Grafana's database.
type Provisioner struct {
@@ -34,10 +34,10 @@ type Provisioner struct {
}
// New returns a new DashboardProvisioner
func New(configDirectory string, store dashboards.Store) (DashboardProvisioner, error) {
func New(ctx context.Context, configDirectory string, store dashboards.Store) (DashboardProvisioner, error) {
logger := log.New("provisioning.dashboard")
cfgReader := &configReader{path: configDirectory, log: logger}
configs, err := cfgReader.readConfig()
configs, err := cfgReader.readConfig(ctx)
if err != nil {
return nil, errutil.Wrap("Failed to read dashboards config", err)
}
@@ -1,6 +1,7 @@
package datasources
import (
"context"
"fmt"
"io/ioutil"
"os"
@@ -17,7 +18,7 @@ type configReader struct {
log log.Logger
}
func (cr *configReader) readConfig(path string) ([]*configs, error) {
func (cr *configReader) readConfig(ctx context.Context, path string) ([]*configs, error) {
var datasources []*configs
files, err := ioutil.ReadDir(path)
@@ -39,7 +40,7 @@ func (cr *configReader) readConfig(path string) ([]*configs, error) {
}
}
err = cr.validateDefaultUniqueness(datasources)
err = cr.validateDefaultUniqueness(ctx, datasources)
if err != nil {
return nil, err
}
@@ -88,7 +89,7 @@ func (cr *configReader) parseDatasourceConfig(path string, file os.FileInfo) (*c
return v0.mapToDatasourceFromConfig(apiVersion.APIVersion), nil
}
func (cr *configReader) validateDefaultUniqueness(datasources []*configs) error {
func (cr *configReader) validateDefaultUniqueness(ctx context.Context, datasources []*configs) error {
defaultCount := map[int64]int{}
for i := range datasources {
if datasources[i].Datasources == nil {
@@ -100,7 +101,7 @@ func (cr *configReader) validateDefaultUniqueness(datasources []*configs) error
ds.OrgID = 1
}
if err := cr.validateAccessAndOrgID(ds); err != nil {
if err := cr.validateAccessAndOrgID(ctx, ds); err != nil {
return fmt.Errorf("failed to provision %q data source: %w", ds.Name, err)
}
@@ -122,8 +123,8 @@ func (cr *configReader) validateDefaultUniqueness(datasources []*configs) error
return nil
}
func (cr *configReader) validateAccessAndOrgID(ds *upsertDataSourceFromConfig) error {
if err := utils.CheckOrgExists(ds.OrgID); err != nil {
func (cr *configReader) validateAccessAndOrgID(ctx context.Context, ds *upsertDataSourceFromConfig) error {
if err := utils.CheckOrgExists(ctx, ds.OrgID); err != nil {
return err
}
@@ -151,20 +151,20 @@ func TestDatasourceAsConfig(t *testing.T) {
t.Run("broken yaml should return error", func(t *testing.T) {
reader := &configReader{}
_, err := reader.readConfig(brokenYaml)
_, err := reader.readConfig(context.Background(), brokenYaml)
require.NotNil(t, err)
})
t.Run("invalid access should warn about invalid value and return 'proxy'", func(t *testing.T) {
reader := &configReader{log: logger}
configs, err := reader.readConfig(invalidAccess)
configs, err := reader.readConfig(context.Background(), invalidAccess)
require.NoError(t, err)
require.Equal(t, configs[0].Datasources[0].Access, models.DS_ACCESS_PROXY)
})
t.Run("skip invalid directory", func(t *testing.T) {
cfgProvider := &configReader{log: log.New("test logger")}
cfg, err := cfgProvider.readConfig("./invalid-directory")
cfg, err := cfgProvider.readConfig(context.Background(), "./invalid-directory")
if err != nil {
t.Fatalf("readConfig return an error %v", err)
}
@@ -175,7 +175,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")}
cfg, err := cfgProvider.readConfig(allProperties)
cfg, err := cfgProvider.readConfig(context.Background(), allProperties)
_ = os.Unsetenv("TEST_VAR")
if err != nil {
t.Fatalf("readConfig return an error %v", err)
@@ -204,7 +204,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")}
cfg, err := cfgProvider.readConfig(versionZero)
cfg, err := cfgProvider.readConfig(context.Background(), versionZero)
if err != nil {
t.Fatalf("readConfig return an error %v", err)
}
@@ -69,7 +69,7 @@ func (dc *DatasourceProvisioner) apply(ctx context.Context, cfg *configs) error
}
func (dc *DatasourceProvisioner) applyChanges(ctx context.Context, configPath string) error {
configs, err := dc.cfgProvider.readConfig(configPath)
configs, err := dc.cfgProvider.readConfig(ctx, configPath)
if err != nil {
return err
}
@@ -5,12 +5,13 @@ import (
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/encryption"
"golang.org/x/net/context"
)
// Provision alert notifiers
func Provision(configDirectory string, encryptionService encryption.Service) error {
func Provision(ctx context.Context, configDirectory string, encryptionService encryption.Service) error {
dc := newNotificationProvisioner(encryptionService, log.New("provisioning.notifiers"))
return dc.applyChanges(configDirectory)
return dc.applyChanges(ctx, configDirectory)
}
// NotificationProvisioner is responsible for provsioning alert notifiers
@@ -132,8 +133,8 @@ func (dc *NotificationProvisioner) mergeNotifications(notificationToMerge []*not
return nil
}
func (dc *NotificationProvisioner) applyChanges(configPath string) error {
configs, err := dc.cfgProvider.readConfig(configPath)
func (dc *NotificationProvisioner) applyChanges(ctx context.Context, configPath string) error {
configs, err := dc.cfgProvider.readConfig(ctx, configPath)
if err != nil {
return err
}
@@ -22,7 +22,7 @@ type configReader struct {
log log.Logger
}
func (cr *configReader) readConfig(path string) ([]*notificationsAsConfig, error) {
func (cr *configReader) readConfig(ctx context.Context, path string) ([]*notificationsAsConfig, error) {
var notifications []*notificationsAsConfig
cr.log.Debug("Looking for alert notification provisioning files", "path", path)
@@ -51,7 +51,7 @@ func (cr *configReader) readConfig(path string) ([]*notificationsAsConfig, error
return nil, err
}
if err := cr.checkOrgIDAndOrgName(notifications); err != nil {
if err := cr.checkOrgIDAndOrgName(ctx, notifications); err != nil {
return nil, err
}
@@ -81,7 +81,7 @@ func (cr *configReader) parseNotificationConfig(path string, file os.FileInfo) (
return cfg.mapToNotificationFromConfig(), nil
}
func (cr *configReader) checkOrgIDAndOrgName(notifications []*notificationsAsConfig) error {
func (cr *configReader) checkOrgIDAndOrgName(ctx context.Context, notifications []*notificationsAsConfig) error {
for i := range notifications {
for _, notification := range notifications[i].Notifications {
if notification.OrgID < 1 {
@@ -91,7 +91,7 @@ func (cr *configReader) checkOrgIDAndOrgName(notifications []*notificationsAsCon
notification.OrgID = 0
}
} else {
if err := utils.CheckOrgExists(notification.OrgID); err != nil {
if err := utils.CheckOrgExists(ctx, notification.OrgID); err != nil {
return fmt.Errorf("failed to provision %q notification: %w", notification.Name, err)
}
}
@@ -1,6 +1,7 @@
package notifiers
import (
"context"
"fmt"
"os"
"testing"
@@ -40,7 +41,7 @@ func TestNotificationAsConfig(t *testing.T) {
for i := 1; i < 5; i++ {
orgCommand := models.CreateOrgCommand{Name: fmt.Sprintf("Main Org. %v", i)}
err := sqlstore.CreateOrg(&orgCommand)
err := sqlstore.CreateOrg(context.Background(), &orgCommand)
require.NoError(t, err)
}
@@ -65,7 +66,7 @@ func TestNotificationAsConfig(t *testing.T) {
log: log.New("test logger"),
}
cfg, err := cfgProvider.readConfig(correctProperties)
cfg, err := cfgProvider.readConfig(context.Background(), correctProperties)
_ = os.Unsetenv("TEST_VAR")
if err != nil {
t.Fatalf("readConfig return an error %v", err)
@@ -140,7 +141,7 @@ func TestNotificationAsConfig(t *testing.T) {
setup()
dc := newNotificationProvisioner(ossencryption.ProvideService(), logger)
err := dc.applyChanges(twoNotificationsConfig)
err := dc.applyChanges(context.Background(), twoNotificationsConfig)
if err != nil {
t.Fatalf("applyChanges return an error %v", err)
}
@@ -170,7 +171,7 @@ func TestNotificationAsConfig(t *testing.T) {
t.Run("should update one notification", func(t *testing.T) {
dc := newNotificationProvisioner(ossencryption.ProvideService(), logger)
err = dc.applyChanges(twoNotificationsConfig)
err = dc.applyChanges(context.Background(), twoNotificationsConfig)
if err != nil {
t.Fatalf("applyChanges return an error %v", err)
}
@@ -194,7 +195,7 @@ func TestNotificationAsConfig(t *testing.T) {
t.Run("Two notifications with is_default", func(t *testing.T) {
setup()
dc := newNotificationProvisioner(ossencryption.ProvideService(), logger)
err := dc.applyChanges(doubleNotificationsConfig)
err := dc.applyChanges(context.Background(), doubleNotificationsConfig)
t.Run("should both be inserted", func(t *testing.T) {
require.NoError(t, err)
notificationsQuery := models.GetAllAlertNotificationsQuery{OrgId: 1}
@@ -237,7 +238,7 @@ func TestNotificationAsConfig(t *testing.T) {
t.Run("should have two new notifications", func(t *testing.T) {
dc := newNotificationProvisioner(ossencryption.ProvideService(), logger)
err := dc.applyChanges(twoNotificationsConfig)
err := dc.applyChanges(context.Background(), twoNotificationsConfig)
if err != nil {
t.Fatalf("applyChanges return an error %v", err)
}
@@ -253,11 +254,11 @@ 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.GetOrgByName(&existingOrg1)
err := sqlstore.GetOrgByName(context.Background(), &existingOrg1)
require.NoError(t, err)
require.NotNil(t, existingOrg1.Result)
existingOrg2 := models.GetOrgByNameQuery{Name: "Main Org. 2"}
err = sqlstore.GetOrgByName(&existingOrg2)
err = sqlstore.GetOrgByName(context.Background(), &existingOrg2)
require.NoError(t, err)
require.NotNil(t, existingOrg2.Result)
@@ -271,7 +272,7 @@ func TestNotificationAsConfig(t *testing.T) {
require.NoError(t, err)
dc := newNotificationProvisioner(ossencryption.ProvideService(), logger)
err = dc.applyChanges(correctPropertiesWithOrgName)
err = dc.applyChanges(context.Background(), correctPropertiesWithOrgName)
if err != nil {
t.Fatalf("applyChanges return an error %v", err)
}
@@ -290,7 +291,7 @@ func TestNotificationAsConfig(t *testing.T) {
t.Run("Config doesn't contain required field", func(t *testing.T) {
setup()
dc := newNotificationProvisioner(ossencryption.ProvideService(), logger)
err := dc.applyChanges(noRequiredFields)
err := dc.applyChanges(context.Background(), noRequiredFields)
require.NotNil(t, err)
errString := err.Error()
@@ -304,7 +305,7 @@ func TestNotificationAsConfig(t *testing.T) {
t.Run("should have not changed repo", func(t *testing.T) {
setup()
dc := newNotificationProvisioner(ossencryption.ProvideService(), logger)
err := dc.applyChanges(emptyFile)
err := dc.applyChanges(context.Background(), emptyFile)
if err != nil {
t.Fatalf("applyChanges return an error %v", err)
}
@@ -321,7 +322,7 @@ func TestNotificationAsConfig(t *testing.T) {
log: log.New("test logger"),
}
_, err := reader.readConfig(brokenYaml)
_, err := reader.readConfig(context.Background(), brokenYaml)
require.NotNil(t, err)
})
@@ -331,7 +332,7 @@ func TestNotificationAsConfig(t *testing.T) {
log: log.New("test logger"),
}
cfg, err := cfgProvider.readConfig(emptyFolder)
cfg, err := cfgProvider.readConfig(context.Background(), emptyFolder)
if err != nil {
t.Fatalf("readConfig return an error %v", err)
}
@@ -343,7 +344,7 @@ func TestNotificationAsConfig(t *testing.T) {
encryptionService: ossencryption.ProvideService(),
log: log.New("test logger"),
}
_, err := cfgProvider.readConfig(unknownNotifier)
_, err := cfgProvider.readConfig(context.Background(), unknownNotifier)
require.NotNil(t, err)
require.Equal(t, err.Error(), `unsupported notification type "nonexisting"`)
})
@@ -353,7 +354,7 @@ func TestNotificationAsConfig(t *testing.T) {
encryptionService: ossencryption.ProvideService(),
log: log.New("test logger"),
}
_, err := cfgProvider.readConfig(incorrectSettings)
_, err := cfgProvider.readConfig(context.Background(), incorrectSettings)
require.NotNil(t, err)
require.Equal(t, err.Error(), "alert validation error: token must be specified when using the Slack chat API")
})
@@ -362,7 +363,7 @@ func TestNotificationAsConfig(t *testing.T) {
func setupBusHandlers(sqlStore *sqlstore.SQLStore) {
bus.AddHandler("getOrg", func(q *models.GetOrgByNameQuery) error {
return sqlstore.GetOrgByName(q)
return sqlstore.GetOrgByName(context.Background(), q)
})
bus.AddHandler("getAlertNotifications", func(q *models.GetAlertNotificationsWithUidQuery) error {
+7 -7
View File
@@ -39,7 +39,7 @@ type ProvisioningService interface {
RunInitProvisioners(ctx context.Context) error
ProvisionDatasources(ctx context.Context) error
ProvisionPlugins() error
ProvisionNotifications() error
ProvisionNotifications(ctx context.Context) error
ProvisionDashboards(ctx context.Context) error
GetDashboardProvisionerResolvedPath(name string) string
GetAllowUIUpdatesFromConfig(name string) bool
@@ -59,7 +59,7 @@ func NewProvisioningServiceImpl() *ProvisioningServiceImpl {
// Used for testing purposes
func newProvisioningServiceImpl(
newDashboardProvisioner dashboards.DashboardProvisionerFactory,
provisionNotifiers func(string, encryption.Service) error,
provisionNotifiers func(context.Context, string, encryption.Service) error,
provisionDatasources func(context.Context, string) error,
provisionPlugins func(string, plugifaces.Store) error,
) *ProvisioningServiceImpl {
@@ -81,7 +81,7 @@ type ProvisioningServiceImpl struct {
pollingCtxCancel context.CancelFunc
newDashboardProvisioner dashboards.DashboardProvisionerFactory
dashboardProvisioner dashboards.DashboardProvisioner
provisionNotifiers func(string, encryption.Service) error
provisionNotifiers func(context.Context, string, encryption.Service) error
provisionDatasources func(context.Context, string) error
provisionPlugins func(string, plugifaces.Store) error
mutex sync.Mutex
@@ -98,7 +98,7 @@ func (ps *ProvisioningServiceImpl) RunInitProvisioners(ctx context.Context) erro
return err
}
err = ps.ProvisionNotifications()
err = ps.ProvisionNotifications(ctx)
if err != nil {
return err
}
@@ -147,15 +147,15 @@ func (ps *ProvisioningServiceImpl) ProvisionPlugins() error {
return errutil.Wrap("app provisioning error", err)
}
func (ps *ProvisioningServiceImpl) ProvisionNotifications() error {
func (ps *ProvisioningServiceImpl) ProvisionNotifications(ctx context.Context) error {
alertNotificationsPath := filepath.Join(ps.Cfg.ProvisioningPath, "notifiers")
err := ps.provisionNotifiers(alertNotificationsPath, ps.EncryptionService)
err := ps.provisionNotifiers(ctx, alertNotificationsPath, ps.EncryptionService)
return errutil.Wrap("Alert notification provisioning error", err)
}
func (ps *ProvisioningServiceImpl) ProvisionDashboards(ctx context.Context) error {
dashboardPath := filepath.Join(ps.Cfg.ProvisioningPath, "dashboards")
dashProvisioner, err := ps.newDashboardProvisioner(dashboardPath, ps.SQLStore)
dashProvisioner, err := ps.newDashboardProvisioner(ctx, dashboardPath, ps.SQLStore)
if err != nil {
return errutil.Wrap("Failed to create provisioner", err)
}
@@ -25,7 +25,7 @@ type ProvisioningServiceMock struct {
RunFunc func(ctx context.Context) error
}
func NewProvisioningServiceMock() *ProvisioningServiceMock {
func NewProvisioningServiceMock(ctx context.Context) *ProvisioningServiceMock {
return &ProvisioningServiceMock{
Calls: &Calls{},
}
@@ -55,7 +55,7 @@ func (mock *ProvisioningServiceMock) ProvisionPlugins() error {
return nil
}
func (mock *ProvisioningServiceMock) ProvisionNotifications() error {
func (mock *ProvisioningServiceMock) ProvisionNotifications(ctx context.Context) error {
mock.Calls.ProvisionNotifications = append(mock.Calls.ProvisionNotifications, nil)
if mock.ProvisionNotificationsFunc != nil {
return mock.ProvisionNotificationsFunc()
@@ -92,7 +92,7 @@ func setup() *serviceTestStruct {
}
serviceTest.service = newProvisioningServiceImpl(
func(string, dboards.Store) (dashboards.DashboardProvisioner, error) {
func(context.Context, string, dboards.Store) (dashboards.DashboardProvisioner, error) {
return serviceTest.mock, nil
},
nil,
+3 -2
View File
@@ -1,6 +1,7 @@
package utils
import (
"context"
"errors"
"fmt"
@@ -8,9 +9,9 @@ import (
"github.com/grafana/grafana/pkg/models"
)
func CheckOrgExists(orgID int64) error {
func CheckOrgExists(ctx context.Context, orgID int64) error {
query := models.GetOrgByIdQuery{Id: orgID}
if err := bus.Dispatch(&query); err != nil {
if err := bus.DispatchCtx(ctx, &query); err != nil {
if errors.Is(err, models.ErrOrgNotFound) {
return err
}
@@ -1,6 +1,7 @@
package utils
import (
"context"
"testing"
"github.com/grafana/grafana/pkg/models"
@@ -14,16 +15,16 @@ func TestCheckOrgExists(t *testing.T) {
sqlstore.InitTestDB(t)
defaultOrg := models.CreateOrgCommand{Name: "Main Org."}
err := sqlstore.CreateOrg(&defaultOrg)
err := sqlstore.CreateOrg(context.Background(), &defaultOrg)
require.NoError(t, err)
t.Run("default org exists", func(t *testing.T) {
err := CheckOrgExists(defaultOrg.Result.Id)
err := CheckOrgExists(context.Background(), defaultOrg.Result.Id)
require.NoError(t, err)
})
t.Run("other org doesn't exist", func(t *testing.T) {
err := CheckOrgExists(defaultOrg.Result.Id + 1)
err := CheckOrgExists(context.Background(), defaultOrg.Result.Id+1)
require.Equal(t, err, models.ErrOrgNotFound)
})
})