diff --git a/conf/defaults.ini b/conf/defaults.ini index 859e0c65d84..9fa38434c95 100644 --- a/conf/defaults.ini +++ b/conf/defaults.ini @@ -1741,6 +1741,7 @@ sas_token_expiration_days = # URL to a remote HTTP image renderer service, e.g. http://localhost:8081/render, will enable Grafana to render panels and dashboards to PNG-images using HTTP requests to an external service. server_url = # If the remote HTTP image renderer service runs on a different server than the Grafana server you may have to configure this to a URL where Grafana is reachable, e.g. http://grafana.domain/. +# The `callback_url` can also be configured to support usage of the image renderer running as a plugin with support for SSL / HTTPS. For example https://localhost:3000/. callback_url = # An auth token that will be sent to and verified by the renderer. The renderer will deny any request without an auth token matching the one configured on the renderer side. renderer_token = - diff --git a/docs/sources/setup-grafana/configure-grafana/_index.md b/docs/sources/setup-grafana/configure-grafana/_index.md index 5c15ff2c0b8..1d50227704a 100644 --- a/docs/sources/setup-grafana/configure-grafana/_index.md +++ b/docs/sources/setup-grafana/configure-grafana/_index.md @@ -2352,6 +2352,8 @@ URL to a remote HTTP image renderer service, for example, `http://localhost:8081 If the remote HTTP image renderer service runs on a different server than the Grafana server you may have to configure this to a URL where Grafana is reachable, for example, http://grafana.domain/. +The `callback_url` can also be configured to support usage of the image renderer running as a plugin with support for SSL / HTTPS. For example https://localhost:3000/. + #### `concurrent_render_request_limit` Concurrent render request limit affects when the /render HTTP endpoint is used. Rendering many images at the same time can overload the server, diff --git a/pkg/services/rendering/rendering.go b/pkg/services/rendering/rendering.go index cb25268154f..744f5e09e18 100644 --- a/pkg/services/rendering/rendering.go +++ b/pkg/services/rendering/rendering.go @@ -81,14 +81,14 @@ func ProvideService(cfg *setting.Cfg, features featuremgmt.FeatureToggles, remot var domain string switch { - case cfg.RendererUrl != "": - // RendererCallbackUrl has already been passed, it won't generate an error. + case cfg.RendererCallbackUrl != "": u, err := url.Parse(cfg.RendererCallbackUrl) if err != nil { + logger.Warn("Image renderer callback url is not valid. " + + "Please provide a valid RendererCallbackUrl. " + + "Read more at https://grafana.com/docs/grafana/latest/administration/image_rendering/") return nil, err } - - sanitizeURL = getSanitizerURL(cfg.RendererUrl) domain = u.Hostname() case cfg.HTTPAddr != setting.DefaultHTTPAddr: domain = cfg.HTTPAddr @@ -96,6 +96,10 @@ 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{ @@ -429,6 +433,11 @@ func (rs *RenderingService) getGrafanaCallbackURL(path string) string { return fmt.Sprintf("%s%s&render=1", rs.Cfg.RendererCallbackUrl, path) } + if rs.Cfg.RendererCallbackUrl != "" { + // &render=1 signals to the legacy redirect layer to + return fmt.Sprintf("%s%s&render=1", rs.Cfg.RendererCallbackUrl, path) + } + protocol := rs.Cfg.Protocol switch protocol { case setting.HTTPScheme: diff --git a/pkg/services/rendering/rendering_test.go b/pkg/services/rendering/rendering_test.go index cdc484baf31..2bcd6463633 100644 --- a/pkg/services/rendering/rendering_test.go +++ b/pkg/services/rendering/rendering_test.go @@ -31,8 +31,15 @@ func TestGetUrl(t *testing.T) { require.Equal(t, rs.Cfg.RendererCallbackUrl+path+"&render=1", url) }) + t.Run("When callback url is configured and https should return domain of callback url plus path", func(t *testing.T) { + rs.Cfg.RendererCallbackUrl = "https://public-grafana.com/" + url := rs.getGrafanaCallbackURL(path) + require.Equal(t, rs.Cfg.RendererCallbackUrl+path+"&render=1", url) + }) + t.Run("When renderer url not configured", func(t *testing.T) { rs.Cfg.RendererUrl = "" + rs.Cfg.RendererCallbackUrl = "" rs.domain = "localhost" rs.Cfg.HTTPPort = "3000"