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
+2 -2
View File
@@ -300,11 +300,11 @@ func (proxy *DataSourceProxy) validateRequest() error {
}
// route match
r1, err := util.CleanRelativePath(proxy.proxyPath)
r1, err := plugins.CleanRelativePath(proxy.proxyPath)
if err != nil {
return err
}
r2, err := util.CleanRelativePath(route.Path)
r2, err := plugins.CleanRelativePath(route.Path)
if err != nil {
return err
}
+4 -5
View File
@@ -13,7 +13,6 @@ import (
"sort"
"strings"
"github.com/grafana/grafana/pkg/plugins/auth"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
@@ -22,6 +21,7 @@ import (
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/plugins/auth"
"github.com/grafana/grafana/pkg/plugins/repo"
ac "github.com/grafana/grafana/pkg/services/accesscontrol"
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
@@ -32,7 +32,6 @@ import (
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsettings"
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util"
"github.com/grafana/grafana/pkg/web"
)
@@ -355,7 +354,7 @@ func (hs *HTTPServer) getPluginAssets(c *contextmodel.ReqContext) {
}
// prepend slash for cleaning relative paths
requestedFile, err := util.CleanRelativePath(web.Params(c.Req)["*"])
requestedFile, err := plugins.CleanRelativePath(web.Params(c.Req)["*"])
if err != nil {
// slash is prepended above therefore this is not expected to fail
c.JsonApiErr(500, "Failed to clean relative file path", err)
@@ -598,9 +597,9 @@ func mdFilepath(mdFilename string) (string, error) {
fileExt := filepath.Ext(mdFilename)
switch fileExt {
case "md":
return util.CleanRelativePath(mdFilename)
return plugins.CleanRelativePath(mdFilename)
case "":
return util.CleanRelativePath(fmt.Sprintf("%s.md", mdFilename))
return plugins.CleanRelativePath(fmt.Sprintf("%s.md", mdFilename))
default:
return "", ErrUnexpectedFileExtension
}
@@ -3,13 +3,14 @@ package httpclientprovider
import (
"testing"
"github.com/grafana/grafana/pkg/services/validations"
"github.com/grafana/grafana-aws-sdk/pkg/awsauth"
sdkhttpclient "github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
"github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/setting"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/plugins/config"
"github.com/grafana/grafana/pkg/services/validations"
"github.com/grafana/grafana/pkg/setting"
)
func TestHTTPClientProvider(t *testing.T) {
@@ -77,7 +78,7 @@ func TestHTTPClientProvider(t *testing.T) {
newProviderFunc = origNewProviderFunc
})
tracer := tracing.InitializeTracerForTest()
_ = New(&setting.Cfg{PluginSettings: setting.PluginSettings{"example": {"har_log_enabled": "true"}}}, &validations.OSSDataSourceRequestURLValidator{}, tracer)
_ = New(&setting.Cfg{PluginSettings: config.PluginSettings{"example": {"har_log_enabled": "true"}}}, &validations.OSSDataSourceRequestURLValidator{}, tracer)
require.Len(t, providerOpts, 1)
o := providerOpts[0]
require.Len(t, o.Middlewares, 10)
@@ -5,12 +5,13 @@ import (
sdkhttpclient "github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
httplogger "github.com/grafana/grafana-plugin-sdk-go/experimental/http_logger"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/plugins/config"
)
const HTTPLoggerMiddlewareName = "http-logger"
func HTTPLoggerMiddleware(cfg setting.PluginSettings) sdkhttpclient.Middleware {
func HTTPLoggerMiddleware(cfg config.PluginSettings) sdkhttpclient.Middleware {
return sdkhttpclient.NamedMiddlewareFunc(HTTPLoggerMiddlewareName, func(opts sdkhttpclient.Options, next http.RoundTripper) http.RoundTripper {
datasourceType, exists := opts.Labels["datasource_type"]
if !exists {
@@ -29,7 +30,7 @@ func HTTPLoggerMiddleware(cfg setting.PluginSettings) sdkhttpclient.Middleware {
})
}
func httpLoggingEnabled(cfg setting.PluginSettings) bool {
func httpLoggingEnabled(cfg config.PluginSettings) bool {
for _, settings := range cfg {
if enabled := settings["har_log_enabled"]; enabled == "true" {
return true
@@ -38,7 +39,7 @@ func httpLoggingEnabled(cfg setting.PluginSettings) bool {
return false
}
func getLoggerSettings(datasourceType string, cfg setting.PluginSettings) (enabled bool, path string) {
func getLoggerSettings(datasourceType string, cfg config.PluginSettings) (enabled bool, path string) {
settings, ok := cfg[datasourceType]
if !ok {
return
@@ -9,15 +9,17 @@ import (
"testing"
"time"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
"github.com/grafana/grafana-plugin-sdk-go/experimental/e2e/storage"
"github.com/grafana/grafana/pkg/setting"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/plugins/config"
)
func TestHTTPLoggerMiddleware(t *testing.T) {
t.Run("Should return middleware name", func(t *testing.T) {
mw := HTTPLoggerMiddleware(setting.PluginSettings{})
mw := HTTPLoggerMiddleware(config.PluginSettings{})
middlewareName, ok := mw.(httpclient.MiddlewareName)
require.True(t, ok)
require.Equal(t, HTTPLoggerMiddlewareName, middlewareName.MiddlewareName())
@@ -27,7 +29,7 @@ func TestHTTPLoggerMiddleware(t *testing.T) {
tempPath := path.Join(os.TempDir(), fmt.Sprintf("http_logger_test_%d.har", time.Now().UnixMilli()))
ctx := &testContext{}
finalRoundTripper := ctx.createRoundTripper("finalrt")
mw := HTTPLoggerMiddleware(setting.PluginSettings{"example-datasource": {"har_log_enabled": "false", "har_log_path": tempPath}})
mw := HTTPLoggerMiddleware(config.PluginSettings{"example-datasource": {"har_log_enabled": "false", "har_log_path": tempPath}})
rt := mw.CreateMiddleware(httpclient.Options{Labels: map[string]string{"datasource_type": "example-datasource"}}, finalRoundTripper)
require.NotNil(t, rt)
@@ -54,7 +56,7 @@ func TestHTTPLoggerMiddleware(t *testing.T) {
}()
ctx := &testContext{}
finalRoundTripper := ctx.createRoundTripper("finalrt")
mw := HTTPLoggerMiddleware(setting.PluginSettings{"example-datasource": {"har_log_enabled": "true", "har_log_path": f.Name()}})
mw := HTTPLoggerMiddleware(config.PluginSettings{"example-datasource": {"har_log_enabled": "true", "har_log_path": f.Name()}})
rt := mw.CreateMiddleware(httpclient.Options{Labels: map[string]string{"datasource_type": "example-datasource"}}, finalRoundTripper)
require.NotNil(t, rt)
@@ -1,20 +1,20 @@
package coreplugin_test
package coreplugin
import (
"context"
"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/coreplugin"
"github.com/grafana/grafana/pkg/plugins/log"
"github.com/grafana/grafana/pkg/plugins/manager/pluginfakes"
"github.com/stretchr/testify/require"
)
func TestCorePlugin(t *testing.T) {
t.Run("New core plugin with empty opts should return expected values", func(t *testing.T) {
factory := coreplugin.New(backend.ServeOpts{})
factory := New(backend.ServeOpts{})
p, err := factory("plugin", log.New("test"), pluginfakes.InitializeNoopTracerForTest(), nil)
require.NoError(t, err)
require.NotNil(t, p)
@@ -36,7 +36,7 @@ func TestCorePlugin(t *testing.T) {
t.Run("New core plugin with handlers set in opts should return expected values", func(t *testing.T) {
checkHealthCalled := false
callResourceCalled := false
factory := coreplugin.New(backend.ServeOpts{
factory := New(backend.ServeOpts{
CheckHealthHandler: backend.CheckHealthHandlerFunc(func(ctx context.Context,
req *backend.CheckHealthRequest) (*backend.CheckHealthResult, error) {
checkHealthCalled = true
@@ -5,18 +5,16 @@ import (
"errors"
"fmt"
"go.opentelemetry.io/otel/trace"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
sdklog "github.com/grafana/grafana-plugin-sdk-go/backend/log"
sdktracing "github.com/grafana/grafana-plugin-sdk-go/backend/tracing"
"github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
"go.opentelemetry.io/otel/trace"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/plugins/backendplugin"
"github.com/grafana/grafana/pkg/plugins/log"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/tsdb/azuremonitor"
cloudmonitoring "github.com/grafana/grafana/pkg/tsdb/cloud-monitoring"
"github.com/grafana/grafana/pkg/tsdb/cloudwatch"
@@ -204,7 +202,7 @@ var ErrCorePluginNotFound = errors.New("core plugin not found")
// NewPlugin factory for creating and initializing a single core plugin.
// Note: cfg only needed for mssql connection pooling defaults.
func NewPlugin(pluginID string, cfg *setting.Cfg, httpClientProvider *httpclient.Provider, tracer trace.Tracer, features featuremgmt.FeatureToggles) (*plugins.Plugin, error) {
func NewPlugin(pluginID string, httpClientProvider *httpclient.Provider, tracer trace.Tracer) (*plugins.Plugin, error) {
jsonData := plugins.JSONData{
ID: pluginID,
AliasIDs: []string{},
@@ -241,7 +239,7 @@ func NewPlugin(pluginID string, cfg *setting.Cfg, httpClientProvider *httpclient
case MySQL:
svc = mysql.ProvideService()
case MSSQL:
svc = mssql.ProvideService(cfg)
svc = mssql.ProvideService()
case Pyroscope:
svc = pyroscope.ProvideService(httpClientProvider)
case Parca:
@@ -4,11 +4,10 @@ import (
"testing"
"github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/plugins/log"
"github.com/grafana/grafana/pkg/plugins/tracing"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/setting"
"github.com/stretchr/testify/require"
)
func TestNewPlugin(t *testing.T) {
@@ -46,7 +45,7 @@ func TestNewPlugin(t *testing.T) {
tc.ExpectedID = tc.ID
}
p, err := NewPlugin(tc.ID, setting.NewCfg(), httpclient.NewProvider(), tracing.NoopTracer(), featuremgmt.WithFeatures())
p, err := NewPlugin(tc.ID, httpclient.NewProvider(), tracing.NoopTracer())
if tc.ExpectedNotFoundErr {
require.ErrorIs(t, err, ErrCorePluginNotFound)
require.Nil(t, p)
+5 -6
View File
@@ -1,9 +1,5 @@
package config
import (
"github.com/grafana/grafana/pkg/setting"
)
// PluginManagementCfg is the configuration for the plugin management system.
// It includes settings which are used to configure different components of plugin management.
type PluginManagementCfg struct {
@@ -11,7 +7,7 @@ type PluginManagementCfg struct {
PluginsPath string
PluginSettings setting.PluginSettings
PluginSettings PluginSettings
PluginsAllowUnsigned []string
DisablePlugins []string
ForwardHostEnvVars []string
@@ -35,8 +31,11 @@ type Features struct {
TempoAlertingEnabled bool
}
// PluginSettings maps plugin id to map of key/value settings.
type PluginSettings map[string]map[string]string
// NewPluginManagementCfg returns a new PluginManagementCfg.
func NewPluginManagementCfg(devMode bool, pluginsPath string, pluginSettings setting.PluginSettings, pluginsAllowUnsigned []string,
func NewPluginManagementCfg(devMode bool, pluginsPath string, pluginSettings PluginSettings, pluginsAllowUnsigned []string,
pluginsCDNURLTemplate string, appURL string, features Features,
grafanaComAPIURL string, disablePlugins []string, forwardHostEnvVars []string, grafanaComAPIToken string,
) *PluginManagementCfg {
@@ -1,4 +1,4 @@
package util
package plugins
import (
"errors"
@@ -1,4 +1,4 @@
package util
package plugins
import (
"path/filepath"
+2 -4
View File
@@ -7,8 +7,6 @@ import (
"os"
"path/filepath"
"strings"
"github.com/grafana/grafana/pkg/util"
)
var (
@@ -110,7 +108,7 @@ func (f LocalFS) walkFunc(basePath string, acc map[string]struct{}) filepath.Wal
// If a nil error is returned, the caller should take care of calling Close() the returned fs.File.
// If the file does not exist, ErrFileNotExist is returned.
func (f LocalFS) Open(name string) (fs.File, error) {
cleanPath, err := util.CleanRelativePath(name)
cleanPath, err := CleanRelativePath(name)
if err != nil {
return nil, err
}
@@ -155,7 +153,7 @@ func (f LocalFS) Files() ([]string, error) {
if err != nil {
return nil, err
}
clenRelPath, err := util.CleanRelativePath(relPath)
clenRelPath, err := CleanRelativePath(relPath)
if err != nil {
continue
}
+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() {
+1 -2
View File
@@ -19,7 +19,6 @@ import (
"github.com/grafana/grafana/pkg/plugins/backendplugin/pluginextensionv2"
"github.com/grafana/grafana/pkg/plugins/log"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/util"
)
var (
@@ -414,7 +413,7 @@ func (p *Plugin) ConvertObjects(ctx context.Context, req *backend.ConversionRequ
}
func (p *Plugin) File(name string) (fs.File, error) {
cleanPath, err := util.CleanRelativePath(name)
cleanPath, err := CleanRelativePath(name)
if err != nil {
// CleanRelativePath should clean and make the path relative so this is not expected to fail
return nil, err
+9 -9
View File
@@ -44,7 +44,6 @@ import (
"github.com/grafana/grafana/pkg/plugins/manager/process"
"github.com/grafana/grafana/pkg/plugins/manager/registry"
"github.com/grafana/grafana/pkg/plugins/manager/signature"
"github.com/grafana/grafana/pkg/plugins/manager/sources"
"github.com/grafana/grafana/pkg/plugins/pluginassets"
"github.com/grafana/grafana/pkg/plugins/pluginscdn"
"github.com/grafana/grafana/pkg/plugins/repo"
@@ -196,6 +195,7 @@ import (
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginexternal"
"github.com/grafana/grafana/pkg/services/pluginsintegration/plugininstaller"
service6 "github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsettings/service"
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsources"
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsso"
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
"github.com/grafana/grafana/pkg/services/pluginsintegration/provisionedplugins"
@@ -370,7 +370,7 @@ func Initialize(ctx context.Context, cfg *setting.Cfg, opts Options, apiOpts api
}
cacheService := localcache.ProvideService()
ossDataSourceRequestValidator := validations.ProvideValidator()
sourcesService := sources.ProvideService(cfg, pluginManagementCfg)
pluginsourcesService := pluginsources.ProvideService(cfg, pluginManagementCfg)
discovery := pipeline.ProvideDiscoveryStage(pluginManagementCfg, inMemory)
keystoreService := keystore.ProvideService(kvStore)
keyRetriever := dynamic.ProvideService(cfg, keystoreService)
@@ -406,7 +406,7 @@ func Initialize(ctx context.Context, cfg *setting.Cfg, opts Options, apiOpts api
testdatasourceService := testdatasource.ProvideService()
postgresService := postgres.ProvideService()
mysqlService := mysql.ProvideService()
mssqlService := mssql.ProvideService(cfg)
mssqlService := mssql.ProvideService()
entityEventsService := store.ProvideEntityEventsService(cfg, sqlStore, featureToggles)
configProvider, err := configprovider.ProvideService(cfg)
if err != nil {
@@ -580,7 +580,7 @@ func Initialize(ctx context.Context, cfg *setting.Cfg, opts Options, apiOpts api
}
errorRegistry := pluginerrs.ProvideErrorTracker()
loaderLoader := loader.ProvideService(pluginManagementCfg, discovery, bootstrap, validate, initialize, terminate, errorRegistry)
pluginstoreService, err := pluginstore.ProvideService(inMemory, sourcesService, loaderLoader, featureToggles)
pluginstoreService, err := pluginstore.ProvideService(inMemory, pluginsourcesService, loaderLoader, featureToggles)
if err != nil {
return nil, err
}
@@ -876,7 +876,7 @@ func Initialize(ctx context.Context, cfg *setting.Cfg, opts Options, apiOpts api
apiService := api4.ProvideService(cfg, routeRegisterImpl, accessControl, userService, authinfoimplService, ossGroups, identitySynchronizer, orgService, ldapImpl, userAuthTokenService, bundleregistryService)
dashboardActivityChannel := live.ProvideDashboardActivityChannel(grafanaLive)
dashboardsAPIBuilder := dashboard.RegisterAPIService(featureToggles, apiserverService, dashboardService, dashboardProvisioningService, service15, dashboardServiceImpl, dashboardPermissionsService, accessControl, accessClient, provisioningServiceImpl, dashboardsStore, registerer, sqlStore, tracingService, resourceClient, dualwriteService, sortService, quotaService, libraryPanelService, eventualRestConfigProvider, userService, libraryElementService, publicDashboardServiceImpl, serviceImpl, dashboardActivityChannel, configProvider)
dataSourceAPIBuilder, err := datasource.RegisterAPIService(featureToggles, apiserverService, middlewareHandler, scopedPluginDatasourceProvider, plugincontextProvider, accessControl, registerer, sourcesService)
dataSourceAPIBuilder, err := datasource.RegisterAPIService(featureToggles, apiserverService, middlewareHandler, scopedPluginDatasourceProvider, plugincontextProvider, accessControl, registerer, pluginsourcesService)
if err != nil {
return nil, err
}
@@ -1030,7 +1030,7 @@ func InitializeForTest(ctx context.Context, t sqlutil.ITestDB, testingT interfac
}
cacheService := localcache.ProvideService()
ossDataSourceRequestValidator := validations.ProvideValidator()
sourcesService := sources.ProvideService(cfg, pluginManagementCfg)
pluginsourcesService := pluginsources.ProvideService(cfg, pluginManagementCfg)
discovery := pipeline.ProvideDiscoveryStage(pluginManagementCfg, inMemory)
keystoreService := keystore.ProvideService(kvStore)
keyRetriever := dynamic.ProvideService(cfg, keystoreService)
@@ -1066,7 +1066,7 @@ func InitializeForTest(ctx context.Context, t sqlutil.ITestDB, testingT interfac
testdatasourceService := testdatasource.ProvideService()
postgresService := postgres.ProvideService()
mysqlService := mysql.ProvideService()
mssqlService := mssql.ProvideService(cfg)
mssqlService := mssql.ProvideService()
entityEventsService := store.ProvideEntityEventsService(cfg, sqlStore, featureToggles)
configProvider, err := configprovider.ProvideService(cfg)
if err != nil {
@@ -1240,7 +1240,7 @@ func InitializeForTest(ctx context.Context, t sqlutil.ITestDB, testingT interfac
}
errorRegistry := pluginerrs.ProvideErrorTracker()
loaderLoader := loader.ProvideService(pluginManagementCfg, discovery, bootstrap, validate, initialize, terminate, errorRegistry)
pluginstoreService, err := pluginstore.ProvideService(inMemory, sourcesService, loaderLoader, featureToggles)
pluginstoreService, err := pluginstore.ProvideService(inMemory, pluginsourcesService, loaderLoader, featureToggles)
if err != nil {
return nil, err
}
@@ -1538,7 +1538,7 @@ func InitializeForTest(ctx context.Context, t sqlutil.ITestDB, testingT interfac
apiService := api4.ProvideService(cfg, routeRegisterImpl, accessControl, userService, authinfoimplService, ossGroups, identitySynchronizer, orgService, ldapImpl, userAuthTokenService, bundleregistryService)
dashboardActivityChannel := live.ProvideDashboardActivityChannel(grafanaLive)
dashboardsAPIBuilder := dashboard.RegisterAPIService(featureToggles, apiserverService, dashboardService, dashboardProvisioningService, service15, dashboardServiceImpl, dashboardPermissionsService, accessControl, accessClient, provisioningServiceImpl, dashboardsStore, registerer, sqlStore, tracingService, resourceClient, dualwriteService, sortService, quotaService, libraryPanelService, eventualRestConfigProvider, userService, libraryElementService, publicDashboardServiceImpl, serviceImpl, dashboardActivityChannel, configProvider)
dataSourceAPIBuilder, err := datasource.RegisterAPIService(featureToggles, apiserverService, middlewareHandler, scopedPluginDatasourceProvider, plugincontextProvider, accessControl, registerer, sourcesService)
dataSourceAPIBuilder, err := datasource.RegisterAPIService(featureToggles, apiserverService, middlewareHandler, scopedPluginDatasourceProvider, plugincontextProvider, accessControl, registerer, pluginsourcesService)
if err != nil {
return nil, err
}
@@ -7,7 +7,6 @@ import (
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
"github.com/grafana/grafana/pkg/util"
)
var _ FileStore = (*FileStoreManager)(nil)
@@ -87,7 +86,7 @@ func (m *FileStoreManager) GetPluginDashboardFileContents(ctx context.Context, a
return nil, errors.New("plugin dashboard file not found")
}
cleanPath, err := util.CleanRelativePath(includedFile.Path)
cleanPath, err := plugins.CleanRelativePath(includedFile.Path)
if err != nil {
// CleanRelativePath should clean and make the path relative so this is not expected to fail
return nil, err
@@ -9,7 +9,6 @@ import (
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/plugins/config"
"github.com/grafana/grafana/pkg/plugins/manager/registry"
"github.com/grafana/grafana/pkg/setting"
)
func TestSkipPlugins(t *testing.T) {
@@ -68,7 +67,7 @@ func TestAsExternal(t *testing.T) {
t.Run("should skip a core plugin", func(t *testing.T) {
cfg := &config.PluginManagementCfg{
PluginSettings: setting.PluginSettings{
PluginSettings: config.PluginSettings{
"plugin1": map[string]string{
"as_external": "true",
},
@@ -17,7 +17,6 @@ import (
"github.com/grafana/grafana/pkg/plugins/manager/signature/statickey"
"github.com/grafana/grafana/pkg/plugins/pluginscdn"
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
"github.com/grafana/grafana/pkg/setting"
)
func TestService_Calculate(t *testing.T) {
@@ -31,7 +30,7 @@ func TestService_Calculate(t *testing.T) {
tcs := []struct {
name string
pluginSettings setting.PluginSettings
pluginSettings config.PluginSettings
plugin pluginstore.Plugin
expected plugins.LoadingStrategy
}{
@@ -81,7 +80,7 @@ func TestService_Calculate(t *testing.T) {
},
{
name: "Expected LoadingStrategyFetch when parent create-plugin version is not set, is configured as CDN enabled and plugin is not angular",
pluginSettings: setting.PluginSettings{
pluginSettings: config.PluginSettings{
"parent-datasource": {
"cdn": "true",
},
@@ -94,7 +93,7 @@ func TestService_Calculate(t *testing.T) {
},
{
name: "Expected LoadingStrategyFetch when parent create-plugin version is not set, is configured as CDN enabled and plugin is angular",
pluginSettings: setting.PluginSettings{
pluginSettings: config.PluginSettings{
"parent-datasource": {
"cdn": "true",
},
@@ -107,7 +106,7 @@ func TestService_Calculate(t *testing.T) {
},
{
name: "Expected LoadingStrategyFetch when parent create-plugin version is not set, is not configured as CDN enabled and plugin is angular",
pluginSettings: setting.PluginSettings{},
pluginSettings: config.PluginSettings{},
plugin: newPlugin(pluginID, withAngular(true), withFS(plugins.NewFakeFS()), func(p pluginstore.Plugin) pluginstore.Plugin {
p.Parent = &pluginstore.ParentPlugin{ID: "parent-datasource"}
return p
@@ -375,9 +374,9 @@ func TestService_ModuleHash(t *testing.T) {
}
t.Run(tc.name, func(t *testing.T) {
var pluginSettings setting.PluginSettings
var pluginSettings config.PluginSettings
if tc.cdn {
pluginSettings = setting.PluginSettings{
pluginSettings = config.PluginSettings{
pluginID: {
"cdn": "true",
},
@@ -412,7 +411,7 @@ func TestService_ModuleHash(t *testing.T) {
func TestService_ModuleHash_Cache(t *testing.T) {
pCfg := &config.PluginManagementCfg{
PluginSettings: setting.PluginSettings{},
PluginSettings: config.PluginSettings{},
Features: config.Features{SriChecksEnabled: true},
}
svc := ProvideService(
@@ -448,7 +447,7 @@ func TestService_ModuleHash_Cache(t *testing.T) {
pCfg = &config.PluginManagementCfg{
PluginsCDNURLTemplate: "https://cdn.grafana.com",
PluginSettings: setting.PluginSettings{
PluginSettings: config.PluginSettings{
pluginID: {
"cdn": "true",
},
@@ -577,14 +576,14 @@ func withClass(class plugins.Class) func(p pluginstore.Plugin) pluginstore.Plugi
}
}
func newCfg(ps setting.PluginSettings) *config.PluginManagementCfg {
func newCfg(ps config.PluginSettings) *config.PluginManagementCfg {
return &config.PluginManagementCfg{
PluginSettings: ps,
}
}
func newPluginSettings(pluginID string, kv map[string]string) setting.PluginSettings {
return setting.PluginSettings{
func newPluginSettings(pluginID string, kv map[string]string) config.PluginSettings {
return config.PluginSettings{
pluginID: kv,
}
}
@@ -48,7 +48,7 @@ type PluginInstanceCfg struct {
Tracing config.Tracing
PluginSettings setting.PluginSettings
PluginSettings config.PluginSettings
AWSAllowedAuthProviders []string
AWSAssumeRoleEnabled bool
@@ -127,8 +127,8 @@ func ProvidePluginInstanceConfig(cfg *setting.Cfg, settingProvider setting.Provi
}, nil
}
func extractPluginSettings(settingProvider setting.Provider) setting.PluginSettings {
ps := setting.PluginSettings{}
func extractPluginSettings(settingProvider setting.Provider) config.PluginSettings {
ps := config.PluginSettings{}
for sectionName, sectionCopy := range settingProvider.Current() {
if !strings.HasPrefix(sectionName, "plugin.") {
continue
@@ -4,6 +4,7 @@ import (
"testing"
"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/services/pluginsintegration/pluginstore"
"github.com/grafana/grafana/pkg/setting"
@@ -12,7 +13,7 @@ import (
func TestService_validateExternal(t *testing.T) {
cfg := setting.NewCfg()
cfg.PluginSettings = setting.PluginSettings{
cfg.PluginSettings = config.PluginSettings{
"grafana-testdata-datasource": map[string]string{
"as_external": "true",
},
@@ -55,6 +55,7 @@ import (
"github.com/grafana/grafana/pkg/services/pluginsintegration/plugininstaller"
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsettings"
pluginSettings "github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsettings/service"
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsources"
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsso"
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
"github.com/grafana/grafana/pkg/services/pluginsintegration/provisionedplugins"
@@ -154,8 +155,8 @@ var WireExtensionSet = wire.NewSet(
wire.Bind(new(managedplugins.Manager), new(*managedplugins.Noop)),
provisionedplugins.NewNoop,
wire.Bind(new(provisionedplugins.Manager), new(*provisionedplugins.Noop)),
sources.ProvideService,
wire.Bind(new(sources.Registry), new(*sources.Service)),
pluginsources.ProvideService,
wire.Bind(new(sources.Registry), new(*pluginsources.Service)),
checkregistry.ProvideService,
wire.Bind(new(checkregistry.CheckService), new(*checkregistry.Service)),
pluginassets2.NewLocalProvider,
@@ -1,4 +1,4 @@
package sources
package pluginsources
import (
"context"
@@ -7,6 +7,7 @@ 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/plugins/manager/sources"
"github.com/grafana/grafana/pkg/setting"
)
@@ -27,7 +28,7 @@ func ProvideService(cfg *setting.Cfg, pCcfg *config.PluginManagementCfg) *Servic
func (s *Service) List(_ context.Context) []plugins.PluginSource {
r := []plugins.PluginSource{
NewLocalSource(
sources.NewLocalSource(
plugins.ClassCore,
s.corePluginPaths(),
),
@@ -38,7 +39,7 @@ func (s *Service) List(_ context.Context) []plugins.PluginSource {
}
func (s *Service) externalPluginSources() []plugins.PluginSource {
localSrcs, err := DirAsLocalSources(s.cfg, s.cfg.PluginsPath, plugins.ClassExternal)
localSrcs, err := sources.DirAsLocalSources(s.cfg, s.cfg.PluginsPath, plugins.ClassExternal)
if err != nil {
s.log.Error("Failed to load external plugins", "error", err)
return []plugins.PluginSource{}
@@ -53,20 +54,20 @@ func (s *Service) externalPluginSources() []plugins.PluginSource {
}
func (s *Service) pluginSettingSources() []plugins.PluginSource {
sources := make([]plugins.PluginSource, 0, len(s.cfg.PluginSettings))
srcs := 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}))
srcs = append(srcs, sources.NewUnsafeLocalSource(plugins.ClassExternal, []string{path}))
} else {
sources = append(sources, NewLocalSource(plugins.ClassExternal, []string{path}))
srcs = append(srcs, sources.NewLocalSource(plugins.ClassExternal, []string{path}))
}
}
return sources
return srcs
}
// corePluginPaths provides a list of the Core plugin file system paths
@@ -1,4 +1,4 @@
package sources
package pluginsources
import (
"context"
@@ -9,13 +9,13 @@ import (
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/plugins/config"
"github.com/grafana/grafana/pkg/plugins/manager/sources"
"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)
testdata := testDataDir(t)
cfg := &setting.Cfg{
StaticRootPath: testdata,
@@ -23,7 +23,7 @@ func TestSources_List(t *testing.T) {
pCfg := &config.PluginManagementCfg{
PluginsPath: filepath.Join(testdata, "pluginRootWithDist"),
PluginSettings: setting.PluginSettings{
PluginSettings: config.PluginSettings{
"foo": map[string]string{
"path": filepath.Join(testdata, "test-app"),
},
@@ -41,7 +41,7 @@ func TestSources_List(t *testing.T) {
require.Len(t, srcs, 5)
require.Equal(t, srcs[0].PluginClass(ctx), plugins.ClassCore)
if localSrc, ok := srcs[0].(*LocalSource); ok {
if localSrc, ok := srcs[0].(*sources.LocalSource); ok {
require.Equal(t, localSrc.Paths(), []string{
filepath.Join(testdata, "app", "plugins", "datasource"),
filepath.Join(testdata, "app", "plugins", "panel"),
@@ -56,7 +56,7 @@ func TestSources_List(t *testing.T) {
require.Equal(t, "", sig.SigningOrg)
require.Equal(t, srcs[1].PluginClass(ctx), plugins.ClassExternal)
if localSrc, ok := srcs[1].(*LocalSource); ok {
if localSrc, ok := srcs[1].(*sources.LocalSource); ok {
require.Equal(t, localSrc.Paths(), []string{
filepath.Join(testdata, "pluginRootWithDist", "datasource"),
})
@@ -68,7 +68,7 @@ func TestSources_List(t *testing.T) {
require.Equal(t, plugins.Signature{}, sig)
require.Equal(t, srcs[2].PluginClass(ctx), plugins.ClassExternal)
if localSrc, ok := srcs[2].(*LocalSource); ok {
if localSrc, ok := srcs[2].(*sources.LocalSource); ok {
require.Equal(t, localSrc.Paths(), []string{
filepath.Join(testdata, "pluginRootWithDist", "dist"),
})
@@ -80,7 +80,7 @@ func TestSources_List(t *testing.T) {
require.Equal(t, plugins.Signature{}, sig)
require.Equal(t, srcs[3].PluginClass(ctx), plugins.ClassExternal)
if localSrc, ok := srcs[3].(*LocalSource); ok {
if localSrc, ok := srcs[3].(*sources.LocalSource); ok {
require.Equal(t, localSrc.Paths(), []string{
filepath.Join(testdata, "pluginRootWithDist", "panel"),
})
@@ -93,9 +93,7 @@ func TestSources_List(t *testing.T) {
})
t.Run("Plugin sources are populated with symbolic links", func(t *testing.T) {
testdata, err := filepath.Abs("../testdata")
require.NoError(t, err)
testdata := testDataDir(t)
cfg := &setting.Cfg{
StaticRootPath: testdata,
}
@@ -113,7 +111,7 @@ func TestSources_List(t *testing.T) {
if _, exists := uris[class]; !exists {
uris[class] = map[string]struct{}{}
}
if localSrc, ok := src.(*LocalSource); ok {
if localSrc, ok := src.(*sources.LocalSource); ok {
for _, path := range localSrc.Paths() {
uris[class][path] = struct{}{}
}
@@ -130,3 +128,12 @@ func TestSources_List(t *testing.T) {
}, "should include external symlinked plugin")
})
}
func testDataDir(t *testing.T) string {
dir, err := filepath.Abs("../../../plugins/manager/testdata")
if err != nil {
t.Errorf("could not construct absolute path of current dir")
return ""
}
return dir
}
@@ -163,7 +163,7 @@ func TestIntegrationPluginManager(t *testing.T) {
td := testdatasource.ProvideService()
pg := postgres.ProvideService()
my := mysql.ProvideService()
ms := mssql.ProvideService(cfg)
ms := mssql.ProvideService()
db := db.InitTestDB(t, sqlstore.InitTestDBOpt{Cfg: cfg})
sv2 := searchV2.ProvideService(cfg, db, nil, nil, tracer, features, nil, nil, nil)
graf := grafanads.ProvideService(sv2, nil, features)
@@ -24,12 +24,12 @@ import (
"github.com/grafana/grafana/pkg/plugins/manager/registry"
"github.com/grafana/grafana/pkg/plugins/manager/signature"
"github.com/grafana/grafana/pkg/plugins/manager/signature/statickey"
"github.com/grafana/grafana/pkg/plugins/manager/sources"
"github.com/grafana/grafana/pkg/plugins/pluginassets"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/pluginsintegration/pipeline"
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginconfig"
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginerrs"
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsources"
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
"github.com/grafana/grafana/pkg/services/pluginsintegration/provisionedplugins"
"github.com/grafana/grafana/pkg/setting"
@@ -64,7 +64,7 @@ func CreateIntegrationTestCtx(t *testing.T, cfg *setting.Cfg, coreRegistry *core
Terminator: term,
})
ps, err := pluginstore.NewPluginStoreForTest(reg, l, sources.ProvideService(cfg, pCfg))
ps, err := pluginstore.NewPluginStoreForTest(reg, l, pluginsources.ProvideService(cfg, pCfg))
require.NoError(t, err)
return &IntegrationTestCtx{
+2 -1
View File
@@ -29,6 +29,7 @@ import (
"github.com/grafana/grafana/pkg/apimachinery/identity"
"github.com/grafana/grafana/pkg/apiserver/rest"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/plugins/config"
"github.com/grafana/grafana/pkg/util"
"github.com/grafana/grafana/pkg/util/osutil"
)
@@ -208,7 +209,7 @@ type Cfg struct {
// Plugins
PluginsEnableAlpha bool
PluginsAppsSkipVerifyTLS bool
PluginSettings PluginSettings
PluginSettings config.PluginSettings
PluginsAllowUnsigned []string
PluginCatalogURL string
PluginCatalogHiddenPlugins []string
+3 -5
View File
@@ -7,6 +7,7 @@ import (
"gopkg.in/ini.v1"
"github.com/grafana/grafana/pkg/plugins/config"
"github.com/grafana/grafana/pkg/util"
)
@@ -15,11 +16,8 @@ const (
PluginUpdateStrategyMinor = "minor"
)
// PluginSettings maps plugin id to map of key/value settings.
type PluginSettings map[string]map[string]string
func extractPluginSettings(sections []*ini.Section) PluginSettings {
psMap := PluginSettings{}
func extractPluginSettings(sections []*ini.Section) config.PluginSettings {
psMap := config.PluginSettings{}
for _, section := range sections {
sectionName := section.Name()
if !strings.HasPrefix(sectionName, "plugin.") {
+4 -4
View File
@@ -13,7 +13,7 @@ import (
_ "github.com/microsoft/go-mssqldb/integratedauth/krb5"
"github.com/grafana/grafana-plugin-sdk-go/backend/log"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/tsdb/mssql/sqleng"
)
@@ -22,10 +22,10 @@ type Service struct {
logger log.Logger
}
func ProvideService(cfg *setting.Cfg) *Service {
func ProvideService() *Service {
logger := backend.NewLoggerWith("logger", "tsdb.mssql")
return &Service{
im: datasource.NewInstanceManager(NewInstanceSettings(cfg, logger)),
im: datasource.NewInstanceManager(NewInstanceSettings(logger)),
logger: logger,
}
}
@@ -48,7 +48,7 @@ func (s *Service) QueryData(ctx context.Context, req *backend.QueryDataRequest)
return dsHandler.QueryData(azusercontext.WithUserFromQueryReq(ctx, req), req)
}
func NewInstanceSettings(cfg *setting.Cfg, logger log.Logger) datasource.InstanceFactoryFunc {
func NewInstanceSettings(logger log.Logger) datasource.InstanceFactoryFunc {
return func(ctx context.Context, settings backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) {
grafCfg := backend.GrafanaConfigFromContext(ctx)
sqlCfg, err := grafCfg.SQL()
+2 -3
View File
@@ -6,7 +6,7 @@ import (
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/backend/datasource"
"github.com/grafana/grafana-plugin-sdk-go/backend/log"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/tsdb/mssql"
)
@@ -20,8 +20,7 @@ func main() {
// ID). When datasource configuration changed Dispose method will be called and
// new datasource instance created using NewSampleDatasource factory.
logger := backend.NewLoggerWith("logger", "tsdb.mssql")
cfg := setting.NewCfg()
if err := datasource.Manage("mssql", mssql.NewInstanceSettings(cfg, logger), datasource.ManageOpts{}); err != nil {
if err := datasource.Manage("mssql", mssql.NewInstanceSettings(logger), datasource.ManageOpts{}); err != nil {
log.DefaultLogger.Error(err.Error())
os.Exit(1)
}
+1 -6
View File
@@ -8,6 +8,7 @@ import (
"strings"
claims "github.com/grafana/authlib/types"
"github.com/grafana/grafana/pkg/apimachinery/identity"
)
@@ -91,12 +92,6 @@ func ClearCookieHeader(req *http.Request, keepCookiesNames []string, skipCookies
}
}
// SetProxyResponseHeaders sets proxy response headers.
// Sets Content-Security-Policy: sandbox
func SetProxyResponseHeaders(header http.Header) {
header.Set("Content-Security-Policy", "sandbox")
}
// SetViaHeader adds Grafana's reverse proxy to the proxy chain.
// Defined in RFC 9110 7.6.3 https://datatracker.ietf.org/doc/html/rfc9110#name-via
func SetViaHeader(header http.Header, major, minor int) {
+2 -1
View File
@@ -11,6 +11,7 @@ import (
glog "github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/middleware/requestmeta"
"github.com/grafana/grafana/pkg/plugins/manager/client"
"github.com/grafana/grafana/pkg/services/contexthandler"
)
@@ -102,7 +103,7 @@ func modifyResponse(logger glog.Logger) func(resp *http.Response) error {
resp.Header.Del(header)
}
SetProxyResponseHeaders(resp.Header)
client.SetCSPHeader(resp.Header)
SetViaHeader(resp.Header, resp.ProtoMajor, resp.ProtoMinor)
requestmeta.WithStatusSource(resp.Request.Context(), resp.StatusCode)