PluginManager: Make remaining plugin state non-global (#32094)

* PluginDashboards: Use plugin manager interface

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* PluginManager: Make panels non-global

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* PluginManager: Make apps non-global

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* PluginManager: Make static routes non-global

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* PluginManager: Make pluginTypes non-global

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
This commit is contained in:
Arve Knudsen
2021-03-18 13:53:01 +01:00
committed by GitHub
parent 1454c3723d
commit a2eda798e7
22 changed files with 293 additions and 233 deletions

View File

@@ -8,7 +8,7 @@ import (
"strings"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/plugins/manager"
"github.com/grafana/grafana/pkg/plugins"
"gopkg.in/yaml.v2"
)
@@ -17,11 +17,12 @@ type configReader interface {
}
type configReaderImpl struct {
log log.Logger
log log.Logger
pluginManager plugins.Manager
}
func newConfigReader(logger log.Logger) configReader {
return &configReaderImpl{log: logger}
func newConfigReader(logger log.Logger, pluginManager plugins.Manager) configReader {
return &configReaderImpl{log: logger, pluginManager: pluginManager}
}
func (cr *configReaderImpl) readConfig(path string) ([]*pluginsAsConfig, error) {
@@ -112,8 +113,8 @@ func (cr *configReaderImpl) validatePluginsConfig(apps []*pluginsAsConfig) error
}
for _, app := range apps[i].Apps {
if !manager.IsAppInstalled(app.PluginID) {
return fmt.Errorf("app plugin not installed: %s", app.PluginID)
if !cr.pluginManager.IsAppInstalled(app.PluginID) {
return fmt.Errorf("app plugin not installed: %q", app.PluginID)
}
}
}

View File

@@ -6,7 +6,6 @@ import (
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/plugins/manager"
"github.com/stretchr/testify/require"
)
@@ -20,36 +19,38 @@ const (
func TestConfigReader(t *testing.T) {
t.Run("Broken yaml should return error", func(t *testing.T) {
reader := newConfigReader(log.New("test logger"))
reader := newConfigReader(log.New("test logger"), nil)
_, err := reader.readConfig(brokenYaml)
require.Error(t, err)
})
t.Run("Skip invalid directory", func(t *testing.T) {
cfgProvider := newConfigReader(log.New("test logger"))
cfgProvider := newConfigReader(log.New("test logger"), nil)
cfg, err := cfgProvider.readConfig(emptyFolder)
require.NoError(t, err)
require.Len(t, cfg, 0)
})
t.Run("Unknown app plugin should return error", func(t *testing.T) {
cfgProvider := newConfigReader(log.New("test logger"))
cfgProvider := newConfigReader(log.New("test logger"), fakePluginManager{})
_, err := cfgProvider.readConfig(unknownApp)
require.Error(t, err)
require.Equal(t, "app plugin not installed: nonexisting", err.Error())
require.Equal(t, "app plugin not installed: \"nonexisting\"", err.Error())
})
t.Run("Read incorrect properties", func(t *testing.T) {
cfgProvider := newConfigReader(log.New("test logger"))
cfgProvider := newConfigReader(log.New("test logger"), nil)
_, err := cfgProvider.readConfig(incorrectSettings)
require.Error(t, err)
require.Equal(t, "app item 1 in configuration doesn't contain required field type", err.Error())
})
t.Run("Can read correct properties", func(t *testing.T) {
manager.Apps = map[string]*plugins.AppPlugin{
"test-plugin": {},
"test-plugin-2": {},
pm := fakePluginManager{
apps: map[string]*plugins.AppPlugin{
"test-plugin": {},
"test-plugin-2": {},
},
}
err := os.Setenv("ENABLE_PLUGIN_VAR", "test-plugin")
@@ -58,7 +59,7 @@ func TestConfigReader(t *testing.T) {
_ = os.Unsetenv("ENABLE_PLUGIN_VAR")
})
cfgProvider := newConfigReader(log.New("test logger"))
cfgProvider := newConfigReader(log.New("test logger"), pm)
cfg, err := cfgProvider.readConfig(correctProperties)
require.NoError(t, err)
require.Len(t, cfg, 1)
@@ -85,3 +86,14 @@ func TestConfigReader(t *testing.T) {
}
})
}
type fakePluginManager struct {
plugins.Manager
apps map[string]*plugins.AppPlugin
}
func (pm fakePluginManager) IsAppInstalled(id string) bool {
_, exists := pm.apps[id]
return exists
}

View File

@@ -6,12 +6,17 @@ import (
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/plugins"
)
// Provision scans a directory for provisioning config files
// and provisions the app in those files.
func Provision(configDirectory string) error {
ap := newAppProvisioner(log.New("provisioning.plugins"))
func Provision(configDirectory string, pluginManager plugins.Manager) error {
logger := log.New("provisioning.plugins")
ap := PluginProvisioner{
log: logger,
cfgProvider: newConfigReader(logger, pluginManager),
}
return ap.applyChanges(configDirectory)
}
@@ -22,13 +27,6 @@ type PluginProvisioner struct {
cfgProvider configReader
}
func newAppProvisioner(log log.Logger) PluginProvisioner {
return PluginProvisioner{
log: log,
cfgProvider: newConfigReader(log),
}
}
func (ap *PluginProvisioner) apply(cfg *pluginsAsConfig) error {
for _, app := range cfg.Apps {
if app.OrgID == 0 && app.OrgName != "" {

View File

@@ -43,7 +43,7 @@ func newProvisioningServiceImpl(
newDashboardProvisioner dashboards.DashboardProvisionerFactory,
provisionNotifiers func(string) error,
provisionDatasources func(string) error,
provisionPlugins func(string) error,
provisionPlugins func(string, plugifaces.Manager) error,
) *provisioningServiceImpl {
return &provisioningServiceImpl{
log: log.New("provisioning"),
@@ -58,13 +58,14 @@ type provisioningServiceImpl struct {
Cfg *setting.Cfg `inject:""`
RequestHandler plugifaces.DataRequestHandler `inject:""`
SQLStore *sqlstore.SQLStore `inject:""`
PluginManager plugifaces.Manager `inject:""`
log log.Logger
pollingCtxCancel context.CancelFunc
newDashboardProvisioner dashboards.DashboardProvisionerFactory
dashboardProvisioner dashboards.DashboardProvisioner
provisionNotifiers func(string) error
provisionDatasources func(string) error
provisionPlugins func(string) error
provisionPlugins func(string, plugifaces.Manager) error
mutex sync.Mutex
}
@@ -124,7 +125,7 @@ func (ps *provisioningServiceImpl) ProvisionDatasources() error {
func (ps *provisioningServiceImpl) ProvisionPlugins() error {
appPath := filepath.Join(ps.Cfg.ProvisioningPath, "plugins")
err := ps.provisionPlugins(appPath)
err := ps.provisionPlugins(appPath, ps.PluginManager)
return errutil.Wrap("app provisioning error", err)
}