Image Renderer: Add support for SSL in plugin mode (#98009)

This commit is contained in:
Nathan Marrs 2025-02-04 11:44:02 -07:00 committed by GitHub
parent ff926c5ac5
commit 6eac07c3a7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 23 additions and 4 deletions

View File

@ -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 = -

View File

@ -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,

View File

@ -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:

View File

@ -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"