Plugins: Remove pkg/infra/fs, pkg/infra/tracing and pkg/infra/process dependencies from pkg/plugins (#115798)

* remove dependency on packages

* update tests

* trigger
This commit is contained in:
Will Browne
2026-01-05 11:12:31 +00:00
committed by GitHub
parent 4e3039e4bd
commit 70b1053ad1
33 changed files with 131 additions and 134 deletions
+5 -2
View File
@@ -14,7 +14,6 @@ import (
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/plugins/manager/registry"
"github.com/grafana/grafana/pkg/util/proxyutil"
)
const (
@@ -124,7 +123,7 @@ func (s *Service) CallResource(ctx context.Context, req *backend.CallResourceReq
res.Headers = map[string][]string{}
}
proxyutil.SetProxyResponseHeaders(res.Headers)
SetCSPHeader(res.Headers)
ensureContentTypeHeader(res)
}
@@ -281,6 +280,10 @@ func (s *Service) ValidateAdmission(ctx context.Context, req *backend.AdmissionR
return plugin.ValidateAdmission(ctx, req)
}
func SetCSPHeader(header http.Header) {
header.Set("Content-Security-Policy", "sandbox")
}
// plugin finds a plugin with `pluginID` from the registry that is not decommissioned
func (s *Service) plugin(ctx context.Context, pluginID, pluginVersion string) (*plugins.Plugin, bool) {
p, exists := s.pluginRegistry.Plugin(ctx, pluginID, pluginVersion)
+3 -5
View File
@@ -8,11 +8,11 @@ import (
"testing"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/plugins/backendplugin"
"github.com/grafana/grafana/pkg/plugins/manager/pluginfakes"
"github.com/grafana/grafana/pkg/util/testutil"
"github.com/stretchr/testify/require"
)
func TestQueryData(t *testing.T) {
@@ -157,9 +157,7 @@ func TestCheckHealth(t *testing.T) {
})
}
func TestIntegrationCallResource(t *testing.T) {
testutil.SkipIntegrationTestInShortMode(t)
func TestCallResource(t *testing.T) {
registry := pluginfakes.NewFakePluginRegistry()
p := &plugins.Plugin{
JSONData: plugins.JSONData{
@@ -13,10 +13,9 @@ import (
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/plugins/config"
"github.com/grafana/grafana/pkg/plugins/log"
"github.com/grafana/grafana/pkg/util"
)
var walk = util.Walk
var walk = plugins.Walk
var (
ErrInvalidPluginJSONFilePath = errors.New("invalid plugin.json filepath was provided")
@@ -215,7 +214,7 @@ func (s *LocalSource) getAbsPluginJSONPaths(path string) ([]string, error) {
}
if fi.Name() == "node_modules" {
return util.ErrWalkSkipDir
return plugins.ErrWalkSkipDir
}
if fi.IsDir() {
-77
View File
@@ -1,77 +0,0 @@
package sources
import (
"context"
"path/filepath"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/plugins/config"
"github.com/grafana/grafana/pkg/plugins/log"
"github.com/grafana/grafana/pkg/setting"
)
type Service struct {
cfg *config.PluginManagementCfg
staticRootPath string
log log.Logger
}
func ProvideService(cfg *setting.Cfg, pCcfg *config.PluginManagementCfg) *Service {
return &Service{
cfg: pCcfg,
staticRootPath: cfg.StaticRootPath,
log: log.New("plugin.sources"),
}
}
func (s *Service) List(_ context.Context) []plugins.PluginSource {
r := []plugins.PluginSource{
NewLocalSource(
plugins.ClassCore,
s.corePluginPaths(),
),
}
r = append(r, s.externalPluginSources()...)
r = append(r, s.pluginSettingSources()...)
return r
}
func (s *Service) externalPluginSources() []plugins.PluginSource {
localSrcs, err := DirAsLocalSources(s.cfg, s.cfg.PluginsPath, plugins.ClassExternal)
if err != nil {
s.log.Error("Failed to load external plugins", "error", err)
return []plugins.PluginSource{}
}
srcs := make([]plugins.PluginSource, len(localSrcs))
for i, src := range localSrcs {
srcs[i] = src
}
return srcs
}
func (s *Service) pluginSettingSources() []plugins.PluginSource {
sources := make([]plugins.PluginSource, 0, len(s.cfg.PluginSettings))
for _, ps := range s.cfg.PluginSettings {
path, exists := ps["path"]
if !exists || path == "" {
continue
}
if s.cfg.DevMode {
sources = append(sources, NewUnsafeLocalSource(plugins.ClassExternal, []string{path}))
} else {
sources = append(sources, NewLocalSource(plugins.ClassExternal, []string{path}))
}
}
return sources
}
// corePluginPaths provides a list of the Core plugin file system paths
func (s *Service) corePluginPaths() []string {
datasourcePaths := filepath.Join(s.staticRootPath, "app", "plugins", "datasource")
panelsPath := filepath.Join(s.staticRootPath, "app", "plugins", "panel")
return []string{datasourcePaths, panelsPath}
}
-132
View File
@@ -1,132 +0,0 @@
package sources
import (
"context"
"path/filepath"
"testing"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/plugins/config"
"github.com/grafana/grafana/pkg/setting"
)
func TestSources_List(t *testing.T) {
t.Run("Plugin sources are populated by default and listed in specific order", func(t *testing.T) {
testdata, err := filepath.Abs("../testdata")
require.NoError(t, err)
cfg := &setting.Cfg{
StaticRootPath: testdata,
}
pCfg := &config.PluginManagementCfg{
PluginsPath: filepath.Join(testdata, "pluginRootWithDist"),
PluginSettings: setting.PluginSettings{
"foo": map[string]string{
"path": filepath.Join(testdata, "test-app"),
},
"bar": map[string]string{
"url": "https://grafana.plugin",
},
},
}
s := ProvideService(cfg, pCfg)
srcs := s.List(context.Background())
ctx := context.Background()
require.Len(t, srcs, 5)
require.Equal(t, srcs[0].PluginClass(ctx), plugins.ClassCore)
if localSrc, ok := srcs[0].(*LocalSource); ok {
require.Equal(t, localSrc.Paths(), []string{
filepath.Join(testdata, "app", "plugins", "datasource"),
filepath.Join(testdata, "app", "plugins", "panel"),
})
} else {
t.Fatalf("Expected LocalSource, got %T", srcs[0])
}
sig, exists := srcs[0].DefaultSignature(ctx, "")
require.True(t, exists)
require.Equal(t, plugins.SignatureStatusInternal, sig.Status)
require.Equal(t, plugins.SignatureType(""), sig.Type)
require.Equal(t, "", sig.SigningOrg)
require.Equal(t, srcs[1].PluginClass(ctx), plugins.ClassExternal)
if localSrc, ok := srcs[1].(*LocalSource); ok {
require.Equal(t, localSrc.Paths(), []string{
filepath.Join(testdata, "pluginRootWithDist", "datasource"),
})
} else {
t.Fatalf("Expected LocalSource, got %T", srcs[1])
}
sig, exists = srcs[1].DefaultSignature(ctx, "")
require.False(t, exists)
require.Equal(t, plugins.Signature{}, sig)
require.Equal(t, srcs[2].PluginClass(ctx), plugins.ClassExternal)
if localSrc, ok := srcs[2].(*LocalSource); ok {
require.Equal(t, localSrc.Paths(), []string{
filepath.Join(testdata, "pluginRootWithDist", "dist"),
})
} else {
t.Fatalf("Expected LocalSource, got %T", srcs[2])
}
sig, exists = srcs[2].DefaultSignature(ctx, "")
require.False(t, exists)
require.Equal(t, plugins.Signature{}, sig)
require.Equal(t, srcs[3].PluginClass(ctx), plugins.ClassExternal)
if localSrc, ok := srcs[3].(*LocalSource); ok {
require.Equal(t, localSrc.Paths(), []string{
filepath.Join(testdata, "pluginRootWithDist", "panel"),
})
} else {
t.Fatalf("Expected LocalSource, got %T", srcs[3])
}
sig, exists = srcs[3].DefaultSignature(ctx, "")
require.False(t, exists)
require.Equal(t, plugins.Signature{}, sig)
})
t.Run("Plugin sources are populated with symbolic links", func(t *testing.T) {
testdata, err := filepath.Abs("../testdata")
require.NoError(t, err)
cfg := &setting.Cfg{
StaticRootPath: testdata,
}
pCfg := &config.PluginManagementCfg{
PluginsPath: filepath.Join(testdata, "symbolic-plugin-dirs"),
}
s := ProvideService(cfg, pCfg)
ctx := context.Background()
srcs := s.List(ctx)
uris := map[plugins.Class]map[string]struct{}{}
for _, src := range srcs {
class := src.PluginClass(ctx)
if _, exists := uris[class]; !exists {
uris[class] = map[string]struct{}{}
}
if localSrc, ok := src.(*LocalSource); ok {
for _, path := range localSrc.Paths() {
uris[class][path] = struct{}{}
}
}
}
require.Equal(t, uris[plugins.ClassCore], map[string]struct{}{
filepath.Join(testdata, "app", "plugins", "datasource"): {},
filepath.Join(testdata, "app", "plugins", "panel"): {},
}, "should include core plugins")
require.Equal(t, uris[plugins.ClassExternal], map[string]struct{}{
filepath.Join(testdata, "symbolic-plugin-dirs", "plugin"): {},
}, "should include external symlinked plugin")
})
}