Plugins: Core plugins register via backend factory provider (#43171)

* refactoring store interface and init flow

* fix import

* fix linter

* refactor resource calling

* load with class

* re-order args

* fix tests

* fix linter

* remove old creator

* add custom config struct

* fix some tests

* cleanup

* fix

* tackle plugins

* fix linter

* refactor and fix test

* add connect failure error

* add fix for azure, cloud monitoring and test data

* restructure

* remove unused err

* add fake tracer for test

* fix grafana ds plugin
This commit is contained in:
Will Browne
2022-01-20 18:16:22 +01:00
committed by GitHub
parent 2fd76ecaf7
commit 7fbc7d019a
30 changed files with 326 additions and 380 deletions
@@ -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 <routeNames>
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
}
@@ -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)
+17 -20
View File
@@ -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
+1 -6
View File
@@ -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{