Renderer: Fix regression on callback URL in plugin mode (#103787)

* Renderer: Fix regression on callback URL in plugin mode

* cleanup

* refactor to not mutate cfg object

* apply review feedback
This commit is contained in:
Agnès Toulet
2025-04-11 15:34:10 +02:00
committed by GitHub
parent f1625d9e56
commit d7c554c25e
6 changed files with 133 additions and 74 deletions
+38 -24
View File
@@ -27,18 +27,19 @@ import (
var _ Service = (*RenderingService)(nil)
type RenderingService struct {
log log.Logger
plugin Plugin
renderAction renderFunc
renderCSVAction renderCSVFunc
sanitizeSVGAction sanitizeFunc
sanitizeURL string
domain string
inProgressCount int32
version string
versionMutex sync.RWMutex
capabilities []Capability
pluginAvailable bool
log log.Logger
plugin Plugin
renderAction renderFunc
renderCSVAction renderCSVFunc
sanitizeSVGAction sanitizeFunc
sanitizeURL string
domain string
inProgressCount int32
version string
versionMutex sync.RWMutex
capabilities []Capability
pluginAvailable bool
rendererCallbackURL string
perRequestRenderKeyProvider renderKeyProvider
Cfg *setting.Cfg
@@ -80,9 +81,24 @@ func ProvideService(cfg *setting.Cfg, features featuremgmt.FeatureToggles, remot
// value used for domain attribute of renderKey cookie
var domain string
// value used by the image renderer to make requests to Grafana
rendererCallbackURL := cfg.RendererCallbackUrl
if cfg.RendererServerUrl != "" {
sanitizeURL = getSanitizerURL(cfg.RendererServerUrl)
// Default value for callback URL using a remote renderer should be AppURL
if rendererCallbackURL == "" {
rendererCallbackURL = cfg.AppURL
}
}
switch {
case cfg.RendererCallbackUrl != "":
u, err := url.Parse(cfg.RendererCallbackUrl)
case rendererCallbackURL != "":
if rendererCallbackURL[len(rendererCallbackURL)-1] != '/' {
rendererCallbackURL += "/"
}
u, err := url.Parse(rendererCallbackURL)
if err != nil {
logger.Warn("Image renderer callback url is not valid. " +
"Please provide a valid RendererCallbackUrl. " +
@@ -96,10 +112,6 @@ func ProvideService(cfg *setting.Cfg, features featuremgmt.FeatureToggles, remot
domain = "localhost"
}
if cfg.RendererUrl != "" {
sanitizeURL = getSanitizerURL(cfg.RendererUrl)
}
var renderKeyProvider renderKeyProvider
if features.IsEnabledGlobally(featuremgmt.FlagRenderAuthJWT) {
renderKeyProvider = &jwtRenderKeyProvider{
@@ -145,6 +157,7 @@ func ProvideService(cfg *setting.Cfg, features featuremgmt.FeatureToggles, remot
domain: domain,
sanitizeURL: sanitizeURL,
pluginAvailable: exists,
rendererCallbackURL: rendererCallbackURL,
}
gob.Register(&RenderUser{})
@@ -215,7 +228,7 @@ func (rs *RenderingService) Run(ctx context.Context) error {
}
func (rs *RenderingService) remoteAvailable() bool {
return rs.Cfg.RendererUrl != ""
return rs.Cfg.RendererServerUrl != ""
}
func (rs *RenderingService) IsAvailable(ctx context.Context) bool {
@@ -424,13 +437,14 @@ func (rs *RenderingService) getNewFilePath(rt RenderType) (string, error) {
// getGrafanaCallbackURL creates a URL to send to the image rendering as callback for rendering a Grafana resource
func (rs *RenderingService) getGrafanaCallbackURL(path string) string {
if rs.Cfg.RendererUrl != "" || rs.Cfg.RendererCallbackUrl != "" {
// The backend rendering service can potentially be remote.
// So we need to use the root_url to ensure the rendering service
// can reach this Grafana instance.
if rs.rendererCallbackURL != "" {
// rendererCallbackURL should be set if:
// - the backend rendering service is remote (default value is cfg.AppURL
// and set when initializing the service)
// - the service is a plugin and Grafana is running behind a proxy changing its domain
// &render=1 signals to the legacy redirect layer to
return fmt.Sprintf("%s%s&render=1", rs.Cfg.RendererCallbackUrl, path)
return fmt.Sprintf("%s%s&render=1", rs.rendererCallbackURL, path)
}
protocol := rs.Cfg.Protocol