diff --git a/pkg/plugins/backendplugin/coreplugin/registry.go b/pkg/plugins/backendplugin/coreplugin/registry.go new file mode 100644 index 00000000000..8b4fe4e802b --- /dev/null +++ b/pkg/plugins/backendplugin/coreplugin/registry.go @@ -0,0 +1,100 @@ +package coreplugin + +import ( + "github.com/grafana/grafana-plugin-sdk-go/backend" + + "github.com/grafana/grafana/pkg/plugins/backendplugin" + "github.com/grafana/grafana/pkg/tsdb/azuremonitor" + "github.com/grafana/grafana/pkg/tsdb/cloudmonitoring" + "github.com/grafana/grafana/pkg/tsdb/cloudwatch" + "github.com/grafana/grafana/pkg/tsdb/elasticsearch" + "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/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/postgres" + "github.com/grafana/grafana/pkg/tsdb/prometheus" + "github.com/grafana/grafana/pkg/tsdb/tempo" + "github.com/grafana/grafana/pkg/tsdb/testdatasource" +) + +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 = "testdata" + PostgreSQL = "postgres" + MySQL = "mysql" + MSSQL = "mssql" + Grafana = "grafana" +) + +type Registry struct { + store map[string]backendplugin.PluginFactoryFunc +} + +func NewRegistry(store map[string]backendplugin.PluginFactoryFunc) *Registry { + return &Registry{ + store: store, + } +} + +func ProvideCoreRegistry(am *azuremonitor.Service, cw *cloudwatch.CloudWatchService, 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) *Registry { + return NewRegistry(map[string]backendplugin.PluginFactoryFunc{ + CloudWatch: asBackendPlugin(cw.Executor), + 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), + }) +} + +func (cr *Registry) Get(pluginID string) backendplugin.PluginFactoryFunc { + return cr.store[pluginID] +} + +func asBackendPlugin(svc interface{}) 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 opts.QueryDataHandler != nil || opts.CallResourceHandler != nil || + opts.CheckHealthHandler != nil || opts.StreamHandler != nil { + return New(opts) + } + + return nil +} diff --git a/pkg/plugins/backendplugin/provider/provider.go b/pkg/plugins/backendplugin/provider/provider.go index eb01d8a9063..53047c91374 100644 --- a/pkg/plugins/backendplugin/provider/provider.go +++ b/pkg/plugins/backendplugin/provider/provider.go @@ -7,18 +7,23 @@ import ( "github.com/grafana/grafana/pkg/infra/log" "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/grpcplugin" "github.com/grafana/grafana/pkg/plugins/backendplugin/pluginextensionv2" ) -type Service struct{} - -func ProvideService() *Service { - return &Service{} +type Service struct { + coreRegistry *coreplugin.Registry } -func (*Service) BackendFactory(ctx context.Context, p *plugins.Plugin) backendplugin.PluginFactoryFunc { - for _, provider := range []PluginBackendProvider{RendererProvider, DefaultProvider} { +func ProvideService(coreRegistry *coreplugin.Registry) *Service { + return &Service{ + coreRegistry: coreRegistry, + } +} + +func (s *Service) BackendFactory(ctx context.Context, p *plugins.Plugin) backendplugin.PluginFactoryFunc { + for _, provider := range []PluginBackendProvider{CorePluginProvider(ctx, s.coreRegistry), RendererProvider, DefaultProvider} { if factory := provider(ctx, p); factory != nil { return factory } @@ -43,6 +48,17 @@ var RendererProvider PluginBackendProvider = func(_ context.Context, p *plugins. } var DefaultProvider PluginBackendProvider = func(_ context.Context, p *plugins.Plugin) backendplugin.PluginFactoryFunc { + // TODO check for executable cmd := plugins.ComposePluginStartCommand(p.Executable) return grpcplugin.NewBackendPlugin(p.ID, filepath.Join(p.PluginDir, cmd)) } + +var CorePluginProvider = func(ctx context.Context, registry *coreplugin.Registry) PluginBackendProvider { + return func(_ context.Context, p *plugins.Plugin) backendplugin.PluginFactoryFunc { + if !p.IsCorePlugin() { + return nil + } + + return registry.Get(p.ID) + } +} diff --git a/pkg/plugins/manager/loader/loader_test.go b/pkg/plugins/manager/loader/loader_test.go index 13c401304f0..9c069a3ce93 100644 --- a/pkg/plugins/manager/loader/loader_test.go +++ b/pkg/plugins/manager/loader/loader_test.go @@ -15,6 +15,8 @@ import ( "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/models" "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/manager/loader/finder" "github.com/grafana/grafana/pkg/plugins/manager/loader/initializer" @@ -904,7 +906,7 @@ func newLoader(cfg *plugins.Cfg) *Loader { return &Loader{ cfg: cfg, pluginFinder: finder.New(), - pluginInitializer: initializer.New(cfg, &provider.Service{}, &fakeLicensingService{}), + pluginInitializer: initializer.New(cfg, provider.ProvideService(coreplugin.NewRegistry(make(map[string]backendplugin.PluginFactoryFunc))), &fakeLicensingService{}), signatureValidator: signature.NewValidator(&signature.UnsignedPluginAuthorizer{Cfg: cfg}), errs: make(map[string]*plugins.SignatureError), log: &fakeLogger{}, diff --git a/pkg/plugins/manager/manager.go b/pkg/plugins/manager/manager.go index 56ad6186bc0..459f037171b 100644 --- a/pkg/plugins/manager/manager.go +++ b/pkg/plugins/manager/manager.go @@ -471,17 +471,10 @@ func (m *PluginManager) shutdown(ctx context.Context) { // corePluginPaths provides a list of the Core plugin paths which need to be scanned on init() func corePluginPaths(cfg *setting.Cfg) []string { - datasourcePaths := []string{ - filepath.Join(cfg.StaticRootPath, "app/plugins/datasource/alertmanager"), - filepath.Join(cfg.StaticRootPath, "app/plugins/datasource/dashboard"), - filepath.Join(cfg.StaticRootPath, "app/plugins/datasource/jaeger"), - filepath.Join(cfg.StaticRootPath, "app/plugins/datasource/mixed"), - filepath.Join(cfg.StaticRootPath, "app/plugins/datasource/zipkin"), - } - + datasourcePaths := filepath.Join(cfg.StaticRootPath, "app/plugins/datasource") panelsPath := filepath.Join(cfg.StaticRootPath, "app/plugins/panel") - return append(datasourcePaths, panelsPath) + return []string{datasourcePaths, panelsPath} } // pluginSettingPaths provides a plugin paths defined in cfg.PluginSettings which need to be scanned on init() diff --git a/pkg/plugins/manager/manager_integration_test.go b/pkg/plugins/manager/manager_integration_test.go index 82d2f559958..e421b163da7 100644 --- a/pkg/plugins/manager/manager_integration_test.go +++ b/pkg/plugins/manager/manager_integration_test.go @@ -2,16 +2,38 @@ package manager import ( "context" + "net/http" "path/filepath" "strings" "testing" + "github.com/grafana/grafana/pkg/infra/tracing" + "go.opentelemetry.io/otel/trace" + + "github.com/grafana/grafana-plugin-sdk-go/backend/httpclient" + "github.com/grafana/grafana/pkg/plugins" + "github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin" "github.com/grafana/grafana/pkg/plugins/backendplugin/provider" "github.com/grafana/grafana/pkg/plugins/manager/loader" "github.com/grafana/grafana/pkg/plugins/manager/signature" "github.com/grafana/grafana/pkg/services/licensing" "github.com/grafana/grafana/pkg/setting" + "github.com/grafana/grafana/pkg/tsdb/azuremonitor" + "github.com/grafana/grafana/pkg/tsdb/cloudmonitoring" + "github.com/grafana/grafana/pkg/tsdb/cloudwatch" + "github.com/grafana/grafana/pkg/tsdb/elasticsearch" + "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/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/postgres" + "github.com/grafana/grafana/pkg/tsdb/prometheus" + "github.com/grafana/grafana/pkg/tsdb/tempo" + "github.com/grafana/grafana/pkg/tsdb/testdatasource" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -40,13 +62,34 @@ func TestPluginManager_int_init(t *testing.T) { }, } + tracer := &fakeTracer{} + license := &licensing.OSSLicensingService{ Cfg: cfg, } + hcp := httpclient.NewProvider() + am := azuremonitor.ProvideService(cfg, hcp, tracer) + cw := cloudwatch.ProvideService(cfg, hcp) + cm := cloudmonitoring.ProvideService(hcp, tracer) + es := elasticsearch.ProvideService(hcp) + grap := graphite.ProvideService(hcp, tracer) + idb := influxdb.ProvideService(hcp) + lk := loki.ProvideService(hcp, tracer) + otsdb := opentsdb.ProvideService(hcp) + pr := prometheus.ProvideService(hcp, tracer) + tmpo := tempo.ProvideService(hcp) + td := testdatasource.ProvideService(cfg) + pg := postgres.ProvideService(cfg) + my := mysql.ProvideService(cfg, hcp) + ms := mssql.ProvideService(cfg) + graf := grafanads.ProvideService(cfg) + + coreRegistry := coreplugin.ProvideCoreRegistry(am, cw, cm, es, grap, idb, lk, otsdb, pr, tmpo, td, pg, my, ms, graf) + pmCfg := plugins.FromGrafanaCfg(cfg) pm, err := ProvideService(cfg, nil, loader.New(pmCfg, license, - &signature.UnsignedPluginAuthorizer{Cfg: pmCfg}, &provider.Service{}), nil) + &signature.UnsignedPluginAuthorizer{Cfg: pmCfg}, provider.ProvideService(coreRegistry)), nil) require.NoError(t, err) verifyCorePluginCatalogue(t, pm) @@ -92,12 +135,27 @@ func verifyCorePluginCatalogue(t *testing.T, pm *PluginManager) { } expDataSources := map[string]struct{}{ - "alertmanager": {}, - "dashboard": {}, - "input": {}, - "jaeger": {}, - "mixed": {}, - "zipkin": {}, + "cloudwatch": {}, + "stackdriver": {}, + "grafana-azure-monitor-datasource": {}, + "elasticsearch": {}, + "graphite": {}, + "influxdb": {}, + "loki": {}, + "opentsdb": {}, + "prometheus": {}, + "tempo": {}, + "testdata": {}, + "postgres": {}, + "mysql": {}, + "mssql": {}, + "grafana": {}, + "alertmanager": {}, + "dashboard": {}, + "input": {}, + "jaeger": {}, + "mixed": {}, + "zipkin": {}, } expApps := map[string]struct{}{ @@ -177,3 +235,19 @@ func verifyPluginStaticRoutes(t *testing.T, pm *PluginManager) { assert.Contains(t, routes, "test-app") assert.Equal(t, routes["test-app"].Directory, testAppPlugin.PluginDir) } + +type fakeTracer struct { + tracing.Tracer +} + +func (ft *fakeTracer) Run(context.Context) error { + return nil +} + +func (ft *fakeTracer) Start(ctx context.Context, _ string, _ ...trace.SpanStartOption) (context.Context, tracing.Span) { + return ctx, nil +} + +func (ft *fakeTracer) Inject(context.Context, http.Header, tracing.Span) { + +} diff --git a/pkg/server/backgroundsvcs/background_services.go b/pkg/server/backgroundsvcs/background_services.go index ce3496a6f33..b25d0292941 100644 --- a/pkg/server/backgroundsvcs/background_services.go +++ b/pkg/server/backgroundsvcs/background_services.go @@ -23,21 +23,6 @@ import ( secretsManager "github.com/grafana/grafana/pkg/services/secrets/manager" "github.com/grafana/grafana/pkg/services/serviceaccounts" "github.com/grafana/grafana/pkg/services/updatechecker" - "github.com/grafana/grafana/pkg/tsdb/azuremonitor" - "github.com/grafana/grafana/pkg/tsdb/cloudmonitoring" - "github.com/grafana/grafana/pkg/tsdb/cloudwatch" - "github.com/grafana/grafana/pkg/tsdb/elasticsearch" - "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/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/postgres" - "github.com/grafana/grafana/pkg/tsdb/prometheus" - "github.com/grafana/grafana/pkg/tsdb/tempo" - "github.com/grafana/grafana/pkg/tsdb/testdatasource" ) func ProvideBackgroundServiceRegistry( @@ -48,11 +33,8 @@ func ProvideBackgroundServiceRegistry( metrics *metrics.InternalMetricsService, usageStats *uss.UsageStats, updateChecker *updatechecker.Service, tracing tracing.Tracer, remoteCache *remotecache.RemoteCache, secretsService *secretsManager.SecretsService, // Need to make sure these are initialized, is there a better place to put them? - _ *azuremonitor.Service, _ *cloudwatch.CloudWatchService, _ *elasticsearch.Service, _ *graphite.Service, - _ *influxdb.Service, _ *loki.Service, _ *opentsdb.Service, _ *prometheus.Service, _ *tempo.Service, - _ *testdatasource.Service, _ *plugindashboards.Service, _ *dashboardsnapshots.Service, - _ *postgres.Service, _ *mysql.Service, _ *mssql.Service, _ *grafanads.Service, _ *cloudmonitoring.Service, - _ *pluginsettings.Service, _ *alerting.AlertNotificationService, _ serviceaccounts.Service, + _ *plugindashboards.Service, _ *dashboardsnapshots.Service, _ *pluginsettings.Service, + _ *alerting.AlertNotificationService, _ serviceaccounts.Service, ) *BackgroundServiceRegistry { return NewBackgroundServiceRegistry( httpServer, diff --git a/pkg/server/wire.go b/pkg/server/wire.go index 47b26a2dfd7..986e78fb74b 100644 --- a/pkg/server/wire.go +++ b/pkg/server/wire.go @@ -23,6 +23,7 @@ import ( "github.com/grafana/grafana/pkg/login/social" "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/plugins" + "github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin" "github.com/grafana/grafana/pkg/plugins/manager" "github.com/grafana/grafana/pkg/plugins/manager/loader" "github.com/grafana/grafana/pkg/plugins/plugincontext" @@ -112,6 +113,7 @@ var wireBasicSet = wire.NewSet( wire.Bind(new(plugins.StaticRouteResolver), new(*manager.PluginManager)), wire.Bind(new(plugins.PluginDashboardManager), new(*manager.PluginManager)), wire.Bind(new(plugins.RendererManager), new(*manager.PluginManager)), + coreplugin.ProvideCoreRegistry, loader.ProvideService, wire.Bind(new(plugins.Loader), new(*loader.Loader)), wire.Bind(new(plugins.ErrorResolver), new(*loader.Loader)), diff --git a/pkg/tsdb/azuremonitor/azuremonitor-resource-handler.go b/pkg/tsdb/azuremonitor/azuremonitor-resource-handler.go index 838fa2126f5..92ee30ec8cb 100644 --- a/pkg/tsdb/azuremonitor/azuremonitor-resource-handler.go +++ b/pkg/tsdb/azuremonitor/azuremonitor-resource-handler.go @@ -85,7 +85,7 @@ func writeResponse(rw http.ResponseWriter, code int, msg string) { } } -func (s *Service) resourceHandler(subDataSource string) func(rw http.ResponseWriter, req *http.Request) { +func (s *Service) handleResourceReq(subDataSource string) func(rw http.ResponseWriter, req *http.Request) { return func(rw http.ResponseWriter, req *http.Request) { azlog.Debug("Received resource call", "url", req.URL.String(), "method", req.Method) @@ -115,11 +115,13 @@ func (s *Service) resourceHandler(subDataSource string) func(rw http.ResponseWri } } -// registerRoutes provides route definitions shared with the frontend. +// newResourceMux provides route definitions shared with the frontend. // Check: /public/app/plugins/datasource/grafana-azure-monitor-datasource/utils/common.ts -func (s *Service) registerRoutes(mux *http.ServeMux) { - mux.HandleFunc("/azuremonitor/", s.resourceHandler(azureMonitor)) - mux.HandleFunc("/appinsights/", s.resourceHandler(appInsights)) - mux.HandleFunc("/loganalytics/", s.resourceHandler(azureLogAnalytics)) - mux.HandleFunc("/resourcegraph/", s.resourceHandler(azureResourceGraph)) +func (s *Service) newResourceMux() *http.ServeMux { + mux := http.NewServeMux() + mux.HandleFunc("/azuremonitor/", s.handleResourceReq(azureMonitor)) + mux.HandleFunc("/appinsights/", s.handleResourceReq(appInsights)) + mux.HandleFunc("/loganalytics/", s.handleResourceReq(azureLogAnalytics)) + mux.HandleFunc("/resourcegraph/", s.handleResourceReq(azureResourceGraph)) + return mux } diff --git a/pkg/tsdb/azuremonitor/azuremonitor-resource-handler_test.go b/pkg/tsdb/azuremonitor/azuremonitor-resource-handler_test.go index 081d24fcbaf..849bb3c9981 100644 --- a/pkg/tsdb/azuremonitor/azuremonitor-resource-handler_test.go +++ b/pkg/tsdb/azuremonitor/azuremonitor-resource-handler_test.go @@ -91,7 +91,7 @@ func (s *fakeProxy) Do(rw http.ResponseWriter, req *http.Request, cli *http.Clie return nil } -func Test_resourceHandler(t *testing.T) { +func Test_handleResourceReq(t *testing.T) { proxy := &fakeProxy{} s := Service{ im: &fakeInstance{ @@ -102,7 +102,6 @@ func Test_resourceHandler(t *testing.T) { }, }, }, - Cfg: &setting.Cfg{}, executors: map[string]azDatasourceExecutor{ azureMonitor: &AzureMonitorDatasource{ proxy: proxy, @@ -114,7 +113,7 @@ func Test_resourceHandler(t *testing.T) { if err != nil { t.Fatalf("Unexpected error %v", err) } - s.resourceHandler(azureMonitor)(rw, req) + s.handleResourceReq(azureMonitor)(rw, req) expectedURL := "https://management.azure.com/subscriptions/44693801" if proxy.requestedURL != expectedURL { t.Errorf("Unexpected result URL. Got %s, expecting %s", proxy.requestedURL, expectedURL) diff --git a/pkg/tsdb/azuremonitor/azuremonitor.go b/pkg/tsdb/azuremonitor/azuremonitor.go index cc82c32210f..b40ecda8695 100644 --- a/pkg/tsdb/azuremonitor/azuremonitor.go +++ b/pkg/tsdb/azuremonitor/azuremonitor.go @@ -12,18 +12,16 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/backend/httpclient" "github.com/grafana/grafana-plugin-sdk-go/backend/instancemgmt" "github.com/grafana/grafana-plugin-sdk-go/backend/resource/httpadapter" + "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/infra/log" "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/setting" "github.com/grafana/grafana/pkg/tsdb/azuremonitor/azcredentials" ) const ( timeSeries = "time_series" - pluginID = "grafana-azure-monitor-datasource" ) var ( @@ -31,7 +29,7 @@ var ( legendKeyFormat = regexp.MustCompile(`\{\{\s*(.+?)\s*\}\}`) ) -func ProvideService(cfg *setting.Cfg, httpClientProvider *httpclient.Provider, pluginStore plugins.Store, tracer tracing.Tracer) *Service { +func ProvideService(cfg *setting.Cfg, httpClientProvider *httpclient.Provider, tracer tracing.Tracer) *Service { proxy := &httpServiceProxy{} executors := map[string]azDatasourceExecutor{ azureMonitor: &AzureMonitorDatasource{proxy: proxy}, @@ -43,37 +41,36 @@ func ProvideService(cfg *setting.Cfg, httpClientProvider *httpclient.Provider, p im := datasource.NewInstanceManager(NewInstanceSettings(cfg, *httpClientProvider, executors)) s := &Service{ - Cfg: cfg, im: im, executors: executors, tracer: tracer, } - mux := s.newMux() - resourceMux := http.NewServeMux() - s.registerRoutes(resourceMux) - factory := coreplugin.New(backend.ServeOpts{ - QueryDataHandler: mux, - CallResourceHandler: httpadapter.New(resourceMux), - }) - - resolver := plugins.CoreDataSourcePathResolver(cfg, pluginID) - if err := pluginStore.AddWithFactory(context.Background(), pluginID, factory, resolver); err != nil { - azlog.Error("Failed to register plugin", "error", err) - } + s.queryMux = s.newQueryMux() + s.resourceHandler = httpadapter.New(s.newResourceMux()) return s } +func (s *Service) QueryData(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) { + return s.queryMux.QueryData(ctx, req) +} + +func (s *Service) CallResource(ctx context.Context, req *backend.CallResourceRequest, sender backend.CallResourceResponseSender) error { + return s.resourceHandler.CallResource(ctx, req, sender) +} + type serviceProxy interface { Do(rw http.ResponseWriter, req *http.Request, cli *http.Client) http.ResponseWriter } type Service struct { - Cfg *setting.Cfg im instancemgmt.InstanceManager executors map[string]azDatasourceExecutor - tracer tracing.Tracer + + queryMux *datasource.QueryTypeMux + resourceHandler backend.CallResourceHandler + tracer tracing.Tracer } type azureMonitorSettings struct { @@ -182,7 +179,7 @@ func (s *Service) getDataSourceFromPluginReq(req *backend.QueryDataRequest) (dat return dsInfo, nil } -func (s *Service) newMux() *datasource.QueryTypeMux { +func (s *Service) newQueryMux() *datasource.QueryTypeMux { mux := datasource.NewQueryTypeMux() for dsType := range s.executors { // Make a copy of the string to keep the reference after the iterator diff --git a/pkg/tsdb/azuremonitor/azuremonitor_test.go b/pkg/tsdb/azuremonitor/azuremonitor_test.go index a4526a8bd51..5b556242295 100644 --- a/pkg/tsdb/azuremonitor/azuremonitor_test.go +++ b/pkg/tsdb/azuremonitor/azuremonitor_test.go @@ -99,10 +99,6 @@ func (f *fakeExecutor) executeTimeSeriesQuery(ctx context.Context, originalQueri } func Test_newMux(t *testing.T) { - cfg := &setting.Cfg{ - Azure: setting.AzureSettings{}, - } - tests := []struct { name string queryType string @@ -126,7 +122,6 @@ func Test_newMux(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { s := &Service{ - Cfg: cfg, im: &fakeInstance{ routes: routes[azureMonitorPublic], services: map[string]datasourceService{ @@ -144,7 +139,7 @@ func Test_newMux(t *testing.T) { }, }, } - mux := s.newMux() + mux := s.newQueryMux() res, err := mux.QueryData(context.Background(), &backend.QueryDataRequest{ PluginContext: backend.PluginContext{}, Queries: []backend.DataQuery{ diff --git a/pkg/tsdb/cloudmonitoring/cloudmonitoring.go b/pkg/tsdb/cloudmonitoring/cloudmonitoring.go index 0cd1a28225e..8cebb467460 100644 --- a/pkg/tsdb/cloudmonitoring/cloudmonitoring.go +++ b/pkg/tsdb/cloudmonitoring/cloudmonitoring.go @@ -16,6 +16,7 @@ import ( "time" "github.com/grafana/grafana-google-sdk-go/pkg/utils" + "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/instancemgmt" @@ -25,10 +26,6 @@ import ( "github.com/grafana/grafana/pkg/infra/httpclient" "github.com/grafana/grafana/pkg/infra/log" "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/datasources" - "github.com/grafana/grafana/pkg/setting" ) @@ -61,8 +58,6 @@ var ( ) const ( - pluginID string = "stackdriver" - gceAuthentication string = "gce" jwtAuthentication string = "jwt" metricQueryType string = "metrics" @@ -72,31 +67,22 @@ const ( perSeriesAlignerDefault string = "ALIGN_MEAN" ) -func ProvideService(cfg *setting.Cfg, httpClientProvider httpclient.Provider, pluginStore plugins.Store, - dsService *datasources.Service, tracer tracing.Tracer) *Service { +func ProvideService(httpClientProvider httpclient.Provider, tracer tracing.Tracer) *Service { s := &Service{ - httpClientProvider: httpClientProvider, - cfg: cfg, - im: datasource.NewInstanceManager(newInstanceSettings(httpClientProvider)), - dsService: dsService, tracer: tracer, + httpClientProvider: httpClientProvider, + im: datasource.NewInstanceManager(newInstanceSettings(httpClientProvider)), } - mux := http.NewServeMux() - s.registerRoutes(mux) - factory := coreplugin.New(backend.ServeOpts{ - QueryDataHandler: s, - CallResourceHandler: httpadapter.New(mux), - CheckHealthHandler: s, - }) + s.resourceHandler = httpadapter.New(s.newResourceMux()) - resolver := plugins.CoreDataSourcePathResolver(cfg, pluginID) - if err := pluginStore.AddWithFactory(context.Background(), pluginID, factory, resolver); err != nil { - slog.Error("Failed to register plugin", "error", err) - } return s } +func (s *Service) CallResource(ctx context.Context, req *backend.CallResourceRequest, sender backend.CallResourceResponseSender) error { + return s.resourceHandler.CallResource(ctx, req, sender) +} + func (s *Service) CheckHealth(ctx context.Context, req *backend.CheckHealthRequest) (*backend.CheckHealthResult, error) { dsInfo, err := s.getDSInfo(req.PluginContext) if err != nil { @@ -138,10 +124,10 @@ func (s *Service) CheckHealth(ctx context.Context, req *backend.CheckHealthReque type Service struct { httpClientProvider httpclient.Provider - cfg *setting.Cfg im instancemgmt.InstanceManager - dsService *datasources.Service tracer tracing.Tracer + + resourceHandler backend.CallResourceHandler } type QueryModel struct { diff --git a/pkg/tsdb/cloudmonitoring/resource_handler.go b/pkg/tsdb/cloudmonitoring/resource_handler.go index 32141147a08..038d8c7fc62 100644 --- a/pkg/tsdb/cloudmonitoring/resource_handler.go +++ b/pkg/tsdb/cloudmonitoring/resource_handler.go @@ -25,13 +25,14 @@ const resourceManagerPath = "/v1/projects" type processResponse func(body []byte) ([]json.RawMessage, string, error) -func (s *Service) registerRoutes(mux *http.ServeMux) { +func (s *Service) newResourceMux() *http.ServeMux { + mux := http.NewServeMux() mux.HandleFunc("/gceDefaultProject", getGCEDefaultProject) - - mux.HandleFunc("/metricDescriptors/", s.resourceHandler(cloudMonitor, processMetricDescriptors)) - mux.HandleFunc("/services/", s.resourceHandler(cloudMonitor, processServices)) - mux.HandleFunc("/slo-services/", s.resourceHandler(cloudMonitor, processSLOs)) - mux.HandleFunc("/projects", s.resourceHandler(resourceManager, processProjects)) + mux.HandleFunc("/metricDescriptors/", s.handleResourceReq(cloudMonitor, processMetricDescriptors)) + mux.HandleFunc("/services/", s.handleResourceReq(cloudMonitor, processServices)) + mux.HandleFunc("/slo-services/", s.handleResourceReq(cloudMonitor, processSLOs)) + mux.HandleFunc("/projects", s.handleResourceReq(resourceManager, processProjects)) + return mux } func getGCEDefaultProject(rw http.ResponseWriter, req *http.Request) { @@ -43,7 +44,7 @@ func getGCEDefaultProject(rw http.ResponseWriter, req *http.Request) { writeResponse(rw, http.StatusOK, project) } -func (s *Service) resourceHandler(subDataSource string, responseFn processResponse) func(rw http.ResponseWriter, req *http.Request) { +func (s *Service) handleResourceReq(subDataSource string, responseFn processResponse) func(rw http.ResponseWriter, req *http.Request) { return func(rw http.ResponseWriter, req *http.Request) { client, code, err := s.setRequestVariables(req, subDataSource) if err != nil { diff --git a/pkg/tsdb/cloudwatch/cloudwatch.go b/pkg/tsdb/cloudwatch/cloudwatch.go index 16306b542f3..ee6eb400207 100644 --- a/pkg/tsdb/cloudwatch/cloudwatch.go +++ b/pkg/tsdb/cloudwatch/cloudwatch.go @@ -27,8 +27,6 @@ import ( "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/infra/httpclient" "github.com/grafana/grafana/pkg/infra/log" - "github.com/grafana/grafana/pkg/plugins" - "github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin" "github.com/grafana/grafana/pkg/setting" ) @@ -56,29 +54,18 @@ const defaultRegion = "default" const logIdentifierInternal = "__log__grafana_internal__" const logStreamIdentifierInternal = "__logstream__grafana_internal__" -const pluginID = "cloudwatch" - var plog = log.New("tsdb.cloudwatch") var aliasFormat = regexp.MustCompile(`\{\{\s*(.+?)\s*\}\}`) -func ProvideService(cfg *setting.Cfg, httpClientProvider httpclient.Provider, pluginStore plugins.Store) (*CloudWatchService, error) { +func ProvideService(cfg *setting.Cfg, httpClientProvider httpclient.Provider) *CloudWatchService { plog.Debug("initing") executor := newExecutor(datasource.NewInstanceManager(NewInstanceSettings(httpClientProvider)), cfg, awsds.NewSessionCache()) - factory := coreplugin.New(backend.ServeOpts{ - QueryDataHandler: executor, - }) - - resolver := plugins.CoreDataSourcePathResolver(cfg, pluginID) - if err := pluginStore.AddWithFactory(context.Background(), pluginID, factory, resolver); err != nil { - plog.Error("Failed to register plugin", "error", err) - return nil, err - } return &CloudWatchService{ Cfg: cfg, Executor: executor, - }, nil + } } type CloudWatchService struct { diff --git a/pkg/tsdb/elasticsearch/elasticsearch.go b/pkg/tsdb/elasticsearch/elasticsearch.go index 558466d57aa..48cb5da2964 100644 --- a/pkg/tsdb/elasticsearch/elasticsearch.go +++ b/pkg/tsdb/elasticsearch/elasticsearch.go @@ -12,47 +12,24 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/backend/instancemgmt" "github.com/grafana/grafana/pkg/infra/httpclient" "github.com/grafana/grafana/pkg/infra/log" - "github.com/grafana/grafana/pkg/plugins" - "github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin" - "github.com/grafana/grafana/pkg/setting" es "github.com/grafana/grafana/pkg/tsdb/elasticsearch/client" "github.com/grafana/grafana/pkg/tsdb/intervalv2" ) var eslog = log.New("tsdb.elasticsearch") -const pluginID = "elasticsearch" - type Service struct { - HTTPClientProvider httpclient.Provider + httpClientProvider httpclient.Provider intervalCalculator intervalv2.Calculator im instancemgmt.InstanceManager } -func ProvideService(cfg *setting.Cfg, httpClientProvider httpclient.Provider, pluginStore plugins.Store) (*Service, error) { +func ProvideService(httpClientProvider httpclient.Provider) *Service { eslog.Debug("initializing") - im := datasource.NewInstanceManager(newInstanceSettings()) - s := newService(im, httpClientProvider) - - factory := coreplugin.New(backend.ServeOpts{ - QueryDataHandler: newService(im, s.HTTPClientProvider), - }) - - if err := pluginStore.AddWithFactory(context.Background(), pluginID, factory, - plugins.CoreDataSourcePathResolver(cfg, pluginID)); err != nil { - eslog.Error("Failed to register plugin", "error", err) - return nil, err - } - - return s, nil -} - -// newService creates a new executor func. -func newService(im instancemgmt.InstanceManager, httpClientProvider httpclient.Provider) *Service { return &Service{ - im: im, - HTTPClientProvider: httpClientProvider, + im: datasource.NewInstanceManager(newInstanceSettings()), + httpClientProvider: httpClientProvider, intervalCalculator: intervalv2.NewCalculator(), } } @@ -67,7 +44,7 @@ func (s *Service) QueryData(ctx context.Context, req *backend.QueryDataRequest) return &backend.QueryDataResponse{}, err } - client, err := es.NewClient(ctx, s.HTTPClientProvider, dsInfo, req.Queries[0].TimeRange) + client, err := es.NewClient(ctx, s.httpClientProvider, dsInfo, req.Queries[0].TimeRange) if err != nil { return &backend.QueryDataResponse{}, err } diff --git a/pkg/tsdb/grafanads/grafana.go b/pkg/tsdb/grafanads/grafana.go index d3cd80b77c5..4c28b32e04b 100644 --- a/pkg/tsdb/grafanads/grafana.go +++ b/pkg/tsdb/grafanads/grafana.go @@ -14,8 +14,6 @@ import ( "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/models" - "github.com/grafana/grafana/pkg/plugins" - "github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin" "github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/tsdb/testdatasource" ) @@ -32,8 +30,6 @@ const DatasourceID = -1 // Grafana DS command. const DatasourceUID = "grafana" -const pluginID = "grafana" - // Make sure Service implements required interfaces. // This is important to do since otherwise we will only get a // not implemented error response from plugin at runtime. @@ -43,11 +39,11 @@ var ( logger = log.New("tsdb.grafana") ) -func ProvideService(cfg *setting.Cfg, pluginStore plugins.Store) *Service { - return newService(cfg, pluginStore) +func ProvideService(cfg *setting.Cfg) *Service { + return newService(cfg) } -func newService(cfg *setting.Cfg, pluginStore plugins.Store) *Service { +func newService(cfg *setting.Cfg) *Service { s := &Service{ staticRootPath: cfg.StaticRootPath, roots: []string{ @@ -59,14 +55,6 @@ func newService(cfg *setting.Cfg, pluginStore plugins.Store) *Service { }, } - resolver := plugins.CoreDataSourcePathResolver(cfg, pluginID) - if err := pluginStore.AddWithFactory(context.Background(), pluginID, coreplugin.New(backend.ServeOpts{ - CheckHealthHandler: s, - QueryDataHandler: s, - }), resolver); err != nil { - logger.Error("Failed to register plugin", "error", err) - return nil - } return s } diff --git a/pkg/tsdb/grafanads/grafana_test.go b/pkg/tsdb/grafanads/grafana_test.go index 07dec0e3325..d16345ce35d 100644 --- a/pkg/tsdb/grafanads/grafana_test.go +++ b/pkg/tsdb/grafanads/grafana_test.go @@ -1,13 +1,10 @@ package grafanads import ( - "context" "encoding/json" "path" "testing" - "github.com/grafana/grafana/pkg/plugins" - "github.com/grafana/grafana/pkg/plugins/backendplugin" "github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana-plugin-sdk-go/backend" @@ -21,7 +18,7 @@ func asJSON(v interface{}) json.RawMessage { } func TestReadFolderListing(t *testing.T) { - ds := newService(&setting.Cfg{StaticRootPath: "../../../public"}, &fakePluginStore{}) + ds := newService(&setting.Cfg{StaticRootPath: "../../../public"}) dr := ds.doListQuery(backend.DataQuery{ QueryType: "x", JSON: asJSON(listQueryModel{ @@ -33,7 +30,7 @@ func TestReadFolderListing(t *testing.T) { } func TestReadCSVFile(t *testing.T) { - ds := newService(&setting.Cfg{StaticRootPath: "../../../public"}, &fakePluginStore{}) + ds := newService(&setting.Cfg{StaticRootPath: "../../../public"}) dr := ds.doReadQuery(backend.DataQuery{ QueryType: "x", JSON: asJSON(readQueryModel{ @@ -43,11 +40,3 @@ func TestReadCSVFile(t *testing.T) { err := experimental.CheckGoldenDataResponse(path.Join("testdata", "jslib.golden.txt"), &dr, true) require.NoError(t, err) } - -type fakePluginStore struct { - plugins.Store -} - -func (ps *fakePluginStore) AddWithFactory(_ context.Context, _ string, _ backendplugin.PluginFactoryFunc, _ plugins.PluginPathResolver) error { - return nil -} diff --git a/pkg/tsdb/graphite/graphite.go b/pkg/tsdb/graphite/graphite.go index 82538d37231..bc3b61e9e9b 100644 --- a/pkg/tsdb/graphite/graphite.go +++ b/pkg/tsdb/graphite/graphite.go @@ -26,8 +26,6 @@ import ( "github.com/grafana/grafana/pkg/infra/httpclient" "github.com/grafana/grafana/pkg/infra/log" "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/setting" "github.com/grafana/grafana/pkg/tsdb/legacydata" ) @@ -39,29 +37,16 @@ type Service struct { } const ( - pluginID = "graphite" TargetFullModelField = "targetFull" TargetModelField = "target" ) -func ProvideService(cfg *setting.Cfg, httpClientProvider httpclient.Provider, pluginStore plugins.Store, tracer tracing.Tracer) (*Service, error) { - s := &Service{ +func ProvideService(httpClientProvider httpclient.Provider, tracer tracing.Tracer) *Service { + return &Service{ logger: log.New("tsdb.graphite"), im: datasource.NewInstanceManager(newInstanceSettings(httpClientProvider)), tracer: tracer, } - - factory := coreplugin.New(backend.ServeOpts{ - QueryDataHandler: s, - }) - - resolver := plugins.CoreDataSourcePathResolver(cfg, pluginID) - if err := pluginStore.AddWithFactory(context.Background(), pluginID, factory, resolver); err != nil { - s.logger.Error("Failed to register plugin", "error", err) - return nil, err - } - - return s, nil } type datasourceInfo struct { diff --git a/pkg/tsdb/influxdb/influxdb.go b/pkg/tsdb/influxdb/influxdb.go index fec2e42c304..ebfe3cf20e4 100644 --- a/pkg/tsdb/influxdb/influxdb.go +++ b/pkg/tsdb/influxdb/influxdb.go @@ -15,18 +15,14 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/backend/instancemgmt" "github.com/grafana/grafana/pkg/infra/httpclient" "github.com/grafana/grafana/pkg/infra/log" - "github.com/grafana/grafana/pkg/plugins" - "github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin" "github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/tsdb/influxdb/flux" "github.com/grafana/grafana/pkg/tsdb/influxdb/models" ) -const pluginID = "influxdb" - type Service struct { - QueryParser *InfluxdbQueryParser - ResponseParser *ResponseParser + queryParser *InfluxdbQueryParser + responseParser *ResponseParser glog log.Logger im instancemgmt.InstanceManager @@ -34,26 +30,13 @@ type Service struct { var ErrInvalidHttpMode = errors.New("'httpMode' should be either 'GET' or 'POST'") -func ProvideService(cfg *setting.Cfg, httpClient httpclient.Provider, pluginStore plugins.Store) (*Service, error) { - im := datasource.NewInstanceManager(newInstanceSettings(httpClient)) - s := &Service{ - QueryParser: &InfluxdbQueryParser{}, - ResponseParser: &ResponseParser{}, +func ProvideService(httpClient httpclient.Provider) *Service { + return &Service{ + queryParser: &InfluxdbQueryParser{}, + responseParser: &ResponseParser{}, glog: log.New("tsdb.influxdb"), - im: im, + im: datasource.NewInstanceManager(newInstanceSettings(httpClient)), } - - factory := coreplugin.New(backend.ServeOpts{ - QueryDataHandler: s, - }) - - resolver := plugins.CoreDataSourcePathResolver(cfg, pluginID) - if err := pluginStore.AddWithFactory(context.Background(), pluginID, factory, resolver); err != nil { - s.glog.Error("Failed to register plugin", "error", err) - return nil, err - } - - return s, nil } func newInstanceSettings(httpClientProvider httpclient.Provider) datasource.InstanceFactoryFunc { @@ -146,7 +129,7 @@ func (s *Service) QueryData(ctx context.Context, req *backend.QueryDataRequest) return &backend.QueryDataResponse{}, fmt.Errorf("InfluxDB returned error status: %s", res.Status) } - resp := s.ResponseParser.Parse(res.Body, query) + resp := s.responseParser.Parse(res.Body, query) return resp, nil } @@ -162,7 +145,7 @@ func (s *Service) getQuery(dsInfo *models.DatasourceInfo, query *backend.QueryDa q := query.Queries[0] - return s.QueryParser.Parse(q) + return s.queryParser.Parse(q) } func (s *Service) createRequest(ctx context.Context, dsInfo *models.DatasourceInfo, query string) (*http.Request, error) { diff --git a/pkg/tsdb/influxdb/influxdb_test.go b/pkg/tsdb/influxdb/influxdb_test.go index da7424ee00f..f3c7d76f085 100644 --- a/pkg/tsdb/influxdb/influxdb_test.go +++ b/pkg/tsdb/influxdb/influxdb_test.go @@ -20,8 +20,8 @@ func TestExecutor_createRequest(t *testing.T) { } query := "SELECT awesomeness FROM somewhere" s := &Service{ - QueryParser: &InfluxdbQueryParser{}, - ResponseParser: &ResponseParser{}, + queryParser: &InfluxdbQueryParser{}, + responseParser: &ResponseParser{}, glog: log.New("test"), } diff --git a/pkg/tsdb/loki/loki.go b/pkg/tsdb/loki/loki.go index ab9a647fc26..a36e2d6340c 100644 --- a/pkg/tsdb/loki/loki.go +++ b/pkg/tsdb/loki/loki.go @@ -17,9 +17,6 @@ import ( "github.com/grafana/grafana/pkg/infra/httpclient" "github.com/grafana/grafana/pkg/infra/log" "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/setting" "github.com/grafana/loki/pkg/logcli/client" "github.com/grafana/loki/pkg/loghttp" "github.com/grafana/loki/pkg/logproto" @@ -29,33 +26,18 @@ import ( "github.com/prometheus/common/model" ) -const pluginID = "loki" - type Service struct { im instancemgmt.InstanceManager plog log.Logger tracer tracing.Tracer } -func ProvideService(cfg *setting.Cfg, httpClientProvider httpclient.Provider, pluginStore plugins.Store, tracer tracing.Tracer) (*Service, error) { - im := datasource.NewInstanceManager(newInstanceSettings(httpClientProvider)) - s := &Service{ - im: im, +func ProvideService(httpClientProvider httpclient.Provider, tracer tracing.Tracer) *Service { + return &Service{ + im: datasource.NewInstanceManager(newInstanceSettings(httpClientProvider)), plog: log.New("tsdb.loki"), tracer: tracer, } - - factory := coreplugin.New(backend.ServeOpts{ - QueryDataHandler: s, - }) - - resolver := plugins.CoreDataSourcePathResolver(cfg, pluginID) - if err := pluginStore.AddWithFactory(context.Background(), pluginID, factory, resolver); err != nil { - s.plog.Error("Failed to register plugin", "error", err) - return nil, err - } - - return s, nil } var ( diff --git a/pkg/tsdb/mssql/mssql.go b/pkg/tsdb/mssql/mssql.go index 792c45a72d5..5145a692da0 100644 --- a/pkg/tsdb/mssql/mssql.go +++ b/pkg/tsdb/mssql/mssql.go @@ -17,8 +17,6 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/data" "github.com/grafana/grafana-plugin-sdk-go/data/sqlutil" "github.com/grafana/grafana/pkg/infra/log" - "github.com/grafana/grafana/pkg/plugins" - "github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin" "github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/tsdb/sqleng" "github.com/grafana/grafana/pkg/util" @@ -26,25 +24,14 @@ import ( var logger = log.New("tsdb.mssql") -const pluginID = "mssql" - type Service struct { im instancemgmt.InstanceManager } -func ProvideService(cfg *setting.Cfg, pluginStore plugins.Store) (*Service, error) { - s := &Service{ +func ProvideService(cfg *setting.Cfg) *Service { + return &Service{ im: datasource.NewInstanceManager(newInstanceSettings(cfg)), } - factory := coreplugin.New(backend.ServeOpts{ - QueryDataHandler: s, - }) - - resolver := plugins.CoreDataSourcePathResolver(cfg, pluginID) - if err := pluginStore.AddWithFactory(context.Background(), pluginID, factory, resolver); err != nil { - logger.Error("Failed to register plugin", "error", err) - } - return s, nil } func (s *Service) getDataSourceHandler(pluginCtx backend.PluginContext) (*sqleng.DataSourceHandler, error) { diff --git a/pkg/tsdb/mysql/mysql.go b/pkg/tsdb/mysql/mysql.go index 19dcf99fbd3..b3ee10a7fe7 100644 --- a/pkg/tsdb/mysql/mysql.go +++ b/pkg/tsdb/mysql/mysql.go @@ -20,14 +20,11 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/data/sqlutil" "github.com/grafana/grafana/pkg/infra/httpclient" "github.com/grafana/grafana/pkg/infra/log" - "github.com/grafana/grafana/pkg/plugins" - "github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin" "github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/tsdb/sqleng" ) const ( - pluginID = "mysql" dateFormat = "2006-01-02" dateTimeFormat1 = "2006-01-02 15:04:05" dateTimeFormat2 = "2006-01-02T15:04:05Z" @@ -44,19 +41,10 @@ func characterEscape(s string, escapeChar string) string { return strings.ReplaceAll(s, escapeChar, url.QueryEscape(escapeChar)) } -func ProvideService(cfg *setting.Cfg, pluginStore plugins.Store, httpClientProvider httpclient.Provider) (*Service, error) { - s := &Service{ +func ProvideService(cfg *setting.Cfg, httpClientProvider httpclient.Provider) *Service { + return &Service{ im: datasource.NewInstanceManager(newInstanceSettings(cfg, httpClientProvider)), } - factory := coreplugin.New(backend.ServeOpts{ - QueryDataHandler: s, - }) - - resolver := plugins.CoreDataSourcePathResolver(cfg, pluginID) - if err := pluginStore.AddWithFactory(context.Background(), pluginID, factory, resolver); err != nil { - logger.Error("Failed to register plugin", "error", err) - } - return s, nil } func newInstanceSettings(cfg *setting.Cfg, httpClientProvider httpclient.Provider) datasource.InstanceFactoryFunc { diff --git a/pkg/tsdb/opentsdb/opentsdb.go b/pkg/tsdb/opentsdb/opentsdb.go index ef42bf1bdbf..8dc65d0ff5c 100644 --- a/pkg/tsdb/opentsdb/opentsdb.go +++ b/pkg/tsdb/opentsdb/opentsdb.go @@ -19,35 +19,20 @@ import ( "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/infra/httpclient" "github.com/grafana/grafana/pkg/infra/log" - "github.com/grafana/grafana/pkg/plugins" - "github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin" "github.com/grafana/grafana/pkg/setting" "golang.org/x/net/context/ctxhttp" ) -const pluginID = "opentsdb" - type Service struct { logger log.Logger im instancemgmt.InstanceManager } -func ProvideService(cfg *setting.Cfg, httpClientProvider httpclient.Provider, pluginStore plugins.Store) (*Service, error) { - im := datasource.NewInstanceManager(newInstanceSettings(httpClientProvider)) - s := &Service{ +func ProvideService(httpClientProvider httpclient.Provider) *Service { + return &Service{ logger: log.New("tsdb.opentsdb"), - im: im, + im: datasource.NewInstanceManager(newInstanceSettings(httpClientProvider)), } - - factory := coreplugin.New(backend.ServeOpts{ - QueryDataHandler: s, - }) - resolver := plugins.CoreDataSourcePathResolver(cfg, pluginID) - if err := pluginStore.AddWithFactory(context.Background(), pluginID, factory, resolver); err != nil { - return nil, err - } - - return s, nil } type datasourceInfo struct { diff --git a/pkg/tsdb/postgres/postgres.go b/pkg/tsdb/postgres/postgres.go index 112c9bc9678..e7e73f0c3ea 100644 --- a/pkg/tsdb/postgres/postgres.go +++ b/pkg/tsdb/postgres/postgres.go @@ -14,8 +14,6 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/data" "github.com/grafana/grafana-plugin-sdk-go/data/sqlutil" "github.com/grafana/grafana/pkg/infra/log" - "github.com/grafana/grafana/pkg/plugins" - "github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin" "github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/tsdb/sqleng" "github.com/grafana/grafana/pkg/util/errutil" @@ -23,22 +21,12 @@ import ( var logger = log.New("tsdb.postgres") -const pluginID = "postgres" - -func ProvideService(cfg *setting.Cfg, pluginStore plugins.Store) (*Service, error) { +func ProvideService(cfg *setting.Cfg) *Service { s := &Service{ tlsManager: newTLSManager(logger, cfg.DataPath), } s.im = datasource.NewInstanceManager(s.newInstanceSettings(cfg)) - factory := coreplugin.New(backend.ServeOpts{ - QueryDataHandler: s, - }) - - resolver := plugins.CoreDataSourcePathResolver(cfg, pluginID) - if err := pluginStore.AddWithFactory(context.Background(), pluginID, factory, resolver); err != nil { - logger.Error("Failed to register plugin", "error", err) - } - return s, nil + return s } type Service struct { diff --git a/pkg/tsdb/prometheus/prometheus.go b/pkg/tsdb/prometheus/prometheus.go index c4d2e33aeb0..e16597c50fb 100644 --- a/pkg/tsdb/prometheus/prometheus.go +++ b/pkg/tsdb/prometheus/prometheus.go @@ -15,9 +15,6 @@ import ( "github.com/grafana/grafana/pkg/infra/httpclient" "github.com/grafana/grafana/pkg/infra/log" "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/setting" "github.com/grafana/grafana/pkg/tsdb/intervalv2" apiv1 "github.com/prometheus/client_golang/api/prometheus/v1" ) @@ -28,34 +25,19 @@ var ( safeRes = 11000 ) -const pluginID = "prometheus" - type Service struct { intervalCalculator intervalv2.Calculator im instancemgmt.InstanceManager tracer tracing.Tracer } -func ProvideService(cfg *setting.Cfg, httpClientProvider httpclient.Provider, pluginStore plugins.Store, tracer tracing.Tracer) (*Service, error) { +func ProvideService(httpClientProvider httpclient.Provider, tracer tracing.Tracer) *Service { plog.Debug("initializing") - im := datasource.NewInstanceManager(newInstanceSettings(httpClientProvider)) - - s := &Service{ + return &Service{ intervalCalculator: intervalv2.NewCalculator(), - im: im, + im: datasource.NewInstanceManager(newInstanceSettings(httpClientProvider)), tracer: tracer, } - - factory := coreplugin.New(backend.ServeOpts{ - QueryDataHandler: s, - }) - resolver := plugins.CoreDataSourcePathResolver(cfg, pluginID) - if err := pluginStore.AddWithFactory(context.Background(), pluginID, factory, resolver); err != nil { - plog.Error("Failed to register plugin", "error", err) - return nil, err - } - - return s, nil } func newInstanceSettings(httpClientProvider httpclient.Provider) datasource.InstanceFactoryFunc { diff --git a/pkg/tsdb/tempo/tempo.go b/pkg/tsdb/tempo/tempo.go index 49ce72dcacd..866f68276e4 100644 --- a/pkg/tsdb/tempo/tempo.go +++ b/pkg/tsdb/tempo/tempo.go @@ -13,38 +13,19 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/data" "github.com/grafana/grafana/pkg/infra/httpclient" "github.com/grafana/grafana/pkg/infra/log" - "github.com/grafana/grafana/pkg/plugins" - "github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin" - "github.com/grafana/grafana/pkg/setting" "go.opentelemetry.io/collector/model/otlp" ) -const pluginID = "tempo" - type Service struct { im instancemgmt.InstanceManager tlog log.Logger } -func ProvideService(cfg *setting.Cfg, httpClientProvider httpclient.Provider, pluginStore plugins.Store) (*Service, error) { - im := datasource.NewInstanceManager(newInstanceSettings(httpClientProvider)) - - s := &Service{ +func ProvideService(httpClientProvider httpclient.Provider) *Service { + return &Service{ tlog: log.New("tsdb.tempo"), - im: im, + im: datasource.NewInstanceManager(newInstanceSettings(httpClientProvider)), } - - factory := coreplugin.New(backend.ServeOpts{ - QueryDataHandler: s, - }) - - resolver := plugins.CoreDataSourcePathResolver(cfg, pluginID) - if err := pluginStore.AddWithFactory(context.Background(), pluginID, factory, resolver); err != nil { - s.tlog.Error("Failed to register plugin", "error", err) - return nil, err - } - - return s, nil } type datasourceInfo struct { diff --git a/pkg/tsdb/testdatasource/resource_handler.go b/pkg/tsdb/testdatasource/resource_handler.go index 2eb5ff1029d..76bbed47e42 100644 --- a/pkg/tsdb/testdatasource/resource_handler.go +++ b/pkg/tsdb/testdatasource/resource_handler.go @@ -15,13 +15,15 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/backend/resource/httpadapter" ) -func (s *Service) RegisterRoutes(mux *http.ServeMux) { +func (s *Service) registerRoutes() *http.ServeMux { + mux := http.NewServeMux() mux.HandleFunc("/", s.testGetHandler) mux.HandleFunc("/scenarios", s.getScenariosHandler) mux.HandleFunc("/stream", s.testStreamHandler) mux.Handle("/test", createJSONHandler(s.logger)) mux.Handle("/test/json", createJSONHandler(s.logger)) mux.HandleFunc("/boom", s.testPanicHandler) + return mux } func (s *Service) testGetHandler(rw http.ResponseWriter, req *http.Request) { diff --git a/pkg/tsdb/testdatasource/testdata.go b/pkg/tsdb/testdatasource/testdata.go index 6242d4f8a70..bac97f146bc 100644 --- a/pkg/tsdb/testdatasource/testdata.go +++ b/pkg/tsdb/testdatasource/testdata.go @@ -2,22 +2,18 @@ package testdatasource import ( "context" - "net/http" "time" "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/resource/httpadapter" "github.com/grafana/grafana-plugin-sdk-go/data" + "github.com/grafana/grafana/pkg/infra/log" - "github.com/grafana/grafana/pkg/plugins" - "github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin" "github.com/grafana/grafana/pkg/setting" ) -const pluginID = "testdata" - -func ProvideService(cfg *setting.Cfg, pluginStore plugins.Store) (*Service, error) { +func ProvideService(cfg *setting.Cfg) *Service { s := &Service{ queryMux: datasource.NewQueryTypeMux(), scenarios: map[string]*Scenario{}, @@ -37,29 +33,25 @@ func ProvideService(cfg *setting.Cfg, pluginStore plugins.Store) (*Service, erro } s.registerScenarios() + s.resourceHandler = httpadapter.New(s.registerRoutes()) - rMux := http.NewServeMux() - s.RegisterRoutes(rMux) - - factory := coreplugin.New(backend.ServeOpts{ - QueryDataHandler: s.queryMux, - CallResourceHandler: httpadapter.New(rMux), - StreamHandler: s, - }) - resolver := plugins.CoreDataSourcePathResolver(cfg, pluginID) - err := pluginStore.AddWithFactory(context.Background(), pluginID, factory, resolver) - if err != nil { - return nil, err - } - - return s, nil + return s } type Service struct { - cfg *setting.Cfg - logger log.Logger - scenarios map[string]*Scenario - frame *data.Frame - labelFrame *data.Frame - queryMux *datasource.QueryTypeMux + cfg *setting.Cfg + logger log.Logger + scenarios map[string]*Scenario + frame *data.Frame + labelFrame *data.Frame + queryMux *datasource.QueryTypeMux + resourceHandler backend.CallResourceHandler +} + +func (s *Service) QueryData(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) { + return s.queryMux.QueryData(ctx, req) +} + +func (s *Service) CallResource(ctx context.Context, req *backend.CallResourceRequest, sender backend.CallResourceResponseSender) error { + return s.resourceHandler.CallResource(ctx, req, sender) } diff --git a/public/app/plugins/datasource/grafana/plugin.json b/public/app/plugins/datasource/grafana/plugin.json index d7d957ec01a..e734903700f 100644 --- a/public/app/plugins/datasource/grafana/plugin.json +++ b/public/app/plugins/datasource/grafana/plugin.json @@ -3,6 +3,7 @@ "name": "-- Grafana --", "id": "grafana", + "backend": true, "builtIn": true, "annotations": true, "metrics": true