Previews: create crawler auth setup service (#47349)

* #46968: add `RetrieveServiceAccountIdByName` to serviceaccounts service

* #46968: improve error logging in rendering service

* #46968: add oss crawler account setup

* #46968: fix tests

* #46968: switch back to ROLE_ADMIN

* #46968: rename to crawlerAuth

* comment crawler_auth.go
This commit is contained in:
Artur Wierzbicki
2022-04-12 19:34:04 +02:00
committed by GitHub
parent 5cb5141c72
commit a4381ebc91
11 changed files with 153 additions and 36 deletions
+5 -4
View File
@@ -26,6 +26,7 @@ type simpleCrawler struct {
thumbnailRepo thumbnailRepo
mode CrawlerMode
thumbnailKind models.ThumbnailKind
auth CrawlerAuth
opts rendering.Opts
status crawlStatus
statusMutex sync.RWMutex
@@ -67,8 +68,8 @@ func (r *simpleCrawler) next(ctx context.Context) (*models.DashboardWithStaleThu
authOpts := rendering.AuthOpts{
OrgID: v.OrgId,
UserID: r.opts.AuthOpts.UserID,
OrgRole: r.opts.AuthOpts.OrgRole,
UserID: r.auth.GetUserId(v.OrgId),
OrgRole: r.auth.GetOrgRole(),
}
if renderingSession, ok := r.renderingSessionByOrgId[v.OrgId]; ok {
@@ -112,7 +113,7 @@ func (d byOrgId) Len() int { return len(d) }
func (d byOrgId) Less(i, j int) bool { return d[i].OrgId > d[j].OrgId }
func (d byOrgId) Swap(i, j int) { d[i], d[j] = d[j], d[i] }
func (r *simpleCrawler) Run(ctx context.Context, authOpts rendering.AuthOpts, mode CrawlerMode, theme models.Theme, thumbnailKind models.ThumbnailKind) error {
func (r *simpleCrawler) Run(ctx context.Context, auth CrawlerAuth, mode CrawlerMode, theme models.Theme, thumbnailKind models.ThumbnailKind) error {
res, err := r.renderService.HasCapability(rendering.ScalingDownImages)
if err != nil {
return err
@@ -150,8 +151,8 @@ func (r *simpleCrawler) Run(ctx context.Context, authOpts rendering.AuthOpts, mo
r.mode = mode
r.thumbnailKind = thumbnailKind
r.auth = auth
r.opts = rendering.Opts{
AuthOpts: authOpts,
TimeoutOpts: rendering.TimeoutOpts{
Timeout: 20 * time.Second,
RequestTimeoutMultiplier: 3,
+41
View File
@@ -0,0 +1,41 @@
package thumbs
import (
"context"
"github.com/grafana/grafana/pkg/models"
)
type CrawlerAuthSetupService interface {
Setup(ctx context.Context) (CrawlerAuth, error)
}
func ProvideCrawlerAuthSetupService() *OSSCrawlerAuthSetupService {
return &OSSCrawlerAuthSetupService{}
}
type OSSCrawlerAuthSetupService struct{}
type CrawlerAuth interface {
GetUserId(orgId int64) int64
GetOrgRole() models.RoleType
}
type staticCrawlerAuth struct {
userId int64
orgRole models.RoleType
}
func (o *staticCrawlerAuth) GetOrgRole() models.RoleType {
return o.orgRole
}
func (o *staticCrawlerAuth) GetUserId(orgId int64) int64 {
return o.userId
}
func (o *OSSCrawlerAuthSetupService) Setup(ctx context.Context) (CrawlerAuth, error) {
// userId:0 and ROLE_ADMIN grants the crawler process permissions to view all dashboards in all folders & orgs
// the process doesn't and shouldn't actually need to edit/modify any resources from the UI
return &staticCrawlerAuth{userId: 0, orgRole: models.ROLE_ADMIN}, nil
}
+1 -2
View File
@@ -5,7 +5,6 @@ import (
"time"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/rendering"
)
type CrawlerMode string
@@ -66,7 +65,7 @@ type dashboardPreviewsSetupConfig struct {
type dashRenderer interface {
// Run Assumes you have already authenticated as admin.
Run(ctx context.Context, authOpts rendering.AuthOpts, mode CrawlerMode, theme models.Theme, kind models.ThumbnailKind) error
Run(ctx context.Context, auth CrawlerAuth, mode CrawlerMode, theme models.Theme, kind models.ThumbnailKind) error
// Assumes you have already authenticated as admin.
Stop() (crawlStatus, error)
+11 -9
View File
@@ -56,22 +56,24 @@ type crawlerScheduleOptions struct {
maxCrawlDuration time.Duration
crawlerMode CrawlerMode
thumbnailKind models.ThumbnailKind
auth rendering.AuthOpts
themes []models.Theme
auth CrawlerAuth
}
func ProvideService(cfg *setting.Cfg, features featuremgmt.FeatureToggles, lockService *serverlock.ServerLockService, renderService rendering.Service, gl *live.GrafanaLive, store *sqlstore.SQLStore) Service {
func ProvideService(cfg *setting.Cfg, features featuremgmt.FeatureToggles, lockService *serverlock.ServerLockService, renderService rendering.Service, gl *live.GrafanaLive, store *sqlstore.SQLStore, authSetupService CrawlerAuthSetupService) Service {
if !features.IsEnabled(featuremgmt.FlagDashboardPreviews) {
return &dummyService{}
}
logger := log.New("thumbnails_service")
thumbnailRepo := newThumbnailRepo(store)
authOpts := rendering.AuthOpts{
OrgID: 0,
UserID: 0,
OrgRole: models.ROLE_ADMIN,
crawlerAuth, err := authSetupService.Setup(context.Background())
if err != nil {
logger.Error("Failed to setup auth for the dashboard previews crawler", "err", err)
return &dummyService{}
}
return &thumbService{
renderingService: renderService,
renderer: newSimpleCrawler(renderService, gl, thumbnailRepo),
@@ -80,7 +82,7 @@ func ProvideService(cfg *setting.Cfg, features featuremgmt.FeatureToggles, lockS
features: features,
lockService: lockService,
crawlLockServiceActionName: "dashboard-crawler",
log: log.New("thumbnails_service"),
log: logger,
scheduleOptions: crawlerScheduleOptions{
tickerInterval: time.Hour,
@@ -89,7 +91,7 @@ func ProvideService(cfg *setting.Cfg, features featuremgmt.FeatureToggles, lockS
crawlerMode: CrawlerModeThumbs,
thumbnailKind: models.ThumbnailKindDefault,
themes: []models.Theme{models.ThemeDark, models.ThemeLight},
auth: authOpts,
auth: crawlerAuth,
},
}
}
@@ -377,7 +379,7 @@ func (hs *thumbService) runOnDemandCrawl(parentCtx context.Context, theme models
// wait for at least a minute after the last completed run
interval := time.Minute
err := hs.lockService.LockAndExecute(crawlerCtx, hs.crawlLockServiceActionName, interval, func(ctx context.Context) {
if err := hs.renderer.Run(crawlerCtx, authOpts, mode, theme, kind); err != nil {
if err := hs.renderer.Run(crawlerCtx, hs.scheduleOptions.auth, mode, theme, kind); err != nil {
hs.log.Error("On demand crawl error", "mode", mode, "theme", theme, "kind", kind, "userId", authOpts.UserID, "orgId", authOpts.OrgID, "orgRole", authOpts.OrgRole)
}
})