mirror of
https://github.com/grafana/grafana.git
synced 2025-07-29 15:02:28 +08:00
Rendering: Store render key in remote cache (#22031)
By storing render key in remote cache it will enable image renderer to use public facing url or load balancer url to render images and thereby remove the requirement of image renderer having to use the url of the originating Grafana instance when running HA setup (multiple Grafana instances). Fixes #17704 Ref grafana/grafana-image-renderer#91
This commit is contained in:

committed by
GitHub

parent
9d7c74ef91
commit
d0a80c59f3
@ -6,9 +6,11 @@ import (
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/remotecache"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/middleware"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/registry"
|
||||
@ -17,11 +19,20 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
remotecache.Register(&RenderUser{})
|
||||
registry.RegisterService(&RenderingService{})
|
||||
}
|
||||
|
||||
var IsPhantomJSEnabled = false
|
||||
|
||||
const renderKeyPrefix = "render-%s"
|
||||
|
||||
type RenderUser struct {
|
||||
OrgID int64
|
||||
UserID int64
|
||||
OrgRole string
|
||||
}
|
||||
|
||||
type RenderingService struct {
|
||||
log log.Logger
|
||||
pluginInfo *plugins.RendererPlugin
|
||||
@ -29,7 +40,8 @@ type RenderingService struct {
|
||||
domain string
|
||||
inProgressCount int
|
||||
|
||||
Cfg *setting.Cfg `inject:""`
|
||||
Cfg *setting.Cfg `inject:""`
|
||||
RemoteCacheService *remotecache.RemoteCache `inject:""`
|
||||
}
|
||||
|
||||
func (rs *RenderingService) Init() error {
|
||||
@ -103,19 +115,40 @@ func (rs *RenderingService) Render(ctx context.Context, opts Opts) (*RenderResul
|
||||
}, nil
|
||||
}
|
||||
|
||||
defer func() {
|
||||
rs.inProgressCount -= 1
|
||||
}()
|
||||
|
||||
rs.inProgressCount += 1
|
||||
|
||||
if rs.renderAction != nil {
|
||||
rs.log.Info("Rendering", "path", opts.Path)
|
||||
return rs.renderAction(ctx, opts)
|
||||
renderKey, err := rs.generateAndStoreRenderKey(opts.OrgId, opts.UserId, opts.OrgRole)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer rs.deleteRenderKey(renderKey)
|
||||
|
||||
defer func() {
|
||||
rs.inProgressCount--
|
||||
}()
|
||||
|
||||
rs.inProgressCount++
|
||||
return rs.renderAction(ctx, renderKey, opts)
|
||||
}
|
||||
return nil, fmt.Errorf("No renderer found")
|
||||
}
|
||||
|
||||
func (rs *RenderingService) GetRenderUser(key string) (*RenderUser, bool) {
|
||||
val, err := rs.RemoteCacheService.Get(fmt.Sprintf(renderKeyPrefix, key))
|
||||
if err != nil {
|
||||
rs.log.Error("Failed to get render key from cache", "error", err)
|
||||
}
|
||||
|
||||
if val != nil {
|
||||
if user, ok := val.(*RenderUser); ok {
|
||||
return user, true
|
||||
}
|
||||
}
|
||||
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (rs *RenderingService) getFilePathForNewImage() (string, error) {
|
||||
rand, err := util.GetRandomString(20)
|
||||
if err != nil {
|
||||
@ -152,6 +185,27 @@ func (rs *RenderingService) getURL(path string) string {
|
||||
return fmt.Sprintf("%s://%s:%s/%s&render=1", protocol, rs.domain, setting.HttpPort, path)
|
||||
}
|
||||
|
||||
func (rs *RenderingService) getRenderKey(orgId, userId int64, orgRole models.RoleType) (string, error) {
|
||||
return middleware.AddRenderAuthKey(orgId, userId, orgRole)
|
||||
func (rs *RenderingService) generateAndStoreRenderKey(orgId, userId int64, orgRole models.RoleType) (string, error) {
|
||||
key, err := util.GetRandomString(32)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
err = rs.RemoteCacheService.Set(fmt.Sprintf(renderKeyPrefix, key), &RenderUser{
|
||||
OrgID: orgId,
|
||||
UserID: userId,
|
||||
OrgRole: string(orgRole),
|
||||
}, 5*time.Minute)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return key, nil
|
||||
}
|
||||
|
||||
func (rs *RenderingService) deleteRenderKey(key string) {
|
||||
err := rs.RemoteCacheService.Delete(fmt.Sprintf(renderKeyPrefix, key))
|
||||
if err != nil {
|
||||
rs.log.Error("Failed to delete render key", "error", err)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user