The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
grafana/pkg/plugins/manager/loader/loader_test.go

948 lines
26 KiB

Plugins: Refactor Plugin Management (#40477) * add core plugin flow * add instrumentation * move func * remove cruft * support external backend plugins * refactor + clean up * remove comments * refactor loader * simplify core plugin path arg * cleanup loggers * move signature validator to plugins package * fix sig packaging * cleanup plugin model * remove unnecessary plugin field * add start+stop for pm * fix failures * add decommissioned state * export fields just to get things flowing * fix comments * set static routes * make image loading idempotent * merge with backend plugin manager * re-use funcs * reorder imports + remove unnecessary interface * add some TODOs + remove unused func * remove unused instrumentation func * simplify client usage * remove import alias * re-use backendplugin.Plugin interface * re order funcs * improve var name * fix log statements * refactor data model * add logic for dupe check during loading * cleanup state setting * refactor loader * cleanup manager interface * add rendering flow * refactor loading + init * add renderer support * fix renderer plugin * reformat imports * track errors * fix plugin signature inheritance * name param in interface * update func comment * fix func arg name * introduce class concept * remove func * fix external plugin check * apply changes from pm-experiment * fix core plugins * fix imports * rename interface * comment API interface * add support for testdata plugin * enable alerting + use correct core plugin contracts * slim manager API * fix param name * fix filter * support static routes * fix rendering * tidy rendering * get tests compiling * fix install+uninstall * start finder test * add finder test coverage * start loader tests * add test for core plugins * load core + bundled test * add test for nested plugin loading * add test files * clean interface + fix registering some core plugins * refactoring * reformat and create sub packages * simplify core plugin init * fix ctx cancel scenario * migrate initializer * remove Init() funcs * add test starter * new logger * flesh out initializer tests * refactoring * remove unused svc * refactor rendering flow * fixup loader tests * add enabled helper func * fix logger name * fix data fetchers * fix case where plugin dir doesn't exist * improve coverage + move dupe checking to loader * remove noisy debug logs * register core plugins automagically * add support for renderer in catalog * make private func + fix req validation * use interface * re-add check for renderer in catalog * tidy up from moving to auto reg core plugins * core plugin registrar * guards * copy over core plugins for test infra * all tests green * renames * propagate new interfaces * kill old manager * get compiling * tidy up * update naming * refactor manager test + cleanup * add more cases to finder test * migrate validator to field * more coverage * refactor dupe checking * add test for plugin class * add coverage for initializer * split out rendering * move * fixup tests * fix uss test * fix frontend settings * fix grafanads test * add check when checking sig errors * fix enabled map * fixup * allow manual setup of CM * rename to cloud-monitoring * remove TODO * add installer interface for testing * loader interface returns * tests passing * refactor + add more coverage * support 'stackdriver' * fix frontend settings loading * improve naming based on package name * small tidy * refactor test * fix renderer start * make cloud-monitoring plugin ID clearer * add plugin update test * add integration tests * don't break all if sig can't be calculated * add root URL check test * add more signature verification tests * update DTO name * update enabled plugins comment * update comments * fix linter * revert fe naming change * fix errors endpoint * reset error code field name * re-order test to help verify * assert -> require * pm check * add missing entry + re-order * re-check * dump icon log * verify manager contents first * reformat * apply PR feedback * apply style changes * fix one vs all loading err * improve log output * only start when no signature error * move log * rework plugin update check * fix test * fix multi loading from cfg.PluginSettings * improve log output #2 * add error abstraction to capture errors without registering a plugin * add debug log * add unsigned warning * e2e test attempt * fix logger * set home path * prevent panic * alternate * ugh.. fix home path * return renderer even if not started * make renderer plugin managed * add fallback renderer icon, update renderer badge + prevent changes when renderer is installed * fix icon loading * rollback renderer changes * use correct field * remove unneccessary block * remove newline * remove unused func * fix bundled plugins base + module fields * remove unused field since refactor * add authorizer abstraction * loader only returns plugins expected to run * fix multi log output
4 years ago
package loader
import (
"errors"
"path/filepath"
"sort"
"testing"
"github.com/stretchr/testify/require"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/stretchr/testify/assert"
"github.com/grafana/grafana/pkg/infra/log"
Plugins: Refactor Plugin Management (#40477) * add core plugin flow * add instrumentation * move func * remove cruft * support external backend plugins * refactor + clean up * remove comments * refactor loader * simplify core plugin path arg * cleanup loggers * move signature validator to plugins package * fix sig packaging * cleanup plugin model * remove unnecessary plugin field * add start+stop for pm * fix failures * add decommissioned state * export fields just to get things flowing * fix comments * set static routes * make image loading idempotent * merge with backend plugin manager * re-use funcs * reorder imports + remove unnecessary interface * add some TODOs + remove unused func * remove unused instrumentation func * simplify client usage * remove import alias * re-use backendplugin.Plugin interface * re order funcs * improve var name * fix log statements * refactor data model * add logic for dupe check during loading * cleanup state setting * refactor loader * cleanup manager interface * add rendering flow * refactor loading + init * add renderer support * fix renderer plugin * reformat imports * track errors * fix plugin signature inheritance * name param in interface * update func comment * fix func arg name * introduce class concept * remove func * fix external plugin check * apply changes from pm-experiment * fix core plugins * fix imports * rename interface * comment API interface * add support for testdata plugin * enable alerting + use correct core plugin contracts * slim manager API * fix param name * fix filter * support static routes * fix rendering * tidy rendering * get tests compiling * fix install+uninstall * start finder test * add finder test coverage * start loader tests * add test for core plugins * load core + bundled test * add test for nested plugin loading * add test files * clean interface + fix registering some core plugins * refactoring * reformat and create sub packages * simplify core plugin init * fix ctx cancel scenario * migrate initializer * remove Init() funcs * add test starter * new logger * flesh out initializer tests * refactoring * remove unused svc * refactor rendering flow * fixup loader tests * add enabled helper func * fix logger name * fix data fetchers * fix case where plugin dir doesn't exist * improve coverage + move dupe checking to loader * remove noisy debug logs * register core plugins automagically * add support for renderer in catalog * make private func + fix req validation * use interface * re-add check for renderer in catalog * tidy up from moving to auto reg core plugins * core plugin registrar * guards * copy over core plugins for test infra * all tests green * renames * propagate new interfaces * kill old manager * get compiling * tidy up * update naming * refactor manager test + cleanup * add more cases to finder test * migrate validator to field * more coverage * refactor dupe checking * add test for plugin class * add coverage for initializer * split out rendering * move * fixup tests * fix uss test * fix frontend settings * fix grafanads test * add check when checking sig errors * fix enabled map * fixup * allow manual setup of CM * rename to cloud-monitoring * remove TODO * add installer interface for testing * loader interface returns * tests passing * refactor + add more coverage * support 'stackdriver' * fix frontend settings loading * improve naming based on package name * small tidy * refactor test * fix renderer start * make cloud-monitoring plugin ID clearer * add plugin update test * add integration tests * don't break all if sig can't be calculated * add root URL check test * add more signature verification tests * update DTO name * update enabled plugins comment * update comments * fix linter * revert fe naming change * fix errors endpoint * reset error code field name * re-order test to help verify * assert -> require * pm check * add missing entry + re-order * re-check * dump icon log * verify manager contents first * reformat * apply PR feedback * apply style changes * fix one vs all loading err * improve log output * only start when no signature error * move log * rework plugin update check * fix test * fix multi loading from cfg.PluginSettings * improve log output #2 * add error abstraction to capture errors without registering a plugin * add debug log * add unsigned warning * e2e test attempt * fix logger * set home path * prevent panic * alternate * ugh.. fix home path * return renderer even if not started * make renderer plugin managed * add fallback renderer icon, update renderer badge + prevent changes when renderer is installed * fix icon loading * rollback renderer changes * use correct field * remove unneccessary block * remove newline * remove unused func * fix bundled plugins base + module fields * remove unused field since refactor * add authorizer abstraction * loader only returns plugins expected to run * fix multi log output
4 years ago
"github.com/grafana/grafana/pkg/plugins"
"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/signature"
"github.com/grafana/grafana/pkg/setting"
)
var compareOpts = cmpopts.IgnoreFields(plugins.Plugin{}, "client", "log")
func TestLoader_Load(t *testing.T) {
corePluginDir, err := filepath.Abs("./../../../../public")
if err != nil {
t.Errorf("could not construct absolute path of core plugins dir")
return
}
parentDir, err := filepath.Abs("../")
if err != nil {
t.Errorf("could not construct absolute path of current dir")
return
}
tests := []struct {
name string
cfg *setting.Cfg
pluginPaths []string
existingPlugins map[string]struct{}
want []*plugins.Plugin
pluginErrors map[string]*plugins.Error
}{
{
name: "Load a Core plugin",
cfg: &setting.Cfg{
StaticRootPath: corePluginDir,
},
pluginPaths: []string{filepath.Join(corePluginDir, "app/plugins/datasource/cloudwatch")},
want: []*plugins.Plugin{
{
JSONData: plugins.JSONData{
ID: "cloudwatch",
Type: "datasource",
Name: "CloudWatch",
Info: plugins.Info{
Author: plugins.InfoLink{
Name: "Grafana Labs",
URL: "https://grafana.com",
},
Description: "Data source for Amazon AWS monitoring service",
Logos: plugins.Logos{
Small: "public/app/plugins/datasource/cloudwatch/img/amazon-web-services.png",
Large: "public/app/plugins/datasource/cloudwatch/img/amazon-web-services.png",
},
},
Includes: []*plugins.Includes{
{Name: "EC2", Path: "dashboards/ec2.json", Type: "dashboard", Role: "Viewer"},
{Name: "EBS", Path: "dashboards/EBS.json", Type: "dashboard", Role: "Viewer"},
{Name: "Lambda", Path: "dashboards/Lambda.json", Type: "dashboard", Role: "Viewer"},
{Name: "Logs", Path: "dashboards/Logs.json", Type: "dashboard", Role: "Viewer"},
{Name: "RDS", Path: "dashboards/RDS.json", Type: "dashboard", Role: "Viewer"},
},
Dependencies: plugins.Dependencies{
GrafanaVersion: "*",
Plugins: []plugins.Dependency{},
},
Category: "cloud",
Annotations: true,
Metrics: true,
Alerting: true,
Logs: true,
QueryOptions: map[string]bool{"minInterval": true},
},
Module: "app/plugins/datasource/cloudwatch/module",
BaseURL: "public/app/plugins/datasource/cloudwatch",
PluginDir: filepath.Join(corePluginDir, "app/plugins/datasource/cloudwatch"),
Signature: "internal",
Class: "core",
},
},
},
{
name: "Load a Bundled plugin",
cfg: &setting.Cfg{
BundledPluginsPath: filepath.Join(parentDir, "testdata"),
},
pluginPaths: []string{"../testdata/valid-v2-signature"},
want: []*plugins.Plugin{
{
JSONData: plugins.JSONData{
ID: "test",
Type: "datasource",
Name: "Test",
Info: plugins.Info{
Author: plugins.InfoLink{
Name: "Will Browne",
URL: "https://willbrowne.com",
},
Version: "1.0.0",
Logos: plugins.Logos{
Small: "public/img/icn-datasource.svg",
Large: "public/img/icn-datasource.svg",
},
Description: "Test",
},
Dependencies: plugins.Dependencies{
GrafanaVersion: "*",
Plugins: []plugins.Dependency{},
},
Executable: "test",
Backend: true,
State: "alpha",
},
Module: "plugins/test/module",
BaseURL: "public/plugins/test",
PluginDir: filepath.Join(parentDir, "testdata/valid-v2-signature/plugin/"),
Signature: "valid",
SignatureType: plugins.GrafanaSignature,
SignatureOrg: "Grafana Labs",
Class: "bundled",
},
},
}, {
name: "Load an External plugin",
cfg: &setting.Cfg{
PluginsPath: filepath.Join(parentDir),
},
pluginPaths: []string{"../testdata/symbolic-plugin-dirs"},
want: []*plugins.Plugin{
{
JSONData: plugins.JSONData{
ID: "test-app",
Type: "app",
Name: "Test App",
Info: plugins.Info{
Author: plugins.InfoLink{
Name: "Test Inc.",
URL: "http://test.com",
},
Logos: plugins.Logos{
Small: "public/plugins/test-app/img/logo_small.png",
Large: "public/plugins/test-app/img/logo_large.png",
},
Links: []plugins.InfoLink{
{Name: "Project site", URL: "http://project.com"},
{Name: "License & Terms", URL: "http://license.com"},
},
Description: "Official Grafana Test App & Dashboard bundle",
Screenshots: []plugins.Screenshots{
{Path: "public/plugins/test-app/img/screenshot1.png", Name: "img1"},
{Path: "public/plugins/test-app/img/screenshot2.png", Name: "img2"},
},
Version: "1.0.0",
Updated: "2015-02-10",
},
Dependencies: plugins.Dependencies{
GrafanaVersion: "3.x.x",
Plugins: []plugins.Dependency{
{Type: "datasource", ID: "graphite", Name: "Graphite", Version: "1.0.0"},
{Type: "panel", ID: "graph", Name: "Graph", Version: "1.0.0"},
},
},
Includes: []*plugins.Includes{
{
Name: "Nginx Connections",
Path: "dashboards/connections.json",
Type: "dashboard",
Role: "Viewer",
Slug: "nginx-connections",
},
{
Name: "Nginx Memory",
Path: "dashboards/memory.json",
Type: "dashboard",
Role: "Viewer",
Slug: "nginx-memory",
},
{
Name: "Nginx Panel",
Type: "panel",
Role: "Viewer",
Slug: "nginx-panel"},
{
Name: "Nginx Datasource",
Type: "datasource",
Role: "Viewer",
Slug: "nginx-datasource",
},
},
},
Class: plugins.External,
Module: "plugins/test-app/module",
BaseURL: "public/plugins/test-app",
PluginDir: filepath.Join(parentDir, "testdata/includes-symlinks"),
Signature: "valid",
SignatureType: plugins.GrafanaSignature,
SignatureOrg: "Grafana Labs",
},
},
}, {
name: "Load an unsigned plugin (development)",
cfg: &setting.Cfg{
PluginsPath: filepath.Join(parentDir),
Env: "development",
},
pluginPaths: []string{"../testdata/unsigned-datasource"},
want: []*plugins.Plugin{
{
JSONData: plugins.JSONData{
ID: "test",
Type: "datasource",
Name: "Test",
Info: plugins.Info{
Author: plugins.InfoLink{
Name: "Grafana Labs",
URL: "https://grafana.com",
},
Logos: plugins.Logos{
Small: "public/img/icn-datasource.svg",
Large: "public/img/icn-datasource.svg",
},
Description: "Test",
},
Dependencies: plugins.Dependencies{
GrafanaVersion: "*",
Plugins: []plugins.Dependency{},
},
Backend: true,
State: plugins.AlphaRelease,
},
Class: plugins.External,
Module: "plugins/test/module",
BaseURL: "public/plugins/test",
PluginDir: filepath.Join(parentDir, "testdata/unsigned-datasource/plugin"),
Signature: "unsigned",
},
},
}, {
name: "Load an unsigned plugin (production)",
cfg: &setting.Cfg{
PluginsPath: filepath.Join(parentDir),
Env: "production",
},
pluginPaths: []string{"../testdata/unsigned-datasource"},
want: []*plugins.Plugin{},
pluginErrors: map[string]*plugins.Error{
"test": {
PluginID: "test",
ErrorCode: "signatureMissing",
},
},
},
{
name: "Load an unsigned plugin using PluginsAllowUnsigned config (production)",
cfg: &setting.Cfg{
PluginsPath: filepath.Join(parentDir),
Env: "production",
PluginsAllowUnsigned: []string{"test"},
},
pluginPaths: []string{"../testdata/unsigned-datasource"},
want: []*plugins.Plugin{
{
JSONData: plugins.JSONData{
ID: "test",
Type: "datasource",
Name: "Test",
Info: plugins.Info{
Author: plugins.InfoLink{
Name: "Grafana Labs",
URL: "https://grafana.com",
},
Logos: plugins.Logos{
Small: "public/img/icn-datasource.svg",
Large: "public/img/icn-datasource.svg",
},
Description: "Test",
},
Dependencies: plugins.Dependencies{
GrafanaVersion: "*",
Plugins: []plugins.Dependency{},
},
Backend: true,
State: plugins.AlphaRelease,
},
Class: plugins.External,
Module: "plugins/test/module",
BaseURL: "public/plugins/test",
PluginDir: filepath.Join(parentDir, "testdata/unsigned-datasource/plugin"),
Signature: "unsigned",
},
},
},
{
name: "Load an unsigned plugin with modified signature (production)",
cfg: &setting.Cfg{
PluginsPath: filepath.Join(parentDir),
Env: "production",
},
pluginPaths: []string{"../testdata/lacking-files"},
want: []*plugins.Plugin{},
pluginErrors: map[string]*plugins.Error{
"test": {
PluginID: "test",
ErrorCode: "signatureModified",
},
},
},
{
name: "Load an unsigned plugin with modified signature using PluginsAllowUnsigned config (production) still includes a signing error",
cfg: &setting.Cfg{
PluginsPath: filepath.Join(parentDir),
Env: "production",
PluginsAllowUnsigned: []string{"test"},
},
pluginPaths: []string{"../testdata/lacking-files"},
want: []*plugins.Plugin{},
pluginErrors: map[string]*plugins.Error{
"test": {
PluginID: "test",
ErrorCode: "signatureModified",
},
},
},
}
for _, tt := range tests {
l := newLoader(tt.cfg)
t.Run(tt.name, func(t *testing.T) {
got, err := l.Load(tt.pluginPaths, tt.existingPlugins)
require.NoError(t, err)
if !cmp.Equal(got, tt.want, compareOpts) {
t.Fatalf("Result mismatch (-want +got):\n%s", cmp.Diff(got, tt.want, compareOpts))
}
pluginErrs := l.PluginErrors()
assert.Equal(t, len(tt.pluginErrors), len(pluginErrs))
for _, pluginErr := range pluginErrs {
assert.Equal(t, tt.pluginErrors[pluginErr.PluginID], pluginErr)
}
})
}
}
func TestLoader_Load_MultiplePlugins(t *testing.T) {
parentDir, err := filepath.Abs("../")
if err != nil {
t.Errorf("could not construct absolute path of current dir")
return
}
t.Run("Load multiple", func(t *testing.T) {
tests := []struct {
name string
cfg *setting.Cfg
pluginPaths []string
appURL string
existingPlugins map[string]struct{}
want []*plugins.Plugin
pluginErrors map[string]*plugins.Error
}{
{
name: "Load multiple plugins (broken, valid, unsigned)",
cfg: &setting.Cfg{
Env: "production",
Plugins: Refactor Plugin Management (#40477) * add core plugin flow * add instrumentation * move func * remove cruft * support external backend plugins * refactor + clean up * remove comments * refactor loader * simplify core plugin path arg * cleanup loggers * move signature validator to plugins package * fix sig packaging * cleanup plugin model * remove unnecessary plugin field * add start+stop for pm * fix failures * add decommissioned state * export fields just to get things flowing * fix comments * set static routes * make image loading idempotent * merge with backend plugin manager * re-use funcs * reorder imports + remove unnecessary interface * add some TODOs + remove unused func * remove unused instrumentation func * simplify client usage * remove import alias * re-use backendplugin.Plugin interface * re order funcs * improve var name * fix log statements * refactor data model * add logic for dupe check during loading * cleanup state setting * refactor loader * cleanup manager interface * add rendering flow * refactor loading + init * add renderer support * fix renderer plugin * reformat imports * track errors * fix plugin signature inheritance * name param in interface * update func comment * fix func arg name * introduce class concept * remove func * fix external plugin check * apply changes from pm-experiment * fix core plugins * fix imports * rename interface * comment API interface * add support for testdata plugin * enable alerting + use correct core plugin contracts * slim manager API * fix param name * fix filter * support static routes * fix rendering * tidy rendering * get tests compiling * fix install+uninstall * start finder test * add finder test coverage * start loader tests * add test for core plugins * load core + bundled test * add test for nested plugin loading * add test files * clean interface + fix registering some core plugins * refactoring * reformat and create sub packages * simplify core plugin init * fix ctx cancel scenario * migrate initializer * remove Init() funcs * add test starter * new logger * flesh out initializer tests * refactoring * remove unused svc * refactor rendering flow * fixup loader tests * add enabled helper func * fix logger name * fix data fetchers * fix case where plugin dir doesn't exist * improve coverage + move dupe checking to loader * remove noisy debug logs * register core plugins automagically * add support for renderer in catalog * make private func + fix req validation * use interface * re-add check for renderer in catalog * tidy up from moving to auto reg core plugins * core plugin registrar * guards * copy over core plugins for test infra * all tests green * renames * propagate new interfaces * kill old manager * get compiling * tidy up * update naming * refactor manager test + cleanup * add more cases to finder test * migrate validator to field * more coverage * refactor dupe checking * add test for plugin class * add coverage for initializer * split out rendering * move * fixup tests * fix uss test * fix frontend settings * fix grafanads test * add check when checking sig errors * fix enabled map * fixup * allow manual setup of CM * rename to cloud-monitoring * remove TODO * add installer interface for testing * loader interface returns * tests passing * refactor + add more coverage * support 'stackdriver' * fix frontend settings loading * improve naming based on package name * small tidy * refactor test * fix renderer start * make cloud-monitoring plugin ID clearer * add plugin update test * add integration tests * don't break all if sig can't be calculated * add root URL check test * add more signature verification tests * update DTO name * update enabled plugins comment * update comments * fix linter * revert fe naming change * fix errors endpoint * reset error code field name * re-order test to help verify * assert -> require * pm check * add missing entry + re-order * re-check * dump icon log * verify manager contents first * reformat * apply PR feedback * apply style changes * fix one vs all loading err * improve log output * only start when no signature error * move log * rework plugin update check * fix test * fix multi loading from cfg.PluginSettings * improve log output #2 * add error abstraction to capture errors without registering a plugin * add debug log * add unsigned warning * e2e test attempt * fix logger * set home path * prevent panic * alternate * ugh.. fix home path * return renderer even if not started * make renderer plugin managed * add fallback renderer icon, update renderer badge + prevent changes when renderer is installed * fix icon loading * rollback renderer changes * use correct field * remove unneccessary block * remove newline * remove unused func * fix bundled plugins base + module fields * remove unused field since refactor * add authorizer abstraction * loader only returns plugins expected to run * fix multi log output
4 years ago
PluginsPath: filepath.Join(parentDir),
},
appURL: "http://localhost:3000",
pluginPaths: []string{
"../testdata/invalid-plugin-json", // test-app
"../testdata/valid-v2-pvt-signature", // test
"../testdata/unsigned-panel", // test-panel
},
want: []*plugins.Plugin{
{
JSONData: plugins.JSONData{
ID: "test",
Type: "datasource",
Name: "Test",
Info: plugins.Info{
Author: plugins.InfoLink{
Name: "Will Browne",
URL: "https://willbrowne.com",
},
Logos: plugins.Logos{
Small: "public/img/icn-datasource.svg",
Large: "public/img/icn-datasource.svg",
},
Description: "Test",
Version: "1.0.0",
},
Dependencies: plugins.Dependencies{
GrafanaVersion: "*",
Plugins: []plugins.Dependency{},
},
Backend: true,
Executable: "test",
State: plugins.AlphaRelease,
},
Class: plugins.External,
Module: "plugins/test/module",
BaseURL: "public/plugins/test",
PluginDir: filepath.Join(parentDir, "testdata/valid-v2-pvt-signature/plugin"),
Signature: "valid",
SignatureType: plugins.PrivateSignature,
SignatureOrg: "Will Browne",
},
},
pluginErrors: map[string]*plugins.Error{
"test": {
PluginID: "test",
ErrorCode: "signatureMissing",
},
},
},
}
for _, tt := range tests {
l := newLoader(tt.cfg)
t.Run(tt.name, func(t *testing.T) {
origAppURL := setting.AppUrl
t.Cleanup(func() {
setting.AppUrl = origAppURL
})
setting.AppUrl = tt.appURL
got, err := l.Load(tt.pluginPaths, tt.existingPlugins)
require.NoError(t, err)
sort.SliceStable(got, func(i, j int) bool {
return got[i].ID < got[j].ID
})
if !cmp.Equal(got, tt.want, compareOpts) {
t.Fatalf("Result mismatch (-want +got):\n%s", cmp.Diff(got, tt.want, compareOpts))
}
})
}
})
}
func TestLoader_Signature_RootURL(t *testing.T) {
const defaultAppURL = "http://localhost:3000/grafana"
parentDir, err := filepath.Abs("../")
if err != nil {
t.Errorf("could not construct absolute path of current dir")
return
}
t.Run("Private signature verification ignores trailing slash in root URL", func(t *testing.T) {
origAppURL := setting.AppUrl
origAppSubURL := setting.AppSubUrl
t.Cleanup(func() {
setting.AppUrl = origAppURL
setting.AppSubUrl = origAppSubURL
})
setting.AppUrl = defaultAppURL
paths := []string{"../testdata/valid-v2-pvt-signature-root-url-uri"}
expected := []*plugins.Plugin{
{
JSONData: plugins.JSONData{
ID: "test",
Type: "datasource",
Name: "Test",
Info: plugins.Info{
Author: plugins.InfoLink{Name: "Will Browne", URL: "https://willbrowne.com"},
Description: "Test",
Logos: plugins.Logos{
Small: "public/img/icn-datasource.svg",
Large: "public/img/icn-datasource.svg",
},
Version: "1.0.0",
},
State: plugins.AlphaRelease,
Dependencies: plugins.Dependencies{GrafanaVersion: "*", Plugins: []plugins.Dependency{}},
Backend: true,
Executable: "test",
},
PluginDir: filepath.Join(parentDir, "/testdata/valid-v2-pvt-signature-root-url-uri/plugin"),
Class: "external",
Signature: "valid",
SignatureType: "private",
SignatureOrg: "Will Browne",
Module: "plugins/test/module",
BaseURL: "public/plugins/test",
},
}
l := newLoader(&setting.Cfg{PluginsPath: filepath.Join(parentDir)})
got, err := l.Load(paths, map[string]struct{}{})
assert.NoError(t, err)
if !cmp.Equal(got, expected, compareOpts) {
t.Fatalf("Result mismatch (-want +got):\n%s", cmp.Diff(got, expected, compareOpts))
}
})
}
func TestLoader_Load_DuplicatePlugins(t *testing.T) {
t.Run("Load duplicate plugin folders", func(t *testing.T) {
pluginDir, err := filepath.Abs("../testdata/test-app")
if err != nil {
t.Errorf("could not construct absolute path of plugin dir")
return
}
expected := []*plugins.Plugin{
{
JSONData: plugins.JSONData{
ID: "test-app",
Type: "app",
Name: "Test App",
Info: plugins.Info{
Author: plugins.InfoLink{
Name: "Test Inc.",
URL: "http://test.com",
},
Description: "Official Grafana Test App & Dashboard bundle",
Version: "1.0.0",
Links: []plugins.InfoLink{
{Name: "Project site", URL: "http://project.com"},
{Name: "License & Terms", URL: "http://license.com"},
},
Logos: plugins.Logos{
Small: "public/plugins/test-app/img/logo_small.png",
Large: "public/plugins/test-app/img/logo_large.png",
},
Screenshots: []plugins.Screenshots{
{Path: "public/plugins/test-app/img/screenshot1.png", Name: "img1"},
{Path: "public/plugins/test-app/img/screenshot2.png", Name: "img2"},
},
Updated: "2015-02-10",
},
Dependencies: plugins.Dependencies{
GrafanaVersion: "3.x.x",
Plugins: []plugins.Dependency{
{Type: "datasource", ID: "graphite", Name: "Graphite", Version: "1.0.0"},
{Type: "panel", ID: "graph", Name: "Graph", Version: "1.0.0"},
},
},
Includes: []*plugins.Includes{
{Name: "Nginx Connections", Path: "dashboards/connections.json", Type: "dashboard", Role: "Viewer", Slug: "nginx-connections"},
{Name: "Nginx Memory", Path: "dashboards/memory.json", Type: "dashboard", Role: "Viewer", Slug: "nginx-memory"},
{Name: "Nginx Panel", Type: "panel", Role: "Viewer", Slug: "nginx-panel"},
{Name: "Nginx Datasource", Type: "datasource", Role: "Viewer", Slug: "nginx-datasource"},
},
Backend: false,
},
PluginDir: pluginDir,
Class: plugins.External,
Signature: plugins.SignatureValid,
SignatureType: plugins.GrafanaSignature,
SignatureOrg: "Grafana Labs",
Module: "plugins/test-app/module",
BaseURL: "public/plugins/test-app",
},
}
l := newLoader(&setting.Cfg{
PluginsPath: filepath.Dir(pluginDir),
})
got, err := l.Load([]string{pluginDir, pluginDir}, map[string]struct{}{})
assert.NoError(t, err)
if !cmp.Equal(got, expected, compareOpts) {
t.Fatalf("Result mismatch (-want +got):\n%s", cmp.Diff(got, expected, compareOpts))
}
})
}
func TestLoader_loadNestedPlugins(t *testing.T) {
parentDir, err := filepath.Abs("../")
if err != nil {
t.Errorf("could not construct absolute path of root dir")
return
}
parent := &plugins.Plugin{
JSONData: plugins.JSONData{
ID: "test-ds",
Type: "datasource",
Name: "Parent",
Info: plugins.Info{
Author: plugins.InfoLink{
Name: "Grafana Labs",
URL: "http://grafana.com",
},
Logos: plugins.Logos{
Small: "public/img/icn-datasource.svg",
Large: "public/img/icn-datasource.svg",
},
Description: "Parent plugin",
Version: "1.0.0",
Updated: "2020-10-20",
},
Dependencies: plugins.Dependencies{
GrafanaVersion: "*",
Plugins: []plugins.Dependency{},
},
Backend: true,
},
Module: "plugins/test-ds/module",
BaseURL: "public/plugins/test-ds",
PluginDir: filepath.Join(parentDir, "testdata/nested-plugins/parent"),
Signature: "valid",
SignatureType: plugins.GrafanaSignature,
SignatureOrg: "Grafana Labs",
Class: "external",
}
child := &plugins.Plugin{
JSONData: plugins.JSONData{
ID: "test-panel",
Type: "panel",
Name: "Child",
Info: plugins.Info{
Author: plugins.InfoLink{
Name: "Grafana Labs",
URL: "http://grafana.com",
},
Logos: plugins.Logos{
Small: "public/img/icn-panel.svg",
Large: "public/img/icn-panel.svg",
},
Description: "Child plugin",
Version: "1.0.1",
Updated: "2020-10-30",
},
Dependencies: plugins.Dependencies{
GrafanaVersion: "*",
Plugins: []plugins.Dependency{},
},
},
Module: "plugins/test-panel/module",
BaseURL: "public/plugins/test-panel",
PluginDir: filepath.Join(parentDir, "testdata/nested-plugins/parent/nested"),
Signature: "valid",
SignatureType: plugins.GrafanaSignature,
SignatureOrg: "Grafana Labs",
Class: "external",
}
parent.Children = []*plugins.Plugin{child}
child.Parent = parent
t.Run("Load nested External plugins", func(t *testing.T) {
expected := []*plugins.Plugin{parent, child}
l := newLoader(&setting.Cfg{
PluginsPath: parentDir,
})
got, err := l.Load([]string{"../testdata/nested-plugins"}, map[string]struct{}{})
assert.NoError(t, err)
// to ensure we can compare with expected
sort.SliceStable(got, func(i, j int) bool {
return got[i].ID < got[j].ID
})
if !cmp.Equal(got, expected, compareOpts) {
t.Fatalf("Result mismatch (-want +got):\n%s", cmp.Diff(got, expected, compareOpts))
}
})
t.Run("Load will exclude plugins that already exist", func(t *testing.T) {
// parent/child links will not be created when either plugins are provided in the existingPlugins map
parent.Children = nil
expected := []*plugins.Plugin{parent}
l := newLoader(&setting.Cfg{
PluginsPath: parentDir,
})
got, err := l.Load([]string{"../testdata/nested-plugins"}, map[string]struct{}{
"test-panel": {},
})
assert.NoError(t, err)
// to ensure we can compare with expected
sort.SliceStable(got, func(i, j int) bool {
return got[i].ID < got[j].ID
})
if !cmp.Equal(got, expected, compareOpts) {
t.Fatalf("Result mismatch (-want +got):\n%s", cmp.Diff(got, expected, compareOpts))
}
})
}
func TestLoader_readPluginJSON(t *testing.T) {
tests := []struct {
name string
pluginPath string
expected plugins.JSONData
failed bool
}{
{
name: "Valid plugin",
pluginPath: "../testdata/test-app/plugin.json",
expected: plugins.JSONData{
ID: "test-app",
Type: "app",
Name: "Test App",
Info: plugins.Info{
Author: plugins.InfoLink{
Name: "Test Inc.",
URL: "http://test.com",
},
Description: "Official Grafana Test App & Dashboard bundle",
Version: "1.0.0",
Links: []plugins.InfoLink{
{Name: "Project site", URL: "http://project.com"},
{Name: "License & Terms", URL: "http://license.com"},
},
Logos: plugins.Logos{
Small: "img/logo_small.png",
Large: "img/logo_large.png",
},
Screenshots: []plugins.Screenshots{
{Path: "img/screenshot1.png", Name: "img1"},
{Path: "img/screenshot2.png", Name: "img2"},
},
Updated: "2015-02-10",
},
Dependencies: plugins.Dependencies{
GrafanaVersion: "3.x.x",
Plugins: []plugins.Dependency{
{Type: "datasource", ID: "graphite", Name: "Graphite", Version: "1.0.0"},
{Type: "panel", ID: "graph", Name: "Graph", Version: "1.0.0"},
},
},
Includes: []*plugins.Includes{
{Name: "Nginx Connections", Path: "dashboards/connections.json", Type: "dashboard"},
{Name: "Nginx Memory", Path: "dashboards/memory.json", Type: "dashboard"},
{Name: "Nginx Panel", Type: "panel"},
{Name: "Nginx Datasource", Type: "datasource"},
},
Backend: false,
},
},
{
name: "Invalid plugin JSON",
pluginPath: "../testdata/invalid-plugin-json/plugin.json",
failed: true,
},
{
name: "Non-existing JSON file",
pluginPath: "nonExistingFile.json",
failed: true,
},
}
l := newLoader(nil)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := l.readPluginJSON(tt.pluginPath)
if (err != nil) && !tt.failed {
t.Errorf("readPluginJSON() error = %v, failed %v", err, tt.failed)
return
}
if !cmp.Equal(got, tt.expected, compareOpts) {
t.Errorf("Unexpected pluginJSONData: %v", cmp.Diff(got, tt.expected, compareOpts))
}
})
}
}
func Test_validatePluginJSON(t *testing.T) {
type args struct {
data plugins.JSONData
}
tests := []struct {
name string
args args
err error
}{
{
name: "Valid case",
args: args{
data: plugins.JSONData{
ID: "grafana-plugin-id",
Type: plugins.DataSource,
},
},
},
{
name: "Invalid plugin ID",
args: args{
data: plugins.JSONData{
Type: plugins.Panel,
},
},
err: ErrInvalidPluginJSON,
},
{
name: "Invalid plugin type",
args: args{
data: plugins.JSONData{
ID: "grafana-plugin-id",
Type: "test",
},
},
err: ErrInvalidPluginJSON,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := validatePluginJSON(tt.args.data); !errors.Is(err, tt.err) {
t.Errorf("validatePluginJSON() = %v, want %v", err, tt.err)
}
})
}
}
func Test_pluginClass(t *testing.T) {
type args struct {
pluginDir string
cfg *setting.Cfg
}
tests := []struct {
name string
args args
expected plugins.Class
}{
{
name: "Core plugin class",
args: args{
pluginDir: "/root/app/plugins/test-app",
cfg: &setting.Cfg{
StaticRootPath: "/root",
},
},
expected: plugins.Core,
},
{
name: "Bundled plugin class",
args: args{
pluginDir: "/test-app",
cfg: &setting.Cfg{
BundledPluginsPath: "/test-app",
},
},
expected: plugins.Bundled,
},
{
name: "External plugin class",
args: args{
pluginDir: "/test-app",
cfg: &setting.Cfg{
PluginsPath: "/test-app",
},
},
expected: plugins.External,
},
{
name: "External plugin class",
args: args{
pluginDir: "/test-app",
cfg: &setting.Cfg{
PluginsPath: "/root",
},
},
expected: plugins.External,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
l := newLoader(tt.args.cfg)
got := l.pluginClass(tt.args.pluginDir)
assert.Equal(t, tt.expected, got)
})
}
}
func newLoader(cfg *setting.Cfg) *Loader {
return &Loader{
cfg: cfg,
pluginFinder: finder.New(cfg),
pluginInitializer: initializer.New(cfg, &fakeLicensingService{}),
signatureValidator: signature.NewValidator(&signature.UnsignedPluginAuthorizer{Cfg: cfg}),
Plugins: Refactor Plugin Management (#40477) * add core plugin flow * add instrumentation * move func * remove cruft * support external backend plugins * refactor + clean up * remove comments * refactor loader * simplify core plugin path arg * cleanup loggers * move signature validator to plugins package * fix sig packaging * cleanup plugin model * remove unnecessary plugin field * add start+stop for pm * fix failures * add decommissioned state * export fields just to get things flowing * fix comments * set static routes * make image loading idempotent * merge with backend plugin manager * re-use funcs * reorder imports + remove unnecessary interface * add some TODOs + remove unused func * remove unused instrumentation func * simplify client usage * remove import alias * re-use backendplugin.Plugin interface * re order funcs * improve var name * fix log statements * refactor data model * add logic for dupe check during loading * cleanup state setting * refactor loader * cleanup manager interface * add rendering flow * refactor loading + init * add renderer support * fix renderer plugin * reformat imports * track errors * fix plugin signature inheritance * name param in interface * update func comment * fix func arg name * introduce class concept * remove func * fix external plugin check * apply changes from pm-experiment * fix core plugins * fix imports * rename interface * comment API interface * add support for testdata plugin * enable alerting + use correct core plugin contracts * slim manager API * fix param name * fix filter * support static routes * fix rendering * tidy rendering * get tests compiling * fix install+uninstall * start finder test * add finder test coverage * start loader tests * add test for core plugins * load core + bundled test * add test for nested plugin loading * add test files * clean interface + fix registering some core plugins * refactoring * reformat and create sub packages * simplify core plugin init * fix ctx cancel scenario * migrate initializer * remove Init() funcs * add test starter * new logger * flesh out initializer tests * refactoring * remove unused svc * refactor rendering flow * fixup loader tests * add enabled helper func * fix logger name * fix data fetchers * fix case where plugin dir doesn't exist * improve coverage + move dupe checking to loader * remove noisy debug logs * register core plugins automagically * add support for renderer in catalog * make private func + fix req validation * use interface * re-add check for renderer in catalog * tidy up from moving to auto reg core plugins * core plugin registrar * guards * copy over core plugins for test infra * all tests green * renames * propagate new interfaces * kill old manager * get compiling * tidy up * update naming * refactor manager test + cleanup * add more cases to finder test * migrate validator to field * more coverage * refactor dupe checking * add test for plugin class * add coverage for initializer * split out rendering * move * fixup tests * fix uss test * fix frontend settings * fix grafanads test * add check when checking sig errors * fix enabled map * fixup * allow manual setup of CM * rename to cloud-monitoring * remove TODO * add installer interface for testing * loader interface returns * tests passing * refactor + add more coverage * support 'stackdriver' * fix frontend settings loading * improve naming based on package name * small tidy * refactor test * fix renderer start * make cloud-monitoring plugin ID clearer * add plugin update test * add integration tests * don't break all if sig can't be calculated * add root URL check test * add more signature verification tests * update DTO name * update enabled plugins comment * update comments * fix linter * revert fe naming change * fix errors endpoint * reset error code field name * re-order test to help verify * assert -> require * pm check * add missing entry + re-order * re-check * dump icon log * verify manager contents first * reformat * apply PR feedback * apply style changes * fix one vs all loading err * improve log output * only start when no signature error * move log * rework plugin update check * fix test * fix multi loading from cfg.PluginSettings * improve log output #2 * add error abstraction to capture errors without registering a plugin * add debug log * add unsigned warning * e2e test attempt * fix logger * set home path * prevent panic * alternate * ugh.. fix home path * return renderer even if not started * make renderer plugin managed * add fallback renderer icon, update renderer badge + prevent changes when renderer is installed * fix icon loading * rollback renderer changes * use correct field * remove unneccessary block * remove newline * remove unused func * fix bundled plugins base + module fields * remove unused field since refactor * add authorizer abstraction * loader only returns plugins expected to run * fix multi log output
4 years ago
errs: make(map[string]*plugins.SignatureError),
log: &fakeLogger{},
Plugins: Refactor Plugin Management (#40477) * add core plugin flow * add instrumentation * move func * remove cruft * support external backend plugins * refactor + clean up * remove comments * refactor loader * simplify core plugin path arg * cleanup loggers * move signature validator to plugins package * fix sig packaging * cleanup plugin model * remove unnecessary plugin field * add start+stop for pm * fix failures * add decommissioned state * export fields just to get things flowing * fix comments * set static routes * make image loading idempotent * merge with backend plugin manager * re-use funcs * reorder imports + remove unnecessary interface * add some TODOs + remove unused func * remove unused instrumentation func * simplify client usage * remove import alias * re-use backendplugin.Plugin interface * re order funcs * improve var name * fix log statements * refactor data model * add logic for dupe check during loading * cleanup state setting * refactor loader * cleanup manager interface * add rendering flow * refactor loading + init * add renderer support * fix renderer plugin * reformat imports * track errors * fix plugin signature inheritance * name param in interface * update func comment * fix func arg name * introduce class concept * remove func * fix external plugin check * apply changes from pm-experiment * fix core plugins * fix imports * rename interface * comment API interface * add support for testdata plugin * enable alerting + use correct core plugin contracts * slim manager API * fix param name * fix filter * support static routes * fix rendering * tidy rendering * get tests compiling * fix install+uninstall * start finder test * add finder test coverage * start loader tests * add test for core plugins * load core + bundled test * add test for nested plugin loading * add test files * clean interface + fix registering some core plugins * refactoring * reformat and create sub packages * simplify core plugin init * fix ctx cancel scenario * migrate initializer * remove Init() funcs * add test starter * new logger * flesh out initializer tests * refactoring * remove unused svc * refactor rendering flow * fixup loader tests * add enabled helper func * fix logger name * fix data fetchers * fix case where plugin dir doesn't exist * improve coverage + move dupe checking to loader * remove noisy debug logs * register core plugins automagically * add support for renderer in catalog * make private func + fix req validation * use interface * re-add check for renderer in catalog * tidy up from moving to auto reg core plugins * core plugin registrar * guards * copy over core plugins for test infra * all tests green * renames * propagate new interfaces * kill old manager * get compiling * tidy up * update naming * refactor manager test + cleanup * add more cases to finder test * migrate validator to field * more coverage * refactor dupe checking * add test for plugin class * add coverage for initializer * split out rendering * move * fixup tests * fix uss test * fix frontend settings * fix grafanads test * add check when checking sig errors * fix enabled map * fixup * allow manual setup of CM * rename to cloud-monitoring * remove TODO * add installer interface for testing * loader interface returns * tests passing * refactor + add more coverage * support 'stackdriver' * fix frontend settings loading * improve naming based on package name * small tidy * refactor test * fix renderer start * make cloud-monitoring plugin ID clearer * add plugin update test * add integration tests * don't break all if sig can't be calculated * add root URL check test * add more signature verification tests * update DTO name * update enabled plugins comment * update comments * fix linter * revert fe naming change * fix errors endpoint * reset error code field name * re-order test to help verify * assert -> require * pm check * add missing entry + re-order * re-check * dump icon log * verify manager contents first * reformat * apply PR feedback * apply style changes * fix one vs all loading err * improve log output * only start when no signature error * move log * rework plugin update check * fix test * fix multi loading from cfg.PluginSettings * improve log output #2 * add error abstraction to capture errors without registering a plugin * add debug log * add unsigned warning * e2e test attempt * fix logger * set home path * prevent panic * alternate * ugh.. fix home path * return renderer even if not started * make renderer plugin managed * add fallback renderer icon, update renderer badge + prevent changes when renderer is installed * fix icon loading * rollback renderer changes * use correct field * remove unneccessary block * remove newline * remove unused func * fix bundled plugins base + module fields * remove unused field since refactor * add authorizer abstraction * loader only returns plugins expected to run * fix multi log output
4 years ago
}
}
type fakeLicensingService struct {
edition string
hasLicense bool
tokenRaw string
}
func (t *fakeLicensingService) HasLicense() bool {
return t.hasLicense
}
func (t *fakeLicensingService) Expiry() int64 {
return 0
}
func (t *fakeLicensingService) Edition() string {
return t.edition
}
func (t *fakeLicensingService) StateInfo() string {
return ""
}
func (t *fakeLicensingService) ContentDeliveryPrefix() string {
return ""
}
func (t *fakeLicensingService) LicenseURL(_ bool) string {
Plugins: Refactor Plugin Management (#40477) * add core plugin flow * add instrumentation * move func * remove cruft * support external backend plugins * refactor + clean up * remove comments * refactor loader * simplify core plugin path arg * cleanup loggers * move signature validator to plugins package * fix sig packaging * cleanup plugin model * remove unnecessary plugin field * add start+stop for pm * fix failures * add decommissioned state * export fields just to get things flowing * fix comments * set static routes * make image loading idempotent * merge with backend plugin manager * re-use funcs * reorder imports + remove unnecessary interface * add some TODOs + remove unused func * remove unused instrumentation func * simplify client usage * remove import alias * re-use backendplugin.Plugin interface * re order funcs * improve var name * fix log statements * refactor data model * add logic for dupe check during loading * cleanup state setting * refactor loader * cleanup manager interface * add rendering flow * refactor loading + init * add renderer support * fix renderer plugin * reformat imports * track errors * fix plugin signature inheritance * name param in interface * update func comment * fix func arg name * introduce class concept * remove func * fix external plugin check * apply changes from pm-experiment * fix core plugins * fix imports * rename interface * comment API interface * add support for testdata plugin * enable alerting + use correct core plugin contracts * slim manager API * fix param name * fix filter * support static routes * fix rendering * tidy rendering * get tests compiling * fix install+uninstall * start finder test * add finder test coverage * start loader tests * add test for core plugins * load core + bundled test * add test for nested plugin loading * add test files * clean interface + fix registering some core plugins * refactoring * reformat and create sub packages * simplify core plugin init * fix ctx cancel scenario * migrate initializer * remove Init() funcs * add test starter * new logger * flesh out initializer tests * refactoring * remove unused svc * refactor rendering flow * fixup loader tests * add enabled helper func * fix logger name * fix data fetchers * fix case where plugin dir doesn't exist * improve coverage + move dupe checking to loader * remove noisy debug logs * register core plugins automagically * add support for renderer in catalog * make private func + fix req validation * use interface * re-add check for renderer in catalog * tidy up from moving to auto reg core plugins * core plugin registrar * guards * copy over core plugins for test infra * all tests green * renames * propagate new interfaces * kill old manager * get compiling * tidy up * update naming * refactor manager test + cleanup * add more cases to finder test * migrate validator to field * more coverage * refactor dupe checking * add test for plugin class * add coverage for initializer * split out rendering * move * fixup tests * fix uss test * fix frontend settings * fix grafanads test * add check when checking sig errors * fix enabled map * fixup * allow manual setup of CM * rename to cloud-monitoring * remove TODO * add installer interface for testing * loader interface returns * tests passing * refactor + add more coverage * support 'stackdriver' * fix frontend settings loading * improve naming based on package name * small tidy * refactor test * fix renderer start * make cloud-monitoring plugin ID clearer * add plugin update test * add integration tests * don't break all if sig can't be calculated * add root URL check test * add more signature verification tests * update DTO name * update enabled plugins comment * update comments * fix linter * revert fe naming change * fix errors endpoint * reset error code field name * re-order test to help verify * assert -> require * pm check * add missing entry + re-order * re-check * dump icon log * verify manager contents first * reformat * apply PR feedback * apply style changes * fix one vs all loading err * improve log output * only start when no signature error * move log * rework plugin update check * fix test * fix multi loading from cfg.PluginSettings * improve log output #2 * add error abstraction to capture errors without registering a plugin * add debug log * add unsigned warning * e2e test attempt * fix logger * set home path * prevent panic * alternate * ugh.. fix home path * return renderer even if not started * make renderer plugin managed * add fallback renderer icon, update renderer badge + prevent changes when renderer is installed * fix icon loading * rollback renderer changes * use correct field * remove unneccessary block * remove newline * remove unused func * fix bundled plugins base + module fields * remove unused field since refactor * add authorizer abstraction * loader only returns plugins expected to run * fix multi log output
4 years ago
return ""
}
func (t *fakeLicensingService) HasValidLicense() bool {
return false
}
func (t *fakeLicensingService) Environment() map[string]string {
return map[string]string{"GF_ENTERPRISE_LICENSE_TEXT": t.tokenRaw}
}
type fakeLogger struct {
log.Logger
}
func (fl fakeLogger) Info(_ string, _ ...interface{}) {
}
func (fl fakeLogger) Debug(_ string, _ ...interface{}) {
}
func (fl fakeLogger) Warn(_ string, _ ...interface{}) {
}