Plugins: Create single point of entry for adding / removing plugins (#55463)

* split out plugin manager

* remove whitespace

* fix tests

* split up tests

* updating naming conventions

* simplify manager

* tidy

* explorations

* fix build

* tidy

* fix tests

* add logger helper

* pass the tests

* tidying

* fix tests

* tidy and re-add test

* store depends on loader

* enrich tests

* fix test

* undo gomod changes
This commit is contained in:
Will Browne
2022-09-23 14:27:01 +02:00
committed by GitHub
parent 003a1cdaa0
commit d0d8544ded
21 changed files with 785 additions and 622 deletions
+8 -4
View File
@@ -9,8 +9,8 @@ import (
"github.com/grafana/grafana/pkg/services/pluginsettings"
)
type fakePluginManager struct {
plugins.Manager
type fakePluginInstaller struct {
plugins.Installer
plugins map[string]fakePlugin
}
@@ -20,7 +20,11 @@ type fakePlugin struct {
version string
}
func (pm *fakePluginManager) Add(_ context.Context, pluginID, version string, _ plugins.CompatOpts) error {
func NewFakePluginInstaller() *fakePluginInstaller {
return &fakePluginInstaller{plugins: map[string]fakePlugin{}}
}
func (pm *fakePluginInstaller) Add(_ context.Context, pluginID, version string, _ plugins.CompatOpts) error {
pm.plugins[pluginID] = fakePlugin{
pluginID: pluginID,
version: version,
@@ -28,7 +32,7 @@ func (pm *fakePluginManager) Add(_ context.Context, pluginID, version string, _
return nil
}
func (pm *fakePluginManager) Remove(_ context.Context, pluginID string) error {
func (pm *fakePluginInstaller) Remove(_ context.Context, pluginID string) error {
delete(pm.plugins, pluginID)
return nil
}
+3 -3
View File
@@ -127,7 +127,7 @@ type HTTPServer struct {
PluginRequestValidator models.PluginRequestValidator
pluginClient plugins.Client
pluginStore plugins.Store
pluginManager plugins.Manager
pluginInstaller plugins.Installer
pluginDashboardService plugindashboards.Service
pluginStaticRouteResolver plugins.StaticRouteResolver
pluginErrorResolver plugins.ErrorResolver
@@ -210,7 +210,7 @@ func ProvideHTTPServer(opts ServerOptions, cfg *setting.Cfg, routeRegister routi
cacheService *localcache.CacheService, sqlStore *sqlstore.SQLStore, alertEngine *alerting.AlertEngine,
pluginRequestValidator models.PluginRequestValidator, pluginStaticRouteResolver plugins.StaticRouteResolver,
pluginDashboardService plugindashboards.Service, pluginStore plugins.Store, pluginClient plugins.Client,
pluginErrorResolver plugins.ErrorResolver, pluginManager plugins.Manager, settingsProvider setting.Provider,
pluginErrorResolver plugins.ErrorResolver, pluginInstaller plugins.Installer, settingsProvider setting.Provider,
dataSourceCache datasources.CacheService, userTokenService models.UserTokenService,
cleanUpService *cleanup.CleanUpService, shortURLService shorturls.Service, queryHistoryService queryhistory.Service, correlationsService correlations.Service,
thumbService thumbs.Service, remoteCache *remotecache.RemoteCache, provisioningService provisioning.ProvisioningService,
@@ -255,7 +255,7 @@ func ProvideHTTPServer(opts ServerOptions, cfg *setting.Cfg, routeRegister routi
SQLStore: sqlStore,
AlertEngine: alertEngine,
PluginRequestValidator: pluginRequestValidator,
pluginManager: pluginManager,
pluginInstaller: pluginInstaller,
pluginClient: pluginClient,
pluginStore: pluginStore,
pluginStaticRouteResolver: pluginStaticRouteResolver,
+2 -2
View File
@@ -413,7 +413,7 @@ func (hs *HTTPServer) InstallPlugin(c *models.ReqContext) response.Response {
}
pluginID := web.Params(c.Req)[":pluginId"]
err := hs.pluginManager.Add(c.Req.Context(), pluginID, dto.Version, plugins.CompatOpts{
err := hs.pluginInstaller.Add(c.Req.Context(), pluginID, dto.Version, plugins.CompatOpts{
GrafanaVersion: hs.Cfg.BuildVersion,
OS: runtime.GOOS,
Arch: runtime.GOARCH,
@@ -448,7 +448,7 @@ func (hs *HTTPServer) InstallPlugin(c *models.ReqContext) response.Response {
func (hs *HTTPServer) UninstallPlugin(c *models.ReqContext) response.Response {
pluginID := web.Params(c.Req)[":pluginId"]
err := hs.pluginManager.Remove(c.Req.Context(), pluginID)
err := hs.pluginInstaller.Remove(c.Req.Context(), pluginID)
if err != nil {
if errors.Is(err, plugins.ErrPluginNotInstalled) {
return response.Error(http.StatusNotFound, "Plugin not installed", err)
+5 -11
View File
@@ -51,16 +51,14 @@ func Test_PluginsInstallAndUninstall(t *testing.T) {
action, testCase.expectedHTTPStatus, testCase.pluginAdminEnabled, testCase.pluginAdminExternalManageEnabled)
}
pm := &fakePluginManager{
plugins: make(map[string]fakePlugin),
}
inst := NewFakePluginInstaller()
for _, tc := range tcs {
srv := SetupAPITestServer(t, func(hs *HTTPServer) {
hs.Cfg = &setting.Cfg{
PluginAdminEnabled: tc.pluginAdminEnabled,
PluginAdminExternalManageEnabled: tc.pluginAdminExternalManageEnabled,
}
hs.pluginManager = pm
hs.pluginInstaller = inst
hs.QuotaService = quotatest.NewQuotaServiceFake()
})
@@ -78,7 +76,7 @@ func Test_PluginsInstallAndUninstall(t *testing.T) {
require.Equal(t, tc.expectedHTTPStatus, resp.StatusCode)
if tc.expectedHTTPStatus == 200 {
require.Equal(t, fakePlugin{pluginID: "test", version: "1.0.2"}, pm.plugins["test"])
require.Equal(t, fakePlugin{pluginID: "test", version: "1.0.2"}, inst.plugins["test"])
}
})
@@ -96,7 +94,7 @@ func Test_PluginsInstallAndUninstall(t *testing.T) {
require.Equal(t, tc.expectedHTTPStatus, resp.StatusCode)
if tc.expectedHTTPStatus == 200 {
require.Empty(t, pm.plugins)
require.Empty(t, inst.plugins)
}
})
}
@@ -125,10 +123,6 @@ func Test_PluginsInstallAndUninstall_AccessControl(t *testing.T) {
action, tc.expectedCode, tc.pluginAdminEnabled, tc.pluginAdminExternalManageEnabled, tc.permissions)
}
pm := &fakePluginManager{
plugins: make(map[string]fakePlugin),
}
for _, tc := range tcs {
sc := setupHTTPServerWithCfg(t, true, &setting.Cfg{
RBACEnabled: true,
@@ -136,7 +130,7 @@ func Test_PluginsInstallAndUninstall_AccessControl(t *testing.T) {
PluginAdminExternalManageEnabled: tc.pluginAdminExternalManageEnabled})
setInitCtxSignedInViewer(sc.initCtx)
setAccessControlPermissions(sc.acmock, tc.permissions, sc.initCtx.OrgID)
sc.hs.pluginManager = pm
sc.hs.pluginInstaller = NewFakePluginInstaller()
t.Run(testName("Install", tc), func(t *testing.T) {
input := strings.NewReader("{ \"version\": \"1.0.2\" }")