mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
parent
42be20cbf3
commit
819c2f4ad8
@ -63,9 +63,9 @@ func TestCallResource(t *testing.T) {
|
|||||||
pCfg, err = config.ProvideConfig(setting.ProvideProvider(cfg), cfg)
|
pCfg, err = config.ProvideConfig(setting.ProvideProvider(cfg), cfg)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
reg := registry.ProvideService()
|
reg := registry.ProvideService()
|
||||||
cdn := pluginscdn.ProvideService(pCfg)
|
|
||||||
l := loader.ProvideService(pCfg, fakes.NewFakeLicensingService(), signature.NewUnsignedAuthorizer(pCfg),
|
l := loader.ProvideService(pCfg, fakes.NewFakeLicensingService(), signature.NewUnsignedAuthorizer(pCfg),
|
||||||
reg, provider.ProvideService(coreRegistry), finder.NewLocalFinder(), fakes.NewFakeRoleRegistry(), cdn, assetpath.ProvideService(cdn))
|
reg, provider.ProvideService(coreRegistry), finder.NewLocalFinder(), fakes.NewFakeRoleRegistry(),
|
||||||
|
assetpath.ProvideService(pluginscdn.ProvideService(pCfg)))
|
||||||
srcs := sources.ProvideService(cfg, pCfg)
|
srcs := sources.ProvideService(cfg, pCfg)
|
||||||
ps, err := store.ProvideService(reg, srcs, l)
|
ps, err := store.ProvideService(reg, srcs, l)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -18,7 +18,6 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/plugins/manager/process"
|
"github.com/grafana/grafana/pkg/plugins/manager/process"
|
||||||
"github.com/grafana/grafana/pkg/plugins/manager/registry"
|
"github.com/grafana/grafana/pkg/plugins/manager/registry"
|
||||||
"github.com/grafana/grafana/pkg/plugins/manager/signature"
|
"github.com/grafana/grafana/pkg/plugins/manager/signature"
|
||||||
"github.com/grafana/grafana/pkg/plugins/pluginscdn"
|
|
||||||
"github.com/grafana/grafana/pkg/plugins/storage"
|
"github.com/grafana/grafana/pkg/plugins/storage"
|
||||||
"github.com/grafana/grafana/pkg/util"
|
"github.com/grafana/grafana/pkg/util"
|
||||||
)
|
)
|
||||||
@ -33,7 +32,6 @@ type Loader struct {
|
|||||||
pluginInitializer initializer.Initializer
|
pluginInitializer initializer.Initializer
|
||||||
signatureValidator signature.Validator
|
signatureValidator signature.Validator
|
||||||
pluginStorage storage.Manager
|
pluginStorage storage.Manager
|
||||||
pluginsCDN *pluginscdn.Service
|
|
||||||
assetPath *assetpath.Service
|
assetPath *assetpath.Service
|
||||||
log log.Logger
|
log log.Logger
|
||||||
cfg *config.Cfg
|
cfg *config.Cfg
|
||||||
@ -43,16 +41,16 @@ type Loader struct {
|
|||||||
|
|
||||||
func ProvideService(cfg *config.Cfg, license plugins.Licensing, authorizer plugins.PluginLoaderAuthorizer,
|
func ProvideService(cfg *config.Cfg, license plugins.Licensing, authorizer plugins.PluginLoaderAuthorizer,
|
||||||
pluginRegistry registry.Service, backendProvider plugins.BackendFactoryProvider, pluginFinder finder.Finder,
|
pluginRegistry registry.Service, backendProvider plugins.BackendFactoryProvider, pluginFinder finder.Finder,
|
||||||
roleRegistry plugins.RoleRegistry, pluginsCDNService *pluginscdn.Service, assetPath *assetpath.Service) *Loader {
|
roleRegistry plugins.RoleRegistry, assetPath *assetpath.Service) *Loader {
|
||||||
return New(cfg, license, authorizer, pluginRegistry, backendProvider, process.NewManager(pluginRegistry),
|
return New(cfg, license, authorizer, pluginRegistry, backendProvider, process.NewManager(pluginRegistry),
|
||||||
storage.FileSystem(log.NewPrettyLogger("loader.fs"), cfg.PluginsPath), roleRegistry, pluginsCDNService,
|
storage.FileSystem(log.NewPrettyLogger("loader.fs"), cfg.PluginsPath), roleRegistry, assetPath,
|
||||||
assetPath, pluginFinder)
|
pluginFinder)
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(cfg *config.Cfg, license plugins.Licensing, authorizer plugins.PluginLoaderAuthorizer,
|
func New(cfg *config.Cfg, license plugins.Licensing, authorizer plugins.PluginLoaderAuthorizer,
|
||||||
pluginRegistry registry.Service, backendProvider plugins.BackendFactoryProvider,
|
pluginRegistry registry.Service, backendProvider plugins.BackendFactoryProvider,
|
||||||
processManager process.Service, pluginStorage storage.Manager, roleRegistry plugins.RoleRegistry,
|
processManager process.Service, pluginStorage storage.Manager, roleRegistry plugins.RoleRegistry,
|
||||||
pluginsCDNService *pluginscdn.Service, assetPath *assetpath.Service, pluginFinder finder.Finder) *Loader {
|
assetPath *assetpath.Service, pluginFinder finder.Finder) *Loader {
|
||||||
return &Loader{
|
return &Loader{
|
||||||
pluginFinder: pluginFinder,
|
pluginFinder: pluginFinder,
|
||||||
pluginRegistry: pluginRegistry,
|
pluginRegistry: pluginRegistry,
|
||||||
@ -64,7 +62,6 @@ func New(cfg *config.Cfg, license plugins.Licensing, authorizer plugins.PluginLo
|
|||||||
log: log.New("plugin.loader"),
|
log: log.New("plugin.loader"),
|
||||||
roleRegistry: roleRegistry,
|
roleRegistry: roleRegistry,
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
pluginsCDN: pluginsCDNService,
|
|
||||||
assetPath: assetPath,
|
assetPath: assetPath,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -86,20 +83,12 @@ func (l *Loader) loadPlugins(ctx context.Context, src plugins.PluginSource, foun
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
var sig plugins.Signature
|
sig, err := signature.Calculate(ctx, l.log, src, p.Primary)
|
||||||
if l.pluginsCDN.PluginSupported(p.Primary.JSONData.ID) {
|
if err != nil {
|
||||||
// CDN plugins have no signature checks for now.
|
l.log.Warn("Could not calculate plugin signature state", "pluginID", p.Primary.JSONData.ID, "err", err)
|
||||||
sig = plugins.Signature{Status: plugins.SignatureValid}
|
continue
|
||||||
} else {
|
|
||||||
var err error
|
|
||||||
sig, err = signature.Calculate(ctx, l.log, src, p.Primary)
|
|
||||||
if err != nil {
|
|
||||||
l.log.Warn("Could not calculate plugin signature state", "pluginID", p.Primary.JSONData.ID, "err", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
class := src.PluginClass(ctx)
|
plugin, err := l.createPluginBase(p.Primary.JSONData, src.PluginClass(ctx), p.Primary.FS)
|
||||||
plugin, err := l.createPluginBase(p.Primary.JSONData, class, p.Primary.FS)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.log.Error("Could not create primary plugin base", "pluginID", p.Primary.JSONData.ID, "err", err)
|
l.log.Error("Could not create primary plugin base", "pluginID", p.Primary.JSONData.ID, "err", err)
|
||||||
continue
|
continue
|
||||||
@ -117,7 +106,7 @@ func (l *Loader) loadPlugins(ctx context.Context, src plugins.PluginSource, foun
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
cp, err := l.createPluginBase(c.JSONData, class, c.FS)
|
cp, err := l.createPluginBase(c.JSONData, plugin.Class, c.FS)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.log.Error("Could not create child plugin base", "pluginID", p.Primary.JSONData.ID, "err", err)
|
l.log.Error("Could not create child plugin base", "pluginID", p.Primary.JSONData.ID, "err", err)
|
||||||
continue
|
continue
|
||||||
@ -154,7 +143,7 @@ func (l *Loader) loadPlugins(ctx context.Context, src plugins.PluginSource, foun
|
|||||||
if !plugin.IsRenderer() && !plugin.IsCorePlugin() {
|
if !plugin.IsRenderer() && !plugin.IsCorePlugin() {
|
||||||
_, err := plugin.FS.Open("module.js")
|
_, err := plugin.FS.Open("module.js")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, plugins.ErrFileNotExist) && !l.pluginsCDN.PluginSupported(plugin.ID) {
|
if errors.Is(err, plugins.ErrFileNotExist) {
|
||||||
l.log.Warn("Plugin missing module.js", "pluginID", plugin.ID,
|
l.log.Warn("Plugin missing module.js", "pluginID", plugin.ID,
|
||||||
"warning", "Missing module.js, If you loaded this plugin from git, make sure to compile it.")
|
"warning", "Missing module.js, If you loaded this plugin from git, make sure to compile it.")
|
||||||
}
|
}
|
||||||
|
@ -447,63 +447,6 @@ func TestLoader_Load(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "Load CDN plugin",
|
|
||||||
class: plugins.External,
|
|
||||||
cfg: &config.Cfg{
|
|
||||||
PluginsCDNURLTemplate: "https://cdn.example.com",
|
|
||||||
PluginSettings: setting.PluginSettings{
|
|
||||||
"grafana-worldmap-panel": {"cdn": "true"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
pluginPaths: []string{"../testdata/cdn"},
|
|
||||||
want: []*plugins.Plugin{
|
|
||||||
{
|
|
||||||
JSONData: plugins.JSONData{
|
|
||||||
ID: "grafana-worldmap-panel",
|
|
||||||
Type: "panel",
|
|
||||||
Name: "Worldmap Panel",
|
|
||||||
Info: plugins.Info{
|
|
||||||
Version: "0.3.3",
|
|
||||||
Links: []plugins.InfoLink{
|
|
||||||
{Name: "Project site", URL: "https://github.com/grafana/worldmap-panel"},
|
|
||||||
{Name: "MIT License", URL: "https://github.com/grafana/worldmap-panel/blob/master/LICENSE"},
|
|
||||||
},
|
|
||||||
Logos: plugins.Logos{
|
|
||||||
// Path substitution
|
|
||||||
Small: "https://cdn.example.com/grafana-worldmap-panel/0.3.3/public/plugins/grafana-worldmap-panel/images/worldmap_logo.svg",
|
|
||||||
Large: "https://cdn.example.com/grafana-worldmap-panel/0.3.3/public/plugins/grafana-worldmap-panel/images/worldmap_logo.svg",
|
|
||||||
},
|
|
||||||
Screenshots: []plugins.Screenshots{
|
|
||||||
{
|
|
||||||
Name: "World",
|
|
||||||
Path: "https://cdn.example.com/grafana-worldmap-panel/0.3.3/public/plugins/grafana-worldmap-panel/images/worldmap-world.png",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "USA",
|
|
||||||
Path: "https://cdn.example.com/grafana-worldmap-panel/0.3.3/public/plugins/grafana-worldmap-panel/images/worldmap-usa.png",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "Light Theme",
|
|
||||||
Path: "https://cdn.example.com/grafana-worldmap-panel/0.3.3/public/plugins/grafana-worldmap-panel/images/worldmap-light-theme.png",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Dependencies: plugins.Dependencies{
|
|
||||||
GrafanaVersion: "3.x.x",
|
|
||||||
Plugins: []plugins.Dependency{},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
FS: plugins.NewLocalFS(map[string]struct{}{
|
|
||||||
filepath.Join(parentDir, "testdata/cdn/plugin", "plugin.json"): {},
|
|
||||||
}, filepath.Join(parentDir, "testdata/cdn/plugin")),
|
|
||||||
Class: plugins.External,
|
|
||||||
Signature: plugins.SignatureValid,
|
|
||||||
BaseURL: "plugin-cdn/grafana-worldmap-panel/0.3.3/public/plugins/grafana-worldmap-panel",
|
|
||||||
Module: "plugin-cdn/grafana-worldmap-panel/0.3.3/public/plugins/grafana-worldmap-panel/module",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
reg := fakes.NewFakePluginRegistry()
|
reg := fakes.NewFakePluginRegistry()
|
||||||
@ -535,6 +478,89 @@ func TestLoader_Load(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestLoader_Load_CustomSource(t *testing.T) {
|
||||||
|
t.Run("Load a plugin", func(t *testing.T) {
|
||||||
|
parentDir, err := filepath.Abs("../")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("could not construct absolute path of current dir")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg := &config.Cfg{
|
||||||
|
PluginsCDNURLTemplate: "https://cdn.example.com",
|
||||||
|
PluginSettings: setting.PluginSettings{
|
||||||
|
"grafana-worldmap-panel": {"cdn": "true"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
pluginPaths := []string{"../testdata/cdn"}
|
||||||
|
expected := []*plugins.Plugin{{
|
||||||
|
JSONData: plugins.JSONData{
|
||||||
|
ID: "grafana-worldmap-panel",
|
||||||
|
Type: "panel",
|
||||||
|
Name: "Worldmap Panel",
|
||||||
|
Info: plugins.Info{
|
||||||
|
Version: "0.3.3",
|
||||||
|
Links: []plugins.InfoLink{
|
||||||
|
{Name: "Project site", URL: "https://github.com/grafana/worldmap-panel"},
|
||||||
|
{Name: "MIT License", URL: "https://github.com/grafana/worldmap-panel/blob/master/LICENSE"},
|
||||||
|
},
|
||||||
|
Logos: plugins.Logos{
|
||||||
|
// Path substitution
|
||||||
|
Small: "https://cdn.example.com/grafana-worldmap-panel/0.3.3/public/plugins/grafana-worldmap-panel/images/worldmap_logo.svg",
|
||||||
|
Large: "https://cdn.example.com/grafana-worldmap-panel/0.3.3/public/plugins/grafana-worldmap-panel/images/worldmap_logo.svg",
|
||||||
|
},
|
||||||
|
Screenshots: []plugins.Screenshots{
|
||||||
|
{
|
||||||
|
Name: "World",
|
||||||
|
Path: "https://cdn.example.com/grafana-worldmap-panel/0.3.3/public/plugins/grafana-worldmap-panel/images/worldmap-world.png",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "USA",
|
||||||
|
Path: "https://cdn.example.com/grafana-worldmap-panel/0.3.3/public/plugins/grafana-worldmap-panel/images/worldmap-usa.png",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Light Theme",
|
||||||
|
Path: "https://cdn.example.com/grafana-worldmap-panel/0.3.3/public/plugins/grafana-worldmap-panel/images/worldmap-light-theme.png",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Dependencies: plugins.Dependencies{
|
||||||
|
GrafanaVersion: "3.x.x",
|
||||||
|
Plugins: []plugins.Dependency{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
FS: plugins.NewLocalFS(map[string]struct{}{
|
||||||
|
filepath.Join(parentDir, "testdata/cdn/plugin", "plugin.json"): {},
|
||||||
|
}, filepath.Join(parentDir, "testdata/cdn/plugin")),
|
||||||
|
Class: plugins.Bundled,
|
||||||
|
Signature: plugins.SignatureValid,
|
||||||
|
BaseURL: "plugin-cdn/grafana-worldmap-panel/0.3.3/public/plugins/grafana-worldmap-panel",
|
||||||
|
Module: "plugin-cdn/grafana-worldmap-panel/0.3.3/public/plugins/grafana-worldmap-panel/module",
|
||||||
|
}}
|
||||||
|
|
||||||
|
l := newLoader(cfg)
|
||||||
|
got, err := l.Load(context.Background(), &fakes.FakePluginSource{
|
||||||
|
PluginClassFunc: func(ctx context.Context) plugins.Class {
|
||||||
|
return plugins.Bundled
|
||||||
|
},
|
||||||
|
PluginURIsFunc: func(ctx context.Context) []string {
|
||||||
|
return pluginPaths
|
||||||
|
},
|
||||||
|
DefaultSignatureFunc: func(ctx context.Context) (plugins.Signature, bool) {
|
||||||
|
return plugins.Signature{
|
||||||
|
Status: plugins.SignatureValid,
|
||||||
|
}, true
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
require.NoError(t, err)
|
||||||
|
if !cmp.Equal(got, expected, compareOpts...) {
|
||||||
|
t.Fatalf("Result mismatch (-want +got):\n%s", cmp.Diff(got, expected, compareOpts...))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestLoader_setDefaultNavURL(t *testing.T) {
|
func TestLoader_setDefaultNavURL(t *testing.T) {
|
||||||
t.Run("When including a dashboard with DefaultNav: true", func(t *testing.T) {
|
t.Run("When including a dashboard with DefaultNav: true", func(t *testing.T) {
|
||||||
pluginWithDashboard := &plugins.Plugin{
|
pluginWithDashboard := &plugins.Plugin{
|
||||||
@ -1304,10 +1330,9 @@ func Test_setPathsBasedOnApp(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func newLoader(cfg *config.Cfg, cbs ...func(loader *Loader)) *Loader {
|
func newLoader(cfg *config.Cfg, cbs ...func(loader *Loader)) *Loader {
|
||||||
cdn := pluginscdn.ProvideService(cfg)
|
|
||||||
l := New(cfg, &fakes.FakeLicensingService{}, signature.NewUnsignedAuthorizer(cfg), fakes.NewFakePluginRegistry(),
|
l := New(cfg, &fakes.FakeLicensingService{}, signature.NewUnsignedAuthorizer(cfg), fakes.NewFakePluginRegistry(),
|
||||||
fakes.NewFakeBackendProcessProvider(), fakes.NewFakeProcessManager(), fakes.NewFakePluginStorage(),
|
fakes.NewFakeBackendProcessProvider(), fakes.NewFakeProcessManager(), fakes.NewFakePluginStorage(),
|
||||||
fakes.NewFakeRoleRegistry(), cdn, assetpath.ProvideService(cdn), finder.NewLocalFinder())
|
fakes.NewFakeRoleRegistry(), assetpath.ProvideService(pluginscdn.ProvideService(cfg)), finder.NewLocalFinder())
|
||||||
|
|
||||||
for _, cb := range cbs {
|
for _, cb := range cbs {
|
||||||
cb(l)
|
cb(l)
|
||||||
|
@ -114,12 +114,10 @@ func TestIntegrationPluginManager(t *testing.T) {
|
|||||||
pCfg, err := config.ProvideConfig(setting.ProvideProvider(cfg), cfg)
|
pCfg, err := config.ProvideConfig(setting.ProvideProvider(cfg), cfg)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
reg := registry.ProvideService()
|
reg := registry.ProvideService()
|
||||||
cdn := pluginscdn.ProvideService(pCfg)
|
|
||||||
|
|
||||||
lic := plicensing.ProvideLicensing(cfg, &licensing.OSSLicensingService{Cfg: cfg})
|
lic := plicensing.ProvideLicensing(cfg, &licensing.OSSLicensingService{Cfg: cfg})
|
||||||
l := loader.ProvideService(pCfg, lic, signature.NewUnsignedAuthorizer(pCfg),
|
l := loader.ProvideService(pCfg, lic, signature.NewUnsignedAuthorizer(pCfg),
|
||||||
reg, provider.ProvideService(coreRegistry), finder.NewLocalFinder(), fakes.NewFakeRoleRegistry(),
|
reg, provider.ProvideService(coreRegistry), finder.NewLocalFinder(), fakes.NewFakeRoleRegistry(),
|
||||||
cdn, assetpath.ProvideService(cdn))
|
assetpath.ProvideService(pluginscdn.ProvideService(pCfg)))
|
||||||
srcs := sources.ProvideService(cfg, pCfg)
|
srcs := sources.ProvideService(cfg, pCfg)
|
||||||
ps, err := store.ProvideService(reg, srcs, l)
|
ps, err := store.ProvideService(reg, srcs, l)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
Loading…
Reference in New Issue
Block a user