Plugins: Add tailored interface for plugins licensing needs (#61045)

* tailored licensing service

* appease linter

* fix

* retrigger
This commit is contained in:
Will Browne 2023-01-18 17:02:54 +00:00 committed by GitHub
parent 61d8ab71a3
commit c54aa18cd8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 76 additions and 87 deletions

View File

@ -20,8 +20,6 @@ type Cfg struct {
PluginSettings setting.PluginSettings PluginSettings setting.PluginSettings
PluginsAllowUnsigned []string PluginsAllowUnsigned []string
EnterpriseLicensePath string
// AWS Plugin Auth // AWS Plugin Auth
AWSAllowedAuthProviders []string AWSAllowedAuthProviders []string
AWSAssumeRoleEnabled bool AWSAssumeRoleEnabled bool
@ -59,7 +57,6 @@ func NewCfg(settingProvider setting.Provider, grafanaCfg *setting.Cfg) *Cfg {
PluginsPath: grafanaCfg.PluginsPath, PluginsPath: grafanaCfg.PluginsPath,
BuildVersion: grafanaCfg.BuildVersion, BuildVersion: grafanaCfg.BuildVersion,
DevMode: settingProvider.KeyValue("", "app_mode").MustBool(grafanaCfg.Env == setting.Dev), DevMode: settingProvider.KeyValue("", "app_mode").MustBool(grafanaCfg.Env == setting.Dev),
EnterpriseLicensePath: settingProvider.KeyValue("enterprise", "license_path").MustString(grafanaCfg.EnterpriseLicensePath),
PluginSettings: extractPluginSettings(settingProvider), PluginSettings: extractPluginSettings(settingProvider),
PluginsAllowUnsigned: allowedUnsigned, PluginsAllowUnsigned: allowedUnsigned,
AWSAllowedAuthProviders: allowedAuth, AWSAllowedAuthProviders: allowedAuth,

View File

@ -75,6 +75,14 @@ type PluginLoaderAuthorizer interface {
CanLoadPlugin(plugin *Plugin) bool CanLoadPlugin(plugin *Plugin) bool
} }
type Licensing interface {
Environment() []string
Edition() string
Path() string
}
// RoleRegistry handles the plugin RBAC roles and their assignments // RoleRegistry handles the plugin RBAC roles and their assignments
type RoleRegistry interface { type RoleRegistry interface {
DeclarePluginRoles(ctx context.Context, ID, name string, registrations []RoleRegistration) error DeclarePluginRoles(ctx context.Context, ID, name string, registrations []RoleRegistration) error

View File

@ -0,0 +1,38 @@
package licensing
import (
"fmt"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/setting"
)
type Service struct {
licensePath string
license models.Licensing
}
func ProvideLicensing(cfg *setting.Cfg, l models.Licensing) *Service {
return &Service{
licensePath: cfg.EnterpriseLicensePath,
license: l,
}
}
func (l Service) Environment() []string {
var env []string
if envProvider, ok := l.license.(models.LicenseEnvironment); ok {
for k, v := range envProvider.Environment() {
env = append(env, fmt.Sprintf("%s=%s", k, v))
}
}
return env
}
func (l Service) Edition() string {
return l.license.Edition()
}
func (l Service) Path() string {
return l.licensePath
}

View File

@ -3,6 +3,7 @@ package fakes
import ( import (
"archive/zip" "archive/zip"
"context" "context"
"fmt"
"sync" "sync"
"github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/backend"
@ -317,43 +318,25 @@ func (pr *FakeBackendProcessProvider) BackendFactory(_ context.Context, p *plugi
} }
type FakeLicensingService struct { type FakeLicensingService struct {
TokenRaw string LicenseEdition string
TokenRaw string
LicensePath string
} }
func NewFakeLicensingService() *FakeLicensingService { func NewFakeLicensingService() *FakeLicensingService {
return &FakeLicensingService{} return &FakeLicensingService{}
} }
func (t *FakeLicensingService) Expiry() int64 { func (s *FakeLicensingService) Edition() string {
return 0 return s.LicenseEdition
} }
func (t *FakeLicensingService) Edition() string { func (s *FakeLicensingService) Path() string {
return "" return s.LicensePath
} }
func (t *FakeLicensingService) StateInfo() string { func (s *FakeLicensingService) Environment() []string {
return "" return []string{fmt.Sprintf("GF_ENTERPRISE_LICENSE_TEXT=%s", s.TokenRaw)}
}
func (t *FakeLicensingService) ContentDeliveryPrefix() string {
return ""
}
func (t *FakeLicensingService) LicenseURL(_ bool) string {
return ""
}
func (t *FakeLicensingService) Environment() map[string]string {
return map[string]string{"GF_ENTERPRISE_LICENSE_TEXT": t.TokenRaw}
}
func (*FakeLicensingService) EnabledFeatures() map[string]bool {
return map[string]bool{}
}
func (*FakeLicensingService) FeatureEnabled(_ string) bool {
return false
} }
type FakeRoleRegistry struct { type FakeRoleRegistry struct {

View File

@ -10,19 +10,18 @@ import (
"github.com/grafana/grafana-azure-sdk-go/azsettings" "github.com/grafana/grafana-azure-sdk-go/azsettings"
"github.com/grafana/grafana/pkg/infra/log" "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"
"github.com/grafana/grafana/pkg/plugins/config" "github.com/grafana/grafana/pkg/plugins/config"
) )
type Initializer struct { type Initializer struct {
cfg *config.Cfg cfg *config.Cfg
license models.Licensing license plugins.Licensing
backendProvider plugins.BackendFactoryProvider backendProvider plugins.BackendFactoryProvider
log log.Logger log log.Logger
} }
func New(cfg *config.Cfg, backendProvider plugins.BackendFactoryProvider, license models.Licensing) Initializer { func New(cfg *config.Cfg, backendProvider plugins.BackendFactoryProvider, license plugins.Licensing) Initializer {
return Initializer{ return Initializer{
cfg: cfg, cfg: cfg,
license: license, license: license,
@ -57,14 +56,9 @@ func (i *Initializer) envVars(plugin *plugins.Plugin) []string {
hostEnv = append( hostEnv = append(
hostEnv, hostEnv,
fmt.Sprintf("GF_EDITION=%s", i.license.Edition()), fmt.Sprintf("GF_EDITION=%s", i.license.Edition()),
fmt.Sprintf("GF_ENTERPRISE_LICENSE_PATH=%s", i.cfg.EnterpriseLicensePath), fmt.Sprintf("GF_ENTERPRISE_LICENSE_PATH=%s", i.license.Path()),
) )
hostEnv = append(hostEnv, i.license.Environment()...)
if envProvider, ok := i.license.(models.LicenseEnvironment); ok {
for k, v := range envProvider.Environment() {
hostEnv = append(hostEnv, fmt.Sprintf("%s=%s", k, v))
}
}
} }
hostEnv = append(hostEnv, i.awsEnvVars()...) hostEnv = append(hostEnv, i.awsEnvVars()...)

View File

@ -11,6 +11,7 @@ import (
"github.com/grafana/grafana/pkg/plugins" "github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/plugins/backendplugin" "github.com/grafana/grafana/pkg/plugins/backendplugin"
"github.com/grafana/grafana/pkg/plugins/config" "github.com/grafana/grafana/pkg/plugins/config"
"github.com/grafana/grafana/pkg/plugins/manager/fakes"
) )
func TestInitializer_Initialize(t *testing.T) { func TestInitializer_Initialize(t *testing.T) {
@ -142,14 +143,14 @@ func TestInitializer_envVars(t *testing.T) {
}, },
} }
licensing := &testLicensingService{ licensing := &fakes.FakeLicensingService{
edition: "test", LicenseEdition: "test",
tokenRaw: "token", TokenRaw: "token",
LicensePath: "/path/to/ent/license",
} }
i := &Initializer{ i := &Initializer{
cfg: &config.Cfg{ cfg: &config.Cfg{
EnterpriseLicensePath: "/path/to/ent/license",
PluginSettings: map[string]map[string]string{ PluginSettings: map[string]map[string]string{
"test": { "test": {
"custom_env_var": "customVal", "custom_env_var": "customVal",
@ -201,43 +202,6 @@ func Test_pluginSettings_ToEnv(t *testing.T) {
} }
type testLicensingService struct {
edition string
tokenRaw string
}
func (t *testLicensingService) Expiry() int64 {
return 0
}
func (t *testLicensingService) Edition() string {
return t.edition
}
func (t *testLicensingService) StateInfo() string {
return ""
}
func (t *testLicensingService) ContentDeliveryPrefix() string {
return ""
}
func (t *testLicensingService) LicenseURL(_ bool) string {
return ""
}
func (t *testLicensingService) Environment() map[string]string {
return map[string]string{"GF_ENTERPRISE_LICENSE_TEXT": t.tokenRaw}
}
func (*testLicensingService) EnabledFeatures() map[string]bool {
return map[string]bool{}
}
func (*testLicensingService) FeatureEnabled(feature string) bool {
return false
}
type fakeBackendProvider struct { type fakeBackendProvider struct {
plugins.BackendFactoryProvider plugins.BackendFactoryProvider

View File

@ -16,7 +16,6 @@ import (
"github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/infra/metrics" "github.com/grafana/grafana/pkg/infra/metrics"
"github.com/grafana/grafana/pkg/infra/slugify" "github.com/grafana/grafana/pkg/infra/slugify"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/plugins" "github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/plugins/config" "github.com/grafana/grafana/pkg/plugins/config"
"github.com/grafana/grafana/pkg/plugins/logger" "github.com/grafana/grafana/pkg/plugins/logger"
@ -50,14 +49,14 @@ type Loader struct {
errs map[string]*plugins.SignatureError errs map[string]*plugins.SignatureError
} }
func ProvideService(cfg *config.Cfg, license models.Licensing, authorizer plugins.PluginLoaderAuthorizer, func ProvideService(cfg *config.Cfg, license plugins.Licensing, authorizer plugins.PluginLoaderAuthorizer,
pluginRegistry registry.Service, backendProvider plugins.BackendFactoryProvider, pluginRegistry registry.Service, backendProvider plugins.BackendFactoryProvider,
roleRegistry plugins.RoleRegistry) *Loader { roleRegistry plugins.RoleRegistry) *Loader {
return New(cfg, license, authorizer, pluginRegistry, backendProvider, process.NewManager(pluginRegistry), return New(cfg, license, authorizer, pluginRegistry, backendProvider, process.NewManager(pluginRegistry),
storage.FileSystem(logger.NewLogger("loader.fs"), cfg.PluginsPath), roleRegistry) storage.FileSystem(logger.NewLogger("loader.fs"), cfg.PluginsPath), roleRegistry)
} }
func New(cfg *config.Cfg, license models.Licensing, authorizer plugins.PluginLoaderAuthorizer, func New(cfg *config.Cfg, license plugins.Licensing, authorizer plugins.PluginLoaderAuthorizer,
pluginRegistry registry.Service, backendProvider plugins.BackendFactoryProvider, pluginRegistry registry.Service, backendProvider plugins.BackendFactoryProvider,
processManager process.Service, pluginStorage storage.Manager, roleRegistry plugins.RoleRegistry) *Loader { processManager process.Service, pluginStorage storage.Manager, roleRegistry plugins.RoleRegistry) *Loader {
return &Loader{ return &Loader{

View File

@ -11,8 +11,6 @@ import (
"github.com/grafana/grafana-azure-sdk-go/azsettings" "github.com/grafana/grafana-azure-sdk-go/azsettings"
"github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/backend/httpclient" "github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
"github.com/grafana/grafana/pkg/tsdb/parca"
"github.com/grafana/grafana/pkg/tsdb/phlare"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gopkg.in/ini.v1" "gopkg.in/ini.v1"
@ -22,6 +20,7 @@ import (
"github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin" "github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin"
"github.com/grafana/grafana/pkg/plugins/backendplugin/provider" "github.com/grafana/grafana/pkg/plugins/backendplugin/provider"
"github.com/grafana/grafana/pkg/plugins/config" "github.com/grafana/grafana/pkg/plugins/config"
plicensing "github.com/grafana/grafana/pkg/plugins/licensing"
"github.com/grafana/grafana/pkg/plugins/manager/client" "github.com/grafana/grafana/pkg/plugins/manager/client"
"github.com/grafana/grafana/pkg/plugins/manager/fakes" "github.com/grafana/grafana/pkg/plugins/manager/fakes"
"github.com/grafana/grafana/pkg/plugins/manager/loader" "github.com/grafana/grafana/pkg/plugins/manager/loader"
@ -43,6 +42,8 @@ import (
"github.com/grafana/grafana/pkg/tsdb/mssql" "github.com/grafana/grafana/pkg/tsdb/mssql"
"github.com/grafana/grafana/pkg/tsdb/mysql" "github.com/grafana/grafana/pkg/tsdb/mysql"
"github.com/grafana/grafana/pkg/tsdb/opentsdb" "github.com/grafana/grafana/pkg/tsdb/opentsdb"
"github.com/grafana/grafana/pkg/tsdb/parca"
"github.com/grafana/grafana/pkg/tsdb/phlare"
"github.com/grafana/grafana/pkg/tsdb/postgres" "github.com/grafana/grafana/pkg/tsdb/postgres"
"github.com/grafana/grafana/pkg/tsdb/prometheus" "github.com/grafana/grafana/pkg/tsdb/prometheus"
"github.com/grafana/grafana/pkg/tsdb/tempo" "github.com/grafana/grafana/pkg/tsdb/tempo"
@ -109,7 +110,9 @@ func TestIntegrationPluginManager(t *testing.T) {
pCfg := config.ProvideConfig(setting.ProvideProvider(cfg), cfg) pCfg := config.ProvideConfig(setting.ProvideProvider(cfg), cfg)
reg := registry.ProvideService() reg := registry.ProvideService()
l := loader.ProvideService(pCfg, &licensing.OSSLicensingService{Cfg: cfg}, signature.NewUnsignedAuthorizer(pCfg),
lic := plicensing.ProvideLicensing(cfg, &licensing.OSSLicensingService{Cfg: cfg})
l := loader.ProvideService(pCfg, lic, signature.NewUnsignedAuthorizer(pCfg),
reg, provider.ProvideService(coreRegistry), fakes.NewFakeRoleRegistry()) reg, provider.ProvideService(coreRegistry), fakes.NewFakeRoleRegistry())
ps, err := store.ProvideService(cfg, pCfg, reg, l) ps, err := store.ProvideService(cfg, pCfg, reg, l)
require.NoError(t, err) require.NoError(t, err)

View File

@ -6,6 +6,7 @@ import (
"github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin" "github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin"
"github.com/grafana/grafana/pkg/plugins/backendplugin/provider" "github.com/grafana/grafana/pkg/plugins/backendplugin/provider"
"github.com/grafana/grafana/pkg/plugins/config" "github.com/grafana/grafana/pkg/plugins/config"
"github.com/grafana/grafana/pkg/plugins/licensing"
"github.com/grafana/grafana/pkg/plugins/manager" "github.com/grafana/grafana/pkg/plugins/manager"
"github.com/grafana/grafana/pkg/plugins/manager/client" "github.com/grafana/grafana/pkg/plugins/manager/client"
"github.com/grafana/grafana/pkg/plugins/manager/loader" "github.com/grafana/grafana/pkg/plugins/manager/loader"
@ -43,6 +44,8 @@ var WireSet = wire.NewSet(
repo.ProvideService, repo.ProvideService,
wire.Bind(new(repo.Service), new(*repo.Manager)), wire.Bind(new(repo.Service), new(*repo.Manager)),
plugincontext.ProvideService, plugincontext.ProvideService,
licensing.ProvideLicensing,
wire.Bind(new(plugins.Licensing), new(*licensing.Service)),
) )
// WireExtensionSet provides a wire.ProviderSet of plugin providers that can be // WireExtensionSet provides a wire.ProviderSet of plugin providers that can be