mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
feat: pass gcom sso_api_token to repo created from install command (#98973)
* feat: pass gcom sso_api_token to repo created from install command * fix * fix: extract gcom section to a func * Update pkg/cmd/grafana-cli/utils/command_line.go Co-authored-by: Giuseppe Guerra <giuseppe.guerra@grafana.com> * fix: only set gcom token when the request is to GCOM --------- Co-authored-by: Giuseppe Guerra <giuseppe.guerra@grafana.com>
This commit is contained in:
parent
79fc26ea87
commit
dfe0712955
@ -90,6 +90,7 @@ type pluginInstallOpts struct {
|
||||
repoURL string
|
||||
pluginURL string
|
||||
pluginDir string
|
||||
gcomToken string
|
||||
}
|
||||
|
||||
func newInstallPluginOpts(c utils.CommandLine) pluginInstallOpts {
|
||||
@ -98,6 +99,7 @@ func newInstallPluginOpts(c utils.CommandLine) pluginInstallOpts {
|
||||
repoURL: c.PluginRepoURL(),
|
||||
pluginURL: c.PluginURL(),
|
||||
pluginDir: c.PluginDirectory(),
|
||||
gcomToken: c.GcomToken(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -132,9 +134,10 @@ func doInstallPlugin(ctx context.Context, pluginID, version string, o pluginInst
|
||||
}
|
||||
|
||||
repository := repo.NewManager(repo.ManagerCfg{
|
||||
SkipTLSVerify: o.insecure,
|
||||
BaseURL: o.repoURL,
|
||||
Logger: services.Logger,
|
||||
SkipTLSVerify: o.insecure,
|
||||
BaseURL: o.repoURL,
|
||||
Logger: services.Logger,
|
||||
GrafanaComAPIToken: o.gcomToken,
|
||||
})
|
||||
|
||||
// FIXME: Re-enable grafanaVersion. This check was broken in 10.2 so disabling it for the moment.
|
||||
|
@ -106,7 +106,8 @@ func TestValidatePluginRepoConfig(t *testing.T) {
|
||||
t.Skip("skipping integration test")
|
||||
}
|
||||
grafDir, cfgPath := testinfra.CreateGrafDir(t, testinfra.GrafanaOpts{
|
||||
GrafanaComAPIURL: "https://grafana-dev.com",
|
||||
GrafanaComAPIURL: "https://grafana-dev.com",
|
||||
GrafanaComSSOAPIToken: "token3",
|
||||
})
|
||||
|
||||
c, err := commandstest.NewCliContext(map[string]string{
|
||||
@ -116,6 +117,9 @@ func TestValidatePluginRepoConfig(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
repoURL := c.PluginRepoURL()
|
||||
require.Equal(t, "https://grafana-dev.com/plugins", repoURL)
|
||||
|
||||
token := c.GcomToken()
|
||||
require.Equal(t, "token3", token)
|
||||
})
|
||||
|
||||
t.Run("Should use config overrides parameter if it is set alongside config parameter", func(t *testing.T) {
|
||||
|
@ -26,6 +26,7 @@ type CommandLine interface {
|
||||
PluginDirectory() string
|
||||
PluginRepoURL() string
|
||||
PluginURL() string
|
||||
GcomToken() string
|
||||
}
|
||||
|
||||
type ApiClient interface {
|
||||
@ -75,12 +76,7 @@ func (c *ContextCommandLine) PluginRepoURL() string {
|
||||
|
||||
// if --config flag is set, try to get the GrafanaComAPIURL setting
|
||||
if c.ConfigFile() != "" {
|
||||
configOptions := strings.Split(c.String("configOverrides"), " ")
|
||||
cfg, err := setting.NewCfgFromArgs(setting.CommandLineArgs{
|
||||
Config: c.ConfigFile(),
|
||||
HomePath: c.HomePath(),
|
||||
Args: append(configOptions, c.Args().Slice()...),
|
||||
})
|
||||
cfg, err := c.Config()
|
||||
|
||||
if err != nil {
|
||||
logger.Debug("Could not parse config file", err)
|
||||
@ -92,6 +88,25 @@ func (c *ContextCommandLine) PluginRepoURL() string {
|
||||
return c.String("repo")
|
||||
}
|
||||
|
||||
func (c *ContextCommandLine) Config() (*setting.Cfg, error) {
|
||||
configOptions := strings.Split(c.String("configOverrides"), " ")
|
||||
return setting.NewCfgFromArgs(setting.CommandLineArgs{
|
||||
Config: c.ConfigFile(),
|
||||
HomePath: c.HomePath(),
|
||||
Args: append(configOptions, c.Args().Slice()...),
|
||||
})
|
||||
}
|
||||
|
||||
func (c *ContextCommandLine) GcomToken() string {
|
||||
cfg, err := c.Config()
|
||||
|
||||
if err != nil {
|
||||
logger.Debug("Could not parse config file", err)
|
||||
return ""
|
||||
}
|
||||
return cfg.GrafanaComSSOAPIToken
|
||||
}
|
||||
|
||||
func (c *ContextCommandLine) PluginURL() string {
|
||||
return c.String("pluginUrl")
|
||||
}
|
||||
|
@ -146,6 +146,19 @@ func (_m *MockCommandLine) PluginURL() string {
|
||||
return r0
|
||||
}
|
||||
|
||||
func (_m *MockCommandLine) GcomToken() string {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 string
|
||||
if rf, ok := ret.Get(0).(func() string); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
r0 = ret.Get(0).(string)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// ShowHelp provides a mock function with given fields:
|
||||
func (_m *MockCommandLine) ShowHelp() error {
|
||||
ret := _m.Called()
|
||||
|
@ -14,6 +14,7 @@ import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/plugins/log"
|
||||
@ -24,16 +25,18 @@ type Client struct {
|
||||
httpClientNoTimeout http.Client
|
||||
retryCount int
|
||||
grafanaComAPIToken string
|
||||
grafanaComAPIURL string
|
||||
|
||||
log log.PrettyLogger
|
||||
}
|
||||
|
||||
func NewClient(skipTLSVerify bool, grafanaComAPIToken string, logger log.PrettyLogger) *Client {
|
||||
func NewClient(skipTLSVerify bool, grafanaComAPIToken, grafanaComAPIURL string, logger log.PrettyLogger) *Client {
|
||||
return &Client{
|
||||
httpClient: MakeHttpClient(skipTLSVerify, 10*time.Second),
|
||||
httpClientNoTimeout: MakeHttpClient(skipTLSVerify, 0),
|
||||
log: logger,
|
||||
grafanaComAPIToken: grafanaComAPIToken,
|
||||
grafanaComAPIURL: grafanaComAPIURL,
|
||||
}
|
||||
}
|
||||
|
||||
@ -233,7 +236,7 @@ func (c *Client) createReq(ctx context.Context, url *url.URL, compatOpts CompatO
|
||||
req.Header.Set("grafana-origin", orig.(string))
|
||||
}
|
||||
|
||||
if c.grafanaComAPIToken != "" {
|
||||
if strings.HasPrefix(url.String(), c.grafanaComAPIURL) && c.grafanaComAPIToken != "" {
|
||||
req.Header.Set("Authorization", "Bearer "+c.grafanaComAPIToken)
|
||||
}
|
||||
|
||||
|
@ -70,7 +70,7 @@ func Test_Download(t *testing.T) {
|
||||
require.Equal(t, 2, count, "should retry on error")
|
||||
})
|
||||
|
||||
t.Run("it should use gcom token when it's available", func(t *testing.T) {
|
||||
t.Run("it should use gcom token when the token is available and request is to GCOM", func(t *testing.T) {
|
||||
expectedToken := "token-test"
|
||||
var gcomCalled bool
|
||||
fakeServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
@ -82,9 +82,29 @@ func Test_Download(t *testing.T) {
|
||||
}))
|
||||
defer fakeServer.Close()
|
||||
cli := fakeServer.Client()
|
||||
repo := Client{httpClient: *cli, httpClientNoTimeout: *cli, log: log.NewPrettyLogger("test"), grafanaComAPIToken: expectedToken}
|
||||
_, err := repo.Download(context.Background(), fakeServer.URL, "", CompatOpts{})
|
||||
pluginURL := fakeServer.URL + "/api/plugins/test-datasource"
|
||||
gcomAPIURL := fakeServer.URL + "/api/plugins"
|
||||
repo := Client{httpClient: *cli, httpClientNoTimeout: *cli, log: log.NewPrettyLogger("test"), grafanaComAPIToken: expectedToken, grafanaComAPIURL: gcomAPIURL}
|
||||
_, err := repo.Download(context.Background(), pluginURL, "", CompatOpts{})
|
||||
require.NoError(t, err)
|
||||
require.True(t, gcomCalled)
|
||||
})
|
||||
|
||||
t.Run("it should not set gcom token when the token is available but request is NOT to GCOM", func(t *testing.T) {
|
||||
expectedToken := "token-test"
|
||||
var serverCalled bool
|
||||
fakeServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
token := r.Header.Get("Authorization")
|
||||
require.Empty(t, token, "token should not be set")
|
||||
err := writeFakeZip(w)
|
||||
require.NoError(t, err)
|
||||
serverCalled = true
|
||||
}))
|
||||
defer fakeServer.Close()
|
||||
cli := fakeServer.Client()
|
||||
repo := Client{httpClient: *cli, httpClientNoTimeout: *cli, log: log.NewPrettyLogger("test"), grafanaComAPIToken: expectedToken, grafanaComAPIURL: "https://grafana.com/api/plugins"}
|
||||
_, err := repo.Download(context.Background(), fakeServer.URL, "", CompatOpts{})
|
||||
require.NoError(t, err)
|
||||
require.True(t, serverCalled)
|
||||
})
|
||||
}
|
||||
|
@ -14,8 +14,7 @@ import (
|
||||
)
|
||||
|
||||
type Manager struct {
|
||||
client *Client
|
||||
baseURL string
|
||||
client *Client
|
||||
|
||||
log log.PrettyLogger
|
||||
}
|
||||
@ -43,9 +42,8 @@ type ManagerCfg struct {
|
||||
|
||||
func NewManager(cfg ManagerCfg) *Manager {
|
||||
return &Manager{
|
||||
baseURL: cfg.BaseURL,
|
||||
client: NewClient(cfg.SkipTLSVerify, cfg.GrafanaComAPIToken, cfg.Logger),
|
||||
log: cfg.Logger,
|
||||
client: NewClient(cfg.SkipTLSVerify, cfg.GrafanaComAPIToken, cfg.BaseURL, cfg.Logger),
|
||||
log: cfg.Logger,
|
||||
}
|
||||
}
|
||||
|
||||
@ -101,12 +99,12 @@ func (m *Manager) PluginVersion(ctx context.Context, pluginID, version string, c
|
||||
}
|
||||
|
||||
func (m *Manager) downloadURL(pluginID, version string) string {
|
||||
return fmt.Sprintf("%s/%s/versions/%s/download", m.baseURL, pluginID, version)
|
||||
return fmt.Sprintf("%s/%s/versions/%s/download", m.client.grafanaComAPIURL, pluginID, version)
|
||||
}
|
||||
|
||||
// grafanaCompatiblePluginVersions will get version info from /api/plugins/$pluginID/versions
|
||||
func (m *Manager) grafanaCompatiblePluginVersions(ctx context.Context, pluginID string, compatOpts CompatOpts) ([]Version, error) {
|
||||
u, err := url.Parse(m.baseURL)
|
||||
u, err := url.Parse(m.client.grafanaComAPIURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -149,6 +149,8 @@ func StartGrafanaEnv(t *testing.T, grafDir, cfgPath string) (string, *server.Tes
|
||||
|
||||
// CreateGrafDir creates the Grafana directory.
|
||||
// The log by default is muted in the regression test, to activate it, pass option EnableLog = true
|
||||
//
|
||||
//nolint:gocyclo
|
||||
func CreateGrafDir(t *testing.T, opts GrafanaOpts) (string, string) {
|
||||
t.Helper()
|
||||
|
||||
@ -459,6 +461,13 @@ func CreateGrafDir(t *testing.T, opts GrafanaOpts) (string, string) {
|
||||
_, err = grafanaComSection.NewKey("api_url", opts.GrafanaComAPIURL)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
if opts.GrafanaComSSOAPIToken != "" {
|
||||
grafanaComSection, err := getOrCreateSection("grafana_com")
|
||||
require.NoError(t, err)
|
||||
_, err = grafanaComSection.NewKey("sso_api_token", opts.GrafanaComSSOAPIToken)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
if opts.UnifiedStorageConfig != nil {
|
||||
for k, v := range opts.UnifiedStorageConfig {
|
||||
section, err := getOrCreateSection(fmt.Sprintf("unified_storage.%s", k))
|
||||
@ -519,6 +528,7 @@ type GrafanaOpts struct {
|
||||
QueryRetries int64
|
||||
GrafanaComAPIURL string
|
||||
UnifiedStorageConfig map[string]setting.UnifiedStorageConfig
|
||||
GrafanaComSSOAPIToken string
|
||||
|
||||
// When "unified-grpc" is selected it will also start the grpc server
|
||||
APIServerStorageType options.StorageType
|
||||
|
Loading…
Reference in New Issue
Block a user