Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c3c5229986 | |||
| 7a2775b1a7 | |||
| d25a8f5e72 | |||
| 48d032e5aa | |||
| ae06690681 |
@@ -30,6 +30,7 @@ require (
|
|||||||
require (
|
require (
|
||||||
cel.dev/expr v0.25.1 // indirect
|
cel.dev/expr v0.25.1 // indirect
|
||||||
github.com/Machiel/slugify v1.0.1 // indirect
|
github.com/Machiel/slugify v1.0.1 // indirect
|
||||||
|
github.com/Masterminds/semver/v3 v3.4.0 // indirect
|
||||||
github.com/NYTimes/gziphandler v1.1.1 // indirect
|
github.com/NYTimes/gziphandler v1.1.1 // indirect
|
||||||
github.com/ProtonMail/go-crypto v1.3.0 // indirect
|
github.com/ProtonMail/go-crypto v1.3.0 // indirect
|
||||||
github.com/antlr4-go/antlr/v4 v4.13.1 // indirect
|
github.com/antlr4-go/antlr/v4 v4.13.1 // indirect
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2
|
|||||||
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
||||||
github.com/Machiel/slugify v1.0.1 h1:EfWSlRWstMadsgzmiV7d0yVd2IFlagWH68Q+DcYCm4E=
|
github.com/Machiel/slugify v1.0.1 h1:EfWSlRWstMadsgzmiV7d0yVd2IFlagWH68Q+DcYCm4E=
|
||||||
github.com/Machiel/slugify v1.0.1/go.mod h1:fTFGn5uWEynW4CUMG7sWkYXOf1UgDxyTM3DbR6Qfg3k=
|
github.com/Machiel/slugify v1.0.1/go.mod h1:fTFGn5uWEynW4CUMG7sWkYXOf1UgDxyTM3DbR6Qfg3k=
|
||||||
|
github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
|
||||||
|
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
|
||||||
github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=
|
github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=
|
||||||
github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
|
github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
|
||||||
github.com/ProtonMail/go-crypto v1.3.0 h1:ILq8+Sf5If5DCpHQp4PbZdS1J7HDFRXz/+xKBiRGFrw=
|
github.com/ProtonMail/go-crypto v1.3.0 h1:ILq8+Sf5If5DCpHQp4PbZdS1J7HDFRXz/+xKBiRGFrw=
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/plugins"
|
|
||||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
|
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -12,25 +11,16 @@ const (
|
|||||||
defaultLocalTTL = 1 * time.Hour
|
defaultLocalTTL = 1 * time.Hour
|
||||||
)
|
)
|
||||||
|
|
||||||
// PluginAssetsCalculator is an interface for calculating plugin asset information.
|
|
||||||
// LocalProvider requires this to calculate loading strategy.
|
|
||||||
type PluginAssetsCalculator interface {
|
|
||||||
LoadingStrategy(ctx context.Context, p pluginstore.Plugin) plugins.LoadingStrategy
|
|
||||||
}
|
|
||||||
|
|
||||||
// LocalProvider retrieves plugin metadata for locally installed plugins.
|
// LocalProvider retrieves plugin metadata for locally installed plugins.
|
||||||
// It uses the plugin store to access plugins that have already been loaded.
|
// It uses the plugin store to access plugins that have already been loaded.
|
||||||
type LocalProvider struct {
|
type LocalProvider struct {
|
||||||
store pluginstore.Store
|
store pluginstore.Store
|
||||||
pluginAssets PluginAssetsCalculator
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewLocalProvider creates a new LocalProvider for locally installed plugins.
|
// NewLocalProvider creates a new LocalProvider for locally installed plugins.
|
||||||
// pluginAssets is required for calculating loading strategy.
|
func NewLocalProvider(pluginStore pluginstore.Store) *LocalProvider {
|
||||||
func NewLocalProvider(pluginStore pluginstore.Store, pluginAssets PluginAssetsCalculator) *LocalProvider {
|
|
||||||
return &LocalProvider{
|
return &LocalProvider{
|
||||||
store: pluginStore,
|
store: pluginStore,
|
||||||
pluginAssets: pluginAssets,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,10 +31,7 @@ func (p *LocalProvider) GetMeta(ctx context.Context, pluginID, version string) (
|
|||||||
return nil, ErrMetaNotFound
|
return nil, ErrMetaNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
loadingStrategy := p.pluginAssets.LoadingStrategy(ctx, plugin)
|
spec := pluginStorePluginToMeta(plugin, plugin.LoadingStrategy, plugin.ModuleHash)
|
||||||
moduleHash := plugin.ModuleHash
|
|
||||||
|
|
||||||
spec := pluginStorePluginToMeta(plugin, loadingStrategy, moduleHash)
|
|
||||||
return &Result{
|
return &Result{
|
||||||
Meta: spec,
|
Meta: spec,
|
||||||
TTL: defaultLocalTTL,
|
TTL: defaultLocalTTL,
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ func (hs *HTTPServer) getFrontendSettings(c *contextmodel.ReqContext) (*dtos.Fro
|
|||||||
Signature: string(panel.Signature),
|
Signature: string(panel.Signature),
|
||||||
Sort: getPanelSort(panel.ID),
|
Sort: getPanelSort(panel.ID),
|
||||||
Angular: panel.Angular,
|
Angular: panel.Angular,
|
||||||
LoadingStrategy: hs.pluginAssets.LoadingStrategy(c.Req.Context(), panel),
|
LoadingStrategy: panel.LoadingStrategy,
|
||||||
Translations: panel.Translations,
|
Translations: panel.Translations,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -531,7 +531,7 @@ func (hs *HTTPServer) getFSDataSources(c *contextmodel.ReqContext, availablePlug
|
|||||||
BaseURL: plugin.BaseURL,
|
BaseURL: plugin.BaseURL,
|
||||||
Angular: plugin.Angular,
|
Angular: plugin.Angular,
|
||||||
MultiValueFilterOperators: plugin.MultiValueFilterOperators,
|
MultiValueFilterOperators: plugin.MultiValueFilterOperators,
|
||||||
LoadingStrategy: hs.pluginAssets.LoadingStrategy(c.Req.Context(), plugin),
|
LoadingStrategy: plugin.LoadingStrategy,
|
||||||
Translations: plugin.Translations,
|
Translations: plugin.Translations,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -638,7 +638,7 @@ func (hs *HTTPServer) newAppDTO(ctx context.Context, plugin pluginstore.Plugin,
|
|||||||
Path: plugin.Module,
|
Path: plugin.Module,
|
||||||
Preload: false,
|
Preload: false,
|
||||||
Angular: plugin.Angular,
|
Angular: plugin.Angular,
|
||||||
LoadingStrategy: hs.pluginAssets.LoadingStrategy(ctx, plugin),
|
LoadingStrategy: plugin.LoadingStrategy,
|
||||||
Extensions: plugin.Extensions,
|
Extensions: plugin.Extensions,
|
||||||
Dependencies: plugin.Dependencies,
|
Dependencies: plugin.Dependencies,
|
||||||
ModuleHash: plugin.ModuleHash,
|
ModuleHash: plugin.ModuleHash,
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||||
"github.com/grafana/grafana/pkg/services/licensing"
|
"github.com/grafana/grafana/pkg/services/licensing"
|
||||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/managedplugins"
|
"github.com/grafana/grafana/pkg/services/pluginsintegration/managedplugins"
|
||||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginassets"
|
|
||||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsettings"
|
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsettings"
|
||||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
|
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
|
||||||
"github.com/grafana/grafana/pkg/services/rendering"
|
"github.com/grafana/grafana/pkg/services/rendering"
|
||||||
@@ -44,7 +43,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/web"
|
"github.com/grafana/grafana/pkg/web"
|
||||||
)
|
)
|
||||||
|
|
||||||
func setupTestEnvironment(t *testing.T, cfg *setting.Cfg, features featuremgmt.FeatureToggles, pstore pluginstore.Store, psettings pluginsettings.Service, passets *pluginassets.Service) (*web.Mux, *HTTPServer) {
|
func setupTestEnvironment(t *testing.T, cfg *setting.Cfg, features featuremgmt.FeatureToggles, pstore pluginstore.Store, psettings pluginsettings.Service) (*web.Mux, *HTTPServer) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
db.InitTestDB(t)
|
db.InitTestDB(t)
|
||||||
// nolint:staticcheck
|
// nolint:staticcheck
|
||||||
@@ -75,11 +74,6 @@ func setupTestEnvironment(t *testing.T, cfg *setting.Cfg, features featuremgmt.F
|
|||||||
pluginsSettings = &pluginsettings.FakePluginSettings{}
|
pluginsSettings = &pluginsettings.FakePluginSettings{}
|
||||||
}
|
}
|
||||||
|
|
||||||
var pluginsAssets = passets
|
|
||||||
if pluginsAssets == nil {
|
|
||||||
pluginsAssets = pluginassets.ProvideService(pluginsCfg, pluginsCDN, pluginStore)
|
|
||||||
}
|
|
||||||
|
|
||||||
hs := &HTTPServer{
|
hs := &HTTPServer{
|
||||||
authnService: &authntest.FakeService{},
|
authnService: &authntest.FakeService{},
|
||||||
Cfg: cfg,
|
Cfg: cfg,
|
||||||
@@ -96,7 +90,6 @@ func setupTestEnvironment(t *testing.T, cfg *setting.Cfg, features featuremgmt.F
|
|||||||
AccessControl: accesscontrolmock.New(),
|
AccessControl: accesscontrolmock.New(),
|
||||||
PluginSettings: pluginsSettings,
|
PluginSettings: pluginsSettings,
|
||||||
pluginsCDNService: pluginsCDN,
|
pluginsCDNService: pluginsCDN,
|
||||||
pluginAssets: pluginsAssets,
|
|
||||||
namespacer: request.GetNamespaceMapper(cfg),
|
namespacer: request.GetNamespaceMapper(cfg),
|
||||||
SocialService: socialimpl.ProvideService(cfg, features, &usagestats.UsageStatsMock{}, supportbundlestest.NewFakeBundleService(), remotecache.NewFakeCacheStorage(), nil, ssosettingstests.NewFakeService()),
|
SocialService: socialimpl.ProvideService(cfg, features, &usagestats.UsageStatsMock{}, supportbundlestest.NewFakeBundleService(), remotecache.NewFakeCacheStorage(), nil, ssosettingstests.NewFakeService()),
|
||||||
managedPluginsService: managedplugins.NewNoop(),
|
managedPluginsService: managedplugins.NewNoop(),
|
||||||
@@ -129,7 +122,7 @@ func TestIntegrationHTTPServer_GetFrontendSettings_hideVersionAnonymous(t *testi
|
|||||||
cfg.BuildVersion = "7.8.9"
|
cfg.BuildVersion = "7.8.9"
|
||||||
cfg.BuildCommit = "01234567"
|
cfg.BuildCommit = "01234567"
|
||||||
|
|
||||||
m, hs := setupTestEnvironment(t, cfg, featuremgmt.WithFeatures(), nil, nil, nil)
|
m, hs := setupTestEnvironment(t, cfg, featuremgmt.WithFeatures(), nil, nil)
|
||||||
|
|
||||||
req := httptest.NewRequest(http.MethodGet, "/api/frontend/settings", nil)
|
req := httptest.NewRequest(http.MethodGet, "/api/frontend/settings", nil)
|
||||||
|
|
||||||
@@ -221,7 +214,7 @@ func TestIntegrationHTTPServer_GetFrontendSettings_pluginsCDNBaseURL(t *testing.
|
|||||||
if test.mutateCfg != nil {
|
if test.mutateCfg != nil {
|
||||||
test.mutateCfg(cfg)
|
test.mutateCfg(cfg)
|
||||||
}
|
}
|
||||||
m, _ := setupTestEnvironment(t, cfg, featuremgmt.WithFeatures(), nil, nil, nil)
|
m, _ := setupTestEnvironment(t, cfg, featuremgmt.WithFeatures(), nil, nil)
|
||||||
req := httptest.NewRequest(http.MethodGet, "/api/frontend/settings", nil)
|
req := httptest.NewRequest(http.MethodGet, "/api/frontend/settings", nil)
|
||||||
|
|
||||||
recorder := httptest.NewRecorder()
|
recorder := httptest.NewRecorder()
|
||||||
@@ -246,7 +239,6 @@ func TestIntegrationHTTPServer_GetFrontendSettings_apps(t *testing.T) {
|
|||||||
desc string
|
desc string
|
||||||
pluginStore func() pluginstore.Store
|
pluginStore func() pluginstore.Store
|
||||||
pluginSettings func() pluginsettings.Service
|
pluginSettings func() pluginsettings.Service
|
||||||
pluginAssets func() *pluginassets.Service
|
|
||||||
expected settings
|
expected settings
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
@@ -263,7 +255,8 @@ func TestIntegrationHTTPServer_GetFrontendSettings_apps(t *testing.T) {
|
|||||||
Type: plugins.TypeApp,
|
Type: plugins.TypeApp,
|
||||||
Preload: true,
|
Preload: true,
|
||||||
},
|
},
|
||||||
FS: &pluginfakes.FakePluginFS{},
|
FS: &pluginfakes.FakePluginFS{},
|
||||||
|
LoadingStrategy: plugins.LoadingStrategyScript,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -273,7 +266,6 @@ func TestIntegrationHTTPServer_GetFrontendSettings_apps(t *testing.T) {
|
|||||||
Plugins: newAppSettings("test-app", false),
|
Plugins: newAppSettings("test-app", false),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
pluginAssets: newPluginAssets(),
|
|
||||||
expected: settings{
|
expected: settings{
|
||||||
Apps: map[string]*plugins.AppDTO{
|
Apps: map[string]*plugins.AppDTO{
|
||||||
"test-app": {
|
"test-app": {
|
||||||
@@ -301,7 +293,8 @@ func TestIntegrationHTTPServer_GetFrontendSettings_apps(t *testing.T) {
|
|||||||
Type: plugins.TypeApp,
|
Type: plugins.TypeApp,
|
||||||
Preload: true,
|
Preload: true,
|
||||||
},
|
},
|
||||||
FS: &pluginfakes.FakePluginFS{},
|
FS: &pluginfakes.FakePluginFS{},
|
||||||
|
LoadingStrategy: plugins.LoadingStrategyScript,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -311,7 +304,6 @@ func TestIntegrationHTTPServer_GetFrontendSettings_apps(t *testing.T) {
|
|||||||
Plugins: newAppSettings("test-app", true),
|
Plugins: newAppSettings("test-app", true),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
pluginAssets: newPluginAssets(),
|
|
||||||
expected: settings{
|
expected: settings{
|
||||||
Apps: map[string]*plugins.AppDTO{
|
Apps: map[string]*plugins.AppDTO{
|
||||||
"test-app": {
|
"test-app": {
|
||||||
@@ -338,8 +330,9 @@ func TestIntegrationHTTPServer_GetFrontendSettings_apps(t *testing.T) {
|
|||||||
Type: plugins.TypeApp,
|
Type: plugins.TypeApp,
|
||||||
Preload: true,
|
Preload: true,
|
||||||
},
|
},
|
||||||
Angular: plugins.AngularMeta{Detected: true},
|
Angular: plugins.AngularMeta{Detected: true},
|
||||||
FS: &pluginfakes.FakePluginFS{},
|
FS: &pluginfakes.FakePluginFS{},
|
||||||
|
LoadingStrategy: plugins.LoadingStrategyFetch,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -349,7 +342,6 @@ func TestIntegrationHTTPServer_GetFrontendSettings_apps(t *testing.T) {
|
|||||||
Plugins: newAppSettings("test-app", true),
|
Plugins: newAppSettings("test-app", true),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
pluginAssets: newPluginAssets(),
|
|
||||||
expected: settings{
|
expected: settings{
|
||||||
Apps: map[string]*plugins.AppDTO{
|
Apps: map[string]*plugins.AppDTO{
|
||||||
"test-app": {
|
"test-app": {
|
||||||
@@ -376,6 +368,7 @@ func TestIntegrationHTTPServer_GetFrontendSettings_apps(t *testing.T) {
|
|||||||
Type: plugins.TypeApp,
|
Type: plugins.TypeApp,
|
||||||
Preload: true,
|
Preload: true,
|
||||||
},
|
},
|
||||||
|
LoadingStrategy: plugins.LoadingStrategyScript,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -385,13 +378,6 @@ func TestIntegrationHTTPServer_GetFrontendSettings_apps(t *testing.T) {
|
|||||||
Plugins: newAppSettings("test-app", true),
|
Plugins: newAppSettings("test-app", true),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
pluginAssets: newPluginAssetsWithConfig(&config.PluginManagementCfg{
|
|
||||||
PluginSettings: map[string]map[string]string{
|
|
||||||
"test-app": {
|
|
||||||
pluginassets.CreatePluginVersionCfgKey: pluginassets.CreatePluginVersionScriptSupportEnabled,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
expected: settings{
|
expected: settings{
|
||||||
Apps: map[string]*plugins.AppDTO{
|
Apps: map[string]*plugins.AppDTO{
|
||||||
"test-app": {
|
"test-app": {
|
||||||
@@ -421,6 +407,7 @@ func TestIntegrationHTTPServer_GetFrontendSettings_apps(t *testing.T) {
|
|||||||
FS: &pluginfakes.FakePluginFS{TypeFunc: func() plugins.FSType {
|
FS: &pluginfakes.FakePluginFS{TypeFunc: func() plugins.FSType {
|
||||||
return plugins.FSTypeCDN
|
return plugins.FSTypeCDN
|
||||||
}},
|
}},
|
||||||
|
LoadingStrategy: plugins.LoadingStrategyFetch,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -430,7 +417,6 @@ func TestIntegrationHTTPServer_GetFrontendSettings_apps(t *testing.T) {
|
|||||||
Plugins: newAppSettings("test-app", true),
|
Plugins: newAppSettings("test-app", true),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
pluginAssets: newPluginAssets(),
|
|
||||||
expected: settings{
|
expected: settings{
|
||||||
Apps: map[string]*plugins.AppDTO{
|
Apps: map[string]*plugins.AppDTO{
|
||||||
"test-app": {
|
"test-app": {
|
||||||
@@ -448,7 +434,7 @@ func TestIntegrationHTTPServer_GetFrontendSettings_apps(t *testing.T) {
|
|||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
cfg := setting.NewCfg()
|
cfg := setting.NewCfg()
|
||||||
m, _ := setupTestEnvironment(t, cfg, featuremgmt.WithFeatures(), test.pluginStore(), test.pluginSettings(), test.pluginAssets())
|
m, _ := setupTestEnvironment(t, cfg, featuremgmt.WithFeatures(), test.pluginStore(), test.pluginSettings())
|
||||||
req := httptest.NewRequest(http.MethodGet, "/api/frontend/settings", nil)
|
req := httptest.NewRequest(http.MethodGet, "/api/frontend/settings", nil)
|
||||||
|
|
||||||
recorder := httptest.NewRecorder()
|
recorder := httptest.NewRecorder()
|
||||||
@@ -549,7 +535,8 @@ func TestIntegrationHTTPServer_GetFrontendSettings_translations(t *testing.T) {
|
|||||||
"en-US": "public/plugins/test-app/locales/en-US/test-app.json",
|
"en-US": "public/plugins/test-app/locales/en-US/test-app.json",
|
||||||
"pt-BR": "public/plugins/test-app/locales/pt-BR/test-app.json",
|
"pt-BR": "public/plugins/test-app/locales/pt-BR/test-app.json",
|
||||||
},
|
},
|
||||||
FS: &pluginfakes.FakePluginFS{},
|
FS: &pluginfakes.FakePluginFS{},
|
||||||
|
LoadingStrategy: plugins.LoadingStrategyScript,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -599,7 +586,8 @@ func TestIntegrationHTTPServer_GetFrontendSettings_translations(t *testing.T) {
|
|||||||
"en-US": "public/plugins/test-app/locales/en-US/test-app.json",
|
"en-US": "public/plugins/test-app/locales/en-US/test-app.json",
|
||||||
"pt-BR": "public/plugins/test-app/locales/pt-BR/test-app.json",
|
"pt-BR": "public/plugins/test-app/locales/pt-BR/test-app.json",
|
||||||
},
|
},
|
||||||
FS: &pluginfakes.FakePluginFS{},
|
FS: &pluginfakes.FakePluginFS{},
|
||||||
|
LoadingStrategy: plugins.LoadingStrategyScript,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -639,7 +627,8 @@ func TestIntegrationHTTPServer_GetFrontendSettings_translations(t *testing.T) {
|
|||||||
"en-US": "public/plugins/test-app/locales/en-US/test-app.json",
|
"en-US": "public/plugins/test-app/locales/en-US/test-app.json",
|
||||||
"pt-BR": "public/plugins/test-app/locales/pt-BR/test-app.json",
|
"pt-BR": "public/plugins/test-app/locales/pt-BR/test-app.json",
|
||||||
},
|
},
|
||||||
FS: &pluginfakes.FakePluginFS{},
|
FS: &pluginfakes.FakePluginFS{},
|
||||||
|
LoadingStrategy: plugins.LoadingStrategyScript,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -667,7 +656,7 @@ func TestIntegrationHTTPServer_GetFrontendSettings_translations(t *testing.T) {
|
|||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
cfg := setting.NewCfg()
|
cfg := setting.NewCfg()
|
||||||
m, hs := setupTestEnvironment(t, cfg, featuremgmt.WithFeatures(), test.pluginStore(), nil, nil)
|
m, hs := setupTestEnvironment(t, cfg, featuremgmt.WithFeatures(), test.pluginStore(), nil)
|
||||||
|
|
||||||
// Create a request with the appropriate context
|
// Create a request with the appropriate context
|
||||||
req := httptest.NewRequest(http.MethodGet, "/api/frontend/settings", nil)
|
req := httptest.NewRequest(http.MethodGet, "/api/frontend/settings", nil)
|
||||||
@@ -704,13 +693,3 @@ func TestIntegrationHTTPServer_GetFrontendSettings_translations(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newPluginAssets() func() *pluginassets.Service {
|
|
||||||
return newPluginAssetsWithConfig(&config.PluginManagementCfg{})
|
|
||||||
}
|
|
||||||
|
|
||||||
func newPluginAssetsWithConfig(pCfg *config.PluginManagementCfg) func() *pluginassets.Service {
|
|
||||||
return func() *pluginassets.Service {
|
|
||||||
return pluginassets.ProvideService(pCfg, pluginscdn.ProvideService(pCfg), &pluginstore.FakePluginStore{})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -82,7 +82,6 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/services/playlist"
|
"github.com/grafana/grafana/pkg/services/playlist"
|
||||||
"github.com/grafana/grafana/pkg/services/plugindashboards"
|
"github.com/grafana/grafana/pkg/services/plugindashboards"
|
||||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/managedplugins"
|
"github.com/grafana/grafana/pkg/services/pluginsintegration/managedplugins"
|
||||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginassets"
|
|
||||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginchecker"
|
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginchecker"
|
||||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/plugincontext"
|
"github.com/grafana/grafana/pkg/services/pluginsintegration/plugincontext"
|
||||||
pluginSettings "github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsettings"
|
pluginSettings "github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsettings"
|
||||||
@@ -151,7 +150,6 @@ type HTTPServer struct {
|
|||||||
pluginDashboardService plugindashboards.Service
|
pluginDashboardService plugindashboards.Service
|
||||||
pluginStaticRouteResolver plugins.StaticRouteResolver
|
pluginStaticRouteResolver plugins.StaticRouteResolver
|
||||||
pluginErrorResolver plugins.ErrorResolver
|
pluginErrorResolver plugins.ErrorResolver
|
||||||
pluginAssets *pluginassets.Service
|
|
||||||
pluginPreinstall pluginchecker.Preinstall
|
pluginPreinstall pluginchecker.Preinstall
|
||||||
SearchService search.Service
|
SearchService search.Service
|
||||||
ShortURLService shorturls.Service
|
ShortURLService shorturls.Service
|
||||||
@@ -255,7 +253,7 @@ func ProvideHTTPServer(opts ServerOptions, cfg *setting.Cfg, routeRegister routi
|
|||||||
encryptionService encryption.Internal, grafanaUpdateChecker *updatemanager.GrafanaService,
|
encryptionService encryption.Internal, grafanaUpdateChecker *updatemanager.GrafanaService,
|
||||||
pluginsUpdateChecker *updatemanager.PluginsService, searchUsersService searchusers.Service,
|
pluginsUpdateChecker *updatemanager.PluginsService, searchUsersService searchusers.Service,
|
||||||
dataSourcesService datasources.DataSourceService, queryDataService query.Service, pluginFileStore plugins.FileStore,
|
dataSourcesService datasources.DataSourceService, queryDataService query.Service, pluginFileStore plugins.FileStore,
|
||||||
serviceaccountsService serviceaccounts.Service, pluginAssets *pluginassets.Service,
|
serviceaccountsService serviceaccounts.Service,
|
||||||
authInfoService login.AuthInfoService, storageService store.StorageService,
|
authInfoService login.AuthInfoService, storageService store.StorageService,
|
||||||
notificationService notifications.Service, dashboardService dashboards.DashboardService,
|
notificationService notifications.Service, dashboardService dashboards.DashboardService,
|
||||||
dashboardProvisioningService dashboards.DashboardProvisioningService, folderService folder.Service,
|
dashboardProvisioningService dashboards.DashboardProvisioningService, folderService folder.Service,
|
||||||
@@ -294,7 +292,6 @@ func ProvideHTTPServer(opts ServerOptions, cfg *setting.Cfg, routeRegister routi
|
|||||||
pluginStore: pluginStore,
|
pluginStore: pluginStore,
|
||||||
pluginStaticRouteResolver: pluginStaticRouteResolver,
|
pluginStaticRouteResolver: pluginStaticRouteResolver,
|
||||||
pluginDashboardService: pluginDashboardService,
|
pluginDashboardService: pluginDashboardService,
|
||||||
pluginAssets: pluginAssets,
|
|
||||||
pluginErrorResolver: pluginErrorResolver,
|
pluginErrorResolver: pluginErrorResolver,
|
||||||
pluginFileStore: pluginFileStore,
|
pluginFileStore: pluginFileStore,
|
||||||
grafanaUpdateChecker: grafanaUpdateChecker,
|
grafanaUpdateChecker: grafanaUpdateChecker,
|
||||||
|
|||||||
+1
-1
@@ -209,7 +209,7 @@ func (hs *HTTPServer) GetPluginSettingByID(c *contextmodel.ReqContext) response.
|
|||||||
SignatureOrg: plugin.SignatureOrg,
|
SignatureOrg: plugin.SignatureOrg,
|
||||||
SecureJsonFields: map[string]bool{},
|
SecureJsonFields: map[string]bool{},
|
||||||
AngularDetected: plugin.Angular.Detected,
|
AngularDetected: plugin.Angular.Detected,
|
||||||
LoadingStrategy: hs.pluginAssets.LoadingStrategy(c.Req.Context(), plugin),
|
LoadingStrategy: plugin.LoadingStrategy,
|
||||||
Extensions: plugin.Extensions,
|
Extensions: plugin.Extensions,
|
||||||
Translations: plugin.Translations,
|
Translations: plugin.Translations,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/services/org/orgtest"
|
"github.com/grafana/grafana/pkg/services/org/orgtest"
|
||||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/managedplugins"
|
"github.com/grafana/grafana/pkg/services/pluginsintegration/managedplugins"
|
||||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginaccesscontrol"
|
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginaccesscontrol"
|
||||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginassets"
|
|
||||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginchecker"
|
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginchecker"
|
||||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsettings"
|
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsettings"
|
||||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
|
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
|
||||||
@@ -675,9 +674,10 @@ func Test_PluginsList_AccessControl(t *testing.T) {
|
|||||||
|
|
||||||
func createPlugin(jd plugins.JSONData, class plugins.Class, files plugins.FS) *plugins.Plugin {
|
func createPlugin(jd plugins.JSONData, class plugins.Class, files plugins.FS) *plugins.Plugin {
|
||||||
return &plugins.Plugin{
|
return &plugins.Plugin{
|
||||||
JSONData: jd,
|
JSONData: jd,
|
||||||
Class: class,
|
Class: class,
|
||||||
FS: files,
|
FS: files,
|
||||||
|
LoadingStrategy: plugins.LoadingStrategyScript,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -844,9 +844,6 @@ func Test_PluginsSettings(t *testing.T) {
|
|||||||
ErrorCode: tc.errCode,
|
ErrorCode: tc.errCode,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
pCfg := &config.PluginManagementCfg{}
|
|
||||||
pluginCDN := pluginscdn.ProvideService(pCfg)
|
|
||||||
hs.pluginAssets = pluginassets.ProvideService(pCfg, pluginCDN, hs.pluginStore)
|
|
||||||
hs.pluginErrorResolver = pluginerrs.ProvideStore(errTracker)
|
hs.pluginErrorResolver = pluginerrs.ProvideStore(errTracker)
|
||||||
hs.pluginsUpdateChecker, err = updatemanager.ProvidePluginsService(
|
hs.pluginsUpdateChecker, err = updatemanager.ProvidePluginsService(
|
||||||
hs.Cfg,
|
hs.Cfg,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ go 1.25.5
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/Machiel/slugify v1.0.1
|
github.com/Machiel/slugify v1.0.1
|
||||||
|
github.com/Masterminds/semver/v3 v3.4.0
|
||||||
github.com/ProtonMail/go-crypto v1.3.0
|
github.com/ProtonMail/go-crypto v1.3.0
|
||||||
github.com/gobwas/glob v0.2.3
|
github.com/gobwas/glob v0.2.3
|
||||||
github.com/google/go-cmp v0.7.0
|
github.com/google/go-cmp v0.7.0
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEK
|
|||||||
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||||
github.com/Machiel/slugify v1.0.1 h1:EfWSlRWstMadsgzmiV7d0yVd2IFlagWH68Q+DcYCm4E=
|
github.com/Machiel/slugify v1.0.1 h1:EfWSlRWstMadsgzmiV7d0yVd2IFlagWH68Q+DcYCm4E=
|
||||||
github.com/Machiel/slugify v1.0.1/go.mod h1:fTFGn5uWEynW4CUMG7sWkYXOf1UgDxyTM3DbR6Qfg3k=
|
github.com/Machiel/slugify v1.0.1/go.mod h1:fTFGn5uWEynW4CUMG7sWkYXOf1UgDxyTM3DbR6Qfg3k=
|
||||||
|
github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
|
||||||
|
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
|
||||||
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
||||||
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||||
github.com/ProtonMail/go-crypto v1.3.0 h1:ILq8+Sf5If5DCpHQp4PbZdS1J7HDFRXz/+xKBiRGFrw=
|
github.com/ProtonMail/go-crypto v1.3.0 h1:ILq8+Sf5If5DCpHQp4PbZdS1J7HDFRXz/+xKBiRGFrw=
|
||||||
|
|||||||
@@ -129,6 +129,7 @@ func TestLoader_Load(t *testing.T) {
|
|||||||
Class: plugins.ClassCore,
|
Class: plugins.ClassCore,
|
||||||
SkipHostEnvVars: true,
|
SkipHostEnvVars: true,
|
||||||
Translations: map[string]string{},
|
Translations: map[string]string{},
|
||||||
|
LoadingStrategy: plugins.LoadingStrategyScript,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -242,6 +243,7 @@ func TestLoader_Load(t *testing.T) {
|
|||||||
SignatureOrg: "Grafana Labs",
|
SignatureOrg: "Grafana Labs",
|
||||||
SkipHostEnvVars: true,
|
SkipHostEnvVars: true,
|
||||||
Translations: map[string]string{},
|
Translations: map[string]string{},
|
||||||
|
LoadingStrategy: plugins.LoadingStrategyScript,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -294,6 +296,7 @@ func TestLoader_Load(t *testing.T) {
|
|||||||
Signature: "unsigned",
|
Signature: "unsigned",
|
||||||
SkipHostEnvVars: true,
|
SkipHostEnvVars: true,
|
||||||
Translations: map[string]string{},
|
Translations: map[string]string{},
|
||||||
|
LoadingStrategy: plugins.LoadingStrategyScript,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -353,6 +356,7 @@ func TestLoader_Load(t *testing.T) {
|
|||||||
Signature: plugins.SignatureStatusUnsigned,
|
Signature: plugins.SignatureStatusUnsigned,
|
||||||
SkipHostEnvVars: true,
|
SkipHostEnvVars: true,
|
||||||
Translations: map[string]string{},
|
Translations: map[string]string{},
|
||||||
|
LoadingStrategy: plugins.LoadingStrategyScript,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -451,6 +455,7 @@ func TestLoader_Load(t *testing.T) {
|
|||||||
BaseURL: "public/plugins/test-app",
|
BaseURL: "public/plugins/test-app",
|
||||||
SkipHostEnvVars: true,
|
SkipHostEnvVars: true,
|
||||||
Translations: map[string]string{},
|
Translations: map[string]string{},
|
||||||
|
LoadingStrategy: plugins.LoadingStrategyScript,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ func DefaultDecorateFuncs(cfg *config.PluginManagementCfg, cdn *pluginscdn.Servi
|
|||||||
AppChildDecorateFunc(),
|
AppChildDecorateFunc(),
|
||||||
SkipHostEnvVarsDecorateFunc(cfg),
|
SkipHostEnvVarsDecorateFunc(cfg),
|
||||||
ModuleHashDecorateFunc(cfg, cdn),
|
ModuleHashDecorateFunc(cfg, cdn),
|
||||||
|
LoadingStrategyDecorateFunc(cfg, cdn),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,3 +167,11 @@ func ModuleHashDecorateFunc(cfg *config.PluginManagementCfg, cdn *pluginscdn.Ser
|
|||||||
return p, nil
|
return p, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LoadingStrategyDecorateFunc returns a DecorateFunc that calculates and sets the loading strategy for the plugin.
|
||||||
|
func LoadingStrategyDecorateFunc(cfg *config.PluginManagementCfg, cdn *pluginscdn.Service) DecorateFunc {
|
||||||
|
return func(_ context.Context, p *plugins.Plugin) (*plugins.Plugin, error) {
|
||||||
|
p.LoadingStrategy = pluginassets.CalculateLoadingStrategy(p, cfg, cdn)
|
||||||
|
return p, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
package pluginassets
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/Masterminds/semver/v3"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/plugins"
|
||||||
|
"github.com/grafana/grafana/pkg/plugins/config"
|
||||||
|
"github.com/grafana/grafana/pkg/plugins/pluginscdn"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
CreatePluginVersionCfgKey = "create_plugin_version"
|
||||||
|
CreatePluginVersionScriptSupportEnabled = "4.15.0"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
scriptLoadingMinSupportedVersion = semver.MustParse(CreatePluginVersionScriptSupportEnabled)
|
||||||
|
)
|
||||||
|
|
||||||
|
// CalculateLoadingStrategy calculates the loading strategy for a plugin.
|
||||||
|
// If a plugin has plugin setting `create_plugin_version` >= 4.15.0, set loadingStrategy to "script".
|
||||||
|
// If a plugin is not loaded via the CDN and is not Angular, set loadingStrategy to "script".
|
||||||
|
// Otherwise, set loadingStrategy to "fetch".
|
||||||
|
func CalculateLoadingStrategy(p *plugins.Plugin, cfg *config.PluginManagementCfg, cdn *pluginscdn.Service) plugins.LoadingStrategy {
|
||||||
|
if cfg != nil && cfg.PluginSettings != nil {
|
||||||
|
if pCfg, ok := cfg.PluginSettings[p.ID]; ok {
|
||||||
|
if compatibleCreatePluginVersion(pCfg) {
|
||||||
|
return plugins.LoadingStrategyScript
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the plugin has a parent
|
||||||
|
if p.Parent != nil {
|
||||||
|
// Check the parent's create_plugin_version setting
|
||||||
|
if pCfg, ok := cfg.PluginSettings[p.Parent.ID]; ok {
|
||||||
|
if compatibleCreatePluginVersion(pCfg) {
|
||||||
|
return plugins.LoadingStrategyScript
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Since the parent plugin is not explicitly configured as script loading compatible,
|
||||||
|
// If the plugin is either loaded from the CDN (via its parent) or contains Angular, we should use fetch
|
||||||
|
if cdnEnabled(p.Parent, cdn) || p.Angular.Detected {
|
||||||
|
return plugins.LoadingStrategyFetch
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !cdnEnabled(p, cdn) && !p.Angular.Detected {
|
||||||
|
return plugins.LoadingStrategyScript
|
||||||
|
}
|
||||||
|
|
||||||
|
return plugins.LoadingStrategyFetch
|
||||||
|
}
|
||||||
|
|
||||||
|
// compatibleCreatePluginVersion checks if the create_plugin_version setting is >= 4.15.0
|
||||||
|
func compatibleCreatePluginVersion(ps map[string]string) bool {
|
||||||
|
if cpv, ok := ps[CreatePluginVersionCfgKey]; ok {
|
||||||
|
createPluginVer, err := semver.NewVersion(cpv)
|
||||||
|
if err != nil {
|
||||||
|
// Invalid semver, treat as incompatible
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return !createPluginVer.LessThan(scriptLoadingMinSupportedVersion)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
+63
-67
@@ -1,20 +1,25 @@
|
|||||||
package pluginassets
|
package pluginassets
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
|
||||||
"github.com/grafana/grafana/pkg/plugins"
|
"github.com/grafana/grafana/pkg/plugins"
|
||||||
"github.com/grafana/grafana/pkg/plugins/config"
|
"github.com/grafana/grafana/pkg/plugins/config"
|
||||||
"github.com/grafana/grafana/pkg/plugins/manager/pluginfakes"
|
|
||||||
"github.com/grafana/grafana/pkg/plugins/pluginscdn"
|
"github.com/grafana/grafana/pkg/plugins/pluginscdn"
|
||||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestService_Calculate(t *testing.T) {
|
// cdnFS is a simple mock FS that returns CDN type
|
||||||
|
type cdnFS struct {
|
||||||
|
plugins.FS
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *cdnFS) Type() plugins.FSType {
|
||||||
|
return plugins.FSTypeCDN
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCalculateLoadingStrategy(t *testing.T) {
|
||||||
const pluginID = "grafana-test-datasource"
|
const pluginID = "grafana-test-datasource"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -26,7 +31,7 @@ func TestService_Calculate(t *testing.T) {
|
|||||||
tcs := []struct {
|
tcs := []struct {
|
||||||
name string
|
name string
|
||||||
pluginSettings config.PluginSettings
|
pluginSettings config.PluginSettings
|
||||||
plugin pluginstore.Plugin
|
plugin *plugins.Plugin
|
||||||
expected plugins.LoadingStrategy
|
expected plugins.LoadingStrategy
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
@@ -34,7 +39,7 @@ func TestService_Calculate(t *testing.T) {
|
|||||||
pluginSettings: newPluginSettings(pluginID, map[string]string{
|
pluginSettings: newPluginSettings(pluginID, map[string]string{
|
||||||
CreatePluginVersionCfgKey: compatVersion,
|
CreatePluginVersionCfgKey: compatVersion,
|
||||||
}),
|
}),
|
||||||
plugin: newPlugin(pluginID, withAngular(false)),
|
plugin: newPluginForLoadingStrategy(pluginID, withAngularForLoadingStrategy(false)),
|
||||||
expected: plugins.LoadingStrategyScript,
|
expected: plugins.LoadingStrategyScript,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -42,9 +47,11 @@ func TestService_Calculate(t *testing.T) {
|
|||||||
pluginSettings: newPluginSettings("parent-datasource", map[string]string{
|
pluginSettings: newPluginSettings("parent-datasource", map[string]string{
|
||||||
CreatePluginVersionCfgKey: compatVersion,
|
CreatePluginVersionCfgKey: compatVersion,
|
||||||
}),
|
}),
|
||||||
plugin: newPlugin(pluginID, withAngular(false), func(p pluginstore.Plugin) pluginstore.Plugin {
|
plugin: newPluginForLoadingStrategy(pluginID, withAngularForLoadingStrategy(false), func(p *plugins.Plugin) {
|
||||||
p.Parent = &pluginstore.ParentPlugin{ID: "parent-datasource"}
|
p.Parent = &plugins.Plugin{
|
||||||
return p
|
JSONData: plugins.JSONData{ID: "parent-datasource"},
|
||||||
|
FS: plugins.NewFakeFS(),
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
expected: plugins.LoadingStrategyScript,
|
expected: plugins.LoadingStrategyScript,
|
||||||
},
|
},
|
||||||
@@ -53,24 +60,21 @@ func TestService_Calculate(t *testing.T) {
|
|||||||
pluginSettings: newPluginSettings(pluginID, map[string]string{
|
pluginSettings: newPluginSettings(pluginID, map[string]string{
|
||||||
CreatePluginVersionCfgKey: futureVersion,
|
CreatePluginVersionCfgKey: futureVersion,
|
||||||
}),
|
}),
|
||||||
plugin: newPlugin(pluginID, withAngular(false), withFS(plugins.NewFakeFS())),
|
plugin: newPluginForLoadingStrategy(pluginID, withAngularForLoadingStrategy(false), withFSForLoadingStrategy(plugins.NewFakeFS())),
|
||||||
expected: plugins.LoadingStrategyScript,
|
expected: plugins.LoadingStrategyScript,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Expected LoadingStrategyScript when create-plugin version is not provided, plugin is not angular and is not configured as CDN enabled",
|
name: "Expected LoadingStrategyScript when create-plugin version is not provided, plugin is not angular and is not configured as CDN enabled",
|
||||||
pluginSettings: newPluginSettings(pluginID, map[string]string{
|
pluginSettings: newPluginSettings(pluginID, map[string]string{}),
|
||||||
// NOTE: cdn key is not set
|
plugin: newPluginForLoadingStrategy(pluginID, withAngularForLoadingStrategy(false), withFSForLoadingStrategy(plugins.NewFakeFS())),
|
||||||
}),
|
expected: plugins.LoadingStrategyScript,
|
||||||
plugin: newPlugin(pluginID, withAngular(false), withFS(plugins.NewFakeFS())),
|
|
||||||
expected: plugins.LoadingStrategyScript,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Expected LoadingStrategyScript when create-plugin version is not compatible, plugin is not angular, is not configured as CDN enabled and does not have a CDN fs",
|
name: "Expected LoadingStrategyScript when create-plugin version is not compatible, plugin is not angular, is not configured as CDN enabled and does not have a CDN fs",
|
||||||
pluginSettings: newPluginSettings(pluginID, map[string]string{
|
pluginSettings: newPluginSettings(pluginID, map[string]string{
|
||||||
CreatePluginVersionCfgKey: incompatVersion,
|
CreatePluginVersionCfgKey: incompatVersion,
|
||||||
// NOTE: cdn key is not set
|
|
||||||
}),
|
}),
|
||||||
plugin: newPlugin(pluginID, withAngular(false), withClass(plugins.ClassExternal), withFS(plugins.NewFakeFS())),
|
plugin: newPluginForLoadingStrategy(pluginID, withAngularForLoadingStrategy(false), withClassForLoadingStrategy(plugins.ClassExternal), withFSForLoadingStrategy(plugins.NewFakeFS())),
|
||||||
expected: plugins.LoadingStrategyScript,
|
expected: plugins.LoadingStrategyScript,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -80,9 +84,11 @@ func TestService_Calculate(t *testing.T) {
|
|||||||
"cdn": "true",
|
"cdn": "true",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
plugin: newPlugin(pluginID, withAngular(false), func(p pluginstore.Plugin) pluginstore.Plugin {
|
plugin: newPluginForLoadingStrategy(pluginID, withAngularForLoadingStrategy(false), func(p *plugins.Plugin) {
|
||||||
p.Parent = &pluginstore.ParentPlugin{ID: "parent-datasource"}
|
p.Parent = &plugins.Plugin{
|
||||||
return p
|
JSONData: plugins.JSONData{ID: "parent-datasource"},
|
||||||
|
FS: plugins.NewFakeFS(),
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
expected: plugins.LoadingStrategyFetch,
|
expected: plugins.LoadingStrategyFetch,
|
||||||
},
|
},
|
||||||
@@ -93,18 +99,22 @@ func TestService_Calculate(t *testing.T) {
|
|||||||
"cdn": "true",
|
"cdn": "true",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
plugin: newPlugin(pluginID, withAngular(true), func(p pluginstore.Plugin) pluginstore.Plugin {
|
plugin: newPluginForLoadingStrategy(pluginID, withAngularForLoadingStrategy(true), func(p *plugins.Plugin) {
|
||||||
p.Parent = &pluginstore.ParentPlugin{ID: "parent-datasource"}
|
p.Parent = &plugins.Plugin{
|
||||||
return p
|
JSONData: plugins.JSONData{ID: "parent-datasource"},
|
||||||
|
FS: plugins.NewFakeFS(),
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
expected: plugins.LoadingStrategyFetch,
|
expected: plugins.LoadingStrategyFetch,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Expected LoadingStrategyFetch when parent create-plugin version is not set, is not configured as CDN enabled and plugin is angular",
|
name: "Expected LoadingStrategyFetch when parent create-plugin version is not set, is not configured as CDN enabled and plugin is angular",
|
||||||
pluginSettings: config.PluginSettings{},
|
pluginSettings: config.PluginSettings{},
|
||||||
plugin: newPlugin(pluginID, withAngular(true), withFS(plugins.NewFakeFS()), func(p pluginstore.Plugin) pluginstore.Plugin {
|
plugin: newPluginForLoadingStrategy(pluginID, withAngularForLoadingStrategy(true), withFSForLoadingStrategy(plugins.NewFakeFS()), func(p *plugins.Plugin) {
|
||||||
p.Parent = &pluginstore.ParentPlugin{ID: "parent-datasource"}
|
p.Parent = &plugins.Plugin{
|
||||||
return p
|
JSONData: plugins.JSONData{ID: "parent-datasource"},
|
||||||
|
FS: plugins.NewFakeFS(),
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
expected: plugins.LoadingStrategyFetch,
|
expected: plugins.LoadingStrategyFetch,
|
||||||
},
|
},
|
||||||
@@ -114,7 +124,7 @@ func TestService_Calculate(t *testing.T) {
|
|||||||
"cdn": "true",
|
"cdn": "true",
|
||||||
CreatePluginVersionCfgKey: incompatVersion,
|
CreatePluginVersionCfgKey: incompatVersion,
|
||||||
}),
|
}),
|
||||||
plugin: newPlugin(pluginID, withAngular(false), withClass(plugins.ClassExternal)),
|
plugin: newPluginForLoadingStrategy(pluginID, withAngularForLoadingStrategy(false), withClassForLoadingStrategy(plugins.ClassExternal), withFSForLoadingStrategy(plugins.NewFakeFS())),
|
||||||
expected: plugins.LoadingStrategyFetch,
|
expected: plugins.LoadingStrategyFetch,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -122,7 +132,7 @@ func TestService_Calculate(t *testing.T) {
|
|||||||
pluginSettings: newPluginSettings(pluginID, map[string]string{
|
pluginSettings: newPluginSettings(pluginID, map[string]string{
|
||||||
CreatePluginVersionCfgKey: incompatVersion,
|
CreatePluginVersionCfgKey: incompatVersion,
|
||||||
}),
|
}),
|
||||||
plugin: newPlugin(pluginID, withAngular(true), withFS(plugins.NewFakeFS())),
|
plugin: newPluginForLoadingStrategy(pluginID, withAngularForLoadingStrategy(true), withFSForLoadingStrategy(plugins.NewFakeFS())),
|
||||||
expected: plugins.LoadingStrategyFetch,
|
expected: plugins.LoadingStrategyFetch,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -131,7 +141,7 @@ func TestService_Calculate(t *testing.T) {
|
|||||||
"cdn": "true",
|
"cdn": "true",
|
||||||
CreatePluginVersionCfgKey: incompatVersion,
|
CreatePluginVersionCfgKey: incompatVersion,
|
||||||
}),
|
}),
|
||||||
plugin: newPlugin(pluginID, withAngular(false)),
|
plugin: newPluginForLoadingStrategy(pluginID, withAngularForLoadingStrategy(false), withFSForLoadingStrategy(plugins.NewFakeFS())),
|
||||||
expected: plugins.LoadingStrategyFetch,
|
expected: plugins.LoadingStrategyFetch,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -139,12 +149,8 @@ func TestService_Calculate(t *testing.T) {
|
|||||||
pluginSettings: newPluginSettings(pluginID, map[string]string{
|
pluginSettings: newPluginSettings(pluginID, map[string]string{
|
||||||
CreatePluginVersionCfgKey: incompatVersion,
|
CreatePluginVersionCfgKey: incompatVersion,
|
||||||
}),
|
}),
|
||||||
plugin: newPlugin(pluginID, withAngular(false), withFS(
|
plugin: newPluginForLoadingStrategy(pluginID, withAngularForLoadingStrategy(false), withFSForLoadingStrategy(
|
||||||
&pluginfakes.FakePluginFS{
|
&cdnFS{FS: plugins.NewFakeFS()},
|
||||||
TypeFunc: func() plugins.FSType {
|
|
||||||
return plugins.FSTypeCDN
|
|
||||||
},
|
|
||||||
},
|
|
||||||
)),
|
)),
|
||||||
expected: plugins.LoadingStrategyFetch,
|
expected: plugins.LoadingStrategyFetch,
|
||||||
},
|
},
|
||||||
@@ -153,63 +159,53 @@ func TestService_Calculate(t *testing.T) {
|
|||||||
pluginSettings: newPluginSettings(pluginID, map[string]string{
|
pluginSettings: newPluginSettings(pluginID, map[string]string{
|
||||||
CreatePluginVersionCfgKey: "invalidSemver",
|
CreatePluginVersionCfgKey: "invalidSemver",
|
||||||
}),
|
}),
|
||||||
plugin: newPlugin(pluginID, withAngular(false), withFS(plugins.NewFakeFS())),
|
plugin: newPluginForLoadingStrategy(pluginID, withAngularForLoadingStrategy(false), withFSForLoadingStrategy(plugins.NewFakeFS())),
|
||||||
expected: plugins.LoadingStrategyScript,
|
expected: plugins.LoadingStrategyScript,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tc := range tcs {
|
for _, tc := range tcs {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
s := &Service{
|
cfg := &config.PluginManagementCfg{
|
||||||
cfg: newCfg(tc.pluginSettings),
|
PluginSettings: tc.pluginSettings,
|
||||||
cdn: pluginscdn.ProvideService(&config.PluginManagementCfg{
|
|
||||||
PluginsCDNURLTemplate: "http://cdn.example.com", // required for cdn.PluginSupported check
|
|
||||||
PluginSettings: tc.pluginSettings,
|
|
||||||
}),
|
|
||||||
log: log.NewNopLogger(),
|
|
||||||
}
|
}
|
||||||
|
cdn := pluginscdn.ProvideService(&config.PluginManagementCfg{
|
||||||
|
PluginsCDNURLTemplate: "http://cdn.example.com", // required for cdn.PluginSupported check
|
||||||
|
PluginSettings: tc.pluginSettings,
|
||||||
|
})
|
||||||
|
|
||||||
got := s.LoadingStrategy(context.Background(), tc.plugin)
|
got := CalculateLoadingStrategy(tc.plugin, cfg, cdn)
|
||||||
assert.Equal(t, tc.expected, got, "unexpected loading strategy")
|
assert.Equal(t, tc.expected, got, "unexpected loading strategy")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newPlugin(pluginID string, cbs ...func(p pluginstore.Plugin) pluginstore.Plugin) pluginstore.Plugin {
|
func newPluginForLoadingStrategy(pluginID string, cbs ...func(*plugins.Plugin)) *plugins.Plugin {
|
||||||
p := pluginstore.Plugin{
|
p := &plugins.Plugin{
|
||||||
JSONData: plugins.JSONData{
|
JSONData: plugins.JSONData{
|
||||||
ID: pluginID,
|
ID: pluginID,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, cb := range cbs {
|
for _, cb := range cbs {
|
||||||
p = cb(p)
|
cb(p)
|
||||||
}
|
}
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
func withFS(fs plugins.FS) func(p pluginstore.Plugin) pluginstore.Plugin {
|
func withAngularForLoadingStrategy(angular bool) func(*plugins.Plugin) {
|
||||||
return func(p pluginstore.Plugin) pluginstore.Plugin {
|
return func(p *plugins.Plugin) {
|
||||||
p.FS = fs
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func withAngular(angular bool) func(p pluginstore.Plugin) pluginstore.Plugin {
|
|
||||||
return func(p pluginstore.Plugin) pluginstore.Plugin {
|
|
||||||
p.Angular = plugins.AngularMeta{Detected: angular}
|
p.Angular = plugins.AngularMeta{Detected: angular}
|
||||||
return p
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func withClass(class plugins.Class) func(p pluginstore.Plugin) pluginstore.Plugin {
|
func withFSForLoadingStrategy(fs plugins.FS) func(*plugins.Plugin) {
|
||||||
return func(p pluginstore.Plugin) pluginstore.Plugin {
|
return func(p *plugins.Plugin) {
|
||||||
|
p.FS = fs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func withClassForLoadingStrategy(class plugins.Class) func(*plugins.Plugin) {
|
||||||
|
return func(p *plugins.Plugin) {
|
||||||
p.Class = class
|
p.Class = class
|
||||||
return p
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func newCfg(ps config.PluginSettings) *config.PluginManagementCfg {
|
|
||||||
return &config.PluginManagementCfg{
|
|
||||||
PluginSettings: ps,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,9 +49,10 @@ type Plugin struct {
|
|||||||
Error *Error
|
Error *Error
|
||||||
|
|
||||||
// SystemJS fields
|
// SystemJS fields
|
||||||
Module string
|
Module string
|
||||||
ModuleHash string
|
ModuleHash string
|
||||||
BaseURL string
|
LoadingStrategy LoadingStrategy
|
||||||
|
BaseURL string
|
||||||
|
|
||||||
Angular AngularMeta
|
Angular AngularMeta
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/services/apiserver/appinstaller"
|
"github.com/grafana/grafana/pkg/services/apiserver/appinstaller"
|
||||||
grafanaauthorizer "github.com/grafana/grafana/pkg/services/apiserver/auth/authorizer"
|
grafanaauthorizer "github.com/grafana/grafana/pkg/services/apiserver/auth/authorizer"
|
||||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginassets"
|
|
||||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
|
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -35,7 +34,6 @@ func ProvideAppInstaller(
|
|||||||
cfgProvider configprovider.ConfigProvider,
|
cfgProvider configprovider.ConfigProvider,
|
||||||
restConfigProvider apiserver.RestConfigProvider,
|
restConfigProvider apiserver.RestConfigProvider,
|
||||||
pluginStore pluginstore.Store,
|
pluginStore pluginstore.Store,
|
||||||
pluginAssetsService *pluginassets.Service,
|
|
||||||
accessControlService accesscontrol.Service, accessClient authlib.AccessClient,
|
accessControlService accesscontrol.Service, accessClient authlib.AccessClient,
|
||||||
features featuremgmt.FeatureToggles,
|
features featuremgmt.FeatureToggles,
|
||||||
) (*AppInstaller, error) {
|
) (*AppInstaller, error) {
|
||||||
@@ -46,7 +44,7 @@ func ProvideAppInstaller(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
localProvider := meta.NewLocalProvider(pluginStore, pluginAssetsService)
|
localProvider := meta.NewLocalProvider(pluginStore)
|
||||||
metaProviderManager := meta.NewProviderManager(localProvider)
|
metaProviderManager := meta.NewProviderManager(localProvider)
|
||||||
authorizer := grafanaauthorizer.NewResourceAuthorizer(accessClient)
|
authorizer := grafanaauthorizer.NewResourceAuthorizer(accessClient)
|
||||||
i, err := pluginsapp.ProvideAppInstaller(authorizer, metaProviderManager)
|
i, err := pluginsapp.ProvideAppInstaller(authorizer, metaProviderManager)
|
||||||
|
|||||||
Generated
+4
-7
@@ -187,7 +187,6 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/managedplugins"
|
"github.com/grafana/grafana/pkg/services/pluginsintegration/managedplugins"
|
||||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pipeline"
|
"github.com/grafana/grafana/pkg/services/pluginsintegration/pipeline"
|
||||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginaccesscontrol"
|
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginaccesscontrol"
|
||||||
pluginassets2 "github.com/grafana/grafana/pkg/services/pluginsintegration/pluginassets"
|
|
||||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginchecker"
|
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginchecker"
|
||||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginconfig"
|
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginconfig"
|
||||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/plugincontext"
|
"github.com/grafana/grafana/pkg/services/pluginsintegration/plugincontext"
|
||||||
@@ -715,7 +714,6 @@ func Initialize(ctx context.Context, cfg *setting.Cfg, opts Options, apiOpts api
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
pluginassetsService := pluginassets2.ProvideService(pluginManagementCfg, pluginscdnService, pluginstoreService)
|
|
||||||
avatarCacheServer := avatar.ProvideAvatarCacheServer(cfg)
|
avatarCacheServer := avatar.ProvideAvatarCacheServer(cfg)
|
||||||
prefService := prefimpl.ProvideService(sqlStore, cfg)
|
prefService := prefimpl.ProvideService(sqlStore, cfg)
|
||||||
dashboardPermissionsService, err := ossaccesscontrol.ProvideDashboardPermissions(cfg, featureToggles, routeRegisterImpl, sqlStore, accessControl, ossLicensingService, dashboardService, folderimplService, acimplService, teamService, userService, actionSetService, dashboardServiceImpl, eventualRestConfigProvider)
|
dashboardPermissionsService, err := ossaccesscontrol.ProvideDashboardPermissions(cfg, featureToggles, routeRegisterImpl, sqlStore, accessControl, ossLicensingService, dashboardService, folderimplService, acimplService, teamService, userService, actionSetService, dashboardServiceImpl, eventualRestConfigProvider)
|
||||||
@@ -753,7 +751,7 @@ func Initialize(ctx context.Context, cfg *setting.Cfg, opts Options, apiOpts api
|
|||||||
}
|
}
|
||||||
idimplService := idimpl.ProvideService(cfg, localSigner, remoteCache, authnService, registerer, tracer)
|
idimplService := idimpl.ProvideService(cfg, localSigner, remoteCache, authnService, registerer, tracer)
|
||||||
verifier := userimpl.ProvideVerifier(cfg, userService, tempuserService, notificationService, idimplService)
|
verifier := userimpl.ProvideVerifier(cfg, userService, tempuserService, notificationService, idimplService)
|
||||||
httpServer, err := api.ProvideHTTPServer(apiOpts, cfg, routeRegisterImpl, inProcBus, renderingService, ossLicensingService, hooksService, cacheService, sqlStore, ossDataSourceRequestValidator, pluginstoreService, service14, pluginstoreService, middlewareHandler, pluginerrsStore, pluginInstaller, ossImpl, cacheServiceImpl, userAuthTokenService, cleanUpService, shortURLService, queryHistoryService, correlationsService, remoteCache, provisioningServiceImpl, accessControl, dataSourceProxyService, searchSearchService, grafanaLive, gateway, plugincontextProvider, contexthandlerContextHandler, logger, featureToggles, alertNG, libraryPanelService, libraryElementService, quotaService, socialService, tracingService, serviceService, grafanaService, pluginsService, ossService, service15, queryServiceImpl, filestoreService, serviceAccountsProxy, pluginassetsService, authinfoimplService, storageService, notificationService, dashboardService, dashboardProvisioningService, folderimplService, ossProvider, serviceImpl, service13, avatarCacheServer, prefService, folderPermissionsService, dashboardPermissionsService, dashverService, starService, csrfCSRF, managedpluginsNoop, playlistService, apikeyService, kvStore, secretsMigrator, secretsService, secretMigrationProviderImpl, secretsKVStore, apiApi, userService, tempuserService, loginattemptimplService, orgService, deletionService, teamService, acimplService, navtreeService, repositoryImpl, tagimplService, searchHTTPService, oauthtokenService, statsService, authnService, pluginscdnService, gatherer, apiAPI, registerer, eventualRestConfigProvider, anonDeviceService, verifier, preinstallImpl)
|
httpServer, err := api.ProvideHTTPServer(apiOpts, cfg, routeRegisterImpl, inProcBus, renderingService, ossLicensingService, hooksService, cacheService, sqlStore, ossDataSourceRequestValidator, pluginstoreService, service14, pluginstoreService, middlewareHandler, pluginerrsStore, pluginInstaller, ossImpl, cacheServiceImpl, userAuthTokenService, cleanUpService, shortURLService, queryHistoryService, correlationsService, remoteCache, provisioningServiceImpl, accessControl, dataSourceProxyService, searchSearchService, grafanaLive, gateway, plugincontextProvider, contexthandlerContextHandler, logger, featureToggles, alertNG, libraryPanelService, libraryElementService, quotaService, socialService, tracingService, serviceService, grafanaService, pluginsService, ossService, service15, queryServiceImpl, filestoreService, serviceAccountsProxy, authinfoimplService, storageService, notificationService, dashboardService, dashboardProvisioningService, folderimplService, ossProvider, serviceImpl, service13, avatarCacheServer, prefService, folderPermissionsService, dashboardPermissionsService, dashverService, starService, csrfCSRF, managedpluginsNoop, playlistService, apikeyService, kvStore, secretsMigrator, secretsService, secretMigrationProviderImpl, secretsKVStore, apiApi, userService, tempuserService, loginattemptimplService, orgService, deletionService, teamService, acimplService, navtreeService, repositoryImpl, tagimplService, searchHTTPService, oauthtokenService, statsService, authnService, pluginscdnService, gatherer, apiAPI, registerer, eventualRestConfigProvider, anonDeviceService, verifier, preinstallImpl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -786,7 +784,7 @@ func Initialize(ctx context.Context, cfg *setting.Cfg, opts Options, apiOpts api
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
appInstaller, err := plugins.ProvideAppInstaller(configProvider, eventualRestConfigProvider, pluginstoreService, pluginassetsService, acimplService, accessClient, featureToggles)
|
appInstaller, err := plugins.ProvideAppInstaller(configProvider, eventualRestConfigProvider, pluginstoreService, acimplService, accessClient, featureToggles)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -1383,7 +1381,6 @@ func InitializeForTest(ctx context.Context, t sqlutil.ITestDB, testingT interfac
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
pluginassetsService := pluginassets2.ProvideService(pluginManagementCfg, pluginscdnService, pluginstoreService)
|
|
||||||
avatarCacheServer := avatar.ProvideAvatarCacheServer(cfg)
|
avatarCacheServer := avatar.ProvideAvatarCacheServer(cfg)
|
||||||
prefService := prefimpl.ProvideService(sqlStore, cfg)
|
prefService := prefimpl.ProvideService(sqlStore, cfg)
|
||||||
dashboardPermissionsService, err := ossaccesscontrol.ProvideDashboardPermissions(cfg, featureToggles, routeRegisterImpl, sqlStore, accessControl, ossLicensingService, dashboardService, folderimplService, acimplService, teamService, userService, actionSetService, dashboardServiceImpl, eventualRestConfigProvider)
|
dashboardPermissionsService, err := ossaccesscontrol.ProvideDashboardPermissions(cfg, featureToggles, routeRegisterImpl, sqlStore, accessControl, ossLicensingService, dashboardService, folderimplService, acimplService, teamService, userService, actionSetService, dashboardServiceImpl, eventualRestConfigProvider)
|
||||||
@@ -1421,7 +1418,7 @@ func InitializeForTest(ctx context.Context, t sqlutil.ITestDB, testingT interfac
|
|||||||
}
|
}
|
||||||
idimplService := idimpl.ProvideService(cfg, localSigner, remoteCache, authnService, registerer, tracer)
|
idimplService := idimpl.ProvideService(cfg, localSigner, remoteCache, authnService, registerer, tracer)
|
||||||
verifier := userimpl.ProvideVerifier(cfg, userService, tempuserService, notificationServiceMock, idimplService)
|
verifier := userimpl.ProvideVerifier(cfg, userService, tempuserService, notificationServiceMock, idimplService)
|
||||||
httpServer, err := api.ProvideHTTPServer(apiOpts, cfg, routeRegisterImpl, inProcBus, renderingService, ossLicensingService, hooksService, cacheService, sqlStore, ossDataSourceRequestValidator, pluginstoreService, service14, pluginstoreService, middlewareHandler, pluginerrsStore, pluginInstaller, ossImpl, cacheServiceImpl, userAuthTokenService, cleanUpService, shortURLService, queryHistoryService, correlationsService, remoteCache, provisioningServiceImpl, accessControl, dataSourceProxyService, searchSearchService, grafanaLive, gateway, plugincontextProvider, contexthandlerContextHandler, logger, featureToggles, alertNG, libraryPanelService, libraryElementService, quotaService, socialService, tracingService, serviceService, grafanaService, pluginsService, ossService, service15, queryServiceImpl, filestoreService, serviceAccountsProxy, pluginassetsService, authinfoimplService, storageService, notificationServiceMock, dashboardService, dashboardProvisioningService, folderimplService, ossProvider, serviceImpl, service13, avatarCacheServer, prefService, folderPermissionsService, dashboardPermissionsService, dashverService, starService, csrfCSRF, managedpluginsNoop, playlistService, apikeyService, kvStore, secretsMigrator, secretsService, secretMigrationProviderImpl, secretsKVStore, apiApi, userService, tempuserService, loginattemptimplService, orgService, deletionService, teamService, acimplService, navtreeService, repositoryImpl, tagimplService, searchHTTPService, oauthtokentestService, statsService, authnService, pluginscdnService, gatherer, apiAPI, registerer, eventualRestConfigProvider, anonDeviceService, verifier, preinstallImpl)
|
httpServer, err := api.ProvideHTTPServer(apiOpts, cfg, routeRegisterImpl, inProcBus, renderingService, ossLicensingService, hooksService, cacheService, sqlStore, ossDataSourceRequestValidator, pluginstoreService, service14, pluginstoreService, middlewareHandler, pluginerrsStore, pluginInstaller, ossImpl, cacheServiceImpl, userAuthTokenService, cleanUpService, shortURLService, queryHistoryService, correlationsService, remoteCache, provisioningServiceImpl, accessControl, dataSourceProxyService, searchSearchService, grafanaLive, gateway, plugincontextProvider, contexthandlerContextHandler, logger, featureToggles, alertNG, libraryPanelService, libraryElementService, quotaService, socialService, tracingService, serviceService, grafanaService, pluginsService, ossService, service15, queryServiceImpl, filestoreService, serviceAccountsProxy, authinfoimplService, storageService, notificationServiceMock, dashboardService, dashboardProvisioningService, folderimplService, ossProvider, serviceImpl, service13, avatarCacheServer, prefService, folderPermissionsService, dashboardPermissionsService, dashverService, starService, csrfCSRF, managedpluginsNoop, playlistService, apikeyService, kvStore, secretsMigrator, secretsService, secretMigrationProviderImpl, secretsKVStore, apiApi, userService, tempuserService, loginattemptimplService, orgService, deletionService, teamService, acimplService, navtreeService, repositoryImpl, tagimplService, searchHTTPService, oauthtokentestService, statsService, authnService, pluginscdnService, gatherer, apiAPI, registerer, eventualRestConfigProvider, anonDeviceService, verifier, preinstallImpl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -1454,7 +1451,7 @@ func InitializeForTest(ctx context.Context, t sqlutil.ITestDB, testingT interfac
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
appInstaller, err := plugins.ProvideAppInstaller(configProvider, eventualRestConfigProvider, pluginstoreService, pluginassetsService, acimplService, accessClient, featureToggles)
|
appInstaller, err := plugins.ProvideAppInstaller(configProvider, eventualRestConfigProvider, pluginstoreService, acimplService, accessClient, featureToggles)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -127,6 +127,7 @@ func TestLoader_Load(t *testing.T) {
|
|||||||
Signature: plugins.SignatureStatusInternal,
|
Signature: plugins.SignatureStatusInternal,
|
||||||
SkipHostEnvVars: true,
|
SkipHostEnvVars: true,
|
||||||
Translations: map[string]string{},
|
Translations: map[string]string{},
|
||||||
|
LoadingStrategy: plugins.LoadingStrategyScript,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -240,6 +241,7 @@ func TestLoader_Load(t *testing.T) {
|
|||||||
SignatureOrg: "Grafana Labs",
|
SignatureOrg: "Grafana Labs",
|
||||||
SkipHostEnvVars: true,
|
SkipHostEnvVars: true,
|
||||||
Translations: map[string]string{},
|
Translations: map[string]string{},
|
||||||
|
LoadingStrategy: plugins.LoadingStrategyScript,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -292,6 +294,7 @@ func TestLoader_Load(t *testing.T) {
|
|||||||
Signature: "unsigned",
|
Signature: "unsigned",
|
||||||
SkipHostEnvVars: true,
|
SkipHostEnvVars: true,
|
||||||
Translations: map[string]string{},
|
Translations: map[string]string{},
|
||||||
|
LoadingStrategy: plugins.LoadingStrategyScript,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -357,6 +360,7 @@ func TestLoader_Load(t *testing.T) {
|
|||||||
Signature: plugins.SignatureStatusUnsigned,
|
Signature: plugins.SignatureStatusUnsigned,
|
||||||
SkipHostEnvVars: true,
|
SkipHostEnvVars: true,
|
||||||
Translations: map[string]string{},
|
Translations: map[string]string{},
|
||||||
|
LoadingStrategy: plugins.LoadingStrategyScript,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -479,6 +483,7 @@ func TestLoader_Load(t *testing.T) {
|
|||||||
BaseURL: "public/plugins/test-app",
|
BaseURL: "public/plugins/test-app",
|
||||||
SkipHostEnvVars: true,
|
SkipHostEnvVars: true,
|
||||||
Translations: map[string]string{},
|
Translations: map[string]string{},
|
||||||
|
LoadingStrategy: plugins.LoadingStrategyScript,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -571,6 +576,7 @@ func TestLoader_Load_ExternalRegistration(t *testing.T) {
|
|||||||
},
|
},
|
||||||
SkipHostEnvVars: true,
|
SkipHostEnvVars: true,
|
||||||
Translations: map[string]string{},
|
Translations: map[string]string{},
|
||||||
|
LoadingStrategy: plugins.LoadingStrategyScript,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -688,6 +694,7 @@ func TestLoader_Load_MultiplePlugins(t *testing.T) {
|
|||||||
SignatureOrg: "Will Browne",
|
SignatureOrg: "Will Browne",
|
||||||
SkipHostEnvVars: true,
|
SkipHostEnvVars: true,
|
||||||
Translations: map[string]string{},
|
Translations: map[string]string{},
|
||||||
|
LoadingStrategy: plugins.LoadingStrategyScript,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
pluginErrors: map[string]*plugins.Error{
|
pluginErrors: map[string]*plugins.Error{
|
||||||
@@ -822,6 +829,7 @@ func TestLoader_Load_RBACReady(t *testing.T) {
|
|||||||
BaseURL: "public/plugins/test-app",
|
BaseURL: "public/plugins/test-app",
|
||||||
SkipHostEnvVars: true,
|
SkipHostEnvVars: true,
|
||||||
Translations: map[string]string{},
|
Translations: map[string]string{},
|
||||||
|
LoadingStrategy: plugins.LoadingStrategyScript,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -906,6 +914,7 @@ func TestLoader_Load_Signature_RootURL(t *testing.T) {
|
|||||||
Module: "public/plugins/test-datasource/module.js",
|
Module: "public/plugins/test-datasource/module.js",
|
||||||
BaseURL: "public/plugins/test-datasource",
|
BaseURL: "public/plugins/test-datasource",
|
||||||
Translations: map[string]string{},
|
Translations: map[string]string{},
|
||||||
|
LoadingStrategy: plugins.LoadingStrategyScript,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1010,6 +1019,7 @@ func TestLoader_Load_DuplicatePlugins(t *testing.T) {
|
|||||||
BaseURL: "public/plugins/test-app",
|
BaseURL: "public/plugins/test-app",
|
||||||
SkipHostEnvVars: true,
|
SkipHostEnvVars: true,
|
||||||
Translations: map[string]string{},
|
Translations: map[string]string{},
|
||||||
|
LoadingStrategy: plugins.LoadingStrategyScript,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1118,6 +1128,7 @@ func TestLoader_Load_SkipUninitializedPlugins(t *testing.T) {
|
|||||||
BaseURL: "public/plugins/test-app",
|
BaseURL: "public/plugins/test-app",
|
||||||
SkipHostEnvVars: true,
|
SkipHostEnvVars: true,
|
||||||
Translations: map[string]string{},
|
Translations: map[string]string{},
|
||||||
|
LoadingStrategy: plugins.LoadingStrategyScript,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1295,6 +1306,7 @@ func TestLoader_Load_NestedPlugins(t *testing.T) {
|
|||||||
Class: plugins.ClassExternal,
|
Class: plugins.ClassExternal,
|
||||||
SkipHostEnvVars: true,
|
SkipHostEnvVars: true,
|
||||||
Translations: map[string]string{},
|
Translations: map[string]string{},
|
||||||
|
LoadingStrategy: plugins.LoadingStrategyScript,
|
||||||
}
|
}
|
||||||
|
|
||||||
child := &plugins.Plugin{
|
child := &plugins.Plugin{
|
||||||
@@ -1354,6 +1366,7 @@ func TestLoader_Load_NestedPlugins(t *testing.T) {
|
|||||||
Class: plugins.ClassExternal,
|
Class: plugins.ClassExternal,
|
||||||
SkipHostEnvVars: true,
|
SkipHostEnvVars: true,
|
||||||
Translations: map[string]string{},
|
Translations: map[string]string{},
|
||||||
|
LoadingStrategy: plugins.LoadingStrategyScript,
|
||||||
}
|
}
|
||||||
|
|
||||||
parent.Children = []*plugins.Plugin{child}
|
parent.Children = []*plugins.Plugin{child}
|
||||||
@@ -1520,6 +1533,7 @@ func TestLoader_Load_NestedPlugins(t *testing.T) {
|
|||||||
Class: plugins.ClassExternal,
|
Class: plugins.ClassExternal,
|
||||||
SkipHostEnvVars: true,
|
SkipHostEnvVars: true,
|
||||||
Translations: map[string]string{},
|
Translations: map[string]string{},
|
||||||
|
LoadingStrategy: plugins.LoadingStrategyScript,
|
||||||
}
|
}
|
||||||
|
|
||||||
child := &plugins.Plugin{
|
child := &plugins.Plugin{
|
||||||
@@ -1587,6 +1601,7 @@ func TestLoader_Load_NestedPlugins(t *testing.T) {
|
|||||||
Class: plugins.ClassExternal,
|
Class: plugins.ClassExternal,
|
||||||
SkipHostEnvVars: true,
|
SkipHostEnvVars: true,
|
||||||
Translations: map[string]string{},
|
Translations: map[string]string{},
|
||||||
|
LoadingStrategy: plugins.LoadingStrategyScript,
|
||||||
}
|
}
|
||||||
|
|
||||||
parent.Children = []*plugins.Plugin{child}
|
parent.Children = []*plugins.Plugin{child}
|
||||||
|
|||||||
@@ -1,90 +0,0 @@
|
|||||||
package pluginassets
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/Masterminds/semver/v3"
|
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
|
||||||
"github.com/grafana/grafana/pkg/plugins"
|
|
||||||
"github.com/grafana/grafana/pkg/plugins/config"
|
|
||||||
"github.com/grafana/grafana/pkg/plugins/pluginscdn"
|
|
||||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
CreatePluginVersionCfgKey = "create_plugin_version"
|
|
||||||
CreatePluginVersionScriptSupportEnabled = "4.15.0"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
scriptLoadingMinSupportedVersion = semver.MustParse(CreatePluginVersionScriptSupportEnabled)
|
|
||||||
)
|
|
||||||
|
|
||||||
func ProvideService(cfg *config.PluginManagementCfg, cdn *pluginscdn.Service, store pluginstore.Store) *Service {
|
|
||||||
return &Service{
|
|
||||||
cfg: cfg,
|
|
||||||
cdn: cdn,
|
|
||||||
store: store,
|
|
||||||
log: log.New("pluginassets"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type Service struct {
|
|
||||||
cfg *config.PluginManagementCfg
|
|
||||||
cdn *pluginscdn.Service
|
|
||||||
store pluginstore.Store
|
|
||||||
log log.Logger
|
|
||||||
}
|
|
||||||
|
|
||||||
// LoadingStrategy calculates the loading strategy for a plugin.
|
|
||||||
// If a plugin has plugin setting `create_plugin_version` >= 4.15.0, set loadingStrategy to "script".
|
|
||||||
// If a plugin is not loaded via the CDN and is not Angular, set loadingStrategy to "script".
|
|
||||||
// Otherwise, set loadingStrategy to "fetch".
|
|
||||||
func (s *Service) LoadingStrategy(_ context.Context, p pluginstore.Plugin) plugins.LoadingStrategy {
|
|
||||||
if pCfg, ok := s.cfg.PluginSettings[p.ID]; ok {
|
|
||||||
if s.compatibleCreatePluginVersion(pCfg) {
|
|
||||||
return plugins.LoadingStrategyScript
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the plugin has a parent
|
|
||||||
if p.Parent != nil {
|
|
||||||
// Check the parent's create_plugin_version setting
|
|
||||||
if pCfg, ok := s.cfg.PluginSettings[p.Parent.ID]; ok {
|
|
||||||
if s.compatibleCreatePluginVersion(pCfg) {
|
|
||||||
return plugins.LoadingStrategyScript
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Since the parent plugin is not explicitly configured as script loading compatible,
|
|
||||||
// If the plugin is either loaded from the CDN (via its parent) or contains Angular, we should use fetch
|
|
||||||
if s.cdnEnabled(p.Parent.ID, p.FS) || p.Angular.Detected {
|
|
||||||
return plugins.LoadingStrategyFetch
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !s.cdnEnabled(p.ID, p.FS) && !p.Angular.Detected {
|
|
||||||
return plugins.LoadingStrategyScript
|
|
||||||
}
|
|
||||||
|
|
||||||
return plugins.LoadingStrategyFetch
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Service) compatibleCreatePluginVersion(ps map[string]string) bool {
|
|
||||||
if cpv, ok := ps[CreatePluginVersionCfgKey]; ok {
|
|
||||||
createPluginVer, err := semver.NewVersion(cpv)
|
|
||||||
if err != nil {
|
|
||||||
s.log.Warn("Failed to parse create plugin version setting as semver", "version", cpv, "error", err)
|
|
||||||
} else {
|
|
||||||
if !createPluginVer.LessThan(scriptLoadingMinSupportedVersion) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Service) cdnEnabled(pluginID string, fs plugins.FS) bool {
|
|
||||||
return s.cdn.PluginSupported(pluginID) || fs.Type().CDN()
|
|
||||||
}
|
|
||||||
@@ -46,7 +46,6 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/loader"
|
"github.com/grafana/grafana/pkg/services/pluginsintegration/loader"
|
||||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/managedplugins"
|
"github.com/grafana/grafana/pkg/services/pluginsintegration/managedplugins"
|
||||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pipeline"
|
"github.com/grafana/grafana/pkg/services/pluginsintegration/pipeline"
|
||||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginassets"
|
|
||||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginchecker"
|
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginchecker"
|
||||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginconfig"
|
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginconfig"
|
||||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/plugincontext"
|
"github.com/grafana/grafana/pkg/services/pluginsintegration/plugincontext"
|
||||||
@@ -131,7 +130,6 @@ var WireSet = wire.NewSet(
|
|||||||
plugincontext.ProvideBaseService,
|
plugincontext.ProvideBaseService,
|
||||||
wire.Bind(new(plugincontext.BasePluginContextProvider), new(*plugincontext.BaseProvider)),
|
wire.Bind(new(plugincontext.BasePluginContextProvider), new(*plugincontext.BaseProvider)),
|
||||||
plugininstaller.ProvideService,
|
plugininstaller.ProvideService,
|
||||||
pluginassets.ProvideService,
|
|
||||||
pluginchecker.ProvidePreinstall,
|
pluginchecker.ProvidePreinstall,
|
||||||
wire.Bind(new(pluginchecker.Preinstall), new(*pluginchecker.PreinstallImpl)),
|
wire.Bind(new(pluginchecker.Preinstall), new(*pluginchecker.PreinstallImpl)),
|
||||||
advisor.ProvideService,
|
advisor.ProvideService,
|
||||||
|
|||||||
@@ -30,9 +30,10 @@ type Plugin struct {
|
|||||||
Error *plugins.Error
|
Error *plugins.Error
|
||||||
|
|
||||||
// SystemJS fields
|
// SystemJS fields
|
||||||
Module string
|
Module string
|
||||||
BaseURL string
|
LoadingStrategy plugins.LoadingStrategy
|
||||||
ModuleHash string
|
BaseURL string
|
||||||
|
ModuleHash string
|
||||||
|
|
||||||
Angular plugins.AngularMeta
|
Angular plugins.AngularMeta
|
||||||
|
|
||||||
@@ -77,6 +78,7 @@ func ToGrafanaDTO(p *plugins.Plugin) Plugin {
|
|||||||
SignatureOrg: p.SignatureOrg,
|
SignatureOrg: p.SignatureOrg,
|
||||||
Error: p.Error,
|
Error: p.Error,
|
||||||
Module: p.Module,
|
Module: p.Module,
|
||||||
|
LoadingStrategy: p.LoadingStrategy,
|
||||||
BaseURL: p.BaseURL,
|
BaseURL: p.BaseURL,
|
||||||
ExternalService: p.ExternalService,
|
ExternalService: p.ExternalService,
|
||||||
Angular: p.Angular,
|
Angular: p.Angular,
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ export function initSystemJSHooks() {
|
|||||||
|
|
||||||
// This instructs SystemJS to load plugin assets using fetch and eval if it returns a truthy value, otherwise
|
// This instructs SystemJS to load plugin assets using fetch and eval if it returns a truthy value, otherwise
|
||||||
// it will load the plugin using a script tag. The logic that sets loadingStrategy comes from the backend.
|
// it will load the plugin using a script tag. The logic that sets loadingStrategy comes from the backend.
|
||||||
// See: pkg/services/pluginsintegration/pluginassets/pluginassets.go
|
// Loading strategy is calculated during bootstrap in pkg/plugins/pluginassets/loadingstrategy.go
|
||||||
systemJSPrototype.shouldFetch = function (url) {
|
systemJSPrototype.shouldFetch = function (url) {
|
||||||
const pluginInfo = getPluginInfoFromCache(url);
|
const pluginInfo = getPluginInfoFromCache(url);
|
||||||
const jsTypeRegEx = /^[^#?]+\.(js)([?#].*)?$/;
|
const jsTypeRegEx = /^[^#?]+\.(js)([?#].*)?$/;
|
||||||
|
|||||||
Reference in New Issue
Block a user