Plugins: Add metrics for fs + cloud provisioning info (#111030)
* add new metrics for plugin fs + cloud provisioning * fix test * update label
This commit is contained in:
@@ -5,6 +5,8 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana-app-sdk/logging"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
advisor "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/plugins/repo"
|
||||
@@ -12,7 +14,6 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginchecker"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/provisionedplugins"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestRun(t *testing.T) {
|
||||
@@ -22,7 +23,7 @@ func TestRun(t *testing.T) {
|
||||
pluginInfo []repo.PluginInfo
|
||||
pluginPreinstalled []string
|
||||
pluginManaged []string
|
||||
pluginProvisioned []string
|
||||
pluginProvisioned []provisionedplugins.Plugin
|
||||
pluginErrors []*plugins.Error
|
||||
expectedFailures []advisor.CheckReportFailure
|
||||
}{
|
||||
@@ -117,7 +118,7 @@ func TestRun(t *testing.T) {
|
||||
pluginInfo: []repo.PluginInfo{
|
||||
{Status: "deprecated", Slug: "plugin5", Version: "1.1.0"}, // This should be ignored
|
||||
},
|
||||
pluginProvisioned: []string{"plugin5"},
|
||||
pluginProvisioned: []provisionedplugins.Plugin{{ID: "plugin5"}},
|
||||
expectedFailures: []advisor.CheckReportFailure{},
|
||||
},
|
||||
{
|
||||
@@ -281,10 +282,10 @@ func (m *mockManagedPlugins) ManagedPlugins(ctx context.Context) []string {
|
||||
|
||||
type mockProvisionedPlugins struct {
|
||||
provisionedplugins.Manager
|
||||
provisioned []string
|
||||
provisioned []provisionedplugins.Plugin
|
||||
}
|
||||
|
||||
func (m *mockProvisionedPlugins) ProvisionedPlugins(ctx context.Context) ([]string, error) {
|
||||
func (m *mockProvisionedPlugins) ProvisionedPlugins(_ context.Context) ([]provisionedplugins.Plugin, error) {
|
||||
return m.provisioned, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -202,6 +202,10 @@ var (
|
||||
|
||||
grafanaPluginTargetInfoDesc *prometheus.GaugeVec
|
||||
|
||||
grafanaPluginFileSystemInfoDesc *prometheus.GaugeVec
|
||||
|
||||
grafanaPluginProvisioningInfoDesc *prometheus.GaugeVec
|
||||
|
||||
// StatsTotalLibraryPanels is a metric of total number of library panels stored in Grafana.
|
||||
StatsTotalLibraryPanels prometheus.Gauge
|
||||
|
||||
@@ -578,6 +582,18 @@ func init() {
|
||||
Namespace: ExporterName,
|
||||
}, []string{"plugin_id", "target"})
|
||||
|
||||
grafanaPluginFileSystemInfoDesc = prometheus.NewGaugeVec(prometheus.GaugeOpts{
|
||||
Name: "plugin_filesystem_info",
|
||||
Help: "A metric with a constant '1' value labeled by pluginId and filesystem type",
|
||||
Namespace: ExporterName,
|
||||
}, []string{"plugin_id", "filesystem_type"})
|
||||
|
||||
grafanaPluginProvisioningInfoDesc = prometheus.NewGaugeVec(prometheus.GaugeOpts{
|
||||
Name: "plugin_provisioning_info",
|
||||
Help: "A metric with a constant '1' value labeled by pluginId and cloud provisioning method",
|
||||
Namespace: ExporterName,
|
||||
}, []string{"plugin_id", "provisioning_method"})
|
||||
|
||||
StatsTotalDashboardVersions = prometheus.NewGauge(prometheus.GaugeOpts{
|
||||
Name: "stat_totals_dashboard_versions",
|
||||
Help: "total amount of dashboard versions in the database",
|
||||
@@ -722,6 +738,14 @@ func SetPluginTargetInformation(pluginID, target string) {
|
||||
grafanaPluginTargetInfoDesc.WithLabelValues(pluginID, target).Set(1)
|
||||
}
|
||||
|
||||
func SetPluginFSInformation(pluginID, fsType string) {
|
||||
grafanaPluginFileSystemInfoDesc.WithLabelValues(pluginID, fsType).Set(1)
|
||||
}
|
||||
|
||||
func SetPluginProvisioningInformation(pluginID, provisioningMethod string) {
|
||||
grafanaPluginProvisioningInfoDesc.WithLabelValues(pluginID, provisioningMethod).Set(1)
|
||||
}
|
||||
|
||||
func initMetricVars(reg prometheus.Registerer) {
|
||||
reg.MustRegister(
|
||||
MInstanceStart,
|
||||
@@ -777,6 +801,8 @@ func initMetricVars(reg prometheus.Registerer) {
|
||||
StatsTotalDataSources,
|
||||
grafanaPluginBuildInfoDesc,
|
||||
grafanaPluginTargetInfoDesc,
|
||||
grafanaPluginFileSystemInfoDesc,
|
||||
grafanaPluginProvisioningInfoDesc,
|
||||
StatsTotalDashboardVersions,
|
||||
StatsTotalAnnotations,
|
||||
StatsTotalAlertRules,
|
||||
|
||||
@@ -72,6 +72,7 @@ type UpdateInfo struct {
|
||||
type FS interface {
|
||||
fs.FS
|
||||
|
||||
Type() string
|
||||
Base() string
|
||||
Files() ([]string, error)
|
||||
Rel(string) (string, error)
|
||||
|
||||
@@ -30,6 +30,10 @@ func NewLocalFS(basePath string) LocalFS {
|
||||
return LocalFS{basePath: basePath}
|
||||
}
|
||||
|
||||
func (f LocalFS) Type() string {
|
||||
return "local"
|
||||
}
|
||||
|
||||
// fileIsAllowed takes an absolute path to a file and an os.FileInfo for that file, and it checks if access to that
|
||||
// file is allowed or not. Access to a file is allowed if the file is in the FS's Base() directory, and if it's a
|
||||
// symbolic link it should not end up outside the plugin's directory.
|
||||
@@ -215,6 +219,10 @@ func NewStaticFS(fs FS) (StaticFS, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (f StaticFS) Type() string {
|
||||
return f.FS.Type()
|
||||
}
|
||||
|
||||
// Open checks that name is an allowed file and, if so, it returns a fs.File to access it, by calling the
|
||||
// underlying FS' Open() method.
|
||||
// If access is denied, the function returns ErrFileNotExist.
|
||||
|
||||
@@ -444,6 +444,10 @@ func NewFakePluginFS(base string) *FakePluginFS {
|
||||
}
|
||||
}
|
||||
|
||||
func (f *FakePluginFS) Type() string {
|
||||
return "fake"
|
||||
}
|
||||
|
||||
func (f *FakePluginFS) Open(name string) (fs.File, error) {
|
||||
if f.OpenFunc != nil {
|
||||
return f.OpenFunc(name)
|
||||
|
||||
@@ -345,6 +345,10 @@ func newPathSeparatorOverrideFS(sep string, ufs plugins.FS) (fsPathSeparatorFile
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (f fsPathSeparatorFiles) Type() string {
|
||||
return f.FS.Type()
|
||||
}
|
||||
|
||||
// Files returns LocalFS.Files(), but all path separators for the current platform (filepath.Separator)
|
||||
// are replaced with f.separator.
|
||||
func (f fsPathSeparatorFiles) Files() ([]string, error) {
|
||||
|
||||
@@ -456,3 +456,20 @@ type QueryCachingConfig struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
TTLMS int64 `json:"TTLMs"`
|
||||
}
|
||||
|
||||
// CloudProvisioningMethod is the method used to provision the plugin in Grafana Cloud.
|
||||
type CloudProvisioningMethod string
|
||||
|
||||
const (
|
||||
// CloudProvisioningMethodUnknown is used when the plugin provisioning method is unknown.
|
||||
CloudProvisioningMethodUnknown CloudProvisioningMethod = "unknown"
|
||||
|
||||
// CloudProvisioningMethodNone is used when the plugin is not provisioned in Grafana Cloud.
|
||||
CloudProvisioningMethodNone CloudProvisioningMethod = "none"
|
||||
|
||||
// CloudProvisioningMethodURL is used when the plugin is provisioned from a URL.
|
||||
CloudProvisioningMethodURL CloudProvisioningMethod = "url"
|
||||
|
||||
// CloudProvisioningMethodCatalog is used when the plugin is provisioned from the catalog.
|
||||
CloudProvisioningMethodCatalog CloudProvisioningMethod = "catalog"
|
||||
)
|
||||
|
||||
@@ -47,6 +47,10 @@ func (f inMemoryFS) Open(fn string) (fs.File, error) {
|
||||
return &inMemoryFile{path: fn, reader: bytes.NewReader(f.files[fn])}, nil
|
||||
}
|
||||
|
||||
func (f inMemoryFS) Type() string {
|
||||
return "in-memory"
|
||||
}
|
||||
|
||||
// NewFakeFS returns a new FS that always returns ErrFileNotExist when trying to Open() and empty Files().
|
||||
func NewFakeFS() FS {
|
||||
return NewInMemoryFS(nil)
|
||||
|
||||
+12
-12
@@ -536,7 +536,8 @@ func Initialize(ctx context.Context, cfg *setting.Cfg, opts Options, apiOpts api
|
||||
registryRegistry := registry2.ProvideExtSvcRegistry(cfg, extSvcAccountsService, serverLockService, featureToggles)
|
||||
service13 := service6.ProvideService(sqlStore, secretsService)
|
||||
serviceregistrationService := serviceregistration.ProvideService(cfg, featureToggles, registryRegistry, service13)
|
||||
initialize := pipeline.ProvideInitializationStage(pluginManagementCfg, inMemory, providerService, processService, serviceregistrationService, acimplService, actionSetService, envVarsProvider, tracingService)
|
||||
noop := provisionedplugins.NewNoop()
|
||||
initialize := pipeline.ProvideInitializationStage(pluginManagementCfg, inMemory, providerService, processService, serviceregistrationService, acimplService, actionSetService, envVarsProvider, tracingService, noop)
|
||||
terminate, err := pipeline.ProvideTerminationStage(pluginManagementCfg, inMemory, processService)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -663,10 +664,9 @@ func Initialize(ctx context.Context, cfg *setting.Cfg, opts Options, apiOpts api
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
noop := managedplugins.NewNoop()
|
||||
provisionedpluginsNoop := provisionedplugins.NewNoop()
|
||||
managedpluginsNoop := managedplugins.NewNoop()
|
||||
preinstallImpl := pluginchecker.ProvidePreinstall(cfg)
|
||||
plugincheckerService := pluginchecker.ProvideService(noop, provisionedpluginsNoop, preinstallImpl)
|
||||
plugincheckerService := pluginchecker.ProvideService(managedpluginsNoop, noop, preinstallImpl)
|
||||
pluginsService, err := updatemanager.ProvidePluginsService(cfg, pluginstoreService, pluginInstaller, tracingService, featureToggles, plugincheckerService)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -715,7 +715,7 @@ func Initialize(ctx context.Context, cfg *setting.Cfg, opts Options, apiOpts api
|
||||
}
|
||||
idimplService := idimpl.ProvideService(cfg, localSigner, remoteCache, authnService, registerer, tracer)
|
||||
verifier := userimpl.ProvideVerifier(cfg, userService, tempuserService, notificationService, idimplService)
|
||||
httpServer, err := api.ProvideHTTPServer(apiOpts, cfg, routeRegisterImpl, inProcBus, renderingService, ossLicensingService, hooksService, cacheService, sqlStore, ossDataSourceRequestValidator, pluginstoreService, service14, pluginstoreService, middlewareHandler, pluginerrsStore, pluginInstaller, ossImpl, cacheServiceImpl, userAuthTokenService, cleanUpService, shortURLService, queryHistoryService, correlationsService, remoteCache, provisioningServiceImpl, accessControl, dataSourceProxyService, searchSearchService, grafanaLive, gateway, plugincontextProvider, contexthandlerContextHandler, logger, featureToggles, alertNG, libraryPanelService, libraryElementService, quotaService, socialService, tracingService, serviceService, grafanaService, pluginsService, ossService, service15, queryServiceImpl, filestoreService, serviceAccountsProxy, pluginassetsService, authinfoimplService, storageService, notificationService, dashboardService, dashboardProvisioningService, folderimplService, ossProvider, serviceImpl, service13, avatarCacheServer, prefService, folderPermissionsService, dashboardPermissionsService, dashverService, starService, csrfCSRF, noop, playlistService, apikeyService, kvStore, secretsMigrator, secretsService, secretMigrationProviderImpl, secretsKVStore, apiApi, userService, tempuserService, loginattemptimplService, orgService, deletionService, teamService, acimplService, navtreeService, repositoryImpl, tagimplService, searchHTTPService, oauthtokenService, statsService, authnService, pluginscdnService, gatherer, apiAPI, registerer, eventualRestConfigProvider, anonDeviceService, verifier, preinstallImpl)
|
||||
httpServer, err := api.ProvideHTTPServer(apiOpts, cfg, routeRegisterImpl, inProcBus, renderingService, ossLicensingService, hooksService, cacheService, sqlStore, ossDataSourceRequestValidator, pluginstoreService, service14, pluginstoreService, middlewareHandler, pluginerrsStore, pluginInstaller, ossImpl, cacheServiceImpl, userAuthTokenService, cleanUpService, shortURLService, queryHistoryService, correlationsService, remoteCache, provisioningServiceImpl, accessControl, dataSourceProxyService, searchSearchService, grafanaLive, gateway, plugincontextProvider, contexthandlerContextHandler, logger, featureToggles, alertNG, libraryPanelService, libraryElementService, quotaService, socialService, tracingService, serviceService, grafanaService, pluginsService, ossService, service15, queryServiceImpl, filestoreService, serviceAccountsProxy, pluginassetsService, authinfoimplService, storageService, notificationService, dashboardService, dashboardProvisioningService, folderimplService, ossProvider, serviceImpl, service13, avatarCacheServer, prefService, folderPermissionsService, dashboardPermissionsService, dashverService, starService, csrfCSRF, managedpluginsNoop, playlistService, apikeyService, kvStore, secretsMigrator, secretsService, secretMigrationProviderImpl, secretsKVStore, apiApi, userService, tempuserService, loginattemptimplService, orgService, deletionService, teamService, acimplService, navtreeService, repositoryImpl, tagimplService, searchHTTPService, oauthtokenService, statsService, authnService, pluginscdnService, gatherer, apiAPI, registerer, eventualRestConfigProvider, anonDeviceService, verifier, preinstallImpl)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -776,7 +776,7 @@ func Initialize(ctx context.Context, cfg *setting.Cfg, opts Options, apiOpts api
|
||||
}
|
||||
zanzanaReconciler := dualwrite2.ProvideZanzanaReconciler(cfg, featureToggles, zanzanaClient, sqlStore, serverLockService, folderimplService)
|
||||
investigationsAppProvider := investigations.RegisterApp(cfg)
|
||||
checkregistryService := checkregistry.ProvideService(service15, pluginstoreService, plugincontextProvider, middlewareHandler, plugincheckerService, repoManager, preinstallImpl, noop, provisionedpluginsNoop, ssosettingsimplService, cfg, pluginerrsStore)
|
||||
checkregistryService := checkregistry.ProvideService(service15, pluginstoreService, plugincontextProvider, middlewareHandler, plugincheckerService, repoManager, preinstallImpl, managedpluginsNoop, noop, ssosettingsimplService, cfg, pluginerrsStore)
|
||||
advisorAppProvider := advisor2.RegisterApp(checkregistryService, cfg)
|
||||
alertingNotificationsAppProvider := notifications2.RegisterApp(cfg, alertNG)
|
||||
appregistryService, err := appregistry.ProvideBuilderRunners(apiserverService, eventualRestConfigProvider, featureToggles, investigationsAppProvider, advisorAppProvider, alertingNotificationsAppProvider, cfg)
|
||||
@@ -1127,7 +1127,8 @@ func InitializeForTest(ctx context.Context, t sqlutil.ITestDB, testingT interfac
|
||||
registryRegistry := registry2.ProvideExtSvcRegistry(cfg, extSvcAccountsService, serverLockService, featureToggles)
|
||||
service13 := service6.ProvideService(sqlStore, secretsService)
|
||||
serviceregistrationService := serviceregistration.ProvideService(cfg, featureToggles, registryRegistry, service13)
|
||||
initialize := pipeline.ProvideInitializationStage(pluginManagementCfg, inMemory, providerService, processService, serviceregistrationService, acimplService, actionSetService, envVarsProvider, tracingService)
|
||||
noop := provisionedplugins.NewNoop()
|
||||
initialize := pipeline.ProvideInitializationStage(pluginManagementCfg, inMemory, providerService, processService, serviceregistrationService, acimplService, actionSetService, envVarsProvider, tracingService, noop)
|
||||
terminate, err := pipeline.ProvideTerminationStage(pluginManagementCfg, inMemory, processService)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -1256,10 +1257,9 @@ func InitializeForTest(ctx context.Context, t sqlutil.ITestDB, testingT interfac
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
noop := managedplugins.NewNoop()
|
||||
provisionedpluginsNoop := provisionedplugins.NewNoop()
|
||||
managedpluginsNoop := managedplugins.NewNoop()
|
||||
preinstallImpl := pluginchecker.ProvidePreinstall(cfg)
|
||||
plugincheckerService := pluginchecker.ProvideService(noop, provisionedpluginsNoop, preinstallImpl)
|
||||
plugincheckerService := pluginchecker.ProvideService(managedpluginsNoop, noop, preinstallImpl)
|
||||
pluginsService, err := updatemanager.ProvidePluginsService(cfg, pluginstoreService, pluginInstaller, tracingService, featureToggles, plugincheckerService)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -1308,7 +1308,7 @@ func InitializeForTest(ctx context.Context, t sqlutil.ITestDB, testingT interfac
|
||||
}
|
||||
idimplService := idimpl.ProvideService(cfg, localSigner, remoteCache, authnService, registerer, tracer)
|
||||
verifier := userimpl.ProvideVerifier(cfg, userService, tempuserService, notificationServiceMock, idimplService)
|
||||
httpServer, err := api.ProvideHTTPServer(apiOpts, cfg, routeRegisterImpl, inProcBus, renderingService, ossLicensingService, hooksService, cacheService, sqlStore, ossDataSourceRequestValidator, pluginstoreService, service14, pluginstoreService, middlewareHandler, pluginerrsStore, pluginInstaller, ossImpl, cacheServiceImpl, userAuthTokenService, cleanUpService, shortURLService, queryHistoryService, correlationsService, remoteCache, provisioningServiceImpl, accessControl, dataSourceProxyService, searchSearchService, grafanaLive, gateway, plugincontextProvider, contexthandlerContextHandler, logger, featureToggles, alertNG, libraryPanelService, libraryElementService, quotaService, socialService, tracingService, serviceService, grafanaService, pluginsService, ossService, service15, queryServiceImpl, filestoreService, serviceAccountsProxy, pluginassetsService, authinfoimplService, storageService, notificationServiceMock, dashboardService, dashboardProvisioningService, folderimplService, ossProvider, serviceImpl, service13, avatarCacheServer, prefService, folderPermissionsService, dashboardPermissionsService, dashverService, starService, csrfCSRF, noop, playlistService, apikeyService, kvStore, secretsMigrator, secretsService, secretMigrationProviderImpl, secretsKVStore, apiApi, userService, tempuserService, loginattemptimplService, orgService, deletionService, teamService, acimplService, navtreeService, repositoryImpl, tagimplService, searchHTTPService, oauthtokentestService, statsService, authnService, pluginscdnService, gatherer, apiAPI, registerer, eventualRestConfigProvider, anonDeviceService, verifier, preinstallImpl)
|
||||
httpServer, err := api.ProvideHTTPServer(apiOpts, cfg, routeRegisterImpl, inProcBus, renderingService, ossLicensingService, hooksService, cacheService, sqlStore, ossDataSourceRequestValidator, pluginstoreService, service14, pluginstoreService, middlewareHandler, pluginerrsStore, pluginInstaller, ossImpl, cacheServiceImpl, userAuthTokenService, cleanUpService, shortURLService, queryHistoryService, correlationsService, remoteCache, provisioningServiceImpl, accessControl, dataSourceProxyService, searchSearchService, grafanaLive, gateway, plugincontextProvider, contexthandlerContextHandler, logger, featureToggles, alertNG, libraryPanelService, libraryElementService, quotaService, socialService, tracingService, serviceService, grafanaService, pluginsService, ossService, service15, queryServiceImpl, filestoreService, serviceAccountsProxy, pluginassetsService, authinfoimplService, storageService, notificationServiceMock, dashboardService, dashboardProvisioningService, folderimplService, ossProvider, serviceImpl, service13, avatarCacheServer, prefService, folderPermissionsService, dashboardPermissionsService, dashverService, starService, csrfCSRF, managedpluginsNoop, playlistService, apikeyService, kvStore, secretsMigrator, secretsService, secretMigrationProviderImpl, secretsKVStore, apiApi, userService, tempuserService, loginattemptimplService, orgService, deletionService, teamService, acimplService, navtreeService, repositoryImpl, tagimplService, searchHTTPService, oauthtokentestService, statsService, authnService, pluginscdnService, gatherer, apiAPI, registerer, eventualRestConfigProvider, anonDeviceService, verifier, preinstallImpl)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1369,7 +1369,7 @@ func InitializeForTest(ctx context.Context, t sqlutil.ITestDB, testingT interfac
|
||||
}
|
||||
zanzanaReconciler := dualwrite2.ProvideZanzanaReconciler(cfg, featureToggles, zanzanaClient, sqlStore, serverLockService, folderimplService)
|
||||
investigationsAppProvider := investigations.RegisterApp(cfg)
|
||||
checkregistryService := checkregistry.ProvideService(service15, pluginstoreService, plugincontextProvider, middlewareHandler, plugincheckerService, repoManager, preinstallImpl, noop, provisionedpluginsNoop, ssosettingsimplService, cfg, pluginerrsStore)
|
||||
checkregistryService := checkregistry.ProvideService(service15, pluginstoreService, plugincontextProvider, middlewareHandler, plugincheckerService, repoManager, preinstallImpl, managedpluginsNoop, noop, ssosettingsimplService, cfg, pluginerrsStore)
|
||||
advisorAppProvider := advisor2.RegisterApp(checkregistryService, cfg)
|
||||
alertingNotificationsAppProvider := notifications2.RegisterApp(cfg, alertNG)
|
||||
appregistryService, err := appregistry.ProvideBuilderRunners(apiserverService, eventualRestConfigProvider, featureToggles, investigationsAppProvider, advisorAppProvider, alertingNotificationsAppProvider, cfg)
|
||||
|
||||
@@ -30,6 +30,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/org"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pipeline"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginerrs"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/provisionedplugins"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
@@ -1558,7 +1559,7 @@ func newLoader(t *testing.T, cfg *config.PluginManagementCfg, reg registry.Servi
|
||||
return ProvideService(cfg, pipeline.ProvideDiscoveryStage(cfg, reg),
|
||||
pipeline.ProvideBootstrapStage(cfg, signature.DefaultCalculator(cfg), assets),
|
||||
pipeline.ProvideValidationStage(cfg, signature.NewValidator(signature.NewUnsignedAuthorizer(cfg)), angularInspector),
|
||||
pipeline.ProvideInitializationStage(cfg, reg, backendFactory, proc, &fakes.FakeAuthService{}, fakes.NewFakeRoleRegistry(), fakes.NewFakeActionSetRegistry(), fakes.NewFakePluginEnvProvider(), tracing.InitializeTracerForTest()),
|
||||
pipeline.ProvideInitializationStage(cfg, reg, backendFactory, proc, &fakes.FakeAuthService{}, fakes.NewFakeRoleRegistry(), fakes.NewFakeActionSetRegistry(), fakes.NewFakePluginEnvProvider(), tracing.InitializeTracerForTest(), provisionedplugins.NewNoop()),
|
||||
terminate, errTracker)
|
||||
}
|
||||
|
||||
@@ -1589,7 +1590,7 @@ func newLoaderWithOpts(t *testing.T, cfg *config.PluginManagementCfg, opts loade
|
||||
return ProvideService(cfg, pipeline.ProvideDiscoveryStage(cfg, reg),
|
||||
pipeline.ProvideBootstrapStage(cfg, signature.DefaultCalculator(cfg), assets),
|
||||
pipeline.ProvideValidationStage(cfg, signature.NewValidator(signature.NewUnsignedAuthorizer(cfg)), angularInspector),
|
||||
pipeline.ProvideInitializationStage(cfg, reg, backendFactoryProvider, proc, authServiceRegistry, fakes.NewFakeRoleRegistry(), fakes.NewFakeActionSetRegistry(), fakes.NewFakePluginEnvProvider(), tracing.InitializeTracerForTest()),
|
||||
pipeline.ProvideInitializationStage(cfg, reg, backendFactoryProvider, proc, authServiceRegistry, fakes.NewFakeRoleRegistry(), fakes.NewFakeActionSetRegistry(), fakes.NewFakePluginEnvProvider(), tracing.InitializeTracerForTest(), provisionedplugins.NewNoop()),
|
||||
terminate, errTracker)
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/registry"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/signature"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginaccesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/provisionedplugins"
|
||||
)
|
||||
|
||||
func ProvideDiscoveryStage(cfg *config.PluginManagementCfg, pr registry.Service) *discovery.Discovery {
|
||||
@@ -67,10 +68,9 @@ func ProvideValidationStage(cfg *config.PluginManagementCfg, sv signature.Valida
|
||||
|
||||
func ProvideInitializationStage(cfg *config.PluginManagementCfg, pr registry.Service, bp plugins.BackendFactoryProvider,
|
||||
pm process.Manager, externalServiceRegistry auth.ExternalServiceRegistry,
|
||||
roleRegistry pluginaccesscontrol.RoleRegistry,
|
||||
actionSetRegistry pluginaccesscontrol.ActionSetRegistry,
|
||||
pluginEnvProvider envvars.Provider,
|
||||
tracer tracing.Tracer) *initialization.Initialize {
|
||||
roleRegistry pluginaccesscontrol.RoleRegistry, actionSetRegistry pluginaccesscontrol.ActionSetRegistry,
|
||||
pluginEnvProvider envvars.Provider, tracer tracing.Tracer, provisionedPluginsManager provisionedplugins.Manager,
|
||||
) *initialization.Initialize {
|
||||
return initialization.New(cfg, initialization.Opts{
|
||||
InitializeFuncs: []initialization.InitializeFunc{
|
||||
ExternalServiceRegistrationStep(cfg, externalServiceRegistry, tracer),
|
||||
@@ -80,6 +80,8 @@ func ProvideInitializationStage(cfg *config.PluginManagementCfg, pr registry.Ser
|
||||
RegisterActionSetsStep(actionSetRegistry),
|
||||
ReportBuildMetrics,
|
||||
ReportTargetMetrics,
|
||||
ReportFSMetrics,
|
||||
ReportCloudProvisioningMetrics(provisionedPluginsManager),
|
||||
initialization.PluginRegistrationStep(pr),
|
||||
},
|
||||
})
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/codes"
|
||||
|
||||
"github.com/grafana/grafana/pkg/cmd/grafana-cli/logger"
|
||||
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
@@ -20,6 +21,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/registry"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/signature"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginaccesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/provisionedplugins"
|
||||
)
|
||||
|
||||
// ExternalServiceRegistration implements an InitializeFunc for registering external services.
|
||||
@@ -139,6 +141,48 @@ func ReportTargetMetrics(_ context.Context, p *plugins.Plugin) (*plugins.Plugin,
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// ReportFSMetrics reports plugin filesystem information for all non-core plugins.
|
||||
func ReportFSMetrics(_ context.Context, p *plugins.Plugin) (*plugins.Plugin, error) {
|
||||
if p.IsCorePlugin() {
|
||||
// No metrics for core plugins
|
||||
return p, nil
|
||||
}
|
||||
|
||||
metrics.SetPluginFSInformation(p.ID, p.FS.Type())
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// ReportCloudProvisioningMetrics reports plugin cloud provisioning information for all non-core plugins.
|
||||
func ReportCloudProvisioningMetrics(ppManaged provisionedplugins.Manager) initialization.InitializeFunc {
|
||||
cloudProvisioningMethod := plugins.CloudProvisioningMethodNone
|
||||
pps, err := ppManaged.ProvisionedPlugins(context.Background())
|
||||
if err != nil {
|
||||
cloudProvisioningMethod = plugins.CloudProvisioningMethodUnknown
|
||||
logger.Warn("Failed to get provisioned plugins", "error", err)
|
||||
}
|
||||
|
||||
return func(ctx context.Context, p *plugins.Plugin) (*plugins.Plugin, error) {
|
||||
if p.IsCorePlugin() {
|
||||
// No metrics for core plugins
|
||||
return p, nil
|
||||
}
|
||||
|
||||
for _, pp := range pps {
|
||||
if pp.ID != p.ID {
|
||||
continue
|
||||
}
|
||||
if pp.URL == "" {
|
||||
cloudProvisioningMethod = plugins.CloudProvisioningMethodCatalog
|
||||
} else {
|
||||
cloudProvisioningMethod = plugins.CloudProvisioningMethodURL
|
||||
}
|
||||
metrics.SetPluginProvisioningInformation(p.ID, string(cloudProvisioningMethod))
|
||||
}
|
||||
|
||||
return p, nil
|
||||
}
|
||||
}
|
||||
|
||||
// SignatureValidation implements a ValidateFunc for validating plugin signatures.
|
||||
type SignatureValidation struct {
|
||||
signatureValidator signature.Validator
|
||||
|
||||
@@ -5,8 +5,8 @@ import (
|
||||
"slices"
|
||||
|
||||
"github.com/Masterminds/semver"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/managedplugins"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/provisionedplugins"
|
||||
@@ -51,11 +51,14 @@ func (s *Service) isManaged(ctx context.Context, pluginID string) bool {
|
||||
|
||||
func (s *Service) isProvisioned(ctx context.Context, pluginID string) bool {
|
||||
if s.provisionedPlugins == nil {
|
||||
var err error
|
||||
s.provisionedPlugins, err = s.provisionedPluginsManager.ProvisionedPlugins(ctx)
|
||||
pps, err := s.provisionedPluginsManager.ProvisionedPlugins(ctx)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
s.provisionedPlugins = make([]string, len(pps))
|
||||
for _, pp := range pps {
|
||||
s.provisionedPlugins = append(s.provisionedPlugins, pp.ID)
|
||||
}
|
||||
}
|
||||
return slices.Contains(s.provisionedPlugins, pluginID)
|
||||
}
|
||||
|
||||
@@ -3,17 +3,22 @@ package provisionedplugins
|
||||
import "context"
|
||||
|
||||
type Manager interface {
|
||||
ProvisionedPlugins(ctx context.Context) ([]string, error)
|
||||
ProvisionedPlugins(ctx context.Context) ([]Plugin, error)
|
||||
}
|
||||
|
||||
var _ Manager = (*Noop)(nil)
|
||||
|
||||
type Plugin struct {
|
||||
ID string
|
||||
URL string
|
||||
}
|
||||
|
||||
type Noop struct{}
|
||||
|
||||
func NewNoop() *Noop {
|
||||
return &Noop{}
|
||||
}
|
||||
|
||||
func (s *Noop) ProvisionedPlugins(_ context.Context) ([]string, error) {
|
||||
return []string{}, nil
|
||||
func (s *Noop) ProvisionedPlugins(_ context.Context) ([]Plugin, error) {
|
||||
return []Plugin{}, nil
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginconfig"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginerrs"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/provisionedplugins"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
@@ -54,7 +55,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()), assetpath.ProvideService(pCfg, cdn, pluginassets.ProvideService()))
|
||||
valid := pipeline.ProvideValidationStage(pCfg, signature.NewValidator(signature.NewUnsignedAuthorizer(pCfg)), angularInspector)
|
||||
init := pipeline.ProvideInitializationStage(pCfg, reg, provider.ProvideService(coreRegistry), proc, &fakes.FakeAuthService{}, fakes.NewFakeRoleRegistry(), fakes.NewFakeActionSetRegistry(), nil, tracing.InitializeTracerForTest())
|
||||
init := pipeline.ProvideInitializationStage(pCfg, reg, provider.ProvideService(coreRegistry), proc, &fakes.FakeAuthService{}, fakes.NewFakeRoleRegistry(), fakes.NewFakeActionSetRegistry(), nil, tracing.InitializeTracerForTest(), provisionedplugins.NewNoop())
|
||||
term, err := pipeline.ProvideTerminationStage(pCfg, reg, proc)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -100,7 +101,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(), &fakes.FakeAuthService{}, fakes.NewFakeRoleRegistry(), fakes.NewFakeActionSetRegistry(), nil, tracing.InitializeTracerForTest())
|
||||
opts.Initializer = pipeline.ProvideInitializationStage(cfg, reg, provider.ProvideService(coreRegistry), process.ProvideService(), &fakes.FakeAuthService{}, fakes.NewFakeRoleRegistry(), fakes.NewFakeActionSetRegistry(), nil, tracing.InitializeTracerForTest(), provisionedplugins.NewNoop())
|
||||
}
|
||||
|
||||
if opts.Terminator == nil {
|
||||
|
||||
Reference in New Issue
Block a user