mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Plugins: Add inititialization stage to plugin loader pipeline (#72667)
* first pass * migrate tests * simplify * fix comments * fix linter * nil checks * remove comment
This commit is contained in:
parent
77e7ae2a1b
commit
ad2705fa0b
@ -73,11 +73,12 @@ func TestCallResource(t *testing.T) {
|
||||
|
||||
discovery := pipeline.ProvideDiscoveryStage(pCfg, finder.NewLocalFinder(pCfg.DevMode), reg)
|
||||
bootstrap := pipeline.ProvideBootstrapStage(pCfg, signature.ProvideService(pCfg, statickey.New()), assetpath.ProvideService(pluginscdn.ProvideService(pCfg)))
|
||||
initialize := pipeline.ProvideInitializationStage(pCfg, reg, fakes.NewFakeLicensingService(), provider.ProvideService(coreRegistry))
|
||||
|
||||
l := loader.ProvideService(pCfg, fakes.NewFakeLicensingService(), signature.NewUnsignedAuthorizer(pCfg),
|
||||
reg, provider.ProvideService(coreRegistry), fakes.NewFakeRoleRegistry(),
|
||||
l := loader.ProvideService(pCfg, signature.NewUnsignedAuthorizer(pCfg),
|
||||
reg, fakes.NewFakeRoleRegistry(),
|
||||
assetpath.ProvideService(pluginscdn.ProvideService(pCfg)),
|
||||
angularInspector, &fakes.FakeOauthService{}, discovery, bootstrap)
|
||||
angularInspector, &fakes.FakeOauthService{}, discovery, bootstrap, initialize)
|
||||
srcs := sources.ProvideService(cfg, pCfg)
|
||||
ps, err := store.ProvideService(reg, srcs, l)
|
||||
require.NoError(t, err)
|
||||
|
@ -463,3 +463,36 @@ func (pr *FakePluginStore) Plugins(_ context.Context, pluginTypes ...plugins.Typ
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
type FakeDiscoverer struct {
|
||||
DiscoverFunc func(ctx context.Context, src plugins.PluginSource) ([]*plugins.FoundBundle, error)
|
||||
}
|
||||
|
||||
func (f *FakeDiscoverer) Discover(ctx context.Context, src plugins.PluginSource) ([]*plugins.FoundBundle, error) {
|
||||
if f.DiscoverFunc != nil {
|
||||
return f.DiscoverFunc(ctx, src)
|
||||
}
|
||||
return []*plugins.FoundBundle{}, nil
|
||||
}
|
||||
|
||||
type FakeBootstrapper struct {
|
||||
BootstrapFunc func(ctx context.Context, src plugins.PluginSource, bundles []*plugins.FoundBundle) ([]*plugins.Plugin, error)
|
||||
}
|
||||
|
||||
func (f *FakeBootstrapper) Bootstrap(ctx context.Context, src plugins.PluginSource, bundles []*plugins.FoundBundle) ([]*plugins.Plugin, error) {
|
||||
if f.BootstrapFunc != nil {
|
||||
return f.BootstrapFunc(ctx, src, bundles)
|
||||
}
|
||||
return []*plugins.Plugin{}, nil
|
||||
}
|
||||
|
||||
type FakeInitializer struct {
|
||||
IntializeFunc func(ctx context.Context, ps []*plugins.Plugin) ([]*plugins.Plugin, error)
|
||||
}
|
||||
|
||||
func (f *FakeInitializer) Initialize(ctx context.Context, ps []*plugins.Plugin) ([]*plugins.Plugin, error) {
|
||||
if f.IntializeFunc != nil {
|
||||
return f.IntializeFunc(ctx, ps)
|
||||
}
|
||||
return []*plugins.Plugin{}, nil
|
||||
}
|
||||
|
@ -1,43 +0,0 @@
|
||||
package initializer
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/plugins/config"
|
||||
"github.com/grafana/grafana/pkg/plugins/envvars"
|
||||
)
|
||||
|
||||
type Initializer struct {
|
||||
envVarProvider envvars.Provider
|
||||
backendProvider plugins.BackendFactoryProvider
|
||||
}
|
||||
|
||||
func New(cfg *config.Cfg, backendProvider plugins.BackendFactoryProvider, license plugins.Licensing) Initializer {
|
||||
return Initializer{
|
||||
envVarProvider: envvars.NewProvider(cfg, license),
|
||||
backendProvider: backendProvider,
|
||||
}
|
||||
}
|
||||
|
||||
func (i *Initializer) Initialize(ctx context.Context, p *plugins.Plugin) error {
|
||||
if p.Backend {
|
||||
backendFactory := i.backendProvider.BackendFactory(ctx, p)
|
||||
if backendFactory == nil {
|
||||
return errors.New("could not find backend factory for plugin")
|
||||
}
|
||||
|
||||
env, err := i.envVarProvider.Get(ctx, p)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if backendClient, err := backendFactory(p.ID, p.Logger(), env); err != nil {
|
||||
return err
|
||||
} else {
|
||||
p.RegisterClient(backendClient)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
@ -11,9 +11,9 @@ import (
|
||||
"github.com/grafana/grafana/pkg/plugins/log"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/loader/angular/angularinspector"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/loader/assetpath"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/loader/initializer"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/pipeline/bootstrap"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/pipeline/discovery"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/pipeline/initialization"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/process"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/registry"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/signature"
|
||||
@ -24,13 +24,13 @@ import (
|
||||
var _ plugins.ErrorResolver = (*Loader)(nil)
|
||||
|
||||
type Loader struct {
|
||||
discovery discovery.Discoverer
|
||||
bootstrap bootstrap.Bootstrapper
|
||||
discovery discovery.Discoverer
|
||||
bootstrap bootstrap.Bootstrapper
|
||||
initializer initialization.Initializer
|
||||
|
||||
processManager process.Service
|
||||
pluginRegistry registry.Service
|
||||
roleRegistry plugins.RoleRegistry
|
||||
pluginInitializer initializer.Initializer
|
||||
signatureValidator signature.Validator
|
||||
externalServiceRegistry oauth.ExternalServiceRegistry
|
||||
assetPath *assetpath.Service
|
||||
@ -42,23 +42,20 @@ type Loader struct {
|
||||
errs map[string]*plugins.SignatureError
|
||||
}
|
||||
|
||||
func ProvideService(cfg *config.Cfg, license plugins.Licensing, authorizer plugins.PluginLoaderAuthorizer,
|
||||
pluginRegistry registry.Service, backendProvider plugins.BackendFactoryProvider,
|
||||
roleRegistry plugins.RoleRegistry, assetPath *assetpath.Service,
|
||||
func ProvideService(cfg *config.Cfg, authorizer plugins.PluginLoaderAuthorizer,
|
||||
pluginRegistry registry.Service, roleRegistry plugins.RoleRegistry, assetPath *assetpath.Service,
|
||||
angularInspector angularinspector.Inspector, externalServiceRegistry oauth.ExternalServiceRegistry,
|
||||
discovery discovery.Discoverer, bootstrap bootstrap.Bootstrapper) *Loader {
|
||||
return New(cfg, license, authorizer, pluginRegistry, backendProvider, process.NewManager(pluginRegistry),
|
||||
roleRegistry, assetPath, angularInspector, externalServiceRegistry, discovery, bootstrap)
|
||||
discovery discovery.Discoverer, bootstrap bootstrap.Bootstrapper, initializer initialization.Initializer) *Loader {
|
||||
return New(cfg, authorizer, pluginRegistry, process.NewManager(pluginRegistry), roleRegistry, assetPath,
|
||||
angularInspector, externalServiceRegistry, discovery, bootstrap, initializer)
|
||||
}
|
||||
|
||||
func New(cfg *config.Cfg, license plugins.Licensing, authorizer plugins.PluginLoaderAuthorizer,
|
||||
pluginRegistry registry.Service, backendProvider plugins.BackendFactoryProvider,
|
||||
func New(cfg *config.Cfg, authorizer plugins.PluginLoaderAuthorizer, pluginRegistry registry.Service,
|
||||
processManager process.Service, roleRegistry plugins.RoleRegistry, assetPath *assetpath.Service,
|
||||
angularInspector angularinspector.Inspector, externalServiceRegistry oauth.ExternalServiceRegistry,
|
||||
discovery discovery.Discoverer, bootstrap bootstrap.Bootstrapper) *Loader {
|
||||
discovery discovery.Discoverer, bootstrap bootstrap.Bootstrapper, initializer initialization.Initializer) *Loader {
|
||||
return &Loader{
|
||||
pluginRegistry: pluginRegistry,
|
||||
pluginInitializer: initializer.New(cfg, backendProvider, license),
|
||||
signatureValidator: signature.NewValidator(authorizer),
|
||||
processManager: processManager,
|
||||
errs: make(map[string]*plugins.SignatureError),
|
||||
@ -70,6 +67,7 @@ func New(cfg *config.Cfg, license plugins.Licensing, authorizer plugins.PluginLo
|
||||
externalServiceRegistry: externalServiceRegistry,
|
||||
discovery: discovery,
|
||||
bootstrap: bootstrap,
|
||||
initializer: initializer,
|
||||
}
|
||||
}
|
||||
|
||||
@ -144,24 +142,9 @@ func (l *Loader) Load(ctx context.Context, src plugins.PluginSource) ([]*plugins
|
||||
// </VERIFICATION STAGE>
|
||||
|
||||
// <INITIALIZATION STAGE>
|
||||
initializedPlugins := make([]*plugins.Plugin, 0, len(verifiedPlugins))
|
||||
for _, p := range verifiedPlugins {
|
||||
err = l.pluginInitializer.Initialize(ctx, p)
|
||||
if err != nil {
|
||||
l.log.Error("Could not initialize plugin", "pluginId", p.ID, "err", err)
|
||||
continue
|
||||
}
|
||||
|
||||
if err = l.pluginRegistry.Add(ctx, p); err != nil {
|
||||
l.log.Error("Could not start plugin", "pluginId", p.ID, "err", err)
|
||||
continue
|
||||
}
|
||||
|
||||
if !p.IsCorePlugin() {
|
||||
l.log.Info("Plugin registered", "pluginID", p.ID)
|
||||
}
|
||||
|
||||
initializedPlugins = append(initializedPlugins, p)
|
||||
initializedPlugins, err := l.initializer.Initialize(ctx, verifiedPlugins)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// </INITIALIZATION STAGE>
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -124,11 +124,11 @@ func TestIntegrationPluginManager(t *testing.T) {
|
||||
|
||||
discovery := pipeline.ProvideDiscoveryStage(pCfg, finder.NewLocalFinder(pCfg.DevMode), reg)
|
||||
bootstrap := pipeline.ProvideBootstrapStage(pCfg, signature.ProvideService(pCfg, statickey.New()), assetpath.ProvideService(pluginscdn.ProvideService(pCfg)))
|
||||
|
||||
l := loader.ProvideService(pCfg, lic, signature.NewUnsignedAuthorizer(pCfg),
|
||||
reg, provider.ProvideService(coreRegistry), fakes.NewFakeRoleRegistry(),
|
||||
initialize := pipeline.ProvideInitializationStage(pCfg, reg, lic, provider.ProvideService(coreRegistry))
|
||||
l := loader.ProvideService(pCfg, signature.NewUnsignedAuthorizer(pCfg),
|
||||
reg, fakes.NewFakeRoleRegistry(),
|
||||
assetpath.ProvideService(pluginscdn.ProvideService(pCfg)),
|
||||
angularInspector, &fakes.FakeOauthService{}, discovery, bootstrap)
|
||||
angularInspector, &fakes.FakeOauthService{}, discovery, bootstrap, initialize)
|
||||
srcs := sources.ProvideService(cfg, pCfg)
|
||||
ps, err := store.ProvideService(reg, srcs, l)
|
||||
require.NoError(t, err)
|
||||
|
@ -47,7 +47,7 @@ func New(cfg *config.Cfg, opts Opts) *Bootstrap {
|
||||
opts.ConstructFunc = DefaultConstructFunc(signature.DefaultCalculator(cfg), assetpath.DefaultService(cfg))
|
||||
}
|
||||
|
||||
if len(opts.DecorateFuncs) == 0 {
|
||||
if opts.DecorateFuncs == nil {
|
||||
opts.DecorateFuncs = DefaultDecorateFuncs
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ func New(cfg *config.Cfg, opts Opts) *Discovery {
|
||||
opts.FindFunc = DefaultFindFunc(cfg)
|
||||
}
|
||||
|
||||
if len(opts.FindFilterFuncs) == 0 {
|
||||
if opts.FindFilterFuncs == nil {
|
||||
opts.FindFilterFuncs = []FindFilterFunc{} // no filters by default
|
||||
}
|
||||
|
||||
|
6
pkg/plugins/manager/pipeline/initialization/doc.go
Normal file
6
pkg/plugins/manager/pipeline/initialization/doc.go
Normal file
@ -0,0 +1,6 @@
|
||||
// Package initialization defines the fourth stage of the plugin loader pipeline.
|
||||
//
|
||||
// The Initialization stage must implement the Initializer interface.
|
||||
// - Initialize(ctx context.Context, ps []*plugins.Plugin) ([]*plugins.Plugin, error)
|
||||
|
||||
package initialization
|
@ -0,0 +1,67 @@
|
||||
package initialization
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/plugins/config"
|
||||
"github.com/grafana/grafana/pkg/plugins/log"
|
||||
)
|
||||
|
||||
// Initializer is responsible for the Initialization stage of the plugin loader pipeline.
|
||||
type Initializer interface {
|
||||
Initialize(ctx context.Context, ps []*plugins.Plugin) ([]*plugins.Plugin, error)
|
||||
}
|
||||
|
||||
// InitializeFunc is the function used for the Initialize step of the Initialization stage.
|
||||
type InitializeFunc func(ctx context.Context, p *plugins.Plugin) (*plugins.Plugin, error)
|
||||
|
||||
type Initialize struct {
|
||||
cfg *config.Cfg
|
||||
initializeSteps []InitializeFunc
|
||||
log log.Logger
|
||||
}
|
||||
|
||||
type Opts struct {
|
||||
InitializeFuncs []InitializeFunc
|
||||
}
|
||||
|
||||
// New returns a new Initialization stage.
|
||||
func New(cfg *config.Cfg, opts Opts) *Initialize {
|
||||
if opts.InitializeFuncs == nil {
|
||||
opts.InitializeFuncs = []InitializeFunc{}
|
||||
}
|
||||
|
||||
return &Initialize{
|
||||
cfg: cfg,
|
||||
initializeSteps: opts.InitializeFuncs,
|
||||
log: log.New("plugins.initialization"),
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize will execute the Initialize steps of the Initialization stage.
|
||||
func (i *Initialize) Initialize(ctx context.Context, ps []*plugins.Plugin) ([]*plugins.Plugin, error) {
|
||||
if len(i.initializeSteps) == 0 {
|
||||
return ps, nil
|
||||
}
|
||||
|
||||
var err error
|
||||
initializedPlugins := make([]*plugins.Plugin, 0, len(ps))
|
||||
for _, p := range ps {
|
||||
var ip *plugins.Plugin
|
||||
stepFailed := false
|
||||
for _, init := range i.initializeSteps {
|
||||
ip, err = init(ctx, p)
|
||||
if err != nil {
|
||||
stepFailed = true
|
||||
i.log.Error("Could not initialize plugin", "pluginId", p.ID, "err", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
if !stepFailed {
|
||||
initializedPlugins = append(initializedPlugins, ip)
|
||||
}
|
||||
}
|
||||
|
||||
return initializedPlugins, nil
|
||||
}
|
90
pkg/plugins/manager/pipeline/initialization/steps.go
Normal file
90
pkg/plugins/manager/pipeline/initialization/steps.go
Normal file
@ -0,0 +1,90 @@
|
||||
package initialization
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/plugins/envvars"
|
||||
"github.com/grafana/grafana/pkg/plugins/log"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/registry"
|
||||
)
|
||||
|
||||
// BackendClientInit implements an InitializeFunc for initializing a backend plugin process.
|
||||
//
|
||||
// It uses the envvars.Provider to retrieve the environment variables required for the plugin and the plugins.BackendFactoryProvider
|
||||
// to get fetch backend factory, which is used to form a connection to the backend plugin process.
|
||||
//
|
||||
// Note: This step does not start the backend plugin process.
|
||||
type BackendClientInit struct {
|
||||
envVarProvider envvars.Provider
|
||||
backendProvider plugins.BackendFactoryProvider
|
||||
log log.Logger
|
||||
}
|
||||
|
||||
// NewBackendClientInitStep returns a new InitializeFunc for registering a backend plugin process.
|
||||
func NewBackendClientInitStep(envVarProvider envvars.Provider,
|
||||
backendProvider plugins.BackendFactoryProvider) InitializeFunc {
|
||||
return newBackendProcessRegistration(envVarProvider, backendProvider).Initialize
|
||||
}
|
||||
|
||||
func newBackendProcessRegistration(envVarProvider envvars.Provider,
|
||||
backendProvider plugins.BackendFactoryProvider) *BackendClientInit {
|
||||
return &BackendClientInit{
|
||||
backendProvider: backendProvider,
|
||||
envVarProvider: envVarProvider,
|
||||
log: log.New("plugins.backend.registration"),
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize will initialize a backend plugin client, if the plugin is a backend plugin.
|
||||
func (b *BackendClientInit) Initialize(ctx context.Context, p *plugins.Plugin) (*plugins.Plugin, error) {
|
||||
if p.Backend {
|
||||
backendFactory := b.backendProvider.BackendFactory(ctx, p)
|
||||
if backendFactory == nil {
|
||||
return nil, errors.New("could not find backend factory for plugin")
|
||||
}
|
||||
|
||||
env, err := b.envVarProvider.Get(ctx, p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if backendClient, err := backendFactory(p.ID, p.Logger(), env); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
p.RegisterClient(backendClient)
|
||||
}
|
||||
}
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// PluginRegistration implements an InitializeFunc for registering a plugin with the plugin registry.
|
||||
type PluginRegistration struct {
|
||||
pluginRegistry registry.Service
|
||||
log log.Logger
|
||||
}
|
||||
|
||||
// NewPluginRegistrationStep returns a new InitializeFunc for registering a plugin with the plugin registry.
|
||||
func NewPluginRegistrationStep(pluginRegistry registry.Service) InitializeFunc {
|
||||
return newPluginRegistration(pluginRegistry).Initialize
|
||||
}
|
||||
|
||||
func newPluginRegistration(pluginRegistry registry.Service) *PluginRegistration {
|
||||
return &PluginRegistration{
|
||||
pluginRegistry: pluginRegistry,
|
||||
log: log.New("plugins.registration"),
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize registers the plugin with the plugin registry.
|
||||
func (r *PluginRegistration) Initialize(ctx context.Context, p *plugins.Plugin) (*plugins.Plugin, error) {
|
||||
if err := r.pluginRegistry.Add(ctx, p); err != nil {
|
||||
r.log.Error("Could not register plugin", "pluginID", p.ID, "err", err)
|
||||
return nil, errors.New("could not register plugin")
|
||||
}
|
||||
if !p.IsCorePlugin() {
|
||||
r.log.Info("Plugin registered", "pluginID", p.ID)
|
||||
}
|
||||
|
||||
return p, nil
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
package initializer
|
||||
package initialization
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/plugins/backendplugin"
|
||||
@ -28,19 +28,15 @@ func TestInitializer_Initialize(t *testing.T) {
|
||||
Class: plugins.ClassCore,
|
||||
}
|
||||
|
||||
i := &Initializer{
|
||||
backendProvider: &fakeBackendProvider{
|
||||
plugin: p,
|
||||
},
|
||||
envVarProvider: &fakeEnvVarsProvider{},
|
||||
}
|
||||
stepFunc := NewBackendClientInitStep(&fakeEnvVarsProvider{}, &fakeBackendProvider{plugin: p})
|
||||
|
||||
err := i.Initialize(context.Background(), p)
|
||||
assert.NoError(t, err)
|
||||
var err error
|
||||
p, err = stepFunc(context.Background(), p)
|
||||
require.NoError(t, err)
|
||||
|
||||
c, exists := p.Client()
|
||||
assert.True(t, exists)
|
||||
assert.NotNil(t, c)
|
||||
require.True(t, exists)
|
||||
require.NotNil(t, c)
|
||||
})
|
||||
|
||||
t.Run("renderer", func(t *testing.T) {
|
||||
@ -56,19 +52,15 @@ func TestInitializer_Initialize(t *testing.T) {
|
||||
Class: plugins.ClassExternal,
|
||||
}
|
||||
|
||||
i := &Initializer{
|
||||
backendProvider: &fakeBackendProvider{
|
||||
plugin: p,
|
||||
},
|
||||
envVarProvider: &fakeEnvVarsProvider{},
|
||||
}
|
||||
stepFunc := NewBackendClientInitStep(&fakeEnvVarsProvider{}, &fakeBackendProvider{plugin: p})
|
||||
|
||||
err := i.Initialize(context.Background(), p)
|
||||
assert.NoError(t, err)
|
||||
var err error
|
||||
p, err = stepFunc(context.Background(), p)
|
||||
require.NoError(t, err)
|
||||
|
||||
c, exists := p.Client()
|
||||
assert.True(t, exists)
|
||||
assert.NotNil(t, c)
|
||||
require.True(t, exists)
|
||||
require.NotNil(t, c)
|
||||
})
|
||||
|
||||
t.Run("secretsmanager", func(t *testing.T) {
|
||||
@ -84,19 +76,15 @@ func TestInitializer_Initialize(t *testing.T) {
|
||||
Class: plugins.ClassExternal,
|
||||
}
|
||||
|
||||
i := &Initializer{
|
||||
backendProvider: &fakeBackendProvider{
|
||||
plugin: p,
|
||||
},
|
||||
envVarProvider: &fakeEnvVarsProvider{},
|
||||
}
|
||||
stepFunc := NewBackendClientInitStep(&fakeEnvVarsProvider{}, &fakeBackendProvider{plugin: p})
|
||||
|
||||
err := i.Initialize(context.Background(), p)
|
||||
assert.NoError(t, err)
|
||||
var err error
|
||||
p, err = stepFunc(context.Background(), p)
|
||||
require.NoError(t, err)
|
||||
|
||||
c, exists := p.Client()
|
||||
assert.True(t, exists)
|
||||
assert.NotNil(t, c)
|
||||
require.True(t, exists)
|
||||
require.NotNil(t, c)
|
||||
})
|
||||
|
||||
t.Run("non backend plugin app", func(t *testing.T) {
|
||||
@ -106,19 +94,17 @@ func TestInitializer_Initialize(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
i := &Initializer{
|
||||
backendProvider: &fakeBackendProvider{
|
||||
plugin: p,
|
||||
},
|
||||
envVarProvider: &fakeEnvVarsProvider{},
|
||||
}
|
||||
i := NewBackendClientInitStep(&fakeEnvVarsProvider{}, &fakeBackendProvider{
|
||||
plugin: p,
|
||||
})
|
||||
|
||||
err := i.Initialize(context.Background(), p)
|
||||
assert.NoError(t, err)
|
||||
var err error
|
||||
p, err = i(context.Background(), p)
|
||||
require.NoError(t, err)
|
||||
|
||||
c, exists := p.Client()
|
||||
assert.False(t, exists)
|
||||
assert.Nil(t, c)
|
||||
require.False(t, exists)
|
||||
require.Nil(t, c)
|
||||
})
|
||||
}
|
||||
|
47
pkg/services/pluginsintegration/loader/loader.go
Normal file
47
pkg/services/pluginsintegration/loader/loader.go
Normal file
@ -0,0 +1,47 @@
|
||||
package loader
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/plugins/config"
|
||||
pluginsLoader "github.com/grafana/grafana/pkg/plugins/manager/loader"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/loader/angular/angularinspector"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/loader/assetpath"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/pipeline/bootstrap"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/pipeline/discovery"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/pipeline/initialization"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/process"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/registry"
|
||||
"github.com/grafana/grafana/pkg/plugins/oauth"
|
||||
)
|
||||
|
||||
var _ plugins.ErrorResolver = (*Loader)(nil)
|
||||
var _ pluginsLoader.Service = (*Loader)(nil)
|
||||
|
||||
type Loader struct {
|
||||
loader *pluginsLoader.Loader
|
||||
}
|
||||
|
||||
func ProvideService(cfg *config.Cfg, authorizer plugins.PluginLoaderAuthorizer, processManager process.Service,
|
||||
pluginRegistry registry.Service, roleRegistry plugins.RoleRegistry, assetPath *assetpath.Service,
|
||||
angularInspector angularinspector.Inspector, externalServiceRegistry oauth.ExternalServiceRegistry,
|
||||
discovery discovery.Discoverer, bootstrap bootstrap.Bootstrapper, initializer initialization.Initializer,
|
||||
) *Loader {
|
||||
return &Loader{
|
||||
loader: pluginsLoader.New(cfg, authorizer, pluginRegistry, processManager, roleRegistry, assetPath,
|
||||
angularInspector, externalServiceRegistry, discovery, bootstrap, initializer),
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Loader) Load(ctx context.Context, src plugins.PluginSource) ([]*plugins.Plugin, error) {
|
||||
return l.loader.Load(ctx, src)
|
||||
}
|
||||
|
||||
func (l *Loader) Unload(ctx context.Context, pluginID string) error {
|
||||
return l.loader.Unload(ctx, pluginID)
|
||||
}
|
||||
|
||||
func (l *Loader) PluginErrors() []*plugins.Error {
|
||||
return l.loader.PluginErrors()
|
||||
}
|
1382
pkg/services/pluginsintegration/loader/loader_test.go
Normal file
1382
pkg/services/pluginsintegration/loader/loader_test.go
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,33 +0,0 @@
|
||||
package pipeline
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/plugins/config"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/loader/assetpath"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/loader/finder"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/pipeline/bootstrap"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/pipeline/discovery"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/registry"
|
||||
)
|
||||
|
||||
func ProvideDiscoveryStage(cfg *config.Cfg, pluginFinder finder.Finder, pluginRegistry registry.Service) *discovery.Discovery {
|
||||
return discovery.New(cfg, discovery.Opts{
|
||||
FindFunc: func(ctx context.Context, src plugins.PluginSource) ([]*plugins.FoundBundle, error) {
|
||||
return pluginFinder.Find(ctx, src)
|
||||
},
|
||||
FindFilterFuncs: []discovery.FindFilterFunc{
|
||||
func(ctx context.Context, _ plugins.Class, bundles []*plugins.FoundBundle) ([]*plugins.FoundBundle, error) {
|
||||
return discovery.NewDuplicatePluginFilterStep(pluginRegistry).Filter(ctx, bundles)
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func ProvideBootstrapStage(cfg *config.Cfg, signatureCalculator plugins.SignatureCalculator, assetPath *assetpath.Service) *bootstrap.Bootstrap {
|
||||
return bootstrap.New(cfg, bootstrap.Opts{
|
||||
ConstructFunc: bootstrap.DefaultConstructFunc(signatureCalculator, assetPath),
|
||||
DecorateFuncs: bootstrap.DefaultDecorateFuncs,
|
||||
})
|
||||
}
|
44
pkg/services/pluginsintegration/pipeline/pipeline.go
Normal file
44
pkg/services/pluginsintegration/pipeline/pipeline.go
Normal file
@ -0,0 +1,44 @@
|
||||
package pipeline
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/plugins/config"
|
||||
"github.com/grafana/grafana/pkg/plugins/envvars"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/loader/assetpath"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/loader/finder"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/pipeline/bootstrap"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/pipeline/discovery"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/pipeline/initialization"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/registry"
|
||||
)
|
||||
|
||||
func ProvideDiscoveryStage(cfg *config.Cfg, pf finder.Finder, pr registry.Service) *discovery.Discovery {
|
||||
return discovery.New(cfg, discovery.Opts{
|
||||
FindFunc: func(ctx context.Context, src plugins.PluginSource) ([]*plugins.FoundBundle, error) {
|
||||
return pf.Find(ctx, src)
|
||||
},
|
||||
FindFilterFuncs: []discovery.FindFilterFunc{
|
||||
func(ctx context.Context, _ plugins.Class, b []*plugins.FoundBundle) ([]*plugins.FoundBundle, error) {
|
||||
return discovery.NewDuplicatePluginFilterStep(pr).Filter(ctx, b)
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func ProvideBootstrapStage(cfg *config.Cfg, sc plugins.SignatureCalculator, a *assetpath.Service) *bootstrap.Bootstrap {
|
||||
return bootstrap.New(cfg, bootstrap.Opts{
|
||||
ConstructFunc: bootstrap.DefaultConstructFunc(sc, a),
|
||||
DecorateFuncs: bootstrap.DefaultDecorateFuncs,
|
||||
})
|
||||
}
|
||||
|
||||
func ProvideInitializationStage(cfg *config.Cfg, pr registry.Service, l plugins.Licensing, bp plugins.BackendFactoryProvider) *initialization.Initialize {
|
||||
return initialization.New(cfg, initialization.Opts{
|
||||
InitializeFuncs: []initialization.InitializeFunc{
|
||||
initialization.NewBackendClientInitStep(envvars.NewProvider(cfg, l), bp),
|
||||
initialization.NewPluginRegistrationStep(pr),
|
||||
},
|
||||
})
|
||||
}
|
@ -11,12 +11,13 @@ import (
|
||||
"github.com/grafana/grafana/pkg/plugins/manager"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/client"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/filestore"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/loader"
|
||||
pluginLoader "github.com/grafana/grafana/pkg/plugins/manager/loader"
|
||||
pAngularInspector "github.com/grafana/grafana/pkg/plugins/manager/loader/angular/angularinspector"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/loader/assetpath"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/loader/finder"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/pipeline/bootstrap"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/pipeline/discovery"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/pipeline/initialization"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/process"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/registry"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/signature"
|
||||
@ -37,6 +38,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/keyretriever/dynamic"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/keystore"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/licensing"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/loader"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pipeline"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/plugincontext"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsettings"
|
||||
@ -65,6 +67,8 @@ var WireSet = wire.NewSet(
|
||||
wire.Bind(new(discovery.Discoverer), new(*discovery.Discovery)),
|
||||
pipeline.ProvideBootstrapStage,
|
||||
wire.Bind(new(bootstrap.Bootstrapper), new(*bootstrap.Bootstrap)),
|
||||
pipeline.ProvideInitializationStage,
|
||||
wire.Bind(new(initialization.Initializer), new(*initialization.Initialize)),
|
||||
|
||||
angularpatternsstore.ProvideService,
|
||||
angulardetectorsprovider.ProvideDynamic,
|
||||
@ -72,7 +76,7 @@ var WireSet = wire.NewSet(
|
||||
wire.Bind(new(pAngularInspector.Inspector), new(*angularinspector.Service)),
|
||||
|
||||
loader.ProvideService,
|
||||
wire.Bind(new(loader.Service), new(*loader.Loader)),
|
||||
wire.Bind(new(pluginLoader.Service), new(*loader.Loader)),
|
||||
wire.Bind(new(plugins.ErrorResolver), new(*loader.Loader)),
|
||||
manager.ProvideInstaller,
|
||||
wire.Bind(new(plugins.Installer), new(*manager.PluginInstaller)),
|
||||
|
Loading…
Reference in New Issue
Block a user