grafana/pkg/plugins/manager/manager_integration_test.go
Gabriel MABILLE 5975c4bc6d
RBAC: Allow app plugins access restriction (#51524)
* RBAC: Allow app plugins restriction

Co-authored-by: Kalle Persson <kalle.persson@grafana.com>

* Fix tests

* Imports

* WIP

* Adding RBAC to AppPluginsRoutes

* Switching middleware order

* Restrict access to resources

* Nit

* Cosmetic changes

* Fix fallback

* Moving declaration to HttpServer

Co-Authored-By: marefr <marcus.efraimsson@gmail.com>

Co-authored-by: Kalle Persson <kalle.persson@grafana.com>
Co-authored-by: marefr <marcus.efraimsson@gmail.com>
2022-07-08 13:24:09 +02:00

260 lines
8.0 KiB
Go

package manager
import (
"context"
"net/http"
"path/filepath"
"strings"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.opentelemetry.io/otel/trace"
"gopkg.in/ini.v1"
"github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
"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/plugins/backendplugin/provider"
"github.com/grafana/grafana/pkg/plugins/manager/loader"
"github.com/grafana/grafana/pkg/plugins/manager/registry"
"github.com/grafana/grafana/pkg/plugins/manager/signature"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/licensing"
"github.com/grafana/grafana/pkg/services/searchV2"
"github.com/grafana/grafana/pkg/services/sqlstore"
"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"
)
func TestPluginManager_int_init(t *testing.T) {
t.Helper()
staticRootPath, err := filepath.Abs("../../../public/")
require.NoError(t, err)
bundledPluginsPath, err := filepath.Abs("../../../plugins-bundled/internal")
require.NoError(t, err)
features := featuremgmt.WithFeatures()
cfg := &setting.Cfg{
Raw: ini.Empty(),
Env: setting.Prod,
StaticRootPath: staticRootPath,
BundledPluginsPath: bundledPluginsPath,
IsFeatureToggleEnabled: features.IsEnabled,
PluginSettings: map[string]map[string]string{
"plugin.datasource-id": {
"path": "testdata/test-app",
},
},
}
tracer := &fakeTracer{}
license := &licensing.OSSLicensingService{
Cfg: cfg,
}
hcp := httpclient.NewProvider()
am := azuremonitor.ProvideService(cfg, hcp, tracer)
cw := cloudwatch.ProvideService(cfg, hcp, features)
cm := cloudmonitoring.ProvideService(hcp, tracer)
es := elasticsearch.ProvideService(hcp)
grap := graphite.ProvideService(hcp, tracer)
idb := influxdb.ProvideService(hcp)
lk := loki.ProvideService(hcp, features, tracer)
otsdb := opentsdb.ProvideService(hcp)
pr := prometheus.ProvideService(hcp, cfg, features, tracer)
tmpo := tempo.ProvideService(hcp)
td := testdatasource.ProvideService(cfg, features)
pg := postgres.ProvideService(cfg)
my := mysql.ProvideService(cfg, hcp)
ms := mssql.ProvideService(cfg)
sv2 := searchV2.ProvideService(cfg, sqlstore.InitTestDB(t), nil, nil)
graf := grafanads.ProvideService(cfg, sv2, nil)
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, registry.NewInMemory(), loader.New(pmCfg, license, signature.NewUnsignedAuthorizer(pmCfg),
provider.ProvideService(coreRegistry)))
require.NoError(t, err)
ctx := context.Background()
verifyCorePluginCatalogue(t, ctx, pm)
verifyBundledPlugins(t, ctx, pm)
verifyPluginStaticRoutes(t, ctx, pm)
}
func verifyCorePluginCatalogue(t *testing.T, ctx context.Context, pm *PluginManager) {
t.Helper()
expPanels := map[string]struct{}{
"alertGroups": {},
"alertlist": {},
"annolist": {},
"barchart": {},
"bargauge": {},
"canvas": {},
"dashlist": {},
"debug": {},
"gauge": {},
"geomap": {},
"gettingstarted": {},
"graph": {},
"heatmap": {},
"heatmap-old": {},
"histogram": {},
"icon": {},
"live": {},
"logs": {},
"candlestick": {},
"news": {},
"nodeGraph": {},
"traces": {},
"piechart": {},
"stat": {},
"state-timeline": {},
"status-history": {},
"table": {},
"table-old": {},
"text": {},
"timeseries": {},
"welcome": {},
"xychart": {},
}
expDataSources := map[string]struct{}{
"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{}{
"test-app": {},
}
panels := pm.Plugins(ctx, plugins.Panel)
assert.Equal(t, len(expPanels), len(panels))
for _, p := range panels {
p, exists := pm.Plugin(ctx, p.ID)
require.NotEqual(t, plugins.PluginDTO{}, p)
assert.True(t, exists)
assert.Contains(t, expPanels, p.ID)
assert.Contains(t, pm.registeredPlugins(ctx), p.ID)
}
dataSources := pm.Plugins(ctx, plugins.DataSource)
assert.Equal(t, len(expDataSources), len(dataSources))
for _, ds := range dataSources {
p, exists := pm.Plugin(ctx, ds.ID)
require.NotEqual(t, plugins.PluginDTO{}, p)
assert.True(t, exists)
assert.Contains(t, expDataSources, ds.ID)
assert.Contains(t, pm.registeredPlugins(ctx), ds.ID)
}
apps := pm.Plugins(ctx, plugins.App)
assert.Equal(t, len(expApps), len(apps))
for _, app := range apps {
p, exists := pm.Plugin(ctx, app.ID)
require.NotEqual(t, plugins.PluginDTO{}, p)
assert.True(t, exists)
assert.Contains(t, expApps, app.ID)
assert.Contains(t, pm.registeredPlugins(ctx), app.ID)
}
assert.Equal(t, len(expPanels)+len(expDataSources)+len(expApps), len(pm.Plugins(ctx)))
}
func verifyBundledPlugins(t *testing.T, ctx context.Context, pm *PluginManager) {
t.Helper()
dsPlugins := make(map[string]struct{})
for _, p := range pm.Plugins(ctx, plugins.DataSource) {
dsPlugins[p.ID] = struct{}{}
}
pluginRoutes := make(map[string]*plugins.StaticRoute)
for _, r := range pm.Routes() {
pluginRoutes[r.PluginID] = r
}
inputPlugin, exists := pm.Plugin(ctx, "input")
require.NotEqual(t, plugins.PluginDTO{}, inputPlugin)
assert.True(t, exists)
assert.NotNil(t, dsPlugins["input"])
for _, pluginID := range []string{"input"} {
assert.Contains(t, pluginRoutes, pluginID)
assert.True(t, strings.HasPrefix(pluginRoutes[pluginID].Directory, inputPlugin.PluginDir))
}
}
func verifyPluginStaticRoutes(t *testing.T, ctx context.Context, pm *PluginManager) {
routes := make(map[string]*plugins.StaticRoute)
for _, route := range pm.Routes() {
routes[route.PluginID] = route
}
assert.Len(t, routes, 2)
inputPlugin, _ := pm.Plugin(ctx, "input")
assert.NotNil(t, routes["input"])
assert.Equal(t, routes["input"].Directory, inputPlugin.PluginDir)
testAppPlugin, _ := pm.Plugin(ctx, "test-app")
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) {
}