mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Plugins: Add token to gcom requests (#96261)
This commit is contained in:
parent
3b8499eaee
commit
a8174f9285
@ -23,7 +23,7 @@ var grafanaComProxyTransport = &http.Transport{
|
|||||||
TLSHandshakeTimeout: 10 * time.Second,
|
TLSHandshakeTimeout: 10 * time.Second,
|
||||||
}
|
}
|
||||||
|
|
||||||
func ReverseProxyGnetReq(logger log.Logger, proxyPath string, version string, grafanaComAPIUrl string) *httputil.ReverseProxy {
|
func ReverseProxyGnetReq(logger log.Logger, proxyPath, version, grafanaComAPIUrl, grafanaComAPIToken string) *httputil.ReverseProxy {
|
||||||
url, _ := url.Parse(grafanaComAPIUrl)
|
url, _ := url.Parse(grafanaComAPIUrl)
|
||||||
|
|
||||||
director := func(req *http.Request) {
|
director := func(req *http.Request) {
|
||||||
@ -40,6 +40,10 @@ func ReverseProxyGnetReq(logger log.Logger, proxyPath string, version string, gr
|
|||||||
|
|
||||||
// send the current Grafana version for each request proxied to GCOM
|
// send the current Grafana version for each request proxied to GCOM
|
||||||
req.Header.Add("grafana-version", version)
|
req.Header.Add("grafana-version", version)
|
||||||
|
|
||||||
|
if grafanaComAPIToken != "" {
|
||||||
|
req.Header.Set("Authorization", "Bearer "+grafanaComAPIToken)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return proxyutil.NewReverseProxy(logger, director)
|
return proxyutil.NewReverseProxy(logger, director)
|
||||||
@ -47,7 +51,7 @@ func ReverseProxyGnetReq(logger log.Logger, proxyPath string, version string, gr
|
|||||||
|
|
||||||
func (hs *HTTPServer) ProxyGnetRequest(c *contextmodel.ReqContext) {
|
func (hs *HTTPServer) ProxyGnetRequest(c *contextmodel.ReqContext) {
|
||||||
proxyPath := web.Params(c.Req)["*"]
|
proxyPath := web.Params(c.Req)["*"]
|
||||||
proxy := ReverseProxyGnetReq(c.Logger, proxyPath, hs.Cfg.BuildVersion, hs.Cfg.GrafanaComAPIURL)
|
proxy := ReverseProxyGnetReq(c.Logger, proxyPath, hs.Cfg.BuildVersion, hs.Cfg.GrafanaComAPIURL, hs.Cfg.PluginInstallToken)
|
||||||
proxy.Transport = grafanaComProxyTransport
|
proxy.Transport = grafanaComProxyTransport
|
||||||
proxy.ServeHTTP(c.Resp, c.Req)
|
proxy.ServeHTTP(c.Resp, c.Req)
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ type PluginManagementCfg struct {
|
|||||||
PluginsCDNURLTemplate string
|
PluginsCDNURLTemplate string
|
||||||
|
|
||||||
GrafanaComAPIURL string
|
GrafanaComAPIURL string
|
||||||
|
GrafanaComAPIToken string
|
||||||
|
|
||||||
GrafanaAppURL string
|
GrafanaAppURL string
|
||||||
|
|
||||||
@ -38,7 +39,7 @@ type Features struct {
|
|||||||
// NewPluginManagementCfg returns a new PluginManagementCfg.
|
// NewPluginManagementCfg returns a new PluginManagementCfg.
|
||||||
func NewPluginManagementCfg(devMode bool, pluginsPath string, pluginSettings setting.PluginSettings, pluginsAllowUnsigned []string,
|
func NewPluginManagementCfg(devMode bool, pluginsPath string, pluginSettings setting.PluginSettings, pluginsAllowUnsigned []string,
|
||||||
pluginsCDNURLTemplate string, appURL string, features Features, angularSupportEnabled bool,
|
pluginsCDNURLTemplate string, appURL string, features Features, angularSupportEnabled bool,
|
||||||
grafanaComAPIURL string, disablePlugins []string, hideAngularDeprecation []string, forwardHostEnvVars []string,
|
grafanaComAPIURL string, disablePlugins []string, hideAngularDeprecation []string, forwardHostEnvVars []string, grafanaComAPIToken string,
|
||||||
) *PluginManagementCfg {
|
) *PluginManagementCfg {
|
||||||
return &PluginManagementCfg{
|
return &PluginManagementCfg{
|
||||||
PluginsPath: pluginsPath,
|
PluginsPath: pluginsPath,
|
||||||
@ -53,5 +54,6 @@ func NewPluginManagementCfg(devMode bool, pluginsPath string, pluginSettings set
|
|||||||
AngularSupportEnabled: angularSupportEnabled,
|
AngularSupportEnabled: angularSupportEnabled,
|
||||||
HideAngularDeprecation: hideAngularDeprecation,
|
HideAngularDeprecation: hideAngularDeprecation,
|
||||||
ForwardHostEnvVars: forwardHostEnvVars,
|
ForwardHostEnvVars: forwardHostEnvVars,
|
||||||
|
GrafanaComAPIToken: grafanaComAPIToken,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,15 +23,17 @@ type Client struct {
|
|||||||
httpClient http.Client
|
httpClient http.Client
|
||||||
httpClientNoTimeout http.Client
|
httpClientNoTimeout http.Client
|
||||||
retryCount int
|
retryCount int
|
||||||
|
grafanaComAPIToken string
|
||||||
|
|
||||||
log log.PrettyLogger
|
log log.PrettyLogger
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewClient(skipTLSVerify bool, logger log.PrettyLogger) *Client {
|
func NewClient(skipTLSVerify bool, grafanaComAPIToken string, logger log.PrettyLogger) *Client {
|
||||||
return &Client{
|
return &Client{
|
||||||
httpClient: MakeHttpClient(skipTLSVerify, 10*time.Second),
|
httpClient: MakeHttpClient(skipTLSVerify, 10*time.Second),
|
||||||
httpClientNoTimeout: MakeHttpClient(skipTLSVerify, 0),
|
httpClientNoTimeout: MakeHttpClient(skipTLSVerify, 0),
|
||||||
log: logger,
|
log: logger,
|
||||||
|
grafanaComAPIToken: grafanaComAPIToken,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,6 +155,14 @@ func (c *Client) downloadFile(ctx context.Context, tmpFile *os.File, pluginURL,
|
|||||||
// Note: This is also used as part of the grafana plugin install CLI operation
|
// Note: This is also used as part of the grafana plugin install CLI operation
|
||||||
bodyReader, err := c.sendReqNoTimeout(ctx, u, compatOpts)
|
bodyReader, err := c.sendReqNoTimeout(ctx, u, compatOpts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
var errResp ErrResponse4xx
|
||||||
|
if errors.As(err, &errResp) {
|
||||||
|
if errResp.StatusCode() == 401 {
|
||||||
|
c.log.Error("Unauthorized download plugin", "error", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if c.retryCount < 3 {
|
if c.retryCount < 3 {
|
||||||
c.retryCount++
|
c.retryCount++
|
||||||
c.log.Debug("Failed downloading. Will retry.")
|
c.log.Debug("Failed downloading. Will retry.")
|
||||||
@ -223,6 +233,10 @@ func (c *Client) createReq(ctx context.Context, url *url.URL, compatOpts CompatO
|
|||||||
req.Header.Set("grafana-origin", orig.(string))
|
req.Header.Set("grafana-origin", orig.(string))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if c.grafanaComAPIToken != "" {
|
||||||
|
req.Header.Set("Authorization", "Bearer "+c.grafanaComAPIToken)
|
||||||
|
}
|
||||||
|
|
||||||
return req, err
|
return req, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,4 +69,22 @@ func Test_Download(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, 2, count, "should retry on error")
|
require.Equal(t, 2, count, "should retry on error")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("it should use gcom token when it's available", func(t *testing.T) {
|
||||||
|
expectedToken := "token-test"
|
||||||
|
var gcomCalled bool
|
||||||
|
fakeServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
token := r.Header.Get("Authorization")
|
||||||
|
require.Equal(t, "Bearer "+expectedToken, token, "gcom token should be set")
|
||||||
|
err := writeFakeZip(w)
|
||||||
|
require.NoError(t, err)
|
||||||
|
gcomCalled = true
|
||||||
|
}))
|
||||||
|
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{})
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.True(t, gcomCalled)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
@ -30,19 +30,21 @@ func ProvideService(cfg *config.PluginManagementCfg) (*Manager, error) {
|
|||||||
SkipTLSVerify: false,
|
SkipTLSVerify: false,
|
||||||
BaseURL: baseURL,
|
BaseURL: baseURL,
|
||||||
Logger: log.NewPrettyLogger("plugin.repository"),
|
Logger: log.NewPrettyLogger("plugin.repository"),
|
||||||
|
GrafanaComAPIToken: cfg.GrafanaComAPIToken,
|
||||||
}), nil
|
}), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type ManagerCfg struct {
|
type ManagerCfg struct {
|
||||||
SkipTLSVerify bool
|
SkipTLSVerify bool
|
||||||
BaseURL string
|
BaseURL string
|
||||||
|
GrafanaComAPIToken string
|
||||||
Logger log.PrettyLogger
|
Logger log.PrettyLogger
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewManager(cfg ManagerCfg) *Manager {
|
func NewManager(cfg ManagerCfg) *Manager {
|
||||||
return &Manager{
|
return &Manager{
|
||||||
baseURL: cfg.BaseURL,
|
baseURL: cfg.BaseURL,
|
||||||
client: NewClient(cfg.SkipTLSVerify, cfg.Logger),
|
client: NewClient(cfg.SkipTLSVerify, cfg.GrafanaComAPIToken, cfg.Logger),
|
||||||
log: cfg.Logger,
|
log: cfg.Logger,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,7 @@ func ProvidePluginManagementConfig(cfg *setting.Cfg, settingProvider setting.Pro
|
|||||||
cfg.DisablePlugins,
|
cfg.DisablePlugins,
|
||||||
cfg.HideAngularDeprecation,
|
cfg.HideAngularDeprecation,
|
||||||
cfg.ForwardHostEnvVars,
|
cfg.ForwardHostEnvVars,
|
||||||
|
cfg.PluginInstallToken,
|
||||||
), nil
|
), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user