From dfc1875061f03dde4b399d433b7795f117706f26 Mon Sep 17 00:00:00 2001 From: Hugo Kiyodi Oshiro Date: Tue, 24 Oct 2023 16:21:37 +0200 Subject: [PATCH] Plugins: Add managed instance installation resources (#76767) * Plugins: Add configs to allow managed install * Expose methods to use with cloud plugin installer * Change plugins installer bind to OSS --- conf/defaults.ini | 2 ++ pkg/plugins/manager/fakes/fakes.go | 8 ++++++++ pkg/plugins/manager/installer.go | 4 ++-- pkg/plugins/repo/client.go | 6 +++--- pkg/plugins/repo/ifaces.go | 2 ++ pkg/plugins/repo/service.go | 6 +++--- pkg/server/wireexts_oss.go | 3 +++ pkg/services/pluginsintegration/pluginsintegration.go | 3 --- pkg/setting/setting.go | 1 + pkg/setting/setting_plugins.go | 3 +++ 10 files changed, 27 insertions(+), 11 deletions(-) diff --git a/conf/defaults.ini b/conf/defaults.ini index f41d4c95cd2..33ef56bce97 100644 --- a/conf/defaults.ini +++ b/conf/defaults.ini @@ -1505,6 +1505,8 @@ public_key_retrieval_disabled = false public_key_retrieval_on_startup = false # Enter a comma-separated list of plugin identifiers to avoid loading (including core plugins). These plugins will be hidden in the catalog. disable_plugins = +# Auth token for plugin installations and removal in managed instances +install_token = #################################### Grafana Live ########################################## [live] diff --git a/pkg/plugins/manager/fakes/fakes.go b/pkg/plugins/manager/fakes/fakes.go index 7d6d9b5ee64..908a3cfd506 100644 --- a/pkg/plugins/manager/fakes/fakes.go +++ b/pkg/plugins/manager/fakes/fakes.go @@ -204,6 +204,7 @@ type FakePluginRepo struct { GetPluginArchiveFunc func(_ context.Context, pluginID, version string, _ repo.CompatOpts) (*repo.PluginArchive, error) GetPluginArchiveByURLFunc func(_ context.Context, archiveURL string, _ repo.CompatOpts) (*repo.PluginArchive, error) GetPluginArchiveInfoFunc func(_ context.Context, pluginID, version string, _ repo.CompatOpts) (*repo.PluginArchiveInfo, error) + PluginVersionFunc func(pluginID, version string, compatOpts repo.CompatOpts) (repo.VersionData, error) } // GetPluginArchive fetches the requested plugin archive. @@ -232,6 +233,13 @@ func (r *FakePluginRepo) GetPluginArchiveInfo(ctx context.Context, pluginID, ver return &repo.PluginArchiveInfo{}, nil } +func (r *FakePluginRepo) PluginVersion(pluginID, version string, compatOpts repo.CompatOpts) (repo.VersionData, error) { + if r.PluginVersionFunc != nil { + return r.PluginVersionFunc(pluginID, version, compatOpts) + } + return repo.VersionData{}, nil +} + type FakePluginStorage struct { ExtractFunc func(_ context.Context, pluginID string, dirNameFunc storage.DirNameGeneratorFunc, z *zip.ReadCloser) (*storage.ExtractedPluginArchive, error) } diff --git a/pkg/plugins/manager/installer.go b/pkg/plugins/manager/installer.go index 8e8f5ce9aad..249b01b8a5b 100644 --- a/pkg/plugins/manager/installer.go +++ b/pkg/plugins/manager/installer.go @@ -45,7 +45,7 @@ func New(pluginRegistry registry.Service, pluginLoader loader.Service, pluginRep } func (m *PluginInstaller) Add(ctx context.Context, pluginID, version string, opts plugins.CompatOpts) error { - compatOpts, err := repoCompatOpts(opts) + compatOpts, err := RepoCompatOpts(opts) if err != nil { return err } @@ -169,7 +169,7 @@ func (m *PluginInstaller) plugin(ctx context.Context, pluginID string) (*plugins return p, true } -func repoCompatOpts(opts plugins.CompatOpts) (repo.CompatOpts, error) { +func RepoCompatOpts(opts plugins.CompatOpts) (repo.CompatOpts, error) { os := opts.OS() arch := opts.Arch() if len(os) == 0 || len(arch) == 0 { diff --git a/pkg/plugins/repo/client.go b/pkg/plugins/repo/client.go index ae366afa2e8..661b752b7f2 100644 --- a/pkg/plugins/repo/client.go +++ b/pkg/plugins/repo/client.go @@ -29,8 +29,8 @@ type Client struct { func NewClient(skipTLSVerify bool, logger log.PrettyLogger) *Client { return &Client{ - httpClient: makeHttpClient(skipTLSVerify, 10*time.Second), - httpClientNoTimeout: makeHttpClient(skipTLSVerify, 0), + httpClient: MakeHttpClient(skipTLSVerify, 10*time.Second), + httpClientNoTimeout: MakeHttpClient(skipTLSVerify, 0), log: logger, } } @@ -234,7 +234,7 @@ func (c *Client) handleResp(res *http.Response, compatOpts CompatOpts) (io.ReadC return res.Body, nil } -func makeHttpClient(skipTLSVerify bool, timeout time.Duration) http.Client { +func MakeHttpClient(skipTLSVerify bool, timeout time.Duration) http.Client { return http.Client{ Timeout: timeout, Transport: &http.Transport{ diff --git a/pkg/plugins/repo/ifaces.go b/pkg/plugins/repo/ifaces.go index 1f63010a285..c68843f7f79 100644 --- a/pkg/plugins/repo/ifaces.go +++ b/pkg/plugins/repo/ifaces.go @@ -14,6 +14,8 @@ type Service interface { GetPluginArchiveByURL(ctx context.Context, archiveURL string, opts CompatOpts) (*PluginArchive, error) // GetPluginArchiveInfo fetches information needed for downloading the requested plugin. GetPluginArchiveInfo(ctx context.Context, pluginID, version string, opts CompatOpts) (*PluginArchiveInfo, error) + // PluginVersion will return plugin version based on the requested information. + PluginVersion(pluginID, version string, compatOpts CompatOpts) (VersionData, error) } type CompatOpts struct { diff --git a/pkg/plugins/repo/service.go b/pkg/plugins/repo/service.go index b6422a1dd8a..0bd1b7a7e6b 100644 --- a/pkg/plugins/repo/service.go +++ b/pkg/plugins/repo/service.go @@ -63,7 +63,7 @@ func (m *Manager) GetPluginArchiveByURL(ctx context.Context, pluginZipURL string // GetPluginArchiveInfo returns the options for downloading the requested plugin (with optional `version`) func (m *Manager) GetPluginArchiveInfo(_ context.Context, pluginID, version string, compatOpts CompatOpts) (*PluginArchiveInfo, error) { - v, err := m.pluginVersion(pluginID, version, compatOpts) + v, err := m.PluginVersion(pluginID, version, compatOpts) if err != nil { return nil, err } @@ -75,8 +75,8 @@ func (m *Manager) GetPluginArchiveInfo(_ context.Context, pluginID, version stri }, nil } -// pluginVersion will return plugin version based on the requested information -func (m *Manager) pluginVersion(pluginID, version string, compatOpts CompatOpts) (VersionData, error) { +// PluginVersion will return plugin version based on the requested information +func (m *Manager) PluginVersion(pluginID, version string, compatOpts CompatOpts) (VersionData, error) { versions, err := m.grafanaCompatiblePluginVersions(pluginID, compatOpts) if err != nil { return VersionData{}, err diff --git a/pkg/server/wireexts_oss.go b/pkg/server/wireexts_oss.go index 9460f2d6595..0c4082fa520 100644 --- a/pkg/server/wireexts_oss.go +++ b/pkg/server/wireexts_oss.go @@ -8,6 +8,7 @@ import ( "github.com/google/wire" "github.com/grafana/grafana/pkg/plugins" + "github.com/grafana/grafana/pkg/plugins/manager" "github.com/grafana/grafana/pkg/registry" "github.com/grafana/grafana/pkg/registry/backgroundsvcs" "github.com/grafana/grafana/pkg/registry/usagestatssvcs" @@ -94,6 +95,8 @@ var wireExtsBasicSet = wire.NewSet( wire.Bind(new(secrets.Migrator), new(*secretsMigrator.SecretsMigrator)), idimpl.ProvideLocalSigner, wire.Bind(new(auth.IDSigner), new(*idimpl.LocalSigner)), + manager.ProvideInstaller, + wire.Bind(new(plugins.Installer), new(*manager.PluginInstaller)), ) var wireExtsSet = wire.NewSet( diff --git a/pkg/services/pluginsintegration/pluginsintegration.go b/pkg/services/pluginsintegration/pluginsintegration.go index 8fd1143ad08..3ba43f36c76 100644 --- a/pkg/services/pluginsintegration/pluginsintegration.go +++ b/pkg/services/pluginsintegration/pluginsintegration.go @@ -11,7 +11,6 @@ import ( "github.com/grafana/grafana/pkg/plugins/backendplugin/provider" pCfg "github.com/grafana/grafana/pkg/plugins/config" "github.com/grafana/grafana/pkg/plugins/log" - "github.com/grafana/grafana/pkg/plugins/manager" "github.com/grafana/grafana/pkg/plugins/manager/client" "github.com/grafana/grafana/pkg/plugins/manager/filestore" pluginLoader "github.com/grafana/grafana/pkg/plugins/manager/loader" @@ -90,8 +89,6 @@ var WireSet = wire.NewSet( wire.Bind(new(pluginerrs.SignatureErrorTracker), new(*pluginerrs.SignatureErrorRegistry)), pluginerrs.ProvideStore, wire.Bind(new(plugins.ErrorResolver), new(*pluginerrs.Store)), - manager.ProvideInstaller, - wire.Bind(new(plugins.Installer), new(*manager.PluginInstaller)), registry.ProvideService, wire.Bind(new(registry.Service), new(*registry.InMemory)), repo.ProvideService, diff --git a/pkg/setting/setting.go b/pkg/setting/setting.go index 48e39f2f411..75c72d471b4 100644 --- a/pkg/setting/setting.go +++ b/pkg/setting/setting.go @@ -246,6 +246,7 @@ type Cfg struct { PluginForcePublicKeyDownload bool PluginSkipPublicKeyDownload bool DisablePlugins []string + PluginInstallToken string PluginsCDNURLTemplate string PluginLogBackendRequests bool diff --git a/pkg/setting/setting_plugins.go b/pkg/setting/setting_plugins.go index 29b8e9102b1..de2e047289f 100644 --- a/pkg/setting/setting_plugins.go +++ b/pkg/setting/setting_plugins.go @@ -64,5 +64,8 @@ func (cfg *Cfg) readPluginSettings(iniFile *ini.File) error { cfg.PluginsCDNURLTemplate = strings.TrimRight(pluginsSection.Key("cdn_base_url").MustString(""), "/") cfg.PluginLogBackendRequests = pluginsSection.Key("log_backend_requests").MustBool(false) + // Installation token for managed plugins + cfg.PluginInstallToken = pluginsSection.Key("install_token").MustString("") + return nil }