Rendering: Add PDFRendering capability (#84438)

* Rendering: Add PDFRendering capability

* fix tests
This commit is contained in:
Agnès Toulet 2024-03-19 08:48:46 +01:00 committed by GitHub
parent d3571c399a
commit 58170d4141
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 47 additions and 14 deletions

View File

@ -3,6 +3,7 @@ package rendering
import (
"context"
"errors"
"fmt"
"github.com/Masterminds/semver"
)
@ -17,7 +18,8 @@ type CapabilityName string
const (
ScalingDownImages CapabilityName = "ScalingDownImages"
FullHeightImages CapabilityName = "FullHeightImages"
SvgSanitization CapabilityName = "SvgSanitization"
SVGSanitization CapabilityName = "SvgSanitization"
PDFRendering CapabilityName = "PdfRendering"
)
var ErrUnknownCapability = errors.New("unknown capability")
@ -55,3 +57,16 @@ func (rs *RenderingService) HasCapability(ctx context.Context, capability Capabi
return CapabilitySupportRequestResult{IsSupported: compiledSemverConstraint.Check(compiledImageRendererVersion), SemverConstraint: semverConstraint}, nil
}
func (rs *RenderingService) IsCapabilitySupported(ctx context.Context, capabilityName CapabilityName) error {
capability, err := rs.HasCapability(ctx, capabilityName)
if err != nil {
return err
}
if !capability.IsSupported {
return fmt.Errorf("%s unsupported, requires image renderer version: %s", capabilityName, capability.SemverConstraint)
}
return nil
}

View File

@ -14,8 +14,6 @@ import (
"os"
"strconv"
"time"
"github.com/grafana/grafana/pkg/services/featuremgmt"
)
var netTransport = &http.Transport{
@ -40,10 +38,6 @@ var (
func (rs *RenderingService) renderViaHTTP(ctx context.Context, renderType RenderType, renderKey string, opts Opts) (*RenderResult, error) {
if renderType == RenderPDF {
if !rs.features.IsEnabled(ctx, featuremgmt.FlagNewPDFRendering) {
return nil, fmt.Errorf("feature 'newPDFRendering' disabled")
}
opts.Encoding = "pdf"
}

View File

@ -127,6 +127,7 @@ type Service interface {
RenderErrorImage(theme models.Theme, error error) (*RenderResult, error)
GetRenderUser(ctx context.Context, key string) (*RenderUser, bool)
HasCapability(ctx context.Context, capability CapabilityName) (CapabilitySupportRequestResult, error)
IsCapabilitySupported(ctx context.Context, capability CapabilityName) error
CreateRenderingSession(ctx context.Context, authOpts AuthOpts, sessionOpts SessionOpts) (Session, error)
SanitizeSVG(ctx context.Context, req *SanitizeSVGRequest) (*SanitizeSVGResponse, error)
}

View File

@ -80,6 +80,20 @@ func (mr *MockServiceMockRecorder) HasCapability(ctx, capability interface{}) *g
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasCapability", reflect.TypeOf((*MockService)(nil).HasCapability), ctx, capability)
}
// IsCapabilitySupported mocks base method.
func (m *MockService) IsCapabilitySupported(ctx context.Context, capability CapabilityName) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "IsCapabilitySupported", ctx, capability)
ret0, _ := ret[0].(error)
return ret0
}
// IsCapabilitySupported indicates an expected call of IsCapabilitySupported.
func (mr *MockServiceMockRecorder) IsCapabilitySupported(ctx, capability interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsCapabilitySupported", reflect.TypeOf((*MockService)(nil).IsCapabilitySupported), ctx, capability)
}
// IsAvailable mocks base method.
func (m *MockService) IsAvailable(ctx context.Context) bool {
m.ctrl.T.Helper()

View File

@ -6,15 +6,10 @@ import (
"fmt"
"github.com/grafana/grafana/pkg/plugins/backendplugin/pluginextensionv2"
"github.com/grafana/grafana/pkg/services/featuremgmt"
)
func (rs *RenderingService) renderViaPlugin(ctx context.Context, renderType RenderType, renderKey string, opts Opts) (*RenderResult, error) {
if renderType == RenderPDF {
if !rs.features.IsEnabled(ctx, featuremgmt.FlagNewPDFRendering) {
return nil, fmt.Errorf("feature 'newPDFRendering' disabled")
}
opts.Encoding = "pdf"
}

View File

@ -125,9 +125,13 @@ func ProvideService(cfg *setting.Cfg, features *featuremgmt.FeatureManager, remo
semverConstraint: ">= 3.4.0",
},
{
name: SvgSanitization,
name: SVGSanitization,
semverConstraint: ">= 3.5.0",
},
{
name: PDFRendering,
semverConstraint: ">= 3.10.0",
},
},
Cfg: cfg,
features: features,
@ -292,6 +296,16 @@ func (rs *RenderingService) render(ctx context.Context, renderType RenderType, o
return rs.renderUnavailableImage(), nil
}
if renderType == RenderPDF || opts.Encoding == "pdf" {
if !rs.features.IsEnabled(ctx, featuremgmt.FlagNewPDFRendering) {
return nil, fmt.Errorf("feature 'newPDFRendering' disabled")
}
if err := rs.IsCapabilitySupported(ctx, PDFRendering); err != nil {
return nil, err
}
}
rs.log.Info("Rendering", "path", opts.Path)
if math.IsInf(opts.DeviceScaleFactor, 0) || math.IsNaN(opts.DeviceScaleFactor) || opts.DeviceScaleFactor == 0 {
opts.DeviceScaleFactor = 1
@ -327,7 +341,7 @@ func (rs *RenderingService) RenderCSV(ctx context.Context, opts CSVOpts, session
}
func (rs *RenderingService) SanitizeSVG(ctx context.Context, req *SanitizeSVGRequest) (*SanitizeSVGResponse, error) {
capability, err := rs.HasCapability(ctx, SvgSanitization)
capability, err := rs.HasCapability(ctx, SVGSanitization)
if err != nil {
return nil, err
}