mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
[WIP] Plugins: Introduce Plugins specific config (#54854)
This commit is contained in:
parent
8b38f9408d
commit
0571d98bba
@ -33,6 +33,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/models"
|
"github.com/grafana/grafana/pkg/models"
|
||||||
"github.com/grafana/grafana/pkg/plugins"
|
"github.com/grafana/grafana/pkg/plugins"
|
||||||
"github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin"
|
"github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin"
|
||||||
|
pluginsCfg "github.com/grafana/grafana/pkg/plugins/config"
|
||||||
"github.com/grafana/grafana/pkg/plugins/manager"
|
"github.com/grafana/grafana/pkg/plugins/manager"
|
||||||
"github.com/grafana/grafana/pkg/plugins/manager/client"
|
"github.com/grafana/grafana/pkg/plugins/manager/client"
|
||||||
pluginDashboards "github.com/grafana/grafana/pkg/plugins/manager/dashboards"
|
pluginDashboards "github.com/grafana/grafana/pkg/plugins/manager/dashboards"
|
||||||
@ -175,6 +176,7 @@ var wireSet = wire.NewSet(
|
|||||||
updatechecker.ProvideGrafanaService,
|
updatechecker.ProvideGrafanaService,
|
||||||
updatechecker.ProvidePluginsService,
|
updatechecker.ProvidePluginsService,
|
||||||
uss.ProvideService,
|
uss.ProvideService,
|
||||||
|
pluginsCfg.ProvideConfig,
|
||||||
registry.ProvideService,
|
registry.ProvideService,
|
||||||
wire.Bind(new(registry.Service), new(*registry.InMemory)),
|
wire.Bind(new(registry.Service), new(*registry.InMemory)),
|
||||||
repo.ProvideService,
|
repo.ProvideService,
|
||||||
|
@ -1,53 +0,0 @@
|
|||||||
package plugins
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/grafana/grafana-azure-sdk-go/azsettings"
|
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Cfg struct {
|
|
||||||
DevMode bool
|
|
||||||
|
|
||||||
PluginsPath string
|
|
||||||
|
|
||||||
PluginSettings setting.PluginSettings
|
|
||||||
PluginsAllowUnsigned []string
|
|
||||||
|
|
||||||
EnterpriseLicensePath string
|
|
||||||
|
|
||||||
// AWS Plugin Auth
|
|
||||||
AWSAllowedAuthProviders []string
|
|
||||||
AWSAssumeRoleEnabled bool
|
|
||||||
|
|
||||||
// Azure Cloud settings
|
|
||||||
Azure *azsettings.AzureSettings
|
|
||||||
|
|
||||||
BuildVersion string // TODO Remove
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewCfg() *Cfg {
|
|
||||||
return &Cfg{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func FromGrafanaCfg(grafanaCfg *setting.Cfg) *Cfg {
|
|
||||||
cfg := &Cfg{}
|
|
||||||
|
|
||||||
cfg.DevMode = grafanaCfg.Env == setting.Dev
|
|
||||||
cfg.PluginsPath = grafanaCfg.PluginsPath
|
|
||||||
|
|
||||||
cfg.PluginSettings = grafanaCfg.PluginSettings
|
|
||||||
cfg.PluginsAllowUnsigned = grafanaCfg.PluginsAllowUnsigned
|
|
||||||
cfg.EnterpriseLicensePath = grafanaCfg.EnterpriseLicensePath
|
|
||||||
|
|
||||||
// AWS
|
|
||||||
cfg.AWSAllowedAuthProviders = grafanaCfg.AWSAllowedAuthProviders
|
|
||||||
cfg.AWSAssumeRoleEnabled = grafanaCfg.AWSAssumeRoleEnabled
|
|
||||||
|
|
||||||
// Azure
|
|
||||||
cfg.Azure = grafanaCfg.Azure
|
|
||||||
|
|
||||||
cfg.BuildVersion = grafanaCfg.BuildVersion
|
|
||||||
|
|
||||||
return cfg
|
|
||||||
}
|
|
86
pkg/plugins/config/config.go
Normal file
86
pkg/plugins/config/config.go
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana-azure-sdk-go/azsettings"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Cfg struct {
|
||||||
|
log log.Logger
|
||||||
|
|
||||||
|
DevMode bool
|
||||||
|
|
||||||
|
PluginSettings setting.PluginSettings
|
||||||
|
PluginsAllowUnsigned []string
|
||||||
|
|
||||||
|
EnterpriseLicensePath string
|
||||||
|
|
||||||
|
// AWS Plugin Auth
|
||||||
|
AWSAllowedAuthProviders []string
|
||||||
|
AWSAssumeRoleEnabled bool
|
||||||
|
|
||||||
|
// Azure Cloud settings
|
||||||
|
Azure *azsettings.AzureSettings
|
||||||
|
|
||||||
|
BuildVersion string // TODO Remove
|
||||||
|
}
|
||||||
|
|
||||||
|
func ProvideConfig(settingProvider setting.Provider, grafanaCfg *setting.Cfg) *Cfg {
|
||||||
|
return NewCfg(settingProvider, grafanaCfg)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCfg(settingProvider setting.Provider, grafanaCfg *setting.Cfg) *Cfg {
|
||||||
|
logger := log.New("plugin.cfg")
|
||||||
|
|
||||||
|
azure := settingProvider.Section("azure")
|
||||||
|
aws := settingProvider.Section("aws")
|
||||||
|
plugins := settingProvider.Section("plugins")
|
||||||
|
|
||||||
|
allowedUnsigned := grafanaCfg.PluginsAllowUnsigned
|
||||||
|
if len(plugins.KeyValue("allow_loading_unsigned_plugins").Value()) > 0 {
|
||||||
|
allowedUnsigned = strings.Split(plugins.KeyValue("allow_loading_unsigned_plugins").Value(), ",")
|
||||||
|
}
|
||||||
|
|
||||||
|
allowedAuth := grafanaCfg.AWSAllowedAuthProviders
|
||||||
|
if len(aws.KeyValue("allowed_auth_providers").Value()) > 0 {
|
||||||
|
allowedUnsigned = strings.Split(settingProvider.KeyValue("plugins", "allow_loading_unsigned_plugins").Value(), ",")
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Cfg{
|
||||||
|
log: logger,
|
||||||
|
BuildVersion: grafanaCfg.BuildVersion,
|
||||||
|
DevMode: settingProvider.KeyValue("", "app_mode").MustBool(grafanaCfg.Env == setting.Dev),
|
||||||
|
EnterpriseLicensePath: settingProvider.KeyValue("enterprise", "license_path").MustString(grafanaCfg.EnterpriseLicensePath),
|
||||||
|
PluginSettings: extractPluginSettings(settingProvider),
|
||||||
|
PluginsAllowUnsigned: allowedUnsigned,
|
||||||
|
AWSAllowedAuthProviders: allowedAuth,
|
||||||
|
AWSAssumeRoleEnabled: aws.KeyValue("assume_role_enabled").MustBool(grafanaCfg.AWSAssumeRoleEnabled),
|
||||||
|
Azure: &azsettings.AzureSettings{
|
||||||
|
Cloud: azure.KeyValue("cloud").MustString(grafanaCfg.Azure.Cloud),
|
||||||
|
ManagedIdentityEnabled: azure.KeyValue("managed_identity_enabled").MustBool(grafanaCfg.Azure.ManagedIdentityEnabled),
|
||||||
|
ManagedIdentityClientId: azure.KeyValue("managed_identity_client_id").MustString(grafanaCfg.Azure.ManagedIdentityClientId),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func extractPluginSettings(settingProvider setting.Provider) setting.PluginSettings {
|
||||||
|
ps := setting.PluginSettings{}
|
||||||
|
for sectionName, sectionCopy := range settingProvider.Current() {
|
||||||
|
if !strings.HasPrefix(sectionName, "plugin.") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// Calling Current() returns a redacted version of section. We need to replace the map values with the unredacted values.
|
||||||
|
section := settingProvider.Section(sectionName)
|
||||||
|
for k := range sectionCopy {
|
||||||
|
sectionCopy[k] = section.KeyValue(k).MustString("")
|
||||||
|
}
|
||||||
|
pluginID := strings.Replace(sectionName, "plugin.", "", 1)
|
||||||
|
ps[pluginID] = sectionCopy
|
||||||
|
}
|
||||||
|
|
||||||
|
return ps
|
||||||
|
}
|
38
pkg/plugins/config/config_test.go
Normal file
38
pkg/plugins/config/config_test.go
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"gopkg.in/ini.v1"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPluginSettings(t *testing.T) {
|
||||||
|
raw, err := ini.Load([]byte(`
|
||||||
|
[plugins]
|
||||||
|
test_key = 123
|
||||||
|
|
||||||
|
[plugin.test-datasource]
|
||||||
|
foo = 5m
|
||||||
|
bar = something
|
||||||
|
|
||||||
|
[plugin.secret-plugin]
|
||||||
|
secret_key = secret
|
||||||
|
normal_key = not a secret`))
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
cfg := &setting.Cfg{Raw: raw}
|
||||||
|
settings := &setting.OSSImpl{Cfg: cfg}
|
||||||
|
|
||||||
|
ps := extractPluginSettings(settings)
|
||||||
|
require.Len(t, ps, 2)
|
||||||
|
require.Len(t, ps["test-datasource"], 2)
|
||||||
|
require.Equal(t, ps["test-datasource"]["foo"], "5m")
|
||||||
|
require.Equal(t, ps["test-datasource"]["bar"], "something")
|
||||||
|
require.Len(t, ps["secret-plugin"], 2)
|
||||||
|
require.Equal(t, ps["secret-plugin"]["secret_key"], "secret")
|
||||||
|
require.Equal(t, ps["secret-plugin"]["normal_key"], "not a secret")
|
||||||
|
}
|
@ -12,16 +12,17 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
"github.com/grafana/grafana/pkg/models"
|
"github.com/grafana/grafana/pkg/models"
|
||||||
"github.com/grafana/grafana/pkg/plugins"
|
"github.com/grafana/grafana/pkg/plugins"
|
||||||
|
"github.com/grafana/grafana/pkg/plugins/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Initializer struct {
|
type Initializer struct {
|
||||||
cfg *plugins.Cfg
|
cfg *config.Cfg
|
||||||
license models.Licensing
|
license models.Licensing
|
||||||
backendProvider plugins.BackendFactoryProvider
|
backendProvider plugins.BackendFactoryProvider
|
||||||
log log.Logger
|
log log.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(cfg *plugins.Cfg, backendProvider plugins.BackendFactoryProvider, license models.Licensing) Initializer {
|
func New(cfg *config.Cfg, backendProvider plugins.BackendFactoryProvider, license models.Licensing) Initializer {
|
||||||
return Initializer{
|
return Initializer{
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
license: license,
|
license: license,
|
||||||
@ -101,7 +102,7 @@ func (ps pluginSettings) asEnvVar(prefix string, hostEnv []string) []string {
|
|||||||
return env
|
return env
|
||||||
}
|
}
|
||||||
|
|
||||||
func getPluginSettings(pluginID string, cfg *plugins.Cfg) pluginSettings {
|
func getPluginSettings(pluginID string, cfg *config.Cfg) pluginSettings {
|
||||||
ps := pluginSettings{}
|
ps := pluginSettings{}
|
||||||
for k, v := range cfg.PluginSettings[pluginID] {
|
for k, v := range cfg.PluginSettings[pluginID] {
|
||||||
if k == "path" || strings.ToLower(k) == "id" {
|
if k == "path" || strings.ToLower(k) == "id" {
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"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/backendplugin"
|
"github.com/grafana/grafana/pkg/plugins/backendplugin"
|
||||||
|
"github.com/grafana/grafana/pkg/plugins/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestInitializer_Initialize(t *testing.T) {
|
func TestInitializer_Initialize(t *testing.T) {
|
||||||
@ -34,7 +35,7 @@ func TestInitializer_Initialize(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
i := &Initializer{
|
i := &Initializer{
|
||||||
cfg: plugins.NewCfg(),
|
cfg: &config.Cfg{},
|
||||||
log: log.NewNopLogger(),
|
log: log.NewNopLogger(),
|
||||||
backendProvider: &fakeBackendProvider{
|
backendProvider: &fakeBackendProvider{
|
||||||
plugin: p,
|
plugin: p,
|
||||||
@ -64,7 +65,7 @@ func TestInitializer_Initialize(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
i := &Initializer{
|
i := &Initializer{
|
||||||
cfg: plugins.NewCfg(),
|
cfg: &config.Cfg{},
|
||||||
log: log.NewNopLogger(),
|
log: log.NewNopLogger(),
|
||||||
backendProvider: &fakeBackendProvider{
|
backendProvider: &fakeBackendProvider{
|
||||||
plugin: p,
|
plugin: p,
|
||||||
@ -94,7 +95,7 @@ func TestInitializer_Initialize(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
i := &Initializer{
|
i := &Initializer{
|
||||||
cfg: plugins.NewCfg(),
|
cfg: &config.Cfg{},
|
||||||
log: log.NewNopLogger(),
|
log: log.NewNopLogger(),
|
||||||
backendProvider: &fakeBackendProvider{
|
backendProvider: &fakeBackendProvider{
|
||||||
plugin: p,
|
plugin: p,
|
||||||
@ -117,7 +118,7 @@ func TestInitializer_Initialize(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
i := &Initializer{
|
i := &Initializer{
|
||||||
cfg: &plugins.Cfg{},
|
cfg: &config.Cfg{},
|
||||||
log: log.NewNopLogger(),
|
log: log.NewNopLogger(),
|
||||||
backendProvider: &fakeBackendProvider{
|
backendProvider: &fakeBackendProvider{
|
||||||
plugin: p,
|
plugin: p,
|
||||||
@ -147,7 +148,7 @@ func TestInitializer_envVars(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
i := &Initializer{
|
i := &Initializer{
|
||||||
cfg: &plugins.Cfg{
|
cfg: &config.Cfg{
|
||||||
EnterpriseLicensePath: "/path/to/ent/license",
|
EnterpriseLicensePath: "/path/to/ent/license",
|
||||||
PluginSettings: map[string]map[string]string{
|
PluginSettings: map[string]map[string]string{
|
||||||
"test": {
|
"test": {
|
||||||
|
@ -19,11 +19,11 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/infra/metrics"
|
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||||
"github.com/grafana/grafana/pkg/models"
|
"github.com/grafana/grafana/pkg/models"
|
||||||
"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/manager/loader/finder"
|
"github.com/grafana/grafana/pkg/plugins/manager/loader/finder"
|
||||||
"github.com/grafana/grafana/pkg/plugins/manager/loader/initializer"
|
"github.com/grafana/grafana/pkg/plugins/manager/loader/initializer"
|
||||||
"github.com/grafana/grafana/pkg/plugins/manager/signature"
|
"github.com/grafana/grafana/pkg/plugins/manager/signature"
|
||||||
"github.com/grafana/grafana/pkg/services/org"
|
"github.com/grafana/grafana/pkg/services/org"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
|
||||||
"github.com/grafana/grafana/pkg/util"
|
"github.com/grafana/grafana/pkg/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -35,7 +35,6 @@ var (
|
|||||||
var _ plugins.ErrorResolver = (*Loader)(nil)
|
var _ plugins.ErrorResolver = (*Loader)(nil)
|
||||||
|
|
||||||
type Loader struct {
|
type Loader struct {
|
||||||
cfg *plugins.Cfg
|
|
||||||
pluginFinder finder.Finder
|
pluginFinder finder.Finder
|
||||||
pluginInitializer initializer.Initializer
|
pluginInitializer initializer.Initializer
|
||||||
signatureValidator signature.Validator
|
signatureValidator signature.Validator
|
||||||
@ -44,15 +43,14 @@ type Loader struct {
|
|||||||
errs map[string]*plugins.SignatureError
|
errs map[string]*plugins.SignatureError
|
||||||
}
|
}
|
||||||
|
|
||||||
func ProvideService(cfg *setting.Cfg, license models.Licensing, authorizer plugins.PluginLoaderAuthorizer,
|
func ProvideService(cfg *config.Cfg, license models.Licensing, authorizer plugins.PluginLoaderAuthorizer,
|
||||||
backendProvider plugins.BackendFactoryProvider) (*Loader, error) {
|
backendProvider plugins.BackendFactoryProvider) (*Loader, error) {
|
||||||
return New(plugins.FromGrafanaCfg(cfg), license, authorizer, backendProvider), nil
|
return New(cfg, license, authorizer, backendProvider), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(cfg *plugins.Cfg, license models.Licensing, authorizer plugins.PluginLoaderAuthorizer,
|
func New(cfg *config.Cfg, license models.Licensing, authorizer plugins.PluginLoaderAuthorizer,
|
||||||
backendProvider plugins.BackendFactoryProvider) *Loader {
|
backendProvider plugins.BackendFactoryProvider) *Loader {
|
||||||
return &Loader{
|
return &Loader{
|
||||||
cfg: cfg,
|
|
||||||
pluginFinder: finder.New(),
|
pluginFinder: finder.New(),
|
||||||
pluginInitializer: initializer.New(cfg, backendProvider, license),
|
pluginInitializer: initializer.New(cfg, backendProvider, license),
|
||||||
signatureValidator: signature.NewValidator(authorizer),
|
signatureValidator: signature.NewValidator(authorizer),
|
||||||
|
@ -7,21 +7,21 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/infra/log/logtest"
|
|
||||||
"github.com/grafana/grafana/pkg/services/org"
|
|
||||||
|
|
||||||
"github.com/google/go-cmp/cmp"
|
"github.com/google/go-cmp/cmp"
|
||||||
"github.com/google/go-cmp/cmp/cmpopts"
|
"github.com/google/go-cmp/cmp/cmpopts"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/infra/log/logtest"
|
||||||
"github.com/grafana/grafana/pkg/plugins"
|
"github.com/grafana/grafana/pkg/plugins"
|
||||||
"github.com/grafana/grafana/pkg/plugins/backendplugin"
|
"github.com/grafana/grafana/pkg/plugins/backendplugin"
|
||||||
"github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin"
|
"github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin"
|
||||||
"github.com/grafana/grafana/pkg/plugins/backendplugin/provider"
|
"github.com/grafana/grafana/pkg/plugins/backendplugin/provider"
|
||||||
|
"github.com/grafana/grafana/pkg/plugins/config"
|
||||||
"github.com/grafana/grafana/pkg/plugins/manager/loader/finder"
|
"github.com/grafana/grafana/pkg/plugins/manager/loader/finder"
|
||||||
"github.com/grafana/grafana/pkg/plugins/manager/loader/initializer"
|
"github.com/grafana/grafana/pkg/plugins/manager/loader/initializer"
|
||||||
"github.com/grafana/grafana/pkg/plugins/manager/signature"
|
"github.com/grafana/grafana/pkg/plugins/manager/signature"
|
||||||
|
"github.com/grafana/grafana/pkg/services/org"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -41,18 +41,16 @@ func TestLoader_Load(t *testing.T) {
|
|||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
class plugins.Class
|
class plugins.Class
|
||||||
cfg *plugins.Cfg
|
cfg *config.Cfg
|
||||||
pluginPaths []string
|
pluginPaths []string
|
||||||
existingPlugins map[string]struct{}
|
existingPlugins map[string]struct{}
|
||||||
want []*plugins.Plugin
|
want []*plugins.Plugin
|
||||||
pluginErrors map[string]*plugins.Error
|
pluginErrors map[string]*plugins.Error
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "Load a Core plugin",
|
name: "Load a Core plugin",
|
||||||
class: plugins.Core,
|
class: plugins.Core,
|
||||||
cfg: &plugins.Cfg{
|
cfg: &config.Cfg{},
|
||||||
PluginsPath: corePluginDir,
|
|
||||||
},
|
|
||||||
pluginPaths: []string{filepath.Join(corePluginDir, "app/plugins/datasource/cloudwatch")},
|
pluginPaths: []string{filepath.Join(corePluginDir, "app/plugins/datasource/cloudwatch")},
|
||||||
want: []*plugins.Plugin{
|
want: []*plugins.Plugin{
|
||||||
{
|
{
|
||||||
@ -99,11 +97,9 @@ func TestLoader_Load(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Load a Bundled plugin",
|
name: "Load a Bundled plugin",
|
||||||
class: plugins.Bundled,
|
class: plugins.Bundled,
|
||||||
cfg: &plugins.Cfg{
|
cfg: &config.Cfg{},
|
||||||
PluginsPath: filepath.Join(parentDir, "testdata"),
|
|
||||||
},
|
|
||||||
pluginPaths: []string{"../testdata/valid-v2-signature"},
|
pluginPaths: []string{"../testdata/valid-v2-signature"},
|
||||||
want: []*plugins.Plugin{
|
want: []*plugins.Plugin{
|
||||||
{
|
{
|
||||||
@ -141,11 +137,9 @@ func TestLoader_Load(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}, {
|
}, {
|
||||||
name: "Load plugin with symbolic links",
|
name: "Load plugin with symbolic links",
|
||||||
class: plugins.External,
|
class: plugins.External,
|
||||||
cfg: &plugins.Cfg{
|
cfg: &config.Cfg{},
|
||||||
PluginsPath: filepath.Join(parentDir),
|
|
||||||
},
|
|
||||||
pluginPaths: []string{"../testdata/symbolic-plugin-dirs"},
|
pluginPaths: []string{"../testdata/symbolic-plugin-dirs"},
|
||||||
want: []*plugins.Plugin{
|
want: []*plugins.Plugin{
|
||||||
{
|
{
|
||||||
@ -221,9 +215,8 @@ func TestLoader_Load(t *testing.T) {
|
|||||||
}, {
|
}, {
|
||||||
name: "Load an unsigned plugin (development)",
|
name: "Load an unsigned plugin (development)",
|
||||||
class: plugins.External,
|
class: plugins.External,
|
||||||
cfg: &plugins.Cfg{
|
cfg: &config.Cfg{
|
||||||
DevMode: true,
|
DevMode: true,
|
||||||
PluginsPath: filepath.Join(parentDir),
|
|
||||||
},
|
},
|
||||||
pluginPaths: []string{"../testdata/unsigned-datasource"},
|
pluginPaths: []string{"../testdata/unsigned-datasource"},
|
||||||
want: []*plugins.Plugin{
|
want: []*plugins.Plugin{
|
||||||
@ -258,11 +251,9 @@ func TestLoader_Load(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}, {
|
}, {
|
||||||
name: "Load an unsigned plugin (production)",
|
name: "Load an unsigned plugin (production)",
|
||||||
class: plugins.External,
|
class: plugins.External,
|
||||||
cfg: &plugins.Cfg{
|
cfg: &config.Cfg{},
|
||||||
PluginsPath: filepath.Join(parentDir),
|
|
||||||
},
|
|
||||||
pluginPaths: []string{"../testdata/unsigned-datasource"},
|
pluginPaths: []string{"../testdata/unsigned-datasource"},
|
||||||
want: []*plugins.Plugin{},
|
want: []*plugins.Plugin{},
|
||||||
pluginErrors: map[string]*plugins.Error{
|
pluginErrors: map[string]*plugins.Error{
|
||||||
@ -275,8 +266,7 @@ func TestLoader_Load(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "Load an unsigned plugin using PluginsAllowUnsigned config (production)",
|
name: "Load an unsigned plugin using PluginsAllowUnsigned config (production)",
|
||||||
class: plugins.External,
|
class: plugins.External,
|
||||||
cfg: &plugins.Cfg{
|
cfg: &config.Cfg{
|
||||||
PluginsPath: filepath.Join(parentDir),
|
|
||||||
PluginsAllowUnsigned: []string{"test-datasource"},
|
PluginsAllowUnsigned: []string{"test-datasource"},
|
||||||
},
|
},
|
||||||
pluginPaths: []string{"../testdata/unsigned-datasource"},
|
pluginPaths: []string{"../testdata/unsigned-datasource"},
|
||||||
@ -313,11 +303,9 @@ func TestLoader_Load(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Load an unsigned plugin with modified signature (production)",
|
name: "Load an unsigned plugin with modified signature (production)",
|
||||||
class: plugins.External,
|
class: plugins.External,
|
||||||
cfg: &plugins.Cfg{
|
cfg: &config.Cfg{},
|
||||||
PluginsPath: filepath.Join(parentDir),
|
|
||||||
},
|
|
||||||
pluginPaths: []string{"../testdata/lacking-files"},
|
pluginPaths: []string{"../testdata/lacking-files"},
|
||||||
want: []*plugins.Plugin{},
|
want: []*plugins.Plugin{},
|
||||||
pluginErrors: map[string]*plugins.Error{
|
pluginErrors: map[string]*plugins.Error{
|
||||||
@ -330,8 +318,7 @@ func TestLoader_Load(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "Load an unsigned plugin with modified signature using PluginsAllowUnsigned config (production) still includes a signing error",
|
name: "Load an unsigned plugin with modified signature using PluginsAllowUnsigned config (production) still includes a signing error",
|
||||||
class: plugins.External,
|
class: plugins.External,
|
||||||
cfg: &plugins.Cfg{
|
cfg: &config.Cfg{
|
||||||
PluginsPath: filepath.Join(parentDir),
|
|
||||||
PluginsAllowUnsigned: []string{"test-datasource"},
|
PluginsAllowUnsigned: []string{"test-datasource"},
|
||||||
},
|
},
|
||||||
pluginPaths: []string{"../testdata/lacking-files"},
|
pluginPaths: []string{"../testdata/lacking-files"},
|
||||||
@ -346,8 +333,7 @@ func TestLoader_Load(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "Load a plugin with manifest which has a file not found in plugin folder",
|
name: "Load a plugin with manifest which has a file not found in plugin folder",
|
||||||
class: plugins.External,
|
class: plugins.External,
|
||||||
cfg: &plugins.Cfg{
|
cfg: &config.Cfg{
|
||||||
PluginsPath: filepath.Join(parentDir),
|
|
||||||
PluginsAllowUnsigned: []string{"test-datasource"},
|
PluginsAllowUnsigned: []string{"test-datasource"},
|
||||||
},
|
},
|
||||||
pluginPaths: []string{"../testdata/invalid-v2-missing-file"},
|
pluginPaths: []string{"../testdata/invalid-v2-missing-file"},
|
||||||
@ -362,8 +348,7 @@ func TestLoader_Load(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "Load a plugin with file which is missing from the manifest",
|
name: "Load a plugin with file which is missing from the manifest",
|
||||||
class: plugins.External,
|
class: plugins.External,
|
||||||
cfg: &plugins.Cfg{
|
cfg: &config.Cfg{
|
||||||
PluginsPath: filepath.Join(parentDir),
|
|
||||||
PluginsAllowUnsigned: []string{"test-datasource"},
|
PluginsAllowUnsigned: []string{"test-datasource"},
|
||||||
},
|
},
|
||||||
pluginPaths: []string{"../testdata/invalid-v2-extra-file"},
|
pluginPaths: []string{"../testdata/invalid-v2-extra-file"},
|
||||||
@ -378,8 +363,7 @@ func TestLoader_Load(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "Load an app with includes",
|
name: "Load an app with includes",
|
||||||
class: plugins.External,
|
class: plugins.External,
|
||||||
cfg: &plugins.Cfg{
|
cfg: &config.Cfg{
|
||||||
PluginsPath: filepath.Join(parentDir),
|
|
||||||
PluginsAllowUnsigned: []string{"test-app"},
|
PluginsAllowUnsigned: []string{"test-app"},
|
||||||
},
|
},
|
||||||
pluginPaths: []string{"../testdata/test-app-with-includes"},
|
pluginPaths: []string{"../testdata/test-app-with-includes"},
|
||||||
@ -509,7 +493,7 @@ func TestLoader_Load_MultiplePlugins(t *testing.T) {
|
|||||||
t.Run("Load multiple", func(t *testing.T) {
|
t.Run("Load multiple", func(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
cfg *plugins.Cfg
|
cfg *config.Cfg
|
||||||
pluginPaths []string
|
pluginPaths []string
|
||||||
appURL string
|
appURL string
|
||||||
existingPlugins map[string]struct{}
|
existingPlugins map[string]struct{}
|
||||||
@ -517,10 +501,8 @@ func TestLoader_Load_MultiplePlugins(t *testing.T) {
|
|||||||
pluginErrors map[string]*plugins.Error
|
pluginErrors map[string]*plugins.Error
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "Load multiple plugins (broken, valid, unsigned)",
|
name: "Load multiple plugins (broken, valid, unsigned)",
|
||||||
cfg: &plugins.Cfg{
|
cfg: &config.Cfg{},
|
||||||
PluginsPath: filepath.Join(parentDir),
|
|
||||||
},
|
|
||||||
appURL: "http://localhost:3000",
|
appURL: "http://localhost:3000",
|
||||||
pluginPaths: []string{
|
pluginPaths: []string{
|
||||||
"../testdata/invalid-plugin-json", // test-app
|
"../testdata/invalid-plugin-json", // test-app
|
||||||
@ -648,7 +630,7 @@ func TestLoader_Signature_RootURL(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
l := newLoader(&plugins.Cfg{PluginsPath: filepath.Join(parentDir)})
|
l := newLoader(&config.Cfg{})
|
||||||
got, err := l.Load(context.Background(), plugins.External, paths, map[string]struct{}{})
|
got, err := l.Load(context.Background(), plugins.External, paths, map[string]struct{}{})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
@ -717,9 +699,7 @@ func TestLoader_Load_DuplicatePlugins(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
l := newLoader(&plugins.Cfg{
|
l := newLoader(&config.Cfg{})
|
||||||
PluginsPath: filepath.Dir(pluginDir),
|
|
||||||
})
|
|
||||||
|
|
||||||
got, err := l.Load(context.Background(), plugins.External, []string{pluginDir, pluginDir}, map[string]struct{}{})
|
got, err := l.Load(context.Background(), plugins.External, []string{pluginDir, pluginDir}, map[string]struct{}{})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
@ -806,9 +786,7 @@ func TestLoader_loadNestedPlugins(t *testing.T) {
|
|||||||
|
|
||||||
t.Run("Load nested External plugins", func(t *testing.T) {
|
t.Run("Load nested External plugins", func(t *testing.T) {
|
||||||
expected := []*plugins.Plugin{parent, child}
|
expected := []*plugins.Plugin{parent, child}
|
||||||
l := newLoader(&plugins.Cfg{
|
l := newLoader(&config.Cfg{})
|
||||||
PluginsPath: rootDir,
|
|
||||||
})
|
|
||||||
|
|
||||||
got, err := l.Load(context.Background(), plugins.External, []string{"../testdata/nested-plugins"}, map[string]struct{}{})
|
got, err := l.Load(context.Background(), plugins.External, []string{"../testdata/nested-plugins"}, map[string]struct{}{})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
@ -828,9 +806,7 @@ func TestLoader_loadNestedPlugins(t *testing.T) {
|
|||||||
parent.Children = nil
|
parent.Children = nil
|
||||||
expected := []*plugins.Plugin{parent}
|
expected := []*plugins.Plugin{parent}
|
||||||
|
|
||||||
l := newLoader(&plugins.Cfg{
|
l := newLoader(&config.Cfg{})
|
||||||
PluginsPath: rootDir,
|
|
||||||
})
|
|
||||||
|
|
||||||
got, err := l.Load(context.Background(), plugins.External, []string{"../testdata/nested-plugins"}, map[string]struct{}{
|
got, err := l.Load(context.Background(), plugins.External, []string{"../testdata/nested-plugins"}, map[string]struct{}{
|
||||||
"test-panel": {},
|
"test-panel": {},
|
||||||
@ -970,9 +946,7 @@ func TestLoader_loadNestedPlugins(t *testing.T) {
|
|||||||
child.Parent = parent
|
child.Parent = parent
|
||||||
|
|
||||||
expected := []*plugins.Plugin{parent, child}
|
expected := []*plugins.Plugin{parent, child}
|
||||||
l := newLoader(&plugins.Cfg{
|
l := newLoader(&config.Cfg{})
|
||||||
PluginsPath: rootDir,
|
|
||||||
})
|
|
||||||
|
|
||||||
got, err := l.Load(context.Background(), plugins.External, []string{"../testdata/app-with-child"}, map[string]struct{}{})
|
got, err := l.Load(context.Background(), plugins.External, []string{"../testdata/app-with-child"}, map[string]struct{}{})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
@ -1169,9 +1143,8 @@ func Test_setPathsBasedOnApp(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func newLoader(cfg *plugins.Cfg) *Loader {
|
func newLoader(cfg *config.Cfg) *Loader {
|
||||||
return &Loader{
|
return &Loader{
|
||||||
cfg: cfg,
|
|
||||||
pluginFinder: finder.New(),
|
pluginFinder: finder.New(),
|
||||||
pluginInitializer: initializer.New(cfg, provider.ProvideService(coreplugin.NewRegistry(make(map[string]backendplugin.PluginFactoryFunc))), &fakeLicensingService{}),
|
pluginInitializer: initializer.New(cfg, provider.ProvideService(coreplugin.NewRegistry(make(map[string]backendplugin.PluginFactoryFunc))), &fakeLicensingService{}),
|
||||||
signatureValidator: signature.NewValidator(signature.NewUnsignedAuthorizer(cfg)),
|
signatureValidator: signature.NewValidator(signature.NewUnsignedAuthorizer(cfg)),
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
|
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"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/logger"
|
"github.com/grafana/grafana/pkg/plugins/logger"
|
||||||
"github.com/grafana/grafana/pkg/plugins/manager/loader"
|
"github.com/grafana/grafana/pkg/plugins/manager/loader"
|
||||||
"github.com/grafana/grafana/pkg/plugins/manager/process"
|
"github.com/grafana/grafana/pkg/plugins/manager/process"
|
||||||
@ -21,7 +22,7 @@ var _ plugins.RendererManager = (*PluginManager)(nil)
|
|||||||
var _ plugins.SecretsPluginManager = (*PluginManager)(nil)
|
var _ plugins.SecretsPluginManager = (*PluginManager)(nil)
|
||||||
|
|
||||||
type PluginManager struct {
|
type PluginManager struct {
|
||||||
cfg *plugins.Cfg
|
cfg *config.Cfg
|
||||||
pluginSources []plugins.PluginSource
|
pluginSources []plugins.PluginSource
|
||||||
pluginRepo repo.Service
|
pluginRepo repo.Service
|
||||||
pluginStorage storage.Manager
|
pluginStorage storage.Manager
|
||||||
@ -31,10 +32,15 @@ type PluginManager struct {
|
|||||||
log log.Logger
|
log log.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
func ProvideService(grafanaCfg *setting.Cfg, pluginRegistry registry.Service, pluginLoader loader.Service,
|
func ProvideService(cfg *config.Cfg, grafCfg *setting.Cfg, pluginRegistry registry.Service, pluginLoader loader.Service,
|
||||||
pluginRepo repo.Service) (*PluginManager, error) {
|
pluginRepo repo.Service) (*PluginManager, error) {
|
||||||
pm := New(plugins.FromGrafanaCfg(grafanaCfg), pluginRegistry, pluginSources(grafanaCfg), pluginLoader,
|
pm := New(cfg, pluginRegistry,
|
||||||
pluginRepo, storage.FileSystem(logger.NewLogger("plugin.fs"), grafanaCfg.PluginsPath),
|
pluginSources(pathData{
|
||||||
|
pluginsPath: grafCfg.PluginsPath,
|
||||||
|
bundledPluginsPath: grafCfg.BundledPluginsPath,
|
||||||
|
staticRootPath: grafCfg.StaticRootPath,
|
||||||
|
}, cfg.PluginSettings),
|
||||||
|
pluginLoader, pluginRepo, storage.FileSystem(logger.NewLogger("plugin.fs"), grafCfg.PluginsPath),
|
||||||
process.NewManager(pluginRegistry),
|
process.NewManager(pluginRegistry),
|
||||||
)
|
)
|
||||||
if err := pm.Init(context.Background()); err != nil {
|
if err := pm.Init(context.Background()); err != nil {
|
||||||
@ -43,7 +49,7 @@ func ProvideService(grafanaCfg *setting.Cfg, pluginRegistry registry.Service, pl
|
|||||||
return pm, nil
|
return pm, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(cfg *plugins.Cfg, pluginRegistry registry.Service, pluginSources []plugins.PluginSource,
|
func New(cfg *config.Cfg, pluginRegistry registry.Service, pluginSources []plugins.PluginSource,
|
||||||
pluginLoader loader.Service, pluginRepo repo.Service, pluginStorage storage.Manager,
|
pluginLoader loader.Service, pluginRepo repo.Service, pluginStorage storage.Manager,
|
||||||
processManager process.Service) *PluginManager {
|
processManager process.Service) *PluginManager {
|
||||||
return &PluginManager{
|
return &PluginManager{
|
||||||
@ -253,26 +259,30 @@ func (m *PluginManager) unregisterAndStop(ctx context.Context, p *plugins.Plugin
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func pluginSources(cfg *setting.Cfg) []plugins.PluginSource {
|
type pathData struct {
|
||||||
|
pluginsPath, bundledPluginsPath, staticRootPath string
|
||||||
|
}
|
||||||
|
|
||||||
|
func pluginSources(p pathData, ps map[string]map[string]string) []plugins.PluginSource {
|
||||||
return []plugins.PluginSource{
|
return []plugins.PluginSource{
|
||||||
{Class: plugins.Core, Paths: corePluginPaths(cfg)},
|
{Class: plugins.Core, Paths: corePluginPaths(p.staticRootPath)},
|
||||||
{Class: plugins.Bundled, Paths: []string{cfg.BundledPluginsPath}},
|
{Class: plugins.Bundled, Paths: []string{p.bundledPluginsPath}},
|
||||||
{Class: plugins.External, Paths: append([]string{cfg.PluginsPath}, pluginSettingPaths(cfg)...)},
|
{Class: plugins.External, Paths: append([]string{p.pluginsPath}, pluginSettingPaths(ps)...)},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// corePluginPaths provides a list of the Core plugin paths which need to be scanned on init()
|
// corePluginPaths provides a list of the Core plugin paths which need to be scanned on init()
|
||||||
func corePluginPaths(cfg *setting.Cfg) []string {
|
func corePluginPaths(staticRootPath string) []string {
|
||||||
datasourcePaths := filepath.Join(cfg.StaticRootPath, "app/plugins/datasource")
|
datasourcePaths := filepath.Join(staticRootPath, "app/plugins/datasource")
|
||||||
panelsPath := filepath.Join(cfg.StaticRootPath, "app/plugins/panel")
|
panelsPath := filepath.Join(staticRootPath, "app/plugins/panel")
|
||||||
return []string{datasourcePaths, panelsPath}
|
return []string{datasourcePaths, panelsPath}
|
||||||
}
|
}
|
||||||
|
|
||||||
// pluginSettingPaths provides a plugin paths defined in cfg.PluginSettings which need to be scanned on init()
|
// pluginSettingPaths provides a plugin paths defined in cfg.PluginSettings which need to be scanned on init()
|
||||||
func pluginSettingPaths(cfg *setting.Cfg) []string {
|
func pluginSettingPaths(ps map[string]map[string]string) []string {
|
||||||
var pluginSettingDirs []string
|
var pluginSettingDirs []string
|
||||||
for _, settings := range cfg.PluginSettings {
|
for _, s := range ps {
|
||||||
path, exists := settings["path"]
|
path, exists := s["path"]
|
||||||
if !exists || path == "" {
|
if !exists || path == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -9,17 +9,19 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"go.opentelemetry.io/otel/trace"
|
|
||||||
"gopkg.in/ini.v1"
|
"gopkg.in/ini.v1"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana-azure-sdk-go/azsettings"
|
||||||
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
"github.com/grafana/grafana-plugin-sdk-go/backend"
|
||||||
"github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
|
"github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"go.opentelemetry.io/otel/trace"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||||
"github.com/grafana/grafana/pkg/plugins"
|
"github.com/grafana/grafana/pkg/plugins"
|
||||||
"github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin"
|
"github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin"
|
||||||
"github.com/grafana/grafana/pkg/plugins/backendplugin/provider"
|
"github.com/grafana/grafana/pkg/plugins/backendplugin/provider"
|
||||||
|
"github.com/grafana/grafana/pkg/plugins/config"
|
||||||
"github.com/grafana/grafana/pkg/plugins/manager/client"
|
"github.com/grafana/grafana/pkg/plugins/manager/client"
|
||||||
"github.com/grafana/grafana/pkg/plugins/manager/loader"
|
"github.com/grafana/grafana/pkg/plugins/manager/loader"
|
||||||
"github.com/grafana/grafana/pkg/plugins/manager/registry"
|
"github.com/grafana/grafana/pkg/plugins/manager/registry"
|
||||||
@ -57,20 +59,27 @@ func TestIntegrationPluginManager_Run(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
features := featuremgmt.WithFeatures()
|
features := featuremgmt.WithFeatures()
|
||||||
|
|
||||||
|
// We use the raw config here as it forms the basis for the setting.Provider implementation
|
||||||
|
// The plugin manager also relies directly on the setting.Cfg struct to provide Grafana specific
|
||||||
|
// properties such as the loading paths
|
||||||
|
raw, err := ini.Load([]byte(`
|
||||||
|
app_mode = production
|
||||||
|
|
||||||
|
[plugin.test-app]
|
||||||
|
path=testdata/test-app
|
||||||
|
|
||||||
|
[plugin.test-panel]
|
||||||
|
not=included
|
||||||
|
`),
|
||||||
|
)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
cfg := &setting.Cfg{
|
cfg := &setting.Cfg{
|
||||||
Raw: ini.Empty(),
|
Raw: raw,
|
||||||
Env: setting.Prod,
|
StaticRootPath: staticRootPath,
|
||||||
StaticRootPath: staticRootPath,
|
BundledPluginsPath: bundledPluginsPath,
|
||||||
BundledPluginsPath: bundledPluginsPath,
|
Azure: &azsettings.AzureSettings{},
|
||||||
IsFeatureToggleEnabled: features.IsEnabled,
|
|
||||||
PluginSettings: map[string]map[string]string{
|
|
||||||
"plugin.test-app": {
|
|
||||||
"path": "testdata/test-app",
|
|
||||||
},
|
|
||||||
"plugin.test-panel": {
|
|
||||||
"not": "included",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tracer := &fakeTracer{}
|
tracer := &fakeTracer{}
|
||||||
@ -99,9 +108,9 @@ func TestIntegrationPluginManager_Run(t *testing.T) {
|
|||||||
|
|
||||||
coreRegistry := coreplugin.ProvideCoreRegistry(am, cw, cm, es, grap, idb, lk, otsdb, pr, tmpo, td, pg, my, ms, graf)
|
coreRegistry := coreplugin.ProvideCoreRegistry(am, cw, cm, es, grap, idb, lk, otsdb, pr, tmpo, td, pg, my, ms, graf)
|
||||||
|
|
||||||
pmCfg := plugins.FromGrafanaCfg(cfg)
|
pCfg := config.ProvideConfig(setting.ProvideProvider(cfg), cfg)
|
||||||
reg := registry.ProvideService()
|
reg := registry.ProvideService()
|
||||||
pm, err := ProvideService(cfg, reg, loader.New(pmCfg, license, signature.NewUnsignedAuthorizer(pmCfg),
|
pm, err := ProvideService(pCfg, cfg, reg, loader.New(pCfg, license, signature.NewUnsignedAuthorizer(pCfg),
|
||||||
provider.ProvideService(coreRegistry)), nil)
|
provider.ProvideService(coreRegistry)), nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
ps := store.ProvideService(reg)
|
ps := store.ProvideService(reg)
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
|
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"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/manager/fakes"
|
"github.com/grafana/grafana/pkg/plugins/manager/fakes"
|
||||||
"github.com/grafana/grafana/pkg/plugins/repo"
|
"github.com/grafana/grafana/pkg/plugins/repo"
|
||||||
"github.com/grafana/grafana/pkg/plugins/storage"
|
"github.com/grafana/grafana/pkg/plugins/storage"
|
||||||
@ -61,7 +62,7 @@ func TestPluginManager_Add_Remove(t *testing.T) {
|
|||||||
}
|
}
|
||||||
proc := fakes.NewFakeProcessManager()
|
proc := fakes.NewFakeProcessManager()
|
||||||
|
|
||||||
pm := New(&plugins.Cfg{}, fakes.NewFakePluginRegistry(), []plugins.PluginSource{}, loader, pluginRepo, fs, proc)
|
pm := New(&config.Cfg{}, fakes.NewFakePluginRegistry(), []plugins.PluginSource{}, loader, pluginRepo, fs, proc)
|
||||||
err := pm.Add(context.Background(), pluginID, v1, plugins.CompatOpts{})
|
err := pm.Add(context.Background(), pluginID, v1, plugins.CompatOpts{})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
@ -175,7 +176,7 @@ func TestPluginManager_Add_Remove(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
proc := fakes.NewFakeProcessManager()
|
proc := fakes.NewFakeProcessManager()
|
||||||
pm := New(&plugins.Cfg{}, reg, []plugins.PluginSource{}, &fakes.FakeLoader{}, &fakes.FakePluginRepo{}, &fakes.FakePluginStorage{}, proc)
|
pm := New(&config.Cfg{}, reg, []plugins.PluginSource{}, &fakes.FakeLoader{}, &fakes.FakePluginRepo{}, &fakes.FakePluginStorage{}, proc)
|
||||||
err := pm.Add(context.Background(), p.ID, "3.2.0", plugins.CompatOpts{})
|
err := pm.Add(context.Background(), p.ID, "3.2.0", plugins.CompatOpts{})
|
||||||
require.ErrorIs(t, err, plugins.ErrInstallCorePlugin)
|
require.ErrorIs(t, err, plugins.ErrInstallCorePlugin)
|
||||||
|
|
||||||
@ -201,7 +202,7 @@ func TestPluginManager_Add_Remove(t *testing.T) {
|
|||||||
func TestPluginManager_Run(t *testing.T) {
|
func TestPluginManager_Run(t *testing.T) {
|
||||||
t.Run("Plugin sources are loaded in order", func(t *testing.T) {
|
t.Run("Plugin sources are loaded in order", func(t *testing.T) {
|
||||||
loader := &fakes.FakeLoader{}
|
loader := &fakes.FakeLoader{}
|
||||||
pm := New(&plugins.Cfg{}, fakes.NewFakePluginRegistry(), []plugins.PluginSource{
|
pm := New(&config.Cfg{}, fakes.NewFakePluginRegistry(), []plugins.PluginSource{
|
||||||
{Class: plugins.Bundled, Paths: []string{"path1"}},
|
{Class: plugins.Bundled, Paths: []string{"path1"}},
|
||||||
{Class: plugins.Core, Paths: []string{"path2"}},
|
{Class: plugins.Core, Paths: []string{"path2"}},
|
||||||
{Class: plugins.External, Paths: []string{"path3"}},
|
{Class: plugins.External, Paths: []string{"path3"}},
|
||||||
@ -227,7 +228,7 @@ func TestManager_Renderer(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
pm := New(&plugins.Cfg{}, reg, []plugins.PluginSource{}, &fakes.FakeLoader{}, &fakes.FakePluginRepo{},
|
pm := New(&config.Cfg{}, reg, []plugins.PluginSource{}, &fakes.FakeLoader{}, &fakes.FakePluginRepo{},
|
||||||
&fakes.FakePluginStorage{}, &fakes.FakeProcessManager{})
|
&fakes.FakePluginStorage{}, &fakes.FakeProcessManager{})
|
||||||
|
|
||||||
r := pm.Renderer(context.Background())
|
r := pm.Renderer(context.Background())
|
||||||
@ -251,7 +252,7 @@ func TestManager_SecretsManager(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
pm := New(&plugins.Cfg{}, reg, []plugins.PluginSource{}, &fakes.FakeLoader{}, &fakes.FakePluginRepo{},
|
pm := New(&config.Cfg{}, reg, []plugins.PluginSource{}, &fakes.FakeLoader{}, &fakes.FakePluginRepo{},
|
||||||
&fakes.FakePluginStorage{}, &fakes.FakeProcessManager{})
|
&fakes.FakePluginStorage{}, &fakes.FakeProcessManager{})
|
||||||
|
|
||||||
r := pm.SecretsManager(context.Background())
|
r := pm.SecretsManager(context.Background())
|
||||||
|
@ -2,21 +2,21 @@ package signature
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/grafana/grafana/pkg/plugins"
|
"github.com/grafana/grafana/pkg/plugins"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/plugins/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewUnsignedAuthorizer(cfg *plugins.Cfg) *UnsignedPluginAuthorizer {
|
func ProvideOSSAuthorizer(cfg *config.Cfg) *UnsignedPluginAuthorizer {
|
||||||
|
return NewUnsignedAuthorizer(cfg)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewUnsignedAuthorizer(cfg *config.Cfg) *UnsignedPluginAuthorizer {
|
||||||
return &UnsignedPluginAuthorizer{
|
return &UnsignedPluginAuthorizer{
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ProvideOSSAuthorizer(cfg *setting.Cfg) *UnsignedPluginAuthorizer {
|
|
||||||
return NewUnsignedAuthorizer(plugins.FromGrafanaCfg(cfg))
|
|
||||||
}
|
|
||||||
|
|
||||||
type UnsignedPluginAuthorizer struct {
|
type UnsignedPluginAuthorizer struct {
|
||||||
cfg *plugins.Cfg
|
cfg *config.Cfg
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *UnsignedPluginAuthorizer) CanLoadPlugin(p *plugins.Plugin) bool {
|
func (u *UnsignedPluginAuthorizer) CanLoadPlugin(p *plugins.Plugin) bool {
|
||||||
|
@ -35,6 +35,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/models"
|
"github.com/grafana/grafana/pkg/models"
|
||||||
"github.com/grafana/grafana/pkg/plugins"
|
"github.com/grafana/grafana/pkg/plugins"
|
||||||
"github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin"
|
"github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin"
|
||||||
|
pluginsCfg "github.com/grafana/grafana/pkg/plugins/config"
|
||||||
"github.com/grafana/grafana/pkg/plugins/manager"
|
"github.com/grafana/grafana/pkg/plugins/manager"
|
||||||
"github.com/grafana/grafana/pkg/plugins/manager/client"
|
"github.com/grafana/grafana/pkg/plugins/manager/client"
|
||||||
pluginDashboards "github.com/grafana/grafana/pkg/plugins/manager/dashboards"
|
pluginDashboards "github.com/grafana/grafana/pkg/plugins/manager/dashboards"
|
||||||
@ -174,6 +175,7 @@ var wireBasicSet = wire.NewSet(
|
|||||||
wire.Bind(new(usagestats.Service), new(*uss.UsageStats)),
|
wire.Bind(new(usagestats.Service), new(*uss.UsageStats)),
|
||||||
registry.ProvideService,
|
registry.ProvideService,
|
||||||
wire.Bind(new(registry.Service), new(*registry.InMemory)),
|
wire.Bind(new(registry.Service), new(*registry.InMemory)),
|
||||||
|
pluginsCfg.ProvideConfig,
|
||||||
repo.ProvideService,
|
repo.ProvideService,
|
||||||
wire.Bind(new(repo.Service), new(*repo.Manager)),
|
wire.Bind(new(repo.Service), new(*repo.Manager)),
|
||||||
manager.ProvideService,
|
manager.ProvideService,
|
||||||
|
@ -189,6 +189,8 @@ func CreateGrafDir(t *testing.T, opts ...GrafanaOpts) (string, string) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
_, err = serverSect.NewKey("port", "0")
|
_, err = serverSect.NewKey("port", "0")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
_, err = serverSect.NewKey("static_root_path", publicDir)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
anonSect, err := cfg.NewSection("auth.anonymous")
|
anonSect, err := cfg.NewSection("auth.anonymous")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
Loading…
Reference in New Issue
Block a user