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

View File

@@ -14,22 +14,45 @@ import (
"github.com/grafana/grafana/pkg/plugins/storage"
)
type FakeLoader struct {
LoadFunc func(_ context.Context, _ plugins.Class, paths []string, _ map[string]struct{}) ([]*plugins.Plugin, error)
LoadedPaths []string
type FakePluginInstaller struct {
AddFunc func(ctx context.Context, pluginID, version string, opts plugins.CompatOpts) error
// Remove removes a plugin from the store.
RemoveFunc func(ctx context.Context, pluginID string) error
}
func (l *FakeLoader) Load(ctx context.Context, class plugins.Class, paths []string, ignore map[string]struct{}) ([]*plugins.Plugin, error) {
if l.LoadFunc != nil {
return l.LoadFunc(ctx, class, paths, ignore)
func (i *FakePluginInstaller) Add(ctx context.Context, pluginID, version string, opts plugins.CompatOpts) error {
if i.AddFunc != nil {
return i.AddFunc(ctx, pluginID, version, opts)
}
return nil
}
l.LoadedPaths = append(l.LoadedPaths, paths...)
func (i *FakePluginInstaller) Remove(ctx context.Context, pluginID string) error {
if i.RemoveFunc != nil {
return i.RemoveFunc(ctx, pluginID)
}
return nil
}
type FakeLoader struct {
LoadFunc func(_ context.Context, _ plugins.Class, paths []string) ([]*plugins.Plugin, error)
UnloadFunc func(_ context.Context, _ string) error
}
func (l *FakeLoader) Load(ctx context.Context, class plugins.Class, paths []string) ([]*plugins.Plugin, error) {
if l.LoadFunc != nil {
return l.LoadFunc(ctx, class, paths)
}
return nil, nil
}
func (l *FakeLoader) Unload(ctx context.Context, pluginID string) error {
if l.UnloadFunc != nil {
return l.UnloadFunc(ctx, pluginID)
}
return nil
}
type FakePluginClient struct {
ID string
Managed bool
@@ -139,6 +162,30 @@ func (pc *FakePluginClient) RunStream(_ context.Context, _ *backend.RunStreamReq
return backendplugin.ErrMethodNotImplemented
}
type FakePluginStore struct {
Store map[string]plugins.PluginDTO
}
func NewFakePluginStore() *FakePluginStore {
return &FakePluginStore{
Store: make(map[string]plugins.PluginDTO),
}
}
func (f *FakePluginStore) Plugin(_ context.Context, id string) (plugins.PluginDTO, bool) {
p, exists := f.Store[id]
return p, exists
}
func (f *FakePluginStore) Plugins(_ context.Context, _ ...plugins.Type) []plugins.PluginDTO {
var res []plugins.PluginDTO
for _, p := range f.Store {
res = append(res, p)
}
return res
}
type FakePluginRegistry struct {
Store map[string]*plugins.Plugin
}
@@ -207,15 +254,20 @@ func (r *FakePluginRepo) GetPluginDownloadOptions(ctx context.Context, pluginID,
}
type FakePluginStorage struct {
Store map[string]struct{}
AddFunc func(_ context.Context, pluginID string, z *zip.ReadCloser) (*storage.ExtractedPluginArchive, error)
RegisterFunc func(_ context.Context, pluginID, pluginDir string) error
RemoveFunc func(_ context.Context, pluginID string) error
Added map[string]string
Removed map[string]int
}
func NewFakePluginStorage() *FakePluginStorage {
return &FakePluginStorage{
Store: map[string]struct{}{},
}
}
func (s *FakePluginStorage) Register(ctx context.Context, pluginID, pluginDir string) error {
s.Added[pluginID] = pluginDir
s.Store[pluginID] = struct{}{}
if s.RegisterFunc != nil {
return s.RegisterFunc(ctx, pluginID, pluginDir)
}
@@ -223,6 +275,7 @@ func (s *FakePluginStorage) Register(ctx context.Context, pluginID, pluginDir st
}
func (s *FakePluginStorage) Add(ctx context.Context, pluginID string, z *zip.ReadCloser) (*storage.ExtractedPluginArchive, error) {
s.Store[pluginID] = struct{}{}
if s.AddFunc != nil {
return s.AddFunc(ctx, pluginID, z)
}
@@ -230,7 +283,7 @@ func (s *FakePluginStorage) Add(ctx context.Context, pluginID string, z *zip.Rea
}
func (s *FakePluginStorage) Remove(ctx context.Context, pluginID string) error {
s.Removed[pluginID]++
delete(s.Store, pluginID)
if s.RemoveFunc != nil {
return s.RemoveFunc(ctx, pluginID)
}
@@ -266,3 +319,63 @@ func (m *FakeProcessManager) Stop(ctx context.Context, pluginID string) error {
}
return nil
}
type FakeBackendProcessProvider struct {
Requested map[string]int
Invoked map[string]int
}
func NewFakeBackendProcessProvider() *FakeBackendProcessProvider {
return &FakeBackendProcessProvider{
Requested: make(map[string]int),
Invoked: make(map[string]int),
}
}
func (pr *FakeBackendProcessProvider) BackendFactory(_ context.Context, p *plugins.Plugin) backendplugin.PluginFactoryFunc {
pr.Requested[p.ID]++
return func(pluginID string, _ log.Logger, _ []string) (backendplugin.Plugin, error) {
pr.Invoked[pluginID]++
return &FakePluginClient{}, nil
}
}
type FakeLicensingService struct {
TokenRaw string
}
func NewFakeLicensingService() *FakeLicensingService {
return &FakeLicensingService{}
}
func (t *FakeLicensingService) Expiry() int64 {
return 0
}
func (t *FakeLicensingService) Edition() string {
return ""
}
func (t *FakeLicensingService) StateInfo() string {
return ""
}
func (t *FakeLicensingService) ContentDeliveryPrefix() string {
return ""
}
func (t *FakeLicensingService) LicenseURL(_ bool) string {
return ""
}
func (t *FakeLicensingService) Environment() map[string]string {
return map[string]string{"GF_ENTERPRISE_LICENSE_TEXT": t.TokenRaw}
}
func (*FakeLicensingService) EnabledFeatures() map[string]bool {
return map[string]bool{}
}
func (*FakeLicensingService) FeatureEnabled(_ string) bool {
return false
}