Plugins: Standardize Golang enum naming convention (#69449)

* standardize enum pattern

* fix up
This commit is contained in:
Will Browne
2023-06-08 12:21:19 +02:00
committed by GitHub
parent 4db6679460
commit a221e1d226
31 changed files with 308 additions and 306 deletions

View File

@ -38,7 +38,7 @@ func (hs *HTTPServer) getFrontendSettings(c *contextmodel.ReqContext) (*dtos.Fro
} }
apps := make(map[string]*plugins.AppDTO, 0) apps := make(map[string]*plugins.AppDTO, 0)
for _, ap := range availablePlugins[plugins.App] { for _, ap := range availablePlugins[plugins.TypeApp] {
apps[ap.Plugin.ID] = newAppDTO( apps[ap.Plugin.ID] = newAppDTO(
ap.Plugin, ap.Plugin,
ap.Settings, ap.Settings,
@ -58,9 +58,9 @@ func (hs *HTTPServer) getFrontendSettings(c *contextmodel.ReqContext) (*dtos.Fro
} }
panels := make(map[string]plugins.PanelDTO) panels := make(map[string]plugins.PanelDTO)
for _, ap := range availablePlugins[plugins.Panel] { for _, ap := range availablePlugins[plugins.TypePanel] {
panel := ap.Plugin panel := ap.Plugin
if panel.State == plugins.AlphaRelease && !hs.Cfg.PluginsEnableAlpha { if panel.State == plugins.ReleaseStateAlpha && !hs.Cfg.PluginsEnableAlpha {
continue continue
} }
@ -313,7 +313,7 @@ func (hs *HTTPServer) getFSDataSources(c *contextmodel.ReqContext, availablePlug
ReadOnly: ds.ReadOnly, ReadOnly: ds.ReadOnly,
} }
ap, exists := availablePlugins.Get(plugins.DataSource, ds.Type) ap, exists := availablePlugins.Get(plugins.TypeDataSource, ds.Type)
if !exists { if !exists {
c.Logger.Error("Could not find plugin definition for data source", "datasource_type", ds.Type) c.Logger.Error("Could not find plugin definition for data source", "datasource_type", ds.Type)
continue continue
@ -399,7 +399,7 @@ func (hs *HTTPServer) getFSDataSources(c *contextmodel.ReqContext, availablePlug
// add data sources that are built in (meaning they are not added via data sources page, nor have any entry in // add data sources that are built in (meaning they are not added via data sources page, nor have any entry in
// the datasource table) // the datasource table)
for _, ds := range hs.pluginStore.Plugins(c.Req.Context(), plugins.DataSource) { for _, ds := range hs.pluginStore.Plugins(c.Req.Context(), plugins.TypeDataSource) {
if ds.BuiltIn { if ds.BuiltIn {
dto := plugins.DataSourceDTO{ dto := plugins.DataSourceDTO{
Type: string(ds.Type), Type: string(ds.Type),
@ -512,7 +512,7 @@ func (hs *HTTPServer) availablePlugins(ctx context.Context, orgID int64) (Availa
} }
apps := make(map[string]*availablePluginDTO) apps := make(map[string]*availablePluginDTO)
for _, app := range hs.pluginStore.Plugins(ctx, plugins.App) { for _, app := range hs.pluginStore.Plugins(ctx, plugins.TypeApp) {
if s, exists := pluginSettingMap[app.ID]; exists { if s, exists := pluginSettingMap[app.ID]; exists {
app.Pinned = s.Pinned app.Pinned = s.Pinned
apps[app.ID] = &availablePluginDTO{ apps[app.ID] = &availablePluginDTO{
@ -521,10 +521,10 @@ func (hs *HTTPServer) availablePlugins(ctx context.Context, orgID int64) (Availa
} }
} }
} }
ap[plugins.App] = apps ap[plugins.TypeApp] = apps
dataSources := make(map[string]*availablePluginDTO) dataSources := make(map[string]*availablePluginDTO)
for _, ds := range hs.pluginStore.Plugins(ctx, plugins.DataSource) { for _, ds := range hs.pluginStore.Plugins(ctx, plugins.TypeDataSource) {
if s, exists := pluginSettingMap[ds.ID]; exists { if s, exists := pluginSettingMap[ds.ID]; exists {
dataSources[ds.ID] = &availablePluginDTO{ dataSources[ds.ID] = &availablePluginDTO{
Plugin: ds, Plugin: ds,
@ -532,10 +532,10 @@ func (hs *HTTPServer) availablePlugins(ctx context.Context, orgID int64) (Availa
} }
} }
} }
ap[plugins.DataSource] = dataSources ap[plugins.TypeDataSource] = dataSources
panels := make(map[string]*availablePluginDTO) panels := make(map[string]*availablePluginDTO)
for _, p := range hs.pluginStore.Plugins(ctx, plugins.Panel) { for _, p := range hs.pluginStore.Plugins(ctx, plugins.TypePanel) {
if s, exists := pluginSettingMap[p.ID]; exists { if s, exists := pluginSettingMap[p.ID]; exists {
panels[p.ID] = &availablePluginDTO{ panels[p.ID] = &availablePluginDTO{
Plugin: p, Plugin: p,
@ -543,7 +543,7 @@ func (hs *HTTPServer) availablePlugins(ctx context.Context, orgID int64) (Availa
} }
} }
} }
ap[plugins.Panel] = panels ap[plugins.TypePanel] = panels
return ap, nil return ap, nil
} }
@ -561,7 +561,7 @@ func (hs *HTTPServer) pluginSettings(ctx context.Context, orgID int64) (map[stri
} }
// fill settings from app plugins // fill settings from app plugins
for _, plugin := range hs.pluginStore.Plugins(ctx, plugins.App) { for _, plugin := range hs.pluginStore.Plugins(ctx, plugins.TypeApp) {
// ignore settings that already exist // ignore settings that already exist
if _, exists := pluginSettings[plugin.ID]; exists { if _, exists := pluginSettings[plugin.ID]; exists {
continue continue

View File

@ -224,7 +224,7 @@ func TestHTTPServer_GetFrontendSettings_apps(t *testing.T) {
JSONData: plugins.JSONData{ JSONData: plugins.JSONData{
ID: "test-app", ID: "test-app",
Info: plugins.Info{Version: "0.5.0"}, Info: plugins.Info{Version: "0.5.0"},
Type: plugins.App, Type: plugins.TypeApp,
Preload: true, Preload: true,
}, },
}, },
@ -257,7 +257,7 @@ func TestHTTPServer_GetFrontendSettings_apps(t *testing.T) {
JSONData: plugins.JSONData{ JSONData: plugins.JSONData{
ID: "test-app", ID: "test-app",
Info: plugins.Info{Version: "0.5.0"}, Info: plugins.Info{Version: "0.5.0"},
Type: plugins.App, Type: plugins.TypeApp,
Preload: true, Preload: true,
}, },
}, },
@ -290,7 +290,7 @@ func TestHTTPServer_GetFrontendSettings_apps(t *testing.T) {
JSONData: plugins.JSONData{ JSONData: plugins.JSONData{
ID: "test-app", ID: "test-app",
Info: plugins.Info{Version: "0.5.0"}, Info: plugins.Info{Version: "0.5.0"},
Type: plugins.App, Type: plugins.TypeApp,
Preload: true, Preload: true,
}, },
AngularDetected: true, AngularDetected: true,

View File

@ -99,7 +99,7 @@ func (hs *HTTPServer) GetPluginList(c *contextmodel.ReqContext) response.Respons
continue continue
} }
if pluginDef.State == plugins.AlphaRelease && !hs.Cfg.PluginsEnableAlpha { if pluginDef.State == plugins.ReleaseStateAlpha && !hs.Cfg.PluginsEnableAlpha {
continue continue
} }

View File

@ -206,7 +206,7 @@ func Test_GetPluginAssets(t *testing.T) {
requestedFile := filepath.Clean(tmpFile.Name()) requestedFile := filepath.Clean(tmpFile.Name())
t.Run("Given a request for an existing plugin file", func(t *testing.T) { t.Run("Given a request for an existing plugin file", func(t *testing.T) {
p := createPlugin(plugins.JSONData{ID: pluginID}, plugins.External, plugins.NewLocalFS(filepath.Dir(requestedFile))) p := createPlugin(plugins.JSONData{ID: pluginID}, plugins.ClassExternal, plugins.NewLocalFS(filepath.Dir(requestedFile)))
pluginRegistry := &fakes.FakePluginRegistry{ pluginRegistry := &fakes.FakePluginRegistry{
Store: map[string]*plugins.Plugin{ Store: map[string]*plugins.Plugin{
p.ID: p, p.ID: p,
@ -224,7 +224,7 @@ func Test_GetPluginAssets(t *testing.T) {
}) })
t.Run("Given a request for a relative path", func(t *testing.T) { t.Run("Given a request for a relative path", func(t *testing.T) {
p := createPlugin(plugins.JSONData{ID: pluginID}, plugins.External, plugins.NewFakeFS()) p := createPlugin(plugins.JSONData{ID: pluginID}, plugins.ClassExternal, plugins.NewFakeFS())
pluginRegistry := &fakes.FakePluginRegistry{ pluginRegistry := &fakes.FakePluginRegistry{
Store: map[string]*plugins.Plugin{ Store: map[string]*plugins.Plugin{
p.ID: p, p.ID: p,
@ -241,7 +241,7 @@ func Test_GetPluginAssets(t *testing.T) {
}) })
t.Run("Given a request for an existing plugin file that is not listed as a signature covered file", func(t *testing.T) { t.Run("Given a request for an existing plugin file that is not listed as a signature covered file", func(t *testing.T) {
p := createPlugin(plugins.JSONData{ID: pluginID}, plugins.Core, plugins.NewLocalFS(filepath.Dir(requestedFile))) p := createPlugin(plugins.JSONData{ID: pluginID}, plugins.ClassCore, plugins.NewLocalFS(filepath.Dir(requestedFile)))
pluginRegistry := &fakes.FakePluginRegistry{ pluginRegistry := &fakes.FakePluginRegistry{
Store: map[string]*plugins.Plugin{ Store: map[string]*plugins.Plugin{
p.ID: p, p.ID: p,
@ -259,7 +259,7 @@ func Test_GetPluginAssets(t *testing.T) {
}) })
t.Run("Given a request for an non-existing plugin file", func(t *testing.T) { t.Run("Given a request for an non-existing plugin file", func(t *testing.T) {
p := createPlugin(plugins.JSONData{ID: pluginID}, plugins.External, plugins.NewFakeFS()) p := createPlugin(plugins.JSONData{ID: pluginID}, plugins.ClassExternal, plugins.NewFakeFS())
service := &fakes.FakePluginRegistry{ service := &fakes.FakePluginRegistry{
Store: map[string]*plugins.Plugin{ Store: map[string]*plugins.Plugin{
p.ID: p, p.ID: p,
@ -552,13 +552,13 @@ func Test_PluginsList_AccessControl(t *testing.T) {
ID: "test-app", Type: "app", Name: "test-app", ID: "test-app", Type: "app", Name: "test-app",
Info: plugins.Info{ Info: plugins.Info{
Version: "1.0.0", Version: "1.0.0",
}}, plugins.External, plugins.NewFakeFS()) }}, plugins.ClassExternal, plugins.NewFakeFS())
p2 := createPlugin( p2 := createPlugin(
plugins.JSONData{ID: "mysql", Type: "datasource", Name: "MySQL", plugins.JSONData{ID: "mysql", Type: "datasource", Name: "MySQL",
Info: plugins.Info{ Info: plugins.Info{
Author: plugins.InfoLink{Name: "Grafana Labs", URL: "https://grafana.com"}, Author: plugins.InfoLink{Name: "Grafana Labs", URL: "https://grafana.com"},
Description: "Data source for MySQL databases", Description: "Data source for MySQL databases",
}}, plugins.Core, plugins.NewFakeFS()) }}, plugins.ClassCore, plugins.NewFakeFS())
pluginRegistry := &fakes.FakePluginRegistry{ pluginRegistry := &fakes.FakePluginRegistry{
Store: map[string]*plugins.Plugin{ Store: map[string]*plugins.Plugin{

View File

@ -80,7 +80,7 @@ func GetLocalPlugin(pluginDir, pluginID string) (plugins.FoundPlugin, error) {
func GetLocalPlugins(pluginDir string) []*plugins.FoundBundle { func GetLocalPlugins(pluginDir string) []*plugins.FoundBundle {
f := finder.NewLocalFinder(&config.Cfg{}) f := finder.NewLocalFinder(&config.Cfg{})
res, err := f.Find(context.Background(), sources.NewLocalSource(plugins.External, []string{pluginDir})) res, err := f.Find(context.Background(), sources.NewLocalSource(plugins.ClassExternal, []string{pluginDir}))
if err != nil { if err != nil {
logger.Error("Could not get local plugins", err) logger.Error("Could not get local plugins", err)
return make([]*plugins.FoundBundle, 0) return make([]*plugins.FoundBundle, 0)

View File

@ -338,13 +338,13 @@ func (s *Service) updateTotalStats(ctx context.Context) bool {
} }
func (s *Service) appCount(ctx context.Context) int { func (s *Service) appCount(ctx context.Context) int {
return len(s.plugins.Plugins(ctx, plugins.App)) return len(s.plugins.Plugins(ctx, plugins.TypeApp))
} }
func (s *Service) panelCount(ctx context.Context) int { func (s *Service) panelCount(ctx context.Context) int {
return len(s.plugins.Plugins(ctx, plugins.Panel)) return len(s.plugins.Plugins(ctx, plugins.TypePanel))
} }
func (s *Service) dataSourceCount(ctx context.Context) int { func (s *Service) dataSourceCount(ctx context.Context) int {
return len(s.plugins.Plugins(ctx, plugins.DataSource)) return len(s.plugins.Plugins(ctx, plugins.TypeDataSource))
} }

View File

@ -124,7 +124,7 @@ func (m *PluginInstaller) Add(ctx context.Context, pluginID, version string, opt
pathsToScan = append(pathsToScan, depArchive.Path) pathsToScan = append(pathsToScan, depArchive.Path)
} }
_, err = m.pluginLoader.Load(ctx, sources.NewLocalSource(plugins.External, pathsToScan)) _, err = m.pluginLoader.Load(ctx, sources.NewLocalSource(plugins.ClassExternal, pathsToScan))
if err != nil { if err != nil {
m.log.Error("Could not load plugins", "paths", pathsToScan, "err", err) m.log.Error("Could not load plugins", "paths", pathsToScan, "err", err)
return err return err

View File

@ -26,7 +26,7 @@ func TestPluginManager_Add_Remove(t *testing.T) {
) )
// mock a plugin to be returned automatically by the plugin loader // mock a plugin to be returned automatically by the plugin loader
pluginV1 := createPlugin(t, pluginID, plugins.External, true, true, func(plugin *plugins.Plugin) { pluginV1 := createPlugin(t, pluginID, plugins.ClassExternal, true, true, func(plugin *plugins.Plugin) {
plugin.Info.Version = v1 plugin.Info.Version = v1
}) })
mockZipV1 := &zip.ReadCloser{Reader: zip.Reader{File: []*zip.File{{ mockZipV1 := &zip.ReadCloser{Reader: zip.Reader{File: []*zip.File{{
@ -85,7 +85,7 @@ func TestPluginManager_Add_Remove(t *testing.T) {
zipNameV2 = "test-panel-2.0.0.zip" zipNameV2 = "test-panel-2.0.0.zip"
) )
// mock a plugin to be returned automatically by the plugin loader // mock a plugin to be returned automatically by the plugin loader
pluginV2 := createPlugin(t, pluginID, plugins.External, true, true, func(plugin *plugins.Plugin) { pluginV2 := createPlugin(t, pluginID, plugins.ClassExternal, true, true, func(plugin *plugins.Plugin) {
plugin.Info.Version = v2 plugin.Info.Version = v2
}) })
@ -93,7 +93,7 @@ func TestPluginManager_Add_Remove(t *testing.T) {
FileHeader: zip.FileHeader{Name: zipNameV2}, FileHeader: zip.FileHeader{Name: zipNameV2},
}}}} }}}}
loader.LoadFunc = func(ctx context.Context, src plugins.PluginSource) ([]*plugins.Plugin, error) { loader.LoadFunc = func(ctx context.Context, src plugins.PluginSource) ([]*plugins.Plugin, error) {
require.Equal(t, plugins.External, src.PluginClass(ctx)) require.Equal(t, plugins.ClassExternal, src.PluginClass(ctx))
require.Equal(t, []string{zipNameV2}, src.PluginURIs(ctx)) require.Equal(t, []string{zipNameV2}, src.PluginURIs(ctx))
return []*plugins.Plugin{pluginV2}, nil return []*plugins.Plugin{pluginV2}, nil
} }
@ -153,8 +153,8 @@ func TestPluginManager_Add_Remove(t *testing.T) {
tcs := []struct { tcs := []struct {
class plugins.Class class plugins.Class
}{ }{
{class: plugins.Core}, {class: plugins.ClassCore},
{class: plugins.Bundled}, {class: plugins.ClassBundled},
} }
for _, tc := range tcs { for _, tc := range tcs {
@ -190,7 +190,7 @@ func createPlugin(t *testing.T, pluginID string, class plugins.Class, managed, b
Class: class, Class: class,
JSONData: plugins.JSONData{ JSONData: plugins.JSONData{
ID: pluginID, ID: pluginID,
Type: plugins.DataSource, Type: plugins.TypeDataSource,
Backend: backend, Backend: backend,
}, },
} }

View File

@ -24,7 +24,7 @@ func ProvideService(cdn *pluginscdn.Service) *Service {
// Base returns the base path for the specified plugin. // Base returns the base path for the specified plugin.
func (s *Service) Base(pluginJSON plugins.JSONData, class plugins.Class, pluginDir string) (string, error) { func (s *Service) Base(pluginJSON plugins.JSONData, class plugins.Class, pluginDir string) (string, error) {
if class == plugins.Core { if class == plugins.ClassCore {
return path.Join("public/app/plugins", string(pluginJSON.Type), filepath.Base(pluginDir)), nil return path.Join("public/app/plugins", string(pluginJSON.Type), filepath.Base(pluginDir)), nil
} }
if s.cdn.PluginSupported(pluginJSON.ID) { if s.cdn.PluginSupported(pluginJSON.ID) {
@ -35,7 +35,7 @@ func (s *Service) Base(pluginJSON plugins.JSONData, class plugins.Class, pluginD
// Module returns the module.js path for the specified plugin. // Module returns the module.js path for the specified plugin.
func (s *Service) Module(pluginJSON plugins.JSONData, class plugins.Class, pluginDir string) (string, error) { func (s *Service) Module(pluginJSON plugins.JSONData, class plugins.Class, pluginDir string) (string, error) {
if class == plugins.Core { if class == plugins.ClassCore {
return path.Join("app/plugins", string(pluginJSON.Type), filepath.Base(pluginDir), "module"), nil return path.Join("app/plugins", string(pluginJSON.Type), filepath.Base(pluginDir), "module"), nil
} }
if s.cdn.PluginSupported(pluginJSON.ID) { if s.cdn.PluginSupported(pluginJSON.ID) {

View File

@ -56,29 +56,29 @@ func TestService(t *testing.T) {
}) })
t.Run("Base", func(t *testing.T) { t.Run("Base", func(t *testing.T) {
base, err := svc.Base(jsonData["one"], plugins.External, extPath("one")) base, err := svc.Base(jsonData["one"], plugins.ClassExternal, extPath("one"))
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, "plugin-cdn/one/1.0.0/public/plugins/one", base) require.Equal(t, "plugin-cdn/one/1.0.0/public/plugins/one", base)
base, err = svc.Base(jsonData["two"], plugins.External, extPath("two")) base, err = svc.Base(jsonData["two"], plugins.ClassExternal, extPath("two"))
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, "public/plugins/two", base) require.Equal(t, "public/plugins/two", base)
base, err = svc.Base(jsonData["table-old"], plugins.Core, tableOldPath) base, err = svc.Base(jsonData["table-old"], plugins.ClassCore, tableOldPath)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, "public/app/plugins/table-old", base) require.Equal(t, "public/app/plugins/table-old", base)
}) })
t.Run("Module", func(t *testing.T) { t.Run("Module", func(t *testing.T) {
module, err := svc.Module(jsonData["one"], plugins.External, extPath("one")) module, err := svc.Module(jsonData["one"], plugins.ClassExternal, extPath("one"))
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, "plugin-cdn/one/1.0.0/public/plugins/one/module", module) require.Equal(t, "plugin-cdn/one/1.0.0/public/plugins/one/module", module)
module, err = svc.Module(jsonData["two"], plugins.External, extPath("two")) module, err = svc.Module(jsonData["two"], plugins.ClassExternal, extPath("two"))
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, "plugins/two/module", module) require.Equal(t, "plugins/two/module", module)
module, err = svc.Module(jsonData["table-old"], plugins.Core, tableOldPath) module, err = svc.Module(jsonData["table-old"], plugins.ClassCore, tableOldPath)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, "app/plugins/table-old/module", module) require.Equal(t, "app/plugins/table-old/module", module)
}) })

View File

@ -43,7 +43,7 @@ func TestFinder_Find(t *testing.T) {
Primary: plugins.FoundPlugin{ Primary: plugins.FoundPlugin{
JSONData: plugins.JSONData{ JSONData: plugins.JSONData{
ID: "test-datasource", ID: "test-datasource",
Type: plugins.DataSource, Type: plugins.TypeDataSource,
Name: "Test", Name: "Test",
Info: plugins.Info{ Info: plugins.Info{
Author: plugins.InfoLink{ Author: plugins.InfoLink{
@ -57,7 +57,7 @@ func TestFinder_Find(t *testing.T) {
GrafanaVersion: "*", GrafanaVersion: "*",
Plugins: []plugins.Dependency{}, Plugins: []plugins.Dependency{},
}, },
State: plugins.AlphaRelease, State: plugins.ReleaseStateAlpha,
Backend: true, Backend: true,
Executable: "test", Executable: "test",
}, },
@ -74,7 +74,7 @@ func TestFinder_Find(t *testing.T) {
Primary: plugins.FoundPlugin{ Primary: plugins.FoundPlugin{
JSONData: plugins.JSONData{ JSONData: plugins.JSONData{
ID: "test-app", ID: "test-app",
Type: plugins.DataSource, Type: plugins.TypeDataSource,
Name: "Parent", Name: "Parent",
Info: plugins.Info{ Info: plugins.Info{
Author: plugins.InfoLink{ Author: plugins.InfoLink{
@ -96,7 +96,7 @@ func TestFinder_Find(t *testing.T) {
{ {
JSONData: plugins.JSONData{ JSONData: plugins.JSONData{
ID: "test-app", ID: "test-app",
Type: plugins.DataSource, Type: plugins.TypeDataSource,
Name: "Child", Name: "Child",
Info: plugins.Info{ Info: plugins.Info{
Author: plugins.InfoLink{ Author: plugins.InfoLink{
@ -126,7 +126,7 @@ func TestFinder_Find(t *testing.T) {
Primary: plugins.FoundPlugin{ Primary: plugins.FoundPlugin{
JSONData: plugins.JSONData{ JSONData: plugins.JSONData{
ID: "test-app", ID: "test-app",
Type: plugins.App, Type: plugins.TypeApp,
Name: "Test App", Name: "Test App",
Info: plugins.Info{ Info: plugins.Info{
Author: plugins.InfoLink{ Author: plugins.InfoLink{
@ -185,7 +185,7 @@ func TestFinder_Find(t *testing.T) {
Primary: plugins.FoundPlugin{ Primary: plugins.FoundPlugin{
JSONData: plugins.JSONData{ JSONData: plugins.JSONData{
ID: "test-app", ID: "test-app",
Type: plugins.DataSource, Type: plugins.TypeDataSource,
Name: "Parent", Name: "Parent",
Info: plugins.Info{ Info: plugins.Info{
Author: plugins.InfoLink{ Author: plugins.InfoLink{
@ -207,7 +207,7 @@ func TestFinder_Find(t *testing.T) {
{ {
JSONData: plugins.JSONData{ JSONData: plugins.JSONData{
ID: "test-app", ID: "test-app",
Type: plugins.DataSource, Type: plugins.TypeDataSource,
Name: "Child", Name: "Child",
Info: plugins.Info{ Info: plugins.Info{
Author: plugins.InfoLink{ Author: plugins.InfoLink{
@ -231,7 +231,7 @@ func TestFinder_Find(t *testing.T) {
Primary: plugins.FoundPlugin{ Primary: plugins.FoundPlugin{
JSONData: plugins.JSONData{ JSONData: plugins.JSONData{
ID: "test-datasource", ID: "test-datasource",
Type: plugins.DataSource, Type: plugins.TypeDataSource,
Name: "Test", Name: "Test",
Info: plugins.Info{ Info: plugins.Info{
Author: plugins.InfoLink{ Author: plugins.InfoLink{
@ -244,7 +244,7 @@ func TestFinder_Find(t *testing.T) {
GrafanaVersion: "*", GrafanaVersion: "*",
Plugins: []plugins.Dependency{}, Plugins: []plugins.Dependency{},
}, },
State: plugins.AlphaRelease, State: plugins.ReleaseStateAlpha,
Backend: true, Backend: true,
}, },
FS: mustNewStaticFSForTests(t, filepath.Join(testData, "invalid-v1-signature/plugin")), FS: mustNewStaticFSForTests(t, filepath.Join(testData, "invalid-v1-signature/plugin")),

View File

@ -16,7 +16,7 @@ func TestInitializer_Initialize(t *testing.T) {
p := &plugins.Plugin{ p := &plugins.Plugin{
JSONData: plugins.JSONData{ JSONData: plugins.JSONData{
ID: "test", ID: "test",
Type: plugins.DataSource, Type: plugins.TypeDataSource,
Includes: []*plugins.Includes{ Includes: []*plugins.Includes{
{ {
Name: "Example dashboard", Name: "Example dashboard",
@ -25,7 +25,7 @@ func TestInitializer_Initialize(t *testing.T) {
}, },
Backend: true, Backend: true,
}, },
Class: plugins.Core, Class: plugins.ClassCore,
} }
i := &Initializer{ i := &Initializer{
@ -47,13 +47,13 @@ func TestInitializer_Initialize(t *testing.T) {
p := &plugins.Plugin{ p := &plugins.Plugin{
JSONData: plugins.JSONData{ JSONData: plugins.JSONData{
ID: "test", ID: "test",
Type: plugins.Renderer, Type: plugins.TypeRenderer,
Dependencies: plugins.Dependencies{ Dependencies: plugins.Dependencies{
GrafanaVersion: ">=8.x", GrafanaVersion: ">=8.x",
}, },
Backend: true, Backend: true,
}, },
Class: plugins.External, Class: plugins.ClassExternal,
} }
i := &Initializer{ i := &Initializer{
@ -75,13 +75,13 @@ func TestInitializer_Initialize(t *testing.T) {
p := &plugins.Plugin{ p := &plugins.Plugin{
JSONData: plugins.JSONData{ JSONData: plugins.JSONData{
ID: "test", ID: "test",
Type: plugins.SecretsManager, Type: plugins.TypeSecretsManager,
Dependencies: plugins.Dependencies{ Dependencies: plugins.Dependencies{
GrafanaVersion: ">=8.x", GrafanaVersion: ">=8.x",
}, },
Backend: true, Backend: true,
}, },
Class: plugins.External, Class: plugins.ClassExternal,
} }
i := &Initializer{ i := &Initializer{

View File

@ -24,6 +24,7 @@ import (
"github.com/grafana/grafana/pkg/plugins/manager/signature/statickey" "github.com/grafana/grafana/pkg/plugins/manager/signature/statickey"
"github.com/grafana/grafana/pkg/plugins/manager/sources" "github.com/grafana/grafana/pkg/plugins/manager/sources"
"github.com/grafana/grafana/pkg/plugins/pluginscdn" "github.com/grafana/grafana/pkg/plugins/pluginscdn"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/setting"
) )
@ -71,14 +72,14 @@ func TestLoader_Load(t *testing.T) {
}{ }{
{ {
name: "Load a Core plugin", name: "Load a Core plugin",
class: plugins.Core, class: plugins.ClassCore,
cfg: &config.Cfg{}, cfg: &config.Cfg{},
pluginPaths: []string{filepath.Join(corePluginDir, "app/plugins/datasource/cloudwatch")}, pluginPaths: []string{filepath.Join(corePluginDir, "app/plugins/datasource/cloudwatch")},
want: []*plugins.Plugin{ want: []*plugins.Plugin{
{ {
JSONData: plugins.JSONData{ JSONData: plugins.JSONData{
ID: "cloudwatch", ID: "cloudwatch",
Type: "datasource", Type: plugins.TypeDataSource,
Name: "CloudWatch", Name: "CloudWatch",
Info: plugins.Info{ Info: plugins.Info{
Author: plugins.InfoLink{ Author: plugins.InfoLink{
@ -114,21 +115,21 @@ func TestLoader_Load(t *testing.T) {
BaseURL: "public/app/plugins/datasource/cloudwatch", BaseURL: "public/app/plugins/datasource/cloudwatch",
FS: mustNewStaticFSForTests(t, filepath.Join(corePluginDir, "app/plugins/datasource/cloudwatch")), FS: mustNewStaticFSForTests(t, filepath.Join(corePluginDir, "app/plugins/datasource/cloudwatch")),
Signature: plugins.SignatureInternal, Signature: plugins.SignatureStatusInternal,
Class: plugins.Core, Class: plugins.ClassCore,
}, },
}, },
}, },
{ {
name: "Load a Bundled plugin", name: "Load a Bundled plugin",
class: plugins.Bundled, class: plugins.ClassBundled,
cfg: &config.Cfg{}, cfg: &config.Cfg{},
pluginPaths: []string{"../testdata/valid-v2-signature"}, pluginPaths: []string{"../testdata/valid-v2-signature"},
want: []*plugins.Plugin{ want: []*plugins.Plugin{
{ {
JSONData: plugins.JSONData{ JSONData: plugins.JSONData{
ID: "test-datasource", ID: "test-datasource",
Type: "datasource", Type: plugins.TypeDataSource,
Name: "Test", Name: "Test",
Info: plugins.Info{ Info: plugins.Info{
Author: plugins.InfoLink{ Author: plugins.InfoLink{
@ -154,14 +155,14 @@ func TestLoader_Load(t *testing.T) {
BaseURL: "public/plugins/test-datasource", BaseURL: "public/plugins/test-datasource",
FS: mustNewStaticFSForTests(t, filepath.Join(parentDir, "testdata/valid-v2-signature/plugin/")), FS: mustNewStaticFSForTests(t, filepath.Join(parentDir, "testdata/valid-v2-signature/plugin/")),
Signature: "valid", Signature: "valid",
SignatureType: plugins.GrafanaSignature, SignatureType: plugins.SignatureTypeGrafana,
SignatureOrg: "Grafana Labs", SignatureOrg: "Grafana Labs",
Class: plugins.Bundled, Class: plugins.ClassBundled,
}, },
}, },
}, { }, {
name: "Load plugin with symbolic links", name: "Load plugin with symbolic links",
class: plugins.External, class: plugins.ClassExternal,
cfg: &config.Cfg{}, cfg: &config.Cfg{},
pluginPaths: []string{"../testdata/symbolic-plugin-dirs"}, pluginPaths: []string{"../testdata/symbolic-plugin-dirs"},
want: []*plugins.Plugin{ want: []*plugins.Plugin{
@ -203,41 +204,41 @@ func TestLoader_Load(t *testing.T) {
Name: "Nginx Connections", Name: "Nginx Connections",
Path: "dashboards/connections.json", Path: "dashboards/connections.json",
Type: "dashboard", Type: "dashboard",
Role: "Viewer", Role: org.RoleViewer,
Slug: "nginx-connections", Slug: "nginx-connections",
}, },
{ {
Name: "Nginx Memory", Name: "Nginx Memory",
Path: "dashboards/memory.json", Path: "dashboards/memory.json",
Type: "dashboard", Type: "dashboard",
Role: "Viewer", Role: org.RoleViewer,
Slug: "nginx-memory", Slug: "nginx-memory",
}, },
{ {
Name: "Nginx Panel", Name: "Nginx Panel",
Type: "panel", Type: string(plugins.TypePanel),
Role: "Viewer", Role: org.RoleViewer,
Slug: "nginx-panel"}, Slug: "nginx-panel"},
{ {
Name: "Nginx Datasource", Name: "Nginx Datasource",
Type: "datasource", Type: string(plugins.TypeDataSource),
Role: "Viewer", Role: org.RoleViewer,
Slug: "nginx-datasource", Slug: "nginx-datasource",
}, },
}, },
}, },
Class: plugins.External, Class: plugins.ClassExternal,
Module: "plugins/test-app/module", Module: "plugins/test-app/module",
BaseURL: "public/plugins/test-app", BaseURL: "public/plugins/test-app",
FS: mustNewStaticFSForTests(t, filepath.Join(parentDir, "testdata/includes-symlinks")), FS: mustNewStaticFSForTests(t, filepath.Join(parentDir, "testdata/includes-symlinks")),
Signature: "valid", Signature: "valid",
SignatureType: plugins.GrafanaSignature, SignatureType: plugins.SignatureTypeGrafana,
SignatureOrg: "Grafana Labs", SignatureOrg: "Grafana Labs",
}, },
}, },
}, { }, {
name: "Load an unsigned plugin (development)", name: "Load an unsigned plugin (development)",
class: plugins.External, class: plugins.ClassExternal,
cfg: &config.Cfg{ cfg: &config.Cfg{
DevMode: true, DevMode: true,
}, },
@ -246,7 +247,7 @@ func TestLoader_Load(t *testing.T) {
{ {
JSONData: plugins.JSONData{ JSONData: plugins.JSONData{
ID: "test-datasource", ID: "test-datasource",
Type: "datasource", Type: plugins.TypeDataSource,
Name: "Test", Name: "Test",
Info: plugins.Info{ Info: plugins.Info{
Author: plugins.InfoLink{ Author: plugins.InfoLink{
@ -264,9 +265,9 @@ func TestLoader_Load(t *testing.T) {
Plugins: []plugins.Dependency{}, Plugins: []plugins.Dependency{},
}, },
Backend: true, Backend: true,
State: plugins.AlphaRelease, State: plugins.ReleaseStateAlpha,
}, },
Class: plugins.External, Class: plugins.ClassExternal,
Module: "plugins/test-datasource/module", Module: "plugins/test-datasource/module",
BaseURL: "public/plugins/test-datasource", BaseURL: "public/plugins/test-datasource",
FS: mustNewStaticFSForTests(t, filepath.Join(parentDir, "testdata/unsigned-datasource/plugin")), FS: mustNewStaticFSForTests(t, filepath.Join(parentDir, "testdata/unsigned-datasource/plugin")),
@ -275,7 +276,7 @@ func TestLoader_Load(t *testing.T) {
}, },
}, { }, {
name: "Load an unsigned plugin (production)", name: "Load an unsigned plugin (production)",
class: plugins.External, class: plugins.ClassExternal,
cfg: &config.Cfg{}, cfg: &config.Cfg{},
pluginPaths: []string{"../testdata/unsigned-datasource"}, pluginPaths: []string{"../testdata/unsigned-datasource"},
want: []*plugins.Plugin{}, want: []*plugins.Plugin{},
@ -288,7 +289,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.ClassExternal,
cfg: &config.Cfg{ cfg: &config.Cfg{
PluginsAllowUnsigned: []string{"test-datasource"}, PluginsAllowUnsigned: []string{"test-datasource"},
}, },
@ -297,7 +298,7 @@ func TestLoader_Load(t *testing.T) {
{ {
JSONData: plugins.JSONData{ JSONData: plugins.JSONData{
ID: "test-datasource", ID: "test-datasource",
Type: "datasource", Type: plugins.TypeDataSource,
Name: "Test", Name: "Test",
Info: plugins.Info{ Info: plugins.Info{
Author: plugins.InfoLink{ Author: plugins.InfoLink{
@ -315,19 +316,19 @@ func TestLoader_Load(t *testing.T) {
Plugins: []plugins.Dependency{}, Plugins: []plugins.Dependency{},
}, },
Backend: true, Backend: true,
State: plugins.AlphaRelease, State: plugins.ReleaseStateAlpha,
}, },
Class: plugins.External, Class: plugins.ClassExternal,
Module: "plugins/test-datasource/module", Module: "plugins/test-datasource/module",
BaseURL: "public/plugins/test-datasource", BaseURL: "public/plugins/test-datasource",
FS: mustNewStaticFSForTests(t, filepath.Join(parentDir, "testdata/unsigned-datasource/plugin")), FS: mustNewStaticFSForTests(t, filepath.Join(parentDir, "testdata/unsigned-datasource/plugin")),
Signature: plugins.SignatureUnsigned, Signature: plugins.SignatureStatusUnsigned,
}, },
}, },
}, },
{ {
name: "Load a plugin with v1 manifest should return signatureInvalid", name: "Load a plugin with v1 manifest should return signatureInvalid",
class: plugins.External, class: plugins.ClassExternal,
cfg: &config.Cfg{}, cfg: &config.Cfg{},
pluginPaths: []string{"../testdata/lacking-files"}, pluginPaths: []string{"../testdata/lacking-files"},
want: []*plugins.Plugin{}, want: []*plugins.Plugin{},
@ -340,7 +341,7 @@ func TestLoader_Load(t *testing.T) {
}, },
{ {
name: "Load a plugin with v1 manifest using PluginsAllowUnsigned config (production) should return signatureInvali", name: "Load a plugin with v1 manifest using PluginsAllowUnsigned config (production) should return signatureInvali",
class: plugins.External, class: plugins.ClassExternal,
cfg: &config.Cfg{ cfg: &config.Cfg{
PluginsAllowUnsigned: []string{"test-datasource"}, PluginsAllowUnsigned: []string{"test-datasource"},
}, },
@ -355,7 +356,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.ClassExternal,
cfg: &config.Cfg{ cfg: &config.Cfg{
PluginsAllowUnsigned: []string{"test-datasource"}, PluginsAllowUnsigned: []string{"test-datasource"},
}, },
@ -370,7 +371,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.ClassExternal,
cfg: &config.Cfg{ cfg: &config.Cfg{
PluginsAllowUnsigned: []string{"test-datasource"}, PluginsAllowUnsigned: []string{"test-datasource"},
}, },
@ -385,7 +386,7 @@ func TestLoader_Load(t *testing.T) {
}, },
{ {
name: "Load an app with includes", name: "Load an app with includes",
class: plugins.External, class: plugins.ClassExternal,
cfg: &config.Cfg{ cfg: &config.Cfg{
PluginsAllowUnsigned: []string{"test-app"}, PluginsAllowUnsigned: []string{"test-app"},
}, },
@ -393,7 +394,7 @@ func TestLoader_Load(t *testing.T) {
want: []*plugins.Plugin{ want: []*plugins.Plugin{
{JSONData: plugins.JSONData{ {JSONData: plugins.JSONData{
ID: "test-app", ID: "test-app",
Type: "app", Type: plugins.TypeApp,
Name: "Test App", Name: "Test App",
Info: plugins.Info{ Info: plugins.Info{
Author: plugins.InfoLink{ Author: plugins.InfoLink{
@ -418,15 +419,15 @@ func TestLoader_Load(t *testing.T) {
Plugins: []plugins.Dependency{}, Plugins: []plugins.Dependency{},
}, },
Includes: []*plugins.Includes{ Includes: []*plugins.Includes{
{Name: "Nginx Memory", Path: "dashboards/memory.json", Type: "dashboard", Role: "Viewer", Slug: "nginx-memory"}, {Name: "Nginx Memory", Path: "dashboards/memory.json", Type: "dashboard", Role: org.RoleViewer, Slug: "nginx-memory"},
{Name: "Root Page (react)", Type: "page", Role: "Viewer", Path: "/a/my-simple-app", DefaultNav: true, AddToNav: true, Slug: "root-page-react"}, {Name: "Root Page (react)", Type: "page", Role: org.RoleViewer, Path: "/a/my-simple-app", DefaultNav: true, AddToNav: true, Slug: "root-page-react"},
}, },
Backend: false, Backend: false,
}, },
DefaultNavURL: "/plugins/test-app/page/root-page-react", DefaultNavURL: "/plugins/test-app/page/root-page-react",
FS: mustNewStaticFSForTests(t, filepath.Join(parentDir, "testdata/test-app-with-includes")), FS: mustNewStaticFSForTests(t, filepath.Join(parentDir, "testdata/test-app-with-includes")),
Class: plugins.External, Class: plugins.ClassExternal,
Signature: plugins.SignatureUnsigned, Signature: plugins.SignatureStatusUnsigned,
Module: "plugins/test-app/module", Module: "plugins/test-app/module",
BaseURL: "public/plugins/test-app", BaseURL: "public/plugins/test-app",
}, },
@ -480,7 +481,7 @@ func TestLoader_Load_CustomSource(t *testing.T) {
expected := []*plugins.Plugin{{ expected := []*plugins.Plugin{{
JSONData: plugins.JSONData{ JSONData: plugins.JSONData{
ID: "grafana-worldmap-panel", ID: "grafana-worldmap-panel",
Type: "panel", Type: plugins.TypePanel,
Name: "Worldmap Panel", Name: "Worldmap Panel",
Info: plugins.Info{ Info: plugins.Info{
Version: "0.3.3", Version: "0.3.3",
@ -514,8 +515,8 @@ func TestLoader_Load_CustomSource(t *testing.T) {
}, },
}, },
FS: mustNewStaticFSForTests(t, filepath.Join(parentDir, "testdata/cdn/plugin")), FS: mustNewStaticFSForTests(t, filepath.Join(parentDir, "testdata/cdn/plugin")),
Class: plugins.Bundled, Class: plugins.ClassBundled,
Signature: plugins.SignatureValid, Signature: plugins.SignatureStatusValid,
BaseURL: "plugin-cdn/grafana-worldmap-panel/0.3.3/public/plugins/grafana-worldmap-panel", BaseURL: "plugin-cdn/grafana-worldmap-panel/0.3.3/public/plugins/grafana-worldmap-panel",
Module: "plugin-cdn/grafana-worldmap-panel/0.3.3/public/plugins/grafana-worldmap-panel/module", Module: "plugin-cdn/grafana-worldmap-panel/0.3.3/public/plugins/grafana-worldmap-panel/module",
}} }}
@ -523,14 +524,14 @@ func TestLoader_Load_CustomSource(t *testing.T) {
l := newLoader(cfg) l := newLoader(cfg)
got, err := l.Load(context.Background(), &fakes.FakePluginSource{ got, err := l.Load(context.Background(), &fakes.FakePluginSource{
PluginClassFunc: func(ctx context.Context) plugins.Class { PluginClassFunc: func(ctx context.Context) plugins.Class {
return plugins.Bundled return plugins.ClassBundled
}, },
PluginURIsFunc: func(ctx context.Context) []string { PluginURIsFunc: func(ctx context.Context) []string {
return pluginPaths return pluginPaths
}, },
DefaultSignatureFunc: func(ctx context.Context) (plugins.Signature, bool) { DefaultSignatureFunc: func(ctx context.Context) (plugins.Signature, bool) {
return plugins.Signature{ return plugins.Signature{
Status: plugins.SignatureValid, Status: plugins.SignatureStatusValid,
}, true }, true
}, },
}) })
@ -627,7 +628,7 @@ func TestLoader_Load_MultiplePlugins(t *testing.T) {
{ {
JSONData: plugins.JSONData{ JSONData: plugins.JSONData{
ID: "test-datasource", ID: "test-datasource",
Type: "datasource", Type: plugins.TypeDataSource,
Name: "Test", Name: "Test",
Info: plugins.Info{ Info: plugins.Info{
Author: plugins.InfoLink{ Author: plugins.InfoLink{
@ -647,14 +648,14 @@ func TestLoader_Load_MultiplePlugins(t *testing.T) {
}, },
Backend: true, Backend: true,
Executable: "test", Executable: "test",
State: plugins.AlphaRelease, State: plugins.ReleaseStateAlpha,
}, },
Class: plugins.External, Class: plugins.ClassExternal,
Module: "plugins/test-datasource/module", Module: "plugins/test-datasource/module",
BaseURL: "public/plugins/test-datasource", BaseURL: "public/plugins/test-datasource",
FS: mustNewStaticFSForTests(t, filepath.Join(parentDir, "testdata/valid-v2-pvt-signature/plugin")), FS: mustNewStaticFSForTests(t, filepath.Join(parentDir, "testdata/valid-v2-pvt-signature/plugin")),
Signature: "valid", Signature: "valid",
SignatureType: plugins.PrivateSignature, SignatureType: plugins.SignatureTypePrivate,
SignatureOrg: "Will Browne", SignatureOrg: "Will Browne",
}, },
}, },
@ -685,7 +686,7 @@ func TestLoader_Load_MultiplePlugins(t *testing.T) {
got, err := l.Load(context.Background(), &fakes.FakePluginSource{ got, err := l.Load(context.Background(), &fakes.FakePluginSource{
PluginClassFunc: func(ctx context.Context) plugins.Class { PluginClassFunc: func(ctx context.Context) plugins.Class {
return plugins.External return plugins.ClassExternal
}, },
PluginURIsFunc: func(ctx context.Context) []string { PluginURIsFunc: func(ctx context.Context) []string {
return tt.pluginPaths return tt.pluginPaths
@ -733,7 +734,7 @@ func TestLoader_Load_RBACReady(t *testing.T) {
{ {
JSONData: plugins.JSONData{ JSONData: plugins.JSONData{
ID: "test-app", ID: "test-app",
Type: "app", Type: plugins.TypeApp,
Name: "Test App", Name: "Test App",
Info: plugins.Info{ Info: plugins.Info{
Author: plugins.InfoLink{ Author: plugins.InfoLink{
@ -772,9 +773,9 @@ func TestLoader_Load_RBACReady(t *testing.T) {
Backend: false, Backend: false,
}, },
FS: mustNewStaticFSForTests(t, pluginDir), FS: mustNewStaticFSForTests(t, pluginDir),
Class: plugins.External, Class: plugins.ClassExternal,
Signature: plugins.SignatureValid, Signature: plugins.SignatureStatusValid,
SignatureType: plugins.PrivateSignature, SignatureType: plugins.SignatureTypePrivate,
SignatureOrg: "gabrielmabille", SignatureOrg: "gabrielmabille",
Module: "plugins/test-app/module", Module: "plugins/test-app/module",
BaseURL: "public/plugins/test-app", BaseURL: "public/plugins/test-app",
@ -800,7 +801,7 @@ func TestLoader_Load_RBACReady(t *testing.T) {
got, err := l.Load(context.Background(), &fakes.FakePluginSource{ got, err := l.Load(context.Background(), &fakes.FakePluginSource{
PluginClassFunc: func(ctx context.Context) plugins.Class { PluginClassFunc: func(ctx context.Context) plugins.Class {
return plugins.External return plugins.ClassExternal
}, },
PluginURIsFunc: func(ctx context.Context) []string { PluginURIsFunc: func(ctx context.Context) []string {
return tt.pluginPaths return tt.pluginPaths
@ -842,7 +843,7 @@ func TestLoader_Load_Signature_RootURL(t *testing.T) {
{ {
JSONData: plugins.JSONData{ JSONData: plugins.JSONData{
ID: "test-datasource", ID: "test-datasource",
Type: "datasource", Type: plugins.TypeDataSource,
Name: "Test", Name: "Test",
Info: plugins.Info{ Info: plugins.Info{
Author: plugins.InfoLink{Name: "Will Browne", URL: "https://willbrowne.com"}, Author: plugins.InfoLink{Name: "Will Browne", URL: "https://willbrowne.com"},
@ -853,15 +854,15 @@ func TestLoader_Load_Signature_RootURL(t *testing.T) {
}, },
Version: "1.0.0", Version: "1.0.0",
}, },
State: plugins.AlphaRelease, State: plugins.ReleaseStateAlpha,
Dependencies: plugins.Dependencies{GrafanaVersion: "*", Plugins: []plugins.Dependency{}}, Dependencies: plugins.Dependencies{GrafanaVersion: "*", Plugins: []plugins.Dependency{}},
Backend: true, Backend: true,
Executable: "test", Executable: "test",
}, },
FS: mustNewStaticFSForTests(t, filepath.Join(parentDir, "/testdata/valid-v2-pvt-signature-root-url-uri/plugin")), FS: mustNewStaticFSForTests(t, filepath.Join(parentDir, "/testdata/valid-v2-pvt-signature-root-url-uri/plugin")),
Class: plugins.External, Class: plugins.ClassExternal,
Signature: plugins.SignatureValid, Signature: plugins.SignatureStatusValid,
SignatureType: plugins.PrivateSignature, SignatureType: plugins.SignatureTypePrivate,
SignatureOrg: "Will Browne", SignatureOrg: "Will Browne",
Module: "plugins/test-datasource/module", Module: "plugins/test-datasource/module",
BaseURL: "public/plugins/test-datasource", BaseURL: "public/plugins/test-datasource",
@ -878,7 +879,7 @@ func TestLoader_Load_Signature_RootURL(t *testing.T) {
}) })
got, err := l.Load(context.Background(), &fakes.FakePluginSource{ got, err := l.Load(context.Background(), &fakes.FakePluginSource{
PluginClassFunc: func(ctx context.Context) plugins.Class { PluginClassFunc: func(ctx context.Context) plugins.Class {
return plugins.External return plugins.ClassExternal
}, },
PluginURIsFunc: func(ctx context.Context) []string { PluginURIsFunc: func(ctx context.Context) []string {
return paths return paths
@ -904,7 +905,7 @@ func TestLoader_Load_DuplicatePlugins(t *testing.T) {
{ {
JSONData: plugins.JSONData{ JSONData: plugins.JSONData{
ID: "test-app", ID: "test-app",
Type: "app", Type: plugins.TypeApp,
Name: "Test App", Name: "Test App",
Info: plugins.Info{ Info: plugins.Info{
Author: plugins.InfoLink{ Author: plugins.InfoLink{
@ -935,17 +936,17 @@ func TestLoader_Load_DuplicatePlugins(t *testing.T) {
}, },
}, },
Includes: []*plugins.Includes{ Includes: []*plugins.Includes{
{Name: "Nginx Connections", Path: "dashboards/connections.json", Type: "dashboard", Role: "Viewer", Slug: "nginx-connections"}, {Name: "Nginx Connections", Path: "dashboards/connections.json", Type: "dashboard", Role: org.RoleViewer, Slug: "nginx-connections"},
{Name: "Nginx Memory", Path: "dashboards/memory.json", Type: "dashboard", Role: "Viewer", Slug: "nginx-memory"}, {Name: "Nginx Memory", Path: "dashboards/memory.json", Type: "dashboard", Role: org.RoleViewer, Slug: "nginx-memory"},
{Name: "Nginx Panel", Type: "panel", Role: "Viewer", Slug: "nginx-panel"}, {Name: "Nginx Panel", Type: "panel", Role: org.RoleViewer, Slug: "nginx-panel"},
{Name: "Nginx Datasource", Type: "datasource", Role: "Viewer", Slug: "nginx-datasource"}, {Name: "Nginx Datasource", Type: "datasource", Role: org.RoleViewer, Slug: "nginx-datasource"},
}, },
Backend: false, Backend: false,
}, },
FS: mustNewStaticFSForTests(t, pluginDir), FS: mustNewStaticFSForTests(t, pluginDir),
Class: plugins.External, Class: plugins.ClassExternal,
Signature: plugins.SignatureValid, Signature: plugins.SignatureStatusValid,
SignatureType: plugins.GrafanaSignature, SignatureType: plugins.SignatureTypeGrafana,
SignatureOrg: "Grafana Labs", SignatureOrg: "Grafana Labs",
Module: "plugins/test-app/module", Module: "plugins/test-app/module",
BaseURL: "public/plugins/test-app", BaseURL: "public/plugins/test-app",
@ -962,7 +963,7 @@ func TestLoader_Load_DuplicatePlugins(t *testing.T) {
}) })
got, err := l.Load(context.Background(), &fakes.FakePluginSource{ got, err := l.Load(context.Background(), &fakes.FakePluginSource{
PluginClassFunc: func(ctx context.Context) plugins.Class { PluginClassFunc: func(ctx context.Context) plugins.Class {
return plugins.External return plugins.ClassExternal
}, },
PluginURIsFunc: func(ctx context.Context) []string { PluginURIsFunc: func(ctx context.Context) []string {
return []string{pluginDir, pluginDir} return []string{pluginDir, pluginDir}
@ -994,7 +995,7 @@ func TestLoader_Load_SkipUninitializedPlugins(t *testing.T) {
{ {
JSONData: plugins.JSONData{ JSONData: plugins.JSONData{
ID: "test-app", ID: "test-app",
Type: "app", Type: plugins.TypeApp,
Name: "Test App", Name: "Test App",
Info: plugins.Info{ Info: plugins.Info{
Author: plugins.InfoLink{ Author: plugins.InfoLink{
@ -1025,17 +1026,17 @@ func TestLoader_Load_SkipUninitializedPlugins(t *testing.T) {
}, },
}, },
Includes: []*plugins.Includes{ Includes: []*plugins.Includes{
{Name: "Nginx Connections", Path: "dashboards/connections.json", Type: "dashboard", Role: "Viewer", Slug: "nginx-connections"}, {Name: "Nginx Connections", Path: "dashboards/connections.json", Type: "dashboard", Role: org.RoleViewer, Slug: "nginx-connections"},
{Name: "Nginx Memory", Path: "dashboards/memory.json", Type: "dashboard", Role: "Viewer", Slug: "nginx-memory"}, {Name: "Nginx Memory", Path: "dashboards/memory.json", Type: "dashboard", Role: org.RoleViewer, Slug: "nginx-memory"},
{Name: "Nginx Panel", Type: "panel", Role: "Viewer", Slug: "nginx-panel"}, {Name: "Nginx Panel", Type: "panel", Role: org.RoleViewer, Slug: "nginx-panel"},
{Name: "Nginx Datasource", Type: "datasource", Role: "Viewer", Slug: "nginx-datasource"}, {Name: "Nginx Datasource", Type: "datasource", Role: org.RoleViewer, Slug: "nginx-datasource"},
}, },
Backend: false, Backend: false,
}, },
FS: mustNewStaticFSForTests(t, pluginDir1), FS: mustNewStaticFSForTests(t, pluginDir1),
Class: plugins.External, Class: plugins.ClassExternal,
Signature: plugins.SignatureValid, Signature: plugins.SignatureStatusValid,
SignatureType: plugins.GrafanaSignature, SignatureType: plugins.SignatureTypeGrafana,
SignatureOrg: "Grafana Labs", SignatureOrg: "Grafana Labs",
Module: "plugins/test-app/module", Module: "plugins/test-app/module",
BaseURL: "public/plugins/test-app", BaseURL: "public/plugins/test-app",
@ -1061,7 +1062,7 @@ func TestLoader_Load_SkipUninitializedPlugins(t *testing.T) {
}) })
got, err := l.Load(context.Background(), &fakes.FakePluginSource{ got, err := l.Load(context.Background(), &fakes.FakePluginSource{
PluginClassFunc: func(ctx context.Context) plugins.Class { PluginClassFunc: func(ctx context.Context) plugins.Class {
return plugins.External return plugins.ClassExternal
}, },
PluginURIsFunc: func(ctx context.Context) []string { PluginURIsFunc: func(ctx context.Context) []string {
return []string{pluginDir1, pluginDir2} return []string{pluginDir1, pluginDir2}
@ -1080,7 +1081,7 @@ func TestLoader_Load_SkipUninitializedPlugins(t *testing.T) {
func TestLoader_Load_Angular(t *testing.T) { func TestLoader_Load_Angular(t *testing.T) {
fakePluginSource := &fakes.FakePluginSource{ fakePluginSource := &fakes.FakePluginSource{
PluginClassFunc: func(ctx context.Context) plugins.Class { PluginClassFunc: func(ctx context.Context) plugins.Class {
return plugins.External return plugins.ClassExternal
}, },
PluginURIsFunc: func(ctx context.Context) []string { PluginURIsFunc: func(ctx context.Context) []string {
return []string{"../testdata/valid-v2-signature"} return []string{"../testdata/valid-v2-signature"}
@ -1138,7 +1139,7 @@ func TestLoader_Load_NestedPlugins(t *testing.T) {
parent := &plugins.Plugin{ parent := &plugins.Plugin{
JSONData: plugins.JSONData{ JSONData: plugins.JSONData{
ID: "test-datasource", ID: "test-datasource",
Type: "datasource", Type: plugins.TypeDataSource,
Name: "Parent", Name: "Parent",
Info: plugins.Info{ Info: plugins.Info{
Author: plugins.InfoLink{ Author: plugins.InfoLink{
@ -1162,16 +1163,16 @@ func TestLoader_Load_NestedPlugins(t *testing.T) {
Module: "plugins/test-datasource/module", Module: "plugins/test-datasource/module",
BaseURL: "public/plugins/test-datasource", BaseURL: "public/plugins/test-datasource",
FS: mustNewStaticFSForTests(t, filepath.Join(rootDir, "testdata/nested-plugins/parent")), FS: mustNewStaticFSForTests(t, filepath.Join(rootDir, "testdata/nested-plugins/parent")),
Signature: plugins.SignatureValid, Signature: plugins.SignatureStatusValid,
SignatureType: plugins.GrafanaSignature, SignatureType: plugins.SignatureTypeGrafana,
SignatureOrg: "Grafana Labs", SignatureOrg: "Grafana Labs",
Class: plugins.External, Class: plugins.ClassExternal,
} }
child := &plugins.Plugin{ child := &plugins.Plugin{
JSONData: plugins.JSONData{ JSONData: plugins.JSONData{
ID: "test-panel", ID: "test-panel",
Type: "panel", Type: plugins.TypePanel,
Name: "Child", Name: "Child",
Info: plugins.Info{ Info: plugins.Info{
Author: plugins.InfoLink{ Author: plugins.InfoLink{
@ -1194,10 +1195,10 @@ func TestLoader_Load_NestedPlugins(t *testing.T) {
Module: "plugins/test-panel/module", Module: "plugins/test-panel/module",
BaseURL: "public/plugins/test-panel", BaseURL: "public/plugins/test-panel",
FS: mustNewStaticFSForTests(t, filepath.Join(rootDir, "testdata/nested-plugins/parent/nested")), FS: mustNewStaticFSForTests(t, filepath.Join(rootDir, "testdata/nested-plugins/parent/nested")),
Signature: plugins.SignatureValid, Signature: plugins.SignatureStatusValid,
SignatureType: plugins.GrafanaSignature, SignatureType: plugins.SignatureTypeGrafana,
SignatureOrg: "Grafana Labs", SignatureOrg: "Grafana Labs",
Class: plugins.External, Class: plugins.ClassExternal,
} }
parent.Children = []*plugins.Plugin{child} parent.Children = []*plugins.Plugin{child}
@ -1215,7 +1216,7 @@ func TestLoader_Load_NestedPlugins(t *testing.T) {
got, err := l.Load(context.Background(), &fakes.FakePluginSource{ got, err := l.Load(context.Background(), &fakes.FakePluginSource{
PluginClassFunc: func(ctx context.Context) plugins.Class { PluginClassFunc: func(ctx context.Context) plugins.Class {
return plugins.External return plugins.ClassExternal
}, },
PluginURIsFunc: func(ctx context.Context) []string { PluginURIsFunc: func(ctx context.Context) []string {
return []string{"../testdata/nested-plugins"} return []string{"../testdata/nested-plugins"}
@ -1238,7 +1239,7 @@ func TestLoader_Load_NestedPlugins(t *testing.T) {
t.Run("Load will exclude plugins that already exist", func(t *testing.T) { t.Run("Load will exclude plugins that already exist", func(t *testing.T) {
got, err := l.Load(context.Background(), &fakes.FakePluginSource{ got, err := l.Load(context.Background(), &fakes.FakePluginSource{
PluginClassFunc: func(ctx context.Context) plugins.Class { PluginClassFunc: func(ctx context.Context) plugins.Class {
return plugins.External return plugins.ClassExternal
}, },
PluginURIsFunc: func(ctx context.Context) []string { PluginURIsFunc: func(ctx context.Context) []string {
return []string{"../testdata/nested-plugins"} return []string{"../testdata/nested-plugins"}
@ -1263,7 +1264,7 @@ func TestLoader_Load_NestedPlugins(t *testing.T) {
parent := &plugins.Plugin{ parent := &plugins.Plugin{
JSONData: plugins.JSONData{ JSONData: plugins.JSONData{
ID: "myorgid-simple-app", ID: "myorgid-simple-app",
Type: "app", Type: plugins.TypeApp,
Name: "Simple App", Name: "Simple App",
Info: plugins.Info{ Info: plugins.Info{
Author: plugins.InfoLink{ Author: plugins.InfoLink{
@ -1292,7 +1293,7 @@ func TestLoader_Load_NestedPlugins(t *testing.T) {
Name: "Root Page (react)", Name: "Root Page (react)",
Path: "/a/myorgid-simple-app", Path: "/a/myorgid-simple-app",
Type: "page", Type: "page",
Role: "Viewer", Role: org.RoleViewer,
AddToNav: true, AddToNav: true,
DefaultNav: true, DefaultNav: true,
Slug: "root-page-react", Slug: "root-page-react",
@ -1301,7 +1302,7 @@ func TestLoader_Load_NestedPlugins(t *testing.T) {
Name: "Root Page (Tab B)", Name: "Root Page (Tab B)",
Path: "/a/myorgid-simple-app/?tab=b", Path: "/a/myorgid-simple-app/?tab=b",
Type: "page", Type: "page",
Role: "Viewer", Role: org.RoleViewer,
AddToNav: true, AddToNav: true,
Slug: "root-page-tab-b", Slug: "root-page-tab-b",
}, },
@ -1309,7 +1310,7 @@ func TestLoader_Load_NestedPlugins(t *testing.T) {
Name: "React Config", Name: "React Config",
Path: "/plugins/myorgid-simple-app/?page=page2", Path: "/plugins/myorgid-simple-app/?page=page2",
Type: "page", Type: "page",
Role: "Admin", Role: org.RoleAdmin,
AddToNav: true, AddToNav: true,
Slug: "react-config", Slug: "react-config",
}, },
@ -1317,14 +1318,14 @@ func TestLoader_Load_NestedPlugins(t *testing.T) {
Name: "Streaming Example", Name: "Streaming Example",
Path: "dashboards/streaming.json", Path: "dashboards/streaming.json",
Type: "dashboard", Type: "dashboard",
Role: "Viewer", Role: org.RoleViewer,
Slug: "streaming-example", Slug: "streaming-example",
}, },
{ {
Name: "Lots of Stats", Name: "Lots of Stats",
Path: "dashboards/stats.json", Path: "dashboards/stats.json",
Type: "dashboard", Type: "dashboard",
Role: "Viewer", Role: org.RoleViewer,
Slug: "lots-of-stats", Slug: "lots-of-stats",
}, },
}, },
@ -1334,16 +1335,16 @@ func TestLoader_Load_NestedPlugins(t *testing.T) {
BaseURL: "public/plugins/myorgid-simple-app", BaseURL: "public/plugins/myorgid-simple-app",
FS: mustNewStaticFSForTests(t, filepath.Join(rootDir, "testdata/app-with-child/dist")), FS: mustNewStaticFSForTests(t, filepath.Join(rootDir, "testdata/app-with-child/dist")),
DefaultNavURL: "/plugins/myorgid-simple-app/page/root-page-react", DefaultNavURL: "/plugins/myorgid-simple-app/page/root-page-react",
Signature: plugins.SignatureValid, Signature: plugins.SignatureStatusValid,
SignatureType: plugins.GrafanaSignature, SignatureType: plugins.SignatureTypeGrafana,
SignatureOrg: "Grafana Labs", SignatureOrg: "Grafana Labs",
Class: plugins.External, Class: plugins.ClassExternal,
} }
child := &plugins.Plugin{ child := &plugins.Plugin{
JSONData: plugins.JSONData{ JSONData: plugins.JSONData{
ID: "myorgid-simple-panel", ID: "myorgid-simple-panel",
Type: "panel", Type: plugins.TypePanel,
Name: "Grafana Panel Plugin Template", Name: "Grafana Panel Plugin Template",
Info: plugins.Info{ Info: plugins.Info{
Author: plugins.InfoLink{ Author: plugins.InfoLink{
@ -1372,10 +1373,10 @@ func TestLoader_Load_NestedPlugins(t *testing.T) {
BaseURL: "public/plugins/myorgid-simple-app", BaseURL: "public/plugins/myorgid-simple-app",
FS: mustNewStaticFSForTests(t, filepath.Join(rootDir, "testdata/app-with-child/dist/child")), FS: mustNewStaticFSForTests(t, filepath.Join(rootDir, "testdata/app-with-child/dist/child")),
IncludedInAppID: parent.ID, IncludedInAppID: parent.ID,
Signature: plugins.SignatureValid, Signature: plugins.SignatureStatusValid,
SignatureType: plugins.GrafanaSignature, SignatureType: plugins.SignatureTypeGrafana,
SignatureOrg: "Grafana Labs", SignatureOrg: "Grafana Labs",
Class: plugins.External, Class: plugins.ClassExternal,
} }
parent.Children = []*plugins.Plugin{child} parent.Children = []*plugins.Plugin{child}
@ -1392,7 +1393,7 @@ func TestLoader_Load_NestedPlugins(t *testing.T) {
}) })
got, err := l.Load(context.Background(), &fakes.FakePluginSource{ got, err := l.Load(context.Background(), &fakes.FakePluginSource{
PluginClassFunc: func(ctx context.Context) plugins.Class { PluginClassFunc: func(ctx context.Context) plugins.Class {
return plugins.External return plugins.ClassExternal
}, },
PluginURIsFunc: func(ctx context.Context) []string { PluginURIsFunc: func(ctx context.Context) []string {
return []string{"../testdata/app-with-child"} return []string{"../testdata/app-with-child"}
@ -1420,10 +1421,10 @@ func Test_setPathsBasedOnApp(t *testing.T) {
} }
parent := &plugins.Plugin{ parent := &plugins.Plugin{
JSONData: plugins.JSONData{ JSONData: plugins.JSONData{
Type: plugins.App, Type: plugins.TypeApp,
ID: "testdata-app", ID: "testdata-app",
}, },
Class: plugins.Core, Class: plugins.ClassCore,
FS: fakes.NewFakePluginFiles("c:\\grafana\\public\\app\\plugins\\app\\testdata-app"), FS: fakes.NewFakePluginFiles("c:\\grafana\\public\\app\\plugins\\app\\testdata-app"),
BaseURL: "public/app/plugins/app/testdata-app", BaseURL: "public/app/plugins/app/testdata-app",
} }

View File

@ -228,7 +228,7 @@ func verifyCorePluginCatalogue(t *testing.T, ctx context.Context, ps *store.Serv
"test-app": {}, "test-app": {},
} }
panels := ps.Plugins(ctx, plugins.Panel) panels := ps.Plugins(ctx, plugins.TypePanel)
require.Equal(t, len(expPanels), len(panels)) require.Equal(t, len(expPanels), len(panels))
for _, p := range panels { for _, p := range panels {
p, exists := ps.Plugin(ctx, p.ID) p, exists := ps.Plugin(ctx, p.ID)
@ -237,7 +237,7 @@ func verifyCorePluginCatalogue(t *testing.T, ctx context.Context, ps *store.Serv
require.Contains(t, expPanels, p.ID) require.Contains(t, expPanels, p.ID)
} }
dataSources := ps.Plugins(ctx, plugins.DataSource) dataSources := ps.Plugins(ctx, plugins.TypeDataSource)
require.Equal(t, len(expDataSources), len(dataSources)) require.Equal(t, len(expDataSources), len(dataSources))
for _, ds := range dataSources { for _, ds := range dataSources {
p, exists := ps.Plugin(ctx, ds.ID) p, exists := ps.Plugin(ctx, ds.ID)
@ -246,7 +246,7 @@ func verifyCorePluginCatalogue(t *testing.T, ctx context.Context, ps *store.Serv
require.Contains(t, expDataSources, ds.ID) require.Contains(t, expDataSources, ds.ID)
} }
apps := ps.Plugins(ctx, plugins.App) apps := ps.Plugins(ctx, plugins.TypeApp)
require.Equal(t, len(expApps), len(apps)) require.Equal(t, len(expApps), len(apps))
for _, app := range apps { for _, app := range apps {
p, exists := ps.Plugin(ctx, app.ID) p, exists := ps.Plugin(ctx, app.ID)
@ -262,7 +262,7 @@ func verifyBundledPlugins(t *testing.T, ctx context.Context, ps *store.Service)
t.Helper() t.Helper()
dsPlugins := make(map[string]struct{}) dsPlugins := make(map[string]struct{})
for _, p := range ps.Plugins(ctx, plugins.DataSource) { for _, p := range ps.Plugins(ctx, plugins.TypeDataSource) {
dsPlugins[p.ID] = struct{}{} dsPlugins[p.ID] = struct{}{}
} }

View File

@ -44,7 +44,7 @@ func TestProcessManager_Start(t *testing.T) {
managed: true, managed: true,
backend: true, backend: true,
signatureError: &plugins.SignatureError{ signatureError: &plugins.SignatureError{
SignatureStatus: plugins.SignatureUnsigned, SignatureStatus: plugins.SignatureStatusUnsigned,
}, },
expectedStartCount: 0, expectedStartCount: 0,
}, },
@ -265,7 +265,7 @@ func createPlugin(t *testing.T, bp backendplugin.Plugin, cbs ...func(p *plugins.
t.Helper() t.Helper()
p := &plugins.Plugin{ p := &plugins.Plugin{
Class: plugins.External, Class: plugins.ClassExternal,
JSONData: plugins.JSONData{ JSONData: plugins.JSONData{
ID: "test-datasource", ID: "test-datasource",
}, },

View File

@ -20,7 +20,7 @@ type UnsignedPluginAuthorizer struct {
} }
func (u *UnsignedPluginAuthorizer) CanLoadPlugin(p *plugins.Plugin) bool { func (u *UnsignedPluginAuthorizer) CanLoadPlugin(p *plugins.Plugin) bool {
if p.Signature != plugins.SignatureUnsigned { if p.Signature != plugins.SignatureStatusUnsigned {
return true return true
} }

View File

@ -104,7 +104,7 @@ func (s *Signature) Calculate(ctx context.Context, src plugins.PluginSource, plu
if len(fsFiles) == 0 { if len(fsFiles) == 0 {
s.log.Warn("No plugin file information in directory", "pluginID", plugin.JSONData.ID) s.log.Warn("No plugin file information in directory", "pluginID", plugin.JSONData.ID)
return plugins.Signature{ return plugins.Signature{
Status: plugins.SignatureInvalid, Status: plugins.SignatureStatusInvalid,
}, nil }, nil
} }
@ -113,13 +113,13 @@ func (s *Signature) Calculate(ctx context.Context, src plugins.PluginSource, plu
if errors.Is(err, plugins.ErrFileNotExist) { if errors.Is(err, plugins.ErrFileNotExist) {
s.log.Debug("Could not find a MANIFEST.txt", "id", plugin.JSONData.ID, "err", err) s.log.Debug("Could not find a MANIFEST.txt", "id", plugin.JSONData.ID, "err", err)
return plugins.Signature{ return plugins.Signature{
Status: plugins.SignatureUnsigned, Status: plugins.SignatureStatusUnsigned,
}, nil }, nil
} }
s.log.Debug("Could not open MANIFEST.txt", "id", plugin.JSONData.ID, "err", err) s.log.Debug("Could not open MANIFEST.txt", "id", plugin.JSONData.ID, "err", err)
return plugins.Signature{ return plugins.Signature{
Status: plugins.SignatureInvalid, Status: plugins.SignatureStatusInvalid,
}, nil }, nil
} }
defer func() { defer func() {
@ -135,7 +135,7 @@ func (s *Signature) Calculate(ctx context.Context, src plugins.PluginSource, plu
if err != nil || len(byteValue) < 10 { if err != nil || len(byteValue) < 10 {
s.log.Debug("MANIFEST.TXT is invalid", "id", plugin.JSONData.ID) s.log.Debug("MANIFEST.TXT is invalid", "id", plugin.JSONData.ID)
return plugins.Signature{ return plugins.Signature{
Status: plugins.SignatureUnsigned, Status: plugins.SignatureStatusUnsigned,
}, nil }, nil
} }
@ -143,20 +143,20 @@ func (s *Signature) Calculate(ctx context.Context, src plugins.PluginSource, plu
if err != nil { if err != nil {
s.log.Warn("Plugin signature invalid", "id", plugin.JSONData.ID, "err", err) s.log.Warn("Plugin signature invalid", "id", plugin.JSONData.ID, "err", err)
return plugins.Signature{ return plugins.Signature{
Status: plugins.SignatureInvalid, Status: plugins.SignatureStatusInvalid,
}, nil }, nil
} }
if !manifest.isV2() { if !manifest.isV2() {
return plugins.Signature{ return plugins.Signature{
Status: plugins.SignatureInvalid, Status: plugins.SignatureStatusInvalid,
}, nil }, nil
} }
// Make sure the versions all match // Make sure the versions all match
if manifest.Plugin != plugin.JSONData.ID || manifest.Version != plugin.JSONData.Info.Version { if manifest.Plugin != plugin.JSONData.ID || manifest.Version != plugin.JSONData.Info.Version {
return plugins.Signature{ return plugins.Signature{
Status: plugins.SignatureModified, Status: plugins.SignatureStatusModified,
}, nil }, nil
} }
@ -169,7 +169,7 @@ func (s *Signature) Calculate(ctx context.Context, src plugins.PluginSource, plu
s.log.Warn("Could not find root URL that matches running application URL", "plugin", plugin.JSONData.ID, s.log.Warn("Could not find root URL that matches running application URL", "plugin", plugin.JSONData.ID,
"appUrl", setting.AppUrl, "rootUrls", manifest.RootURLs) "appUrl", setting.AppUrl, "rootUrls", manifest.RootURLs)
return plugins.Signature{ return plugins.Signature{
Status: plugins.SignatureInvalid, Status: plugins.SignatureStatusInvalid,
}, nil }, nil
} }
} }
@ -181,7 +181,7 @@ func (s *Signature) Calculate(ctx context.Context, src plugins.PluginSource, plu
err = verifyHash(s.log, plugin, p, hash) err = verifyHash(s.log, plugin, p, hash)
if err != nil { if err != nil {
return plugins.Signature{ return plugins.Signature{
Status: plugins.SignatureModified, Status: plugins.SignatureStatusModified,
}, nil }, nil
} }
@ -195,7 +195,7 @@ func (s *Signature) Calculate(ctx context.Context, src plugins.PluginSource, plu
f = toSlash(f) f = toSlash(f)
// Ignoring unsigned Chromium debug.log so it doesn't invalidate the signature for Renderer plugin running on Windows // Ignoring unsigned Chromium debug.log so it doesn't invalidate the signature for Renderer plugin running on Windows
if runningWindows && plugin.JSONData.Type == plugins.Renderer && f == "chrome-win/debug.log" { if runningWindows && plugin.JSONData.Type == plugins.TypeRenderer && f == "chrome-win/debug.log" {
continue continue
} }
@ -210,13 +210,13 @@ func (s *Signature) Calculate(ctx context.Context, src plugins.PluginSource, plu
if len(unsignedFiles) > 0 { if len(unsignedFiles) > 0 {
s.log.Warn("The following files were not included in the signature", "plugin", plugin.JSONData.ID, "files", unsignedFiles) s.log.Warn("The following files were not included in the signature", "plugin", plugin.JSONData.ID, "files", unsignedFiles)
return plugins.Signature{ return plugins.Signature{
Status: plugins.SignatureModified, Status: plugins.SignatureStatusModified,
}, nil }, nil
} }
s.log.Debug("Plugin signature valid", "id", plugin.JSONData.ID) s.log.Debug("Plugin signature valid", "id", plugin.JSONData.ID)
return plugins.Signature{ return plugins.Signature{
Status: plugins.SignatureValid, Status: plugins.SignatureStatusValid,
Type: manifest.SignatureType, Type: manifest.SignatureType,
SigningOrg: manifest.SignedByOrgName, SigningOrg: manifest.SignedByOrgName,
}, nil }, nil
@ -273,7 +273,7 @@ func urlMatch(specs []string, target string, signatureType plugins.SignatureType
return true, nil return true, nil
} }
if signatureType != plugins.PrivateGlobSignature { if signatureType != plugins.SignatureTypePrivateGlob {
continue continue
} }

View File

@ -118,7 +118,7 @@ khdr/tZ1PDgRxMqB/u+Vtbpl0xSxgblnrDOYMSI=
assert.Equal(t, int64(1605807018050), manifest.Time) assert.Equal(t, int64(1605807018050), manifest.Time)
assert.Equal(t, "7e4d0c6a708866e7", manifest.KeyID) assert.Equal(t, "7e4d0c6a708866e7", manifest.KeyID)
assert.Equal(t, "2.0.0", manifest.ManifestVersion) assert.Equal(t, "2.0.0", manifest.ManifestVersion)
assert.Equal(t, plugins.PrivateSignature, manifest.SignatureType) assert.Equal(t, plugins.SignatureTypePrivate, manifest.SignatureType)
assert.Equal(t, "willbrowne", manifest.SignedByOrg) assert.Equal(t, "willbrowne", manifest.SignedByOrg)
assert.Equal(t, "Will Browne", manifest.SignedByOrgName) assert.Equal(t, "Will Browne", manifest.SignedByOrgName)
assert.Equal(t, []string{"http://localhost:3000/"}, manifest.RootURLs) assert.Equal(t, []string{"http://localhost:3000/"}, manifest.RootURLs)
@ -135,15 +135,15 @@ func TestCalculate(t *testing.T) {
{ {
appURL: "https://dev.grafana.com", appURL: "https://dev.grafana.com",
expectedSignature: plugins.Signature{ expectedSignature: plugins.Signature{
Status: plugins.SignatureValid, Status: plugins.SignatureStatusValid,
Type: plugins.GrafanaSignature, Type: plugins.SignatureTypeGrafana,
SigningOrg: "Grafana Labs", SigningOrg: "Grafana Labs",
}, },
}, },
{ {
appURL: "https://non.matching.url.com", appURL: "https://non.matching.url.com",
expectedSignature: plugins.Signature{ expectedSignature: plugins.Signature{
Status: plugins.SignatureInvalid, Status: plugins.SignatureStatusInvalid,
}, },
}, },
} }
@ -165,7 +165,7 @@ func TestCalculate(t *testing.T) {
s := ProvideService(&config.Cfg{}, statickey.New()) s := ProvideService(&config.Cfg{}, statickey.New())
sig, err := s.Calculate(context.Background(), &fakes.FakePluginSource{ sig, err := s.Calculate(context.Background(), &fakes.FakePluginSource{
PluginClassFunc: func(ctx context.Context) plugins.Class { PluginClassFunc: func(ctx context.Context) plugins.Class {
return plugins.External return plugins.ClassExternal
}, },
}, plugins.FoundPlugin{ }, plugins.FoundPlugin{
JSONData: plugins.JSONData{ JSONData: plugins.JSONData{
@ -193,12 +193,12 @@ func TestCalculate(t *testing.T) {
s := ProvideService(&config.Cfg{}, statickey.New()) s := ProvideService(&config.Cfg{}, statickey.New())
sig, err := s.Calculate(context.Background(), &fakes.FakePluginSource{ sig, err := s.Calculate(context.Background(), &fakes.FakePluginSource{
PluginClassFunc: func(ctx context.Context) plugins.Class { PluginClassFunc: func(ctx context.Context) plugins.Class {
return plugins.External return plugins.ClassExternal
}, },
}, plugins.FoundPlugin{ }, plugins.FoundPlugin{
JSONData: plugins.JSONData{ JSONData: plugins.JSONData{
ID: "test-renderer", ID: "test-renderer",
Type: plugins.Renderer, Type: plugins.TypeRenderer,
Info: plugins.Info{ Info: plugins.Info{
Version: "1.0.0", Version: "1.0.0",
}, },
@ -207,8 +207,8 @@ func TestCalculate(t *testing.T) {
}) })
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, plugins.Signature{ require.Equal(t, plugins.Signature{
Status: plugins.SignatureValid, Status: plugins.SignatureStatusValid,
Type: plugins.GrafanaSignature, Type: plugins.SignatureTypeGrafana,
SigningOrg: "Grafana Labs", SigningOrg: "Grafana Labs",
}, sig) }, sig)
}) })
@ -261,12 +261,12 @@ func TestCalculate(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
sig, err := s.Calculate(context.Background(), &fakes.FakePluginSource{ sig, err := s.Calculate(context.Background(), &fakes.FakePluginSource{
PluginClassFunc: func(ctx context.Context) plugins.Class { PluginClassFunc: func(ctx context.Context) plugins.Class {
return plugins.External return plugins.ClassExternal
}, },
}, plugins.FoundPlugin{ }, plugins.FoundPlugin{
JSONData: plugins.JSONData{ JSONData: plugins.JSONData{
ID: "myorgid-simple-app", ID: "myorgid-simple-app",
Type: plugins.App, Type: plugins.TypeApp,
Info: plugins.Info{ Info: plugins.Info{
Version: "%VERSION%", Version: "%VERSION%",
}, },
@ -275,8 +275,8 @@ func TestCalculate(t *testing.T) {
}) })
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, plugins.Signature{ require.Equal(t, plugins.Signature{
Status: plugins.SignatureValid, Status: plugins.SignatureStatusValid,
Type: plugins.GrafanaSignature, Type: plugins.SignatureTypeGrafana,
SigningOrg: "Grafana Labs", SigningOrg: "Grafana Labs",
}, sig) }, sig)
}) })
@ -545,7 +545,7 @@ func Test_urlMatch_privateGlob(t *testing.T) {
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
got, err := urlMatch(tt.args.specs, tt.args.target, plugins.PrivateGlobSignature) got, err := urlMatch(tt.args.specs, tt.args.target, plugins.SignatureTypePrivateGlob)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, tt.shouldMatch, got) require.Equal(t, tt.shouldMatch, got)
}) })
@ -661,7 +661,7 @@ func Test_urlMatch_private(t *testing.T) {
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
got, err := urlMatch(tt.args.specs, tt.args.target, plugins.PrivateSignature) got, err := urlMatch(tt.args.specs, tt.args.target, plugins.SignatureTypePrivate)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, tt.shouldMatch, got) require.Equal(t, tt.shouldMatch, got)
}) })
@ -741,7 +741,7 @@ func createV2Manifest(t *testing.T, cbs ...func(*PluginManifest)) *PluginManifes
"plugin.json": "55556b845e91935cc48fae3aa67baf0f22694c3f", "plugin.json": "55556b845e91935cc48fae3aa67baf0f22694c3f",
}, },
ManifestVersion: "2.0.0", ManifestVersion: "2.0.0",
SignatureType: plugins.GrafanaSignature, SignatureType: plugins.SignatureTypeGrafana,
SignedByOrg: "grafana", SignedByOrg: "grafana",
SignedByOrgName: "grafana", SignedByOrgName: "grafana",
} }

View File

@ -46,27 +46,27 @@ func (s *Validator) Validate(plugin *plugins.Plugin) *plugins.SignatureError {
} }
switch plugin.Signature { switch plugin.Signature {
case plugins.SignatureUnsigned: case plugins.SignatureStatusUnsigned:
if authorized := s.authorizer.CanLoadPlugin(plugin); !authorized { if authorized := s.authorizer.CanLoadPlugin(plugin); !authorized {
s.log.Debug("Plugin is unsigned", "pluginID", plugin.ID) s.log.Debug("Plugin is unsigned", "pluginID", plugin.ID)
return &plugins.SignatureError{ return &plugins.SignatureError{
PluginID: plugin.ID, PluginID: plugin.ID,
SignatureStatus: plugins.SignatureUnsigned, SignatureStatus: plugins.SignatureStatusUnsigned,
} }
} }
s.log.Warn("Permitting unsigned plugin. This is not recommended", "pluginID", plugin.ID) s.log.Warn("Permitting unsigned plugin. This is not recommended", "pluginID", plugin.ID)
return nil return nil
case plugins.SignatureInvalid: case plugins.SignatureStatusInvalid:
s.log.Debug("Plugin has an invalid signature", "pluginID", plugin.ID) s.log.Debug("Plugin has an invalid signature", "pluginID", plugin.ID)
return &plugins.SignatureError{ return &plugins.SignatureError{
PluginID: plugin.ID, PluginID: plugin.ID,
SignatureStatus: plugins.SignatureInvalid, SignatureStatus: plugins.SignatureStatusInvalid,
} }
case plugins.SignatureModified: case plugins.SignatureStatusModified:
s.log.Debug("Plugin has a modified signature", "pluginID", plugin.ID) s.log.Debug("Plugin has a modified signature", "pluginID", plugin.ID)
return &plugins.SignatureError{ return &plugins.SignatureError{
PluginID: plugin.ID, PluginID: plugin.ID,
SignatureStatus: plugins.SignatureModified, SignatureStatus: plugins.SignatureStatusModified,
} }
default: default:
s.log.Debug("Plugin has an unrecognized plugin signature state", "pluginID", plugin.ID, "signature", s.log.Debug("Plugin has an unrecognized plugin signature state", "pluginID", plugin.ID, "signature",

View File

@ -28,9 +28,9 @@ func (s *LocalSource) PluginURIs(_ context.Context) []string {
func (s *LocalSource) DefaultSignature(_ context.Context) (plugins.Signature, bool) { func (s *LocalSource) DefaultSignature(_ context.Context) (plugins.Signature, bool) {
switch s.class { switch s.class {
case plugins.Core: case plugins.ClassCore:
return plugins.Signature{ return plugins.Signature{
Status: plugins.SignatureInternal, Status: plugins.SignatureStatusInternal,
}, true }, true
default: default:
return plugins.Signature{}, false return plugins.Signature{}, false

View File

@ -26,9 +26,9 @@ func ProvideService(gCfg *setting.Cfg, cfg *config.Cfg) *Service {
func (s *Service) List(_ context.Context) []plugins.PluginSource { func (s *Service) List(_ context.Context) []plugins.PluginSource {
return []plugins.PluginSource{ return []plugins.PluginSource{
NewLocalSource(plugins.Core, corePluginPaths(s.gCfg.StaticRootPath)), NewLocalSource(plugins.ClassCore, corePluginPaths(s.gCfg.StaticRootPath)),
NewLocalSource(plugins.Bundled, []string{s.gCfg.BundledPluginsPath}), NewLocalSource(plugins.ClassBundled, []string{s.gCfg.BundledPluginsPath}),
NewLocalSource(plugins.External, append([]string{s.cfg.PluginsPath}, pluginFSPaths(s.cfg.PluginSettings)...)), NewLocalSource(plugins.ClassExternal, append([]string{s.cfg.PluginsPath}, pluginFSPaths(s.cfg.PluginSettings)...)),
} }
} }

View File

@ -35,21 +35,21 @@ func TestSources_List(t *testing.T) {
require.Len(t, srcs, 3) require.Len(t, srcs, 3)
require.Equal(t, srcs[0].PluginClass(ctx), plugins.Core) require.Equal(t, srcs[0].PluginClass(ctx), plugins.ClassCore)
require.Equal(t, srcs[0].PluginURIs(ctx), []string{"app/plugins/datasource", "app/plugins/panel"}) require.Equal(t, srcs[0].PluginURIs(ctx), []string{"app/plugins/datasource", "app/plugins/panel"})
sig, exists := srcs[0].DefaultSignature(ctx) sig, exists := srcs[0].DefaultSignature(ctx)
require.True(t, exists) require.True(t, exists)
require.Equal(t, plugins.SignatureInternal, sig.Status) require.Equal(t, plugins.SignatureStatusInternal, sig.Status)
require.Equal(t, plugins.SignatureType(""), sig.Type) require.Equal(t, plugins.SignatureType(""), sig.Type)
require.Equal(t, "", sig.SigningOrg) require.Equal(t, "", sig.SigningOrg)
require.Equal(t, srcs[1].PluginClass(ctx), plugins.Bundled) require.Equal(t, srcs[1].PluginClass(ctx), plugins.ClassBundled)
require.Equal(t, srcs[1].PluginURIs(ctx), []string{"path1"}) require.Equal(t, srcs[1].PluginURIs(ctx), []string{"path1"})
sig, exists = srcs[1].DefaultSignature(ctx) sig, exists = srcs[1].DefaultSignature(ctx)
require.False(t, exists) require.False(t, exists)
require.Equal(t, plugins.Signature{}, sig) require.Equal(t, plugins.Signature{}, sig)
require.Equal(t, srcs[2].PluginClass(ctx), plugins.External) require.Equal(t, srcs[2].PluginClass(ctx), plugins.ClassExternal)
require.Equal(t, srcs[2].PluginURIs(ctx), []string{"path2", "path3"}) require.Equal(t, srcs[2].PluginURIs(ctx), []string{"path2", "path3"})
sig, exists = srcs[2].DefaultSignature(ctx) sig, exists = srcs[2].DefaultSignature(ctx)
require.False(t, exists) require.False(t, exists)

View File

@ -25,7 +25,7 @@ func TestStore_ProvideService(t *testing.T) {
return []plugins.PluginSource{ return []plugins.PluginSource{
&fakes.FakePluginSource{ &fakes.FakePluginSource{
PluginClassFunc: func(ctx context.Context) plugins.Class { PluginClassFunc: func(ctx context.Context) plugins.Class {
return plugins.Bundled return plugins.ClassBundled
}, },
PluginURIsFunc: func(ctx context.Context) []string { PluginURIsFunc: func(ctx context.Context) []string {
return []string{"path1"} return []string{"path1"}
@ -33,7 +33,7 @@ func TestStore_ProvideService(t *testing.T) {
}, },
&fakes.FakePluginSource{ &fakes.FakePluginSource{
PluginClassFunc: func(ctx context.Context) plugins.Class { PluginClassFunc: func(ctx context.Context) plugins.Class {
return plugins.External return plugins.ClassExternal
}, },
PluginURIsFunc: func(ctx context.Context) []string { PluginURIsFunc: func(ctx context.Context) []string {
return []string{"path2", "path3"} return []string{"path2", "path3"}
@ -71,11 +71,11 @@ func TestStore_Plugin(t *testing.T) {
func TestStore_Plugins(t *testing.T) { func TestStore_Plugins(t *testing.T) {
t.Run("Plugin returns all non-decommissioned plugins by type", func(t *testing.T) { t.Run("Plugin returns all non-decommissioned plugins by type", func(t *testing.T) {
p1 := &plugins.Plugin{JSONData: plugins.JSONData{ID: "a-test-datasource", Type: plugins.DataSource}} p1 := &plugins.Plugin{JSONData: plugins.JSONData{ID: "a-test-datasource", Type: plugins.TypeDataSource}}
p2 := &plugins.Plugin{JSONData: plugins.JSONData{ID: "b-test-panel", Type: plugins.Panel}} p2 := &plugins.Plugin{JSONData: plugins.JSONData{ID: "b-test-panel", Type: plugins.TypePanel}}
p3 := &plugins.Plugin{JSONData: plugins.JSONData{ID: "c-test-panel", Type: plugins.Panel}} p3 := &plugins.Plugin{JSONData: plugins.JSONData{ID: "c-test-panel", Type: plugins.TypePanel}}
p4 := &plugins.Plugin{JSONData: plugins.JSONData{ID: "d-test-app", Type: plugins.App}} p4 := &plugins.Plugin{JSONData: plugins.JSONData{ID: "d-test-app", Type: plugins.TypeApp}}
p5 := &plugins.Plugin{JSONData: plugins.JSONData{ID: "e-test-panel", Type: plugins.Panel}} p5 := &plugins.Plugin{JSONData: plugins.JSONData{ID: "e-test-panel", Type: plugins.TypePanel}}
p5.RegisterClient(&DecommissionedPlugin{}) p5.RegisterClient(&DecommissionedPlugin{})
ps := New(newFakePluginRegistry(map[string]*plugins.Plugin{ ps := New(newFakePluginRegistry(map[string]*plugins.Plugin{
@ -89,28 +89,28 @@ func TestStore_Plugins(t *testing.T) {
pss := ps.Plugins(context.Background()) pss := ps.Plugins(context.Background())
require.Equal(t, pss, []plugins.PluginDTO{p1.ToDTO(), p2.ToDTO(), p3.ToDTO(), p4.ToDTO()}) require.Equal(t, pss, []plugins.PluginDTO{p1.ToDTO(), p2.ToDTO(), p3.ToDTO(), p4.ToDTO()})
pss = ps.Plugins(context.Background(), plugins.App) pss = ps.Plugins(context.Background(), plugins.TypeApp)
require.Equal(t, pss, []plugins.PluginDTO{p4.ToDTO()}) require.Equal(t, pss, []plugins.PluginDTO{p4.ToDTO()})
pss = ps.Plugins(context.Background(), plugins.Panel) pss = ps.Plugins(context.Background(), plugins.TypePanel)
require.Equal(t, pss, []plugins.PluginDTO{p2.ToDTO(), p3.ToDTO()}) require.Equal(t, pss, []plugins.PluginDTO{p2.ToDTO(), p3.ToDTO()})
pss = ps.Plugins(context.Background(), plugins.DataSource) pss = ps.Plugins(context.Background(), plugins.TypeDataSource)
require.Equal(t, pss, []plugins.PluginDTO{p1.ToDTO()}) require.Equal(t, pss, []plugins.PluginDTO{p1.ToDTO()})
pss = ps.Plugins(context.Background(), plugins.DataSource, plugins.App, plugins.Panel) pss = ps.Plugins(context.Background(), plugins.TypeDataSource, plugins.TypeApp, plugins.TypePanel)
require.Equal(t, pss, []plugins.PluginDTO{p1.ToDTO(), p2.ToDTO(), p3.ToDTO(), p4.ToDTO()}) require.Equal(t, pss, []plugins.PluginDTO{p1.ToDTO(), p2.ToDTO(), p3.ToDTO(), p4.ToDTO()})
}) })
} }
func TestStore_Routes(t *testing.T) { func TestStore_Routes(t *testing.T) {
t.Run("Routes returns all static routes for non-decommissioned plugins", func(t *testing.T) { t.Run("Routes returns all static routes for non-decommissioned plugins", func(t *testing.T) {
p1 := &plugins.Plugin{JSONData: plugins.JSONData{ID: "a-test-renderer", Type: plugins.Renderer}, FS: fakes.NewFakePluginFiles("/some/dir")} p1 := &plugins.Plugin{JSONData: plugins.JSONData{ID: "a-test-renderer", Type: plugins.TypeRenderer}, FS: fakes.NewFakePluginFiles("/some/dir")}
p2 := &plugins.Plugin{JSONData: plugins.JSONData{ID: "b-test-panel", Type: plugins.Panel}, FS: fakes.NewFakePluginFiles("/grafana/")} p2 := &plugins.Plugin{JSONData: plugins.JSONData{ID: "b-test-panel", Type: plugins.TypePanel}, FS: fakes.NewFakePluginFiles("/grafana/")}
p3 := &plugins.Plugin{JSONData: plugins.JSONData{ID: "c-test-secrets", Type: plugins.SecretsManager}, FS: fakes.NewFakePluginFiles("./secrets"), Class: plugins.Core} p3 := &plugins.Plugin{JSONData: plugins.JSONData{ID: "c-test-secrets", Type: plugins.TypeSecretsManager}, FS: fakes.NewFakePluginFiles("./secrets"), Class: plugins.ClassCore}
p4 := &plugins.Plugin{JSONData: plugins.JSONData{ID: "d-test-datasource", Type: plugins.DataSource}, FS: fakes.NewFakePluginFiles("../test")} p4 := &plugins.Plugin{JSONData: plugins.JSONData{ID: "d-test-datasource", Type: plugins.TypeDataSource}, FS: fakes.NewFakePluginFiles("../test")}
p5 := &plugins.Plugin{JSONData: plugins.JSONData{ID: "e-test-app", Type: plugins.App}, FS: fakes.NewFakePluginFiles("any/path")} p5 := &plugins.Plugin{JSONData: plugins.JSONData{ID: "e-test-app", Type: plugins.TypeApp}, FS: fakes.NewFakePluginFiles("any/path")}
p6 := &plugins.Plugin{JSONData: plugins.JSONData{ID: "f-test-app", Type: plugins.App}} p6 := &plugins.Plugin{JSONData: plugins.JSONData{ID: "f-test-app", Type: plugins.TypeApp}}
p6.RegisterClient(&DecommissionedPlugin{}) p6.RegisterClient(&DecommissionedPlugin{})
ps := New(newFakePluginRegistry(map[string]*plugins.Plugin{ ps := New(newFakePluginRegistry(map[string]*plugins.Plugin{
@ -133,9 +133,9 @@ func TestStore_Routes(t *testing.T) {
func TestStore_Renderer(t *testing.T) { func TestStore_Renderer(t *testing.T) {
t.Run("Renderer returns a single (non-decommissioned) renderer plugin", func(t *testing.T) { t.Run("Renderer returns a single (non-decommissioned) renderer plugin", func(t *testing.T) {
p1 := &plugins.Plugin{JSONData: plugins.JSONData{ID: "test-renderer", Type: plugins.Renderer}} p1 := &plugins.Plugin{JSONData: plugins.JSONData{ID: "test-renderer", Type: plugins.TypeRenderer}}
p2 := &plugins.Plugin{JSONData: plugins.JSONData{ID: "test-panel", Type: plugins.Panel}} p2 := &plugins.Plugin{JSONData: plugins.JSONData{ID: "test-panel", Type: plugins.TypePanel}}
p3 := &plugins.Plugin{JSONData: plugins.JSONData{ID: "test-app", Type: plugins.App}} p3 := &plugins.Plugin{JSONData: plugins.JSONData{ID: "test-app", Type: plugins.TypeApp}}
ps := New(newFakePluginRegistry(map[string]*plugins.Plugin{ ps := New(newFakePluginRegistry(map[string]*plugins.Plugin{
p1.ID: p1, p1.ID: p1,
@ -150,10 +150,10 @@ func TestStore_Renderer(t *testing.T) {
func TestStore_SecretsManager(t *testing.T) { func TestStore_SecretsManager(t *testing.T) {
t.Run("Renderer returns a single (non-decommissioned) secrets manager plugin", func(t *testing.T) { t.Run("Renderer returns a single (non-decommissioned) secrets manager plugin", func(t *testing.T) {
p1 := &plugins.Plugin{JSONData: plugins.JSONData{ID: "test-renderer", Type: plugins.Renderer}} p1 := &plugins.Plugin{JSONData: plugins.JSONData{ID: "test-renderer", Type: plugins.TypeRenderer}}
p2 := &plugins.Plugin{JSONData: plugins.JSONData{ID: "test-panel", Type: plugins.Panel}} p2 := &plugins.Plugin{JSONData: plugins.JSONData{ID: "test-panel", Type: plugins.TypePanel}}
p3 := &plugins.Plugin{JSONData: plugins.JSONData{ID: "test-secrets", Type: plugins.SecretsManager}} p3 := &plugins.Plugin{JSONData: plugins.JSONData{ID: "test-secrets", Type: plugins.TypeSecretsManager}}
p4 := &plugins.Plugin{JSONData: plugins.JSONData{ID: "test-datasource", Type: plugins.DataSource}} p4 := &plugins.Plugin{JSONData: plugins.JSONData{ID: "test-datasource", Type: plugins.TypeDataSource}}
ps := New(newFakePluginRegistry(map[string]*plugins.Plugin{ ps := New(newFakePluginRegistry(map[string]*plugins.Plugin{
p1.ID: p1, p1.ID: p1,

View File

@ -46,13 +46,13 @@ type SignatureError struct {
func (e SignatureError) Error() string { func (e SignatureError) Error() string {
switch e.SignatureStatus { switch e.SignatureStatus {
case SignatureInvalid: case SignatureStatusInvalid:
return fmt.Sprintf("plugin '%s' has an invalid signature", e.PluginID) return fmt.Sprintf("plugin '%s' has an invalid signature", e.PluginID)
case SignatureModified: case SignatureStatusModified:
return fmt.Sprintf("plugin '%s' has an modified signature", e.PluginID) return fmt.Sprintf("plugin '%s' has an modified signature", e.PluginID)
case SignatureUnsigned: case SignatureStatusUnsigned:
return fmt.Sprintf("plugin '%s' has no signature", e.PluginID) return fmt.Sprintf("plugin '%s' has no signature", e.PluginID)
case SignatureInternal, SignatureValid: case SignatureStatusInternal, SignatureStatusValid:
return "" return ""
} }
@ -61,13 +61,13 @@ func (e SignatureError) Error() string {
func (e SignatureError) AsErrorCode() ErrorCode { func (e SignatureError) AsErrorCode() ErrorCode {
switch e.SignatureStatus { switch e.SignatureStatus {
case SignatureInvalid: case SignatureStatusInvalid:
return signatureInvalid return errorCodeSignatureInvalid
case SignatureModified: case SignatureStatusModified:
return signatureModified return errorCodeSignatureModified
case SignatureUnsigned: case SignatureStatusUnsigned:
return signatureMissing return errorCodeSignatureMissing
case SignatureInternal, SignatureValid: case SignatureStatusInternal, SignatureStatusValid:
return "" return ""
} }
@ -155,40 +155,41 @@ type StaticRoute struct {
type SignatureStatus string type SignatureStatus string
func (ss SignatureStatus) IsValid() bool { func (ss SignatureStatus) IsValid() bool {
return ss == SignatureValid return ss == SignatureStatusValid
} }
func (ss SignatureStatus) IsInternal() bool { func (ss SignatureStatus) IsInternal() bool {
return ss == SignatureInternal return ss == SignatureStatusInternal
} }
const ( const (
SignatureInternal SignatureStatus = "internal" // core plugin, no signature SignatureStatusInternal SignatureStatus = "internal" // core plugin, no signature
SignatureValid SignatureStatus = "valid" // signed and accurate MANIFEST SignatureStatusValid SignatureStatus = "valid" // signed and accurate MANIFEST
SignatureInvalid SignatureStatus = "invalid" // invalid signature SignatureStatusInvalid SignatureStatus = "invalid" // invalid signature
SignatureModified SignatureStatus = "modified" // valid signature, but content mismatch SignatureStatusModified SignatureStatus = "modified" // valid signature, but content mismatch
SignatureUnsigned SignatureStatus = "unsigned" // no MANIFEST file SignatureStatusUnsigned SignatureStatus = "unsigned" // no MANIFEST file
) )
type ReleaseState string type ReleaseState string
const ( const (
AlphaRelease ReleaseState = "alpha" ReleaseStateAlpha ReleaseState = "alpha"
) )
type SignatureType string type SignatureType string
const ( const (
GrafanaSignature SignatureType = "grafana" SignatureTypeGrafana SignatureType = "grafana"
CommercialSignature SignatureType = "commercial" SignatureTypeCommercial SignatureType = "commercial"
CommunitySignature SignatureType = "community" SignatureTypeCommunity SignatureType = "community"
PrivateSignature SignatureType = "private" SignatureTypePrivate SignatureType = "private"
PrivateGlobSignature SignatureType = "private-glob" SignatureTypePrivateGlob SignatureType = "private-glob"
) )
func (s SignatureType) IsValid() bool { func (s SignatureType) IsValid() bool {
switch s { switch s {
case GrafanaSignature, CommercialSignature, CommunitySignature, PrivateSignature, PrivateGlobSignature: case SignatureTypeGrafana, SignatureTypeCommercial, SignatureTypeCommunity, SignatureTypePrivate,
SignatureTypePrivateGlob:
return true return true
} }
return false return false
@ -265,9 +266,9 @@ type AppDTO struct {
} }
const ( const (
signatureMissing ErrorCode = "signatureMissing" errorCodeSignatureMissing ErrorCode = "signatureMissing"
signatureModified ErrorCode = "signatureModified" errorCodeSignatureModified ErrorCode = "signatureModified"
signatureInvalid ErrorCode = "signatureInvalid" errorCodeSignatureInvalid ErrorCode = "signatureInvalid"
) )
type ErrorCode string type ErrorCode string

View File

@ -101,11 +101,11 @@ func (p PluginDTO) Base() string {
} }
func (p PluginDTO) IsApp() bool { func (p PluginDTO) IsApp() bool {
return p.Type == App return p.Type == TypeApp
} }
func (p PluginDTO) IsCorePlugin() bool { func (p PluginDTO) IsCorePlugin() bool {
return p.Class == Core return p.Class == ClassCore
} }
// JSONData represents the plugin's plugin.json // JSONData represents the plugin's plugin.json
@ -459,35 +459,35 @@ func (p *Plugin) StaticRoute() *StaticRoute {
} }
func (p *Plugin) IsRenderer() bool { func (p *Plugin) IsRenderer() bool {
return p.Type == Renderer return p.Type == TypeRenderer
} }
func (p *Plugin) IsSecretsManager() bool { func (p *Plugin) IsSecretsManager() bool {
return p.Type == SecretsManager return p.Type == TypeSecretsManager
} }
func (p *Plugin) IsApp() bool { func (p *Plugin) IsApp() bool {
return p.Type == App return p.Type == TypeApp
} }
func (p *Plugin) IsCorePlugin() bool { func (p *Plugin) IsCorePlugin() bool {
return p.Class == Core return p.Class == ClassCore
} }
func (p *Plugin) IsBundledPlugin() bool { func (p *Plugin) IsBundledPlugin() bool {
return p.Class == Bundled return p.Class == ClassBundled
} }
func (p *Plugin) IsExternalPlugin() bool { func (p *Plugin) IsExternalPlugin() bool {
return p.Class == External return p.Class == ClassExternal
} }
type Class string type Class string
const ( const (
Core Class = "core" ClassCore Class = "core"
Bundled Class = "bundled" ClassBundled Class = "bundled"
External Class = "external" ClassExternal Class = "external"
) )
func (c Class) String() string { func (c Class) String() string {
@ -495,26 +495,26 @@ func (c Class) String() string {
} }
var PluginTypes = []Type{ var PluginTypes = []Type{
DataSource, TypeDataSource,
Panel, TypePanel,
App, TypeApp,
Renderer, TypeRenderer,
SecretsManager, TypeSecretsManager,
} }
type Type string type Type string
const ( const (
DataSource Type = "datasource" TypeDataSource Type = "datasource"
Panel Type = "panel" TypePanel Type = "panel"
App Type = "app" TypeApp Type = "app"
Renderer Type = "renderer" TypeRenderer Type = "renderer"
SecretsManager Type = "secretsmanager" TypeSecretsManager Type = "secretsmanager"
) )
func (pt Type) IsValid() bool { func (pt Type) IsValid() bool {
switch pt { switch pt {
case DataSource, Panel, App, Renderer, SecretsManager: case TypeDataSource, TypePanel, TypeApp, TypeRenderer, TypeSecretsManager:
return true return true
} }
return false return false

View File

@ -28,7 +28,7 @@ func Test_ReadPluginJSON(t *testing.T) {
}, },
expected: JSONData{ expected: JSONData{
ID: "test-app", ID: "test-app",
Type: "app", Type: TypeApp,
Name: "Test App", Name: "Test App",
Info: Info{ Info: Info{
Author: InfoLink{ Author: InfoLink{
@ -91,7 +91,7 @@ func Test_ReadPluginJSON(t *testing.T) {
}, },
expected: JSONData{ expected: JSONData{
ID: "grafana-piechart-panel", ID: "grafana-piechart-panel",
Type: "panel", Type: TypePanel,
Name: "Pie Chart (old)", Name: "Pie Chart (old)",
Dependencies: Dependencies{ Dependencies: Dependencies{
GrafanaVersion: "*", GrafanaVersion: "*",
@ -114,7 +114,7 @@ func Test_ReadPluginJSON(t *testing.T) {
expected: JSONData{ expected: JSONData{
ID: "grafana-pyroscope-datasource", ID: "grafana-pyroscope-datasource",
Alias: "phlare", // Hardcoded from the parser Alias: "phlare", // Hardcoded from the parser
Type: "datasource", Type: TypeDataSource,
Dependencies: Dependencies{ Dependencies: Dependencies{
GrafanaDependency: "", GrafanaDependency: "",
GrafanaVersion: "*", GrafanaVersion: "*",
@ -153,7 +153,7 @@ func Test_validatePluginJSON(t *testing.T) {
args: args{ args: args{
data: JSONData{ data: JSONData{
ID: "grafana-plugin-id", ID: "grafana-plugin-id",
Type: DataSource, Type: TypeDataSource,
}, },
}, },
}, },
@ -161,7 +161,7 @@ func Test_validatePluginJSON(t *testing.T) {
name: "Invalid plugin ID", name: "Invalid plugin ID",
args: args{ args: args{
data: JSONData{ data: JSONData{
Type: Panel, Type: TypePanel,
}, },
}, },
err: ErrInvalidPluginJSON, err: ErrInvalidPluginJSON,

View File

@ -36,7 +36,7 @@ func (s *ServiceImpl) addAppLinks(treeRoot *navtree.NavTreeRoot, c *contextmodel
return false return false
} }
for _, plugin := range s.pluginStore.Plugins(c.Req.Context(), plugins.App) { for _, plugin := range s.pluginStore.Plugins(c.Req.Context(), plugins.TypeApp) {
if !isPluginEnabled(plugin) { if !isPluginEnabled(plugin) {
continue continue
} }

View File

@ -37,7 +37,7 @@ func TestAddAppLinks(t *testing.T) {
JSONData: plugins.JSONData{ JSONData: plugins.JSONData{
ID: "test-app1", ID: "test-app1",
Name: "Test app1 name", Name: "Test app1 name",
Type: plugins.App, Type: plugins.TypeApp,
Includes: []*plugins.Includes{ Includes: []*plugins.Includes{
{ {
Name: "Catalog", Name: "Catalog",
@ -60,7 +60,7 @@ func TestAddAppLinks(t *testing.T) {
JSONData: plugins.JSONData{ JSONData: plugins.JSONData{
ID: "test-app2", ID: "test-app2",
Name: "Test app2 name", Name: "Test app2 name",
Type: plugins.App, Type: plugins.TypeApp,
Includes: []*plugins.Includes{ Includes: []*plugins.Includes{
{ {
Name: "Hello", Name: "Hello",
@ -77,7 +77,7 @@ func TestAddAppLinks(t *testing.T) {
JSONData: plugins.JSONData{ JSONData: plugins.JSONData{
ID: "test-app3", ID: "test-app3",
Name: "Test app3 name", Name: "Test app3 name",
Type: plugins.App, Type: plugins.TypeApp,
Includes: []*plugins.Includes{ Includes: []*plugins.Includes{
{ {
Name: "Default page", Name: "Default page",
@ -402,7 +402,7 @@ func TestAddAppLinksAccessControl(t *testing.T) {
testApp1 := plugins.PluginDTO{ testApp1 := plugins.PluginDTO{
JSONData: plugins.JSONData{ JSONData: plugins.JSONData{
ID: "test-app1", Name: "Test app1 name", Type: plugins.App, ID: "test-app1", Name: "Test app1 name", Type: plugins.TypeApp,
Includes: []*plugins.Includes{ Includes: []*plugins.Includes{
{ {
Name: "Catalog", Name: "Catalog",

View File

@ -78,14 +78,14 @@ func NewStaticDashboardSummaryBuilder(lookup DatasourceLookup, sanitize bool) en
p.Fields["type"] = panel.Type p.Fields["type"] = panel.Type
if panel.Type != "row" { if panel.Type != "row" {
panelRefs.Add(entity.ExternalEntityReferencePlugin, string(plugins.Panel), panel.Type) panelRefs.Add(entity.ExternalEntityReferencePlugin, string(plugins.TypePanel), panel.Type)
dashboardRefs.Add(entity.ExternalEntityReferencePlugin, string(plugins.Panel), panel.Type) dashboardRefs.Add(entity.ExternalEntityReferencePlugin, string(plugins.TypePanel), panel.Type)
} }
for _, v := range panel.Datasource { for _, v := range panel.Datasource {
dashboardRefs.Add(entity.StandardKindDataSource, v.Type, v.UID) dashboardRefs.Add(entity.StandardKindDataSource, v.Type, v.UID)
panelRefs.Add(entity.StandardKindDataSource, v.Type, v.UID) panelRefs.Add(entity.StandardKindDataSource, v.Type, v.UID)
if v.Type != "" { if v.Type != "" {
dashboardRefs.Add(entity.ExternalEntityReferencePlugin, string(plugins.DataSource), v.Type) dashboardRefs.Add(entity.ExternalEntityReferencePlugin, string(plugins.TypeDataSource), v.Type)
} }
} }
for _, v := range panel.Transformer { for _, v := range panel.Transformer {

View File

@ -134,33 +134,33 @@ func TestPluginUpdateChecker_checkForUpdates(t *testing.T) {
JSONData: plugins.JSONData{ JSONData: plugins.JSONData{
ID: "test-ds", ID: "test-ds",
Info: plugins.Info{Version: "0.9.0"}, Info: plugins.Info{Version: "0.9.0"},
Type: plugins.DataSource, Type: plugins.TypeDataSource,
}, },
Class: plugins.External, Class: plugins.ClassExternal,
}, },
{ {
JSONData: plugins.JSONData{ JSONData: plugins.JSONData{
ID: "test-app", ID: "test-app",
Info: plugins.Info{Version: "0.5.0"}, Info: plugins.Info{Version: "0.5.0"},
Type: plugins.App, Type: plugins.TypeApp,
}, },
Class: plugins.External, Class: plugins.ClassExternal,
}, },
{ {
JSONData: plugins.JSONData{ JSONData: plugins.JSONData{
ID: "test-panel", ID: "test-panel",
Info: plugins.Info{Version: "2.5.7"}, Info: plugins.Info{Version: "2.5.7"},
Type: plugins.Panel, Type: plugins.TypePanel,
}, },
Class: plugins.Bundled, Class: plugins.ClassBundled,
}, },
{ {
JSONData: plugins.JSONData{ JSONData: plugins.JSONData{
ID: "test-core-panel", ID: "test-core-panel",
Info: plugins.Info{Version: "0.0.1"}, Info: plugins.Info{Version: "0.0.1"},
Type: plugins.Panel, Type: plugins.TypePanel,
}, },
Class: plugins.Core, Class: plugins.ClassCore,
}, },
}, },
}, },

View File

@ -672,7 +672,7 @@ func createTestPlugin(id string) (*plugins.Plugin, *testPlugin) {
JSONData: plugins.JSONData{ JSONData: plugins.JSONData{
ID: id, ID: id,
}, },
Class: plugins.Core, Class: plugins.ClassCore,
} }
p.SetLogger(log.New("test-plugin")) p.SetLogger(log.New("test-plugin"))