Plugins: Remove pkg/tsdb/* as dependency (#115886)

* remove deps

* singular

* add rest

* make update-workspace

* undo go.mod changes
This commit is contained in:
Will Browne
2026-01-07 11:28:25 +00:00
committed by GitHub
parent 0bfcc55411
commit ec55871b9b
9 changed files with 20 additions and 23 deletions
@@ -0,0 +1,279 @@
package coreplugin
import (
"context"
"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/pkg/plugins"
"github.com/grafana/grafana/pkg/plugins/backendplugin"
"github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin"
"github.com/grafana/grafana/pkg/plugins/backendplugin/provider"
"github.com/grafana/grafana/pkg/plugins/log"
"github.com/grafana/grafana/pkg/tsdb/azuremonitor"
cloudmonitoring "github.com/grafana/grafana/pkg/tsdb/cloud-monitoring"
"github.com/grafana/grafana/pkg/tsdb/cloudwatch"
"github.com/grafana/grafana/pkg/tsdb/elasticsearch"
postgres "github.com/grafana/grafana/pkg/tsdb/grafana-postgresql-datasource"
pyroscope "github.com/grafana/grafana/pkg/tsdb/grafana-pyroscope-datasource"
testdatasource "github.com/grafana/grafana/pkg/tsdb/grafana-testdata-datasource"
"github.com/grafana/grafana/pkg/tsdb/grafanads"
"github.com/grafana/grafana/pkg/tsdb/graphite"
"github.com/grafana/grafana/pkg/tsdb/influxdb"
"github.com/grafana/grafana/pkg/tsdb/jaeger"
"github.com/grafana/grafana/pkg/tsdb/loki"
"github.com/grafana/grafana/pkg/tsdb/mssql"
"github.com/grafana/grafana/pkg/tsdb/mysql"
"github.com/grafana/grafana/pkg/tsdb/opentsdb"
"github.com/grafana/grafana/pkg/tsdb/parca"
"github.com/grafana/grafana/pkg/tsdb/prometheus"
"github.com/grafana/grafana/pkg/tsdb/tempo"
"github.com/grafana/grafana/pkg/tsdb/zipkin"
)
const (
CloudWatch = "cloudwatch"
CloudMonitoring = "stackdriver"
AzureMonitor = "grafana-azure-monitor-datasource"
Elasticsearch = "elasticsearch"
Graphite = "graphite"
InfluxDB = "influxdb"
Loki = "loki"
OpenTSDB = "opentsdb"
Prometheus = "prometheus"
Tempo = "tempo"
TestData = "grafana-testdata-datasource"
TestDataAlias = "testdata"
PostgreSQL = "grafana-postgresql-datasource"
MySQL = "mysql"
MSSQL = "mssql"
Grafana = "grafana"
Pyroscope = "grafana-pyroscope-datasource"
Parca = "parca"
Zipkin = "zipkin"
Jaeger = "jaeger"
)
func init() {
// Non-optimal global solution to replace plugin SDK default loggers for core plugins.
sdklog.DefaultLogger = &logWrapper{logger: log.New("plugin.coreplugin")}
backend.Logger = sdklog.DefaultLogger
backend.NewLoggerWith = func(args ...any) sdklog.Logger {
for i, arg := range args {
// Obtain logger name from args.
if s, ok := arg.(string); ok && s == "logger" {
l := &logWrapper{logger: log.New(args[i+1].(string))}
// new args slice without logger name and logger name value
if len(args) > 2 {
newArgs := make([]any, 0, len(args)-2)
newArgs = append(newArgs, args[:i]...)
newArgs = append(newArgs, args[i+2:]...)
return l.With(newArgs...)
}
return l
}
}
return sdklog.DefaultLogger
}
}
type Registry struct {
store map[string]backendplugin.PluginFactoryFunc
}
func NewRegistry(store map[string]backendplugin.PluginFactoryFunc) *Registry {
return &Registry{
store: store,
}
}
func ProvideCoreProvider(coreRegistry *Registry) plugins.BackendFactoryProvider {
return provider.New(coreRegistry.BackendFactoryProvider(), provider.DefaultProvider)
}
func ProvideCoreRegistry(tracer trace.Tracer, am *azuremonitor.Service, cw *cloudwatch.Service, cm *cloudmonitoring.Service,
es *elasticsearch.Service, grap *graphite.Service, idb *influxdb.Service, lk *loki.Service, otsdb *opentsdb.Service,
pr *prometheus.Service, t *tempo.Service, td *testdatasource.Service, pg *postgres.Service, my *mysql.Service,
ms *mssql.Service, graf *grafanads.Service, pyroscope *pyroscope.Service, parca *parca.Service, zipkin *zipkin.Service, jaeger *jaeger.Service) *Registry {
// Non-optimal global solution to replace plugin SDK default tracer for core plugins.
sdktracing.InitDefaultTracer(tracer)
return NewRegistry(map[string]backendplugin.PluginFactoryFunc{
CloudWatch: asBackendPlugin(cw),
CloudMonitoring: asBackendPlugin(cm),
AzureMonitor: asBackendPlugin(am),
Elasticsearch: asBackendPlugin(es),
Graphite: asBackendPlugin(grap),
InfluxDB: asBackendPlugin(idb),
Loki: asBackendPlugin(lk),
OpenTSDB: asBackendPlugin(otsdb),
Prometheus: asBackendPlugin(pr),
Tempo: asBackendPlugin(t),
TestData: asBackendPlugin(td),
PostgreSQL: asBackendPlugin(pg),
MySQL: asBackendPlugin(my),
MSSQL: asBackendPlugin(ms),
Grafana: asBackendPlugin(graf),
Pyroscope: asBackendPlugin(pyroscope),
Parca: asBackendPlugin(parca),
Zipkin: asBackendPlugin(zipkin),
Jaeger: asBackendPlugin(jaeger),
})
}
func (cr *Registry) Get(pluginID string) backendplugin.PluginFactoryFunc {
return cr.store[pluginID]
}
func (cr *Registry) BackendFactoryProvider() func(_ context.Context, p *plugins.Plugin) backendplugin.PluginFactoryFunc {
return func(_ context.Context, p *plugins.Plugin) backendplugin.PluginFactoryFunc {
if !p.IsCorePlugin() {
return nil
}
return cr.Get(p.ID)
}
}
func asBackendPlugin(svc any) backendplugin.PluginFactoryFunc {
opts := backend.ServeOpts{}
if queryHandler, ok := svc.(backend.QueryDataHandler); ok {
opts.QueryDataHandler = queryHandler
}
if resourceHandler, ok := svc.(backend.CallResourceHandler); ok {
opts.CallResourceHandler = resourceHandler
}
if streamHandler, ok := svc.(backend.StreamHandler); ok {
opts.StreamHandler = streamHandler
}
if healthHandler, ok := svc.(backend.CheckHealthHandler); ok {
opts.CheckHealthHandler = healthHandler
}
if storageHandler, ok := svc.(backend.AdmissionHandler); ok {
opts.AdmissionHandler = storageHandler
}
if opts.QueryDataHandler != nil || opts.CallResourceHandler != nil ||
opts.CheckHealthHandler != nil || opts.StreamHandler != nil {
return coreplugin.New(opts)
}
return nil
}
type logWrapper struct {
logger log.Logger
}
func (l *logWrapper) Debug(msg string, args ...any) {
l.logger.Debug(msg, args...)
}
func (l *logWrapper) Info(msg string, args ...any) {
l.logger.Info(msg, args...)
}
func (l *logWrapper) Warn(msg string, args ...any) {
l.logger.Warn(msg, args...)
}
func (l *logWrapper) Error(msg string, args ...any) {
l.logger.Error(msg, args...)
}
func (l *logWrapper) Level() sdklog.Level {
return sdklog.NoLevel
}
func (l *logWrapper) With(args ...any) sdklog.Logger {
return &logWrapper{
logger: l.logger.New(args...),
}
}
func (l *logWrapper) FromContext(ctx context.Context) sdklog.Logger {
return &logWrapper{
logger: l.logger.FromContext(ctx),
}
}
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, httpClientProvider *httpclient.Provider, tracer trace.Tracer) (*plugins.Plugin, error) {
jsonData := plugins.JSONData{
ID: pluginID,
AliasIDs: []string{},
}
var svc any
switch pluginID {
case TestData, TestDataAlias:
jsonData.ID = TestData
jsonData.AliasIDs = append(jsonData.AliasIDs, TestDataAlias)
svc = testdatasource.ProvideService()
case CloudWatch:
svc = cloudwatch.ProvideService()
case CloudMonitoring:
svc = cloudmonitoring.ProvideService(httpClientProvider)
case AzureMonitor:
svc = azuremonitor.ProvideService(httpClientProvider)
case Elasticsearch:
svc = elasticsearch.ProvideService(httpClientProvider)
case Graphite:
svc = graphite.ProvideService(httpClientProvider, tracer)
case InfluxDB:
svc = influxdb.ProvideService(httpClientProvider)
case Loki:
svc = loki.ProvideService(httpClientProvider, tracer)
case OpenTSDB:
svc = opentsdb.ProvideService(httpClientProvider)
case Prometheus:
svc = prometheus.ProvideService(httpClientProvider)
case Tempo:
svc = tempo.ProvideService(httpClientProvider, tracer)
case PostgreSQL:
svc = postgres.ProvideService()
case MySQL:
svc = mysql.ProvideService()
case MSSQL:
svc = mssql.ProvideService()
case Pyroscope:
svc = pyroscope.ProvideService(httpClientProvider)
case Parca:
svc = parca.ProvideService(httpClientProvider)
case Zipkin:
svc = zipkin.ProvideService(httpClientProvider)
case Jaeger:
svc = jaeger.ProvideService(httpClientProvider)
default:
return nil, ErrCorePluginNotFound
}
p := plugins.Plugin{
JSONData: jsonData,
Class: plugins.ClassCore,
}
p.SetLogger(log.New(fmt.Sprintf("plugin.%s", p.ID)))
backendFactory := asBackendPlugin(svc)
if backendFactory == nil {
return nil, ErrCorePluginNotFound
}
bp, err := backendFactory(p.ID, p.Logger(), tracer, nil)
if err != nil {
return nil, err
}
p.RegisterClient(bp)
return &p, nil
}
@@ -0,0 +1,76 @@
package coreplugin
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"
)
func TestNewPlugin(t *testing.T) {
tcs := []struct {
ID string
ExpectedID string
ExpectedAlias string
ExpectedNotFoundErr bool
}{
{ID: AzureMonitor},
{ID: CloudMonitoring},
{ID: CloudWatch},
{ID: Elasticsearch},
{ID: Grafana, ExpectedNotFoundErr: true},
{ID: Graphite},
{ID: InfluxDB},
{ID: Loki},
{ID: MSSQL},
{ID: MySQL},
{ID: OpenTSDB},
{ID: Parca},
{ID: PostgreSQL},
{ID: Prometheus},
{ID: Pyroscope},
{ID: Tempo},
{ID: TestData, ExpectedAlias: TestDataAlias},
{ID: TestDataAlias, ExpectedID: TestData, ExpectedAlias: TestDataAlias},
{ID: Zipkin},
{ID: Jaeger},
}
for _, tc := range tcs {
t.Run(tc.ID, func(t *testing.T) {
if tc.ExpectedID == "" {
tc.ExpectedID = tc.ID
}
p, err := NewPlugin(tc.ID, httpclient.NewProvider(), tracing.NoopTracer())
if tc.ExpectedNotFoundErr {
require.ErrorIs(t, err, ErrCorePluginNotFound)
require.Nil(t, p)
} else {
require.NoError(t, err)
require.NotNil(t, p)
require.Equal(t, tc.ExpectedID, p.ID)
if tc.ExpectedAlias != "" {
require.Equal(t, tc.ExpectedAlias, p.AliasIDs[0])
}
c, exists := p.Client()
require.True(t, exists)
require.NotNil(t, c)
}
})
}
}
func TestLogger(t *testing.T) {
t.Run("logger.With should create a new logger", func(t *testing.T) {
wrapper := &logWrapper{
logger: log.New("test"),
}
newLogger := wrapper.With("key", "value")
require.NotSame(t, newLogger.(*logWrapper).logger, wrapper.logger, "`With` should not return the same instance")
})
}
@@ -6,7 +6,6 @@ import (
"github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/plugins/auth"
"github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin"
"github.com/grafana/grafana/pkg/plugins/config"
"github.com/grafana/grafana/pkg/plugins/envvars"
"github.com/grafana/grafana/pkg/plugins/manager/loader/angular/angularinspector"
@@ -19,6 +18,7 @@ import (
"github.com/grafana/grafana/pkg/plugins/manager/registry"
"github.com/grafana/grafana/pkg/plugins/manager/signature"
"github.com/grafana/grafana/pkg/plugins/pluginassets"
"github.com/grafana/grafana/pkg/services/pluginsintegration/coreplugin"
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginaccesscontrol"
"github.com/grafana/grafana/pkg/services/pluginsintegration/provisionedplugins"
)
@@ -10,8 +10,6 @@ import (
"github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/plugins/auth"
"github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin"
"github.com/grafana/grafana/pkg/plugins/backendplugin/provider"
"github.com/grafana/grafana/pkg/plugins/envvars"
"github.com/grafana/grafana/pkg/plugins/log"
"github.com/grafana/grafana/pkg/plugins/manager/client"
@@ -39,6 +37,7 @@ import (
"github.com/grafana/grafana/pkg/services/pluginsintegration/angularinspector"
"github.com/grafana/grafana/pkg/services/pluginsintegration/angularpatternsstore"
"github.com/grafana/grafana/pkg/services/pluginsintegration/clientmiddleware"
"github.com/grafana/grafana/pkg/services/pluginsintegration/coreplugin"
"github.com/grafana/grafana/pkg/services/pluginsintegration/installsync"
"github.com/grafana/grafana/pkg/services/pluginsintegration/keyretriever"
"github.com/grafana/grafana/pkg/services/pluginsintegration/keyretriever/dynamic"
@@ -146,8 +145,7 @@ var WireSet = wire.NewSet(
// WireExtensionSet provides a wire.ProviderSet of plugin providers that can be
// extended.
var WireExtensionSet = wire.NewSet(
provider.ProvideService,
wire.Bind(new(plugins.BackendFactoryProvider), new(*provider.Service)),
coreplugin.ProvideCoreProvider,
signature.ProvideOSSAuthorizer,
wire.Bind(new(plugins.PluginLoaderAuthorizer), new(*signature.UnsignedPluginAuthorizer)),
ProvideClientWithMiddlewares,
@@ -19,10 +19,10 @@ import (
"github.com/grafana/grafana/pkg/infra/fs"
"github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/pluginsintegration"
"github.com/grafana/grafana/pkg/services/pluginsintegration/coreplugin"
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
"github.com/grafana/grafana/pkg/services/searchV2"
"github.com/grafana/grafana/pkg/services/sqlstore"
@@ -8,8 +8,6 @@ import (
"github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/plugins/backendplugin"
"github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin"
"github.com/grafana/grafana/pkg/plugins/backendplugin/provider"
pluginsCfg "github.com/grafana/grafana/pkg/plugins/config"
"github.com/grafana/grafana/pkg/plugins/manager/client"
"github.com/grafana/grafana/pkg/plugins/manager/loader"
@@ -27,6 +25,7 @@ import (
"github.com/grafana/grafana/pkg/plugins/pluginassets"
"github.com/grafana/grafana/pkg/plugins/pluginerrs"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/pluginsintegration/coreplugin"
"github.com/grafana/grafana/pkg/services/pluginsintegration/pipeline"
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginconfig"
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsources"
@@ -52,7 +51,7 @@ func CreateIntegrationTestCtx(t *testing.T, cfg *setting.Cfg, coreRegistry *core
disc := pipeline.ProvideDiscoveryStage(pCfg, reg)
boot := pipeline.ProvideBootstrapStage(pCfg, signature.ProvideService(pCfg, statickey.New()), pluginassets.NewLocalProvider())
valid := pipeline.ProvideValidationStage(pCfg, signature.NewValidator(signature.NewUnsignedAuthorizer(pCfg)), angularInspector)
init := pipeline.ProvideInitializationStage(pCfg, reg, provider.ProvideService(coreRegistry), proc, &pluginfakes.FakeAuthService{}, pluginfakes.NewFakeRoleRegistry(), pluginfakes.NewFakeActionSetRegistry(), nil, tracing.InitializeTracerForTest(), provisionedplugins.NewNoop())
init := pipeline.ProvideInitializationStage(pCfg, reg, coreplugin.ProvideCoreProvider(coreRegistry), proc, &pluginfakes.FakeAuthService{}, pluginfakes.NewFakeRoleRegistry(), pluginfakes.NewFakeActionSetRegistry(), nil, tracing.InitializeTracerForTest(), provisionedplugins.NewNoop())
term, err := pipeline.ProvideTerminationStage(pCfg, reg, proc)
require.NoError(t, err)
@@ -98,7 +97,7 @@ func CreateTestLoader(t *testing.T, cfg *pluginsCfg.PluginManagementCfg, opts Lo
if opts.Initializer == nil {
reg := registry.ProvideService()
coreRegistry := coreplugin.NewRegistry(make(map[string]backendplugin.PluginFactoryFunc))
opts.Initializer = pipeline.ProvideInitializationStage(cfg, reg, provider.ProvideService(coreRegistry), process.ProvideService(), &pluginfakes.FakeAuthService{}, pluginfakes.NewFakeRoleRegistry(), pluginfakes.NewFakeActionSetRegistry(), nil, tracing.InitializeTracerForTest(), provisionedplugins.NewNoop())
opts.Initializer = pipeline.ProvideInitializationStage(cfg, reg, coreplugin.ProvideCoreProvider(coreRegistry), process.ProvideService(), &pluginfakes.FakeAuthService{}, pluginfakes.NewFakeRoleRegistry(), pluginfakes.NewFakeActionSetRegistry(), nil, tracing.InitializeTracerForTest(), provisionedplugins.NewNoop())
}
if opts.Terminator == nil {