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

View File

@ -75,6 +75,14 @@ type PluginLoaderAuthorizer interface {
CanLoadPlugin(plugin *Plugin) bool
}
type Licensing interface {
Environment() []string
Edition() string
Path() string
}
// RoleRegistry handles the plugin RBAC roles and their assignments
type RoleRegistry interface {
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 (
"archive/zip"
"context"
"fmt"
"sync"
"github.com/grafana/grafana-plugin-sdk-go/backend"
@ -317,43 +318,25 @@ func (pr *FakeBackendProcessProvider) BackendFactory(_ context.Context, p *plugi
}
type FakeLicensingService struct {
TokenRaw string
LicenseEdition string
TokenRaw string
LicensePath string
}
func NewFakeLicensingService() *FakeLicensingService {
return &FakeLicensingService{}
}
func (t *FakeLicensingService) Expiry() int64 {
return 0
func (s *FakeLicensingService) Edition() string {
return s.LicenseEdition
}
func (t *FakeLicensingService) Edition() string {
return ""
func (s *FakeLicensingService) Path() string {
return s.LicensePath
}
func (t *FakeLicensingService) StateInfo() string {
return ""
}
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
func (s *FakeLicensingService) Environment() []string {
return []string{fmt.Sprintf("GF_ENTERPRISE_LICENSE_TEXT=%s", s.TokenRaw)}
}
type FakeRoleRegistry struct {

View File

@ -10,19 +10,18 @@ import (
"github.com/grafana/grafana-azure-sdk-go/azsettings"
"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/config"
)
type Initializer struct {
cfg *config.Cfg
license models.Licensing
license plugins.Licensing
backendProvider plugins.BackendFactoryProvider
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{
cfg: cfg,
license: license,
@ -57,14 +56,9 @@ func (i *Initializer) envVars(plugin *plugins.Plugin) []string {
hostEnv = append(
hostEnv,
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()),
)
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.license.Environment()...)
}
hostEnv = append(hostEnv, i.awsEnvVars()...)

View File

@ -11,6 +11,7 @@ import (
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/plugins/backendplugin"
"github.com/grafana/grafana/pkg/plugins/config"
"github.com/grafana/grafana/pkg/plugins/manager/fakes"
)
func TestInitializer_Initialize(t *testing.T) {
@ -142,14 +143,14 @@ func TestInitializer_envVars(t *testing.T) {
},
}
licensing := &testLicensingService{
edition: "test",
tokenRaw: "token",
licensing := &fakes.FakeLicensingService{
LicenseEdition: "test",
TokenRaw: "token",
LicensePath: "/path/to/ent/license",
}
i := &Initializer{
cfg: &config.Cfg{
EnterpriseLicensePath: "/path/to/ent/license",
PluginSettings: map[string]map[string]string{
"test": {
"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 {
plugins.BackendFactoryProvider

View File

@ -16,7 +16,6 @@ import (
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/infra/metrics"
"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/config"
"github.com/grafana/grafana/pkg/plugins/logger"
@ -50,14 +49,14 @@ type Loader struct {
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,
roleRegistry plugins.RoleRegistry) *Loader {
return New(cfg, license, authorizer, pluginRegistry, backendProvider, process.NewManager(pluginRegistry),
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,
processManager process.Service, pluginStorage storage.Manager, roleRegistry plugins.RoleRegistry) *Loader {
return &Loader{

View File

@ -11,8 +11,6 @@ import (
"github.com/grafana/grafana-azure-sdk-go/azsettings"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"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"
"gopkg.in/ini.v1"
@ -22,6 +20,7 @@ import (
"github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin"
"github.com/grafana/grafana/pkg/plugins/backendplugin/provider"
"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/fakes"
"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/mysql"
"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/prometheus"
"github.com/grafana/grafana/pkg/tsdb/tempo"
@ -109,7 +110,9 @@ func TestIntegrationPluginManager(t *testing.T) {
pCfg := config.ProvideConfig(setting.ProvideProvider(cfg), cfg)
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())
ps, err := store.ProvideService(cfg, pCfg, reg, l)
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/provider"
"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/client"
"github.com/grafana/grafana/pkg/plugins/manager/loader"
@ -43,6 +44,8 @@ var WireSet = wire.NewSet(
repo.ProvideService,
wire.Bind(new(repo.Service), new(*repo.Manager)),
plugincontext.ProvideService,
licensing.ProvideLicensing,
wire.Bind(new(plugins.Licensing), new(*licensing.Service)),
)
// WireExtensionSet provides a wire.ProviderSet of plugin providers that can be