Files
grafana/pkg/services/libraryelements/libraryelements.go
2025-10-31 08:14:38 +03:00

118 lines
5.4 KiB
Go

package libraryelements
import (
"context"
"encoding/json"
"github.com/grafana/grafana/pkg/api/routing"
"github.com/grafana/grafana/pkg/apimachinery/identity"
"github.com/grafana/grafana/pkg/infra/db"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/services/accesscontrol"
grafanaapiserver "github.com/grafana/grafana/pkg/services/apiserver"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/folder"
"github.com/grafana/grafana/pkg/services/libraryelements/model"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
)
func ProvideService(cfg *setting.Cfg, sqlStore db.DB, routeRegister routing.RouteRegister, folderService folder.Service, features featuremgmt.FeatureToggles, ac accesscontrol.AccessControl, dashboardsService dashboards.DashboardService, clientConfigProvider grafanaapiserver.DirectRestConfigProvider, userService user.Service) *LibraryElementService {
l := &LibraryElementService{
Cfg: cfg,
SQLStore: sqlStore,
RouteRegister: routeRegister,
folderService: folderService,
dashboardsService: dashboardsService,
log: log.New("library-elements"),
features: features,
AccessControl: ac,
k8sHandler: newLibraryElementsK8sHandler(cfg, clientConfigProvider, folderService, userService, dashboardsService),
}
l.registerAPIEndpoints()
ac.RegisterScopeAttributeResolver(LibraryPanelUIDScopeResolver(l, l.folderService))
return l
}
// Service is a service for operating on library elements.
type Service interface {
CreateElement(c context.Context, signedInUser identity.Requester, cmd model.CreateLibraryElementCommand) (model.LibraryElementDTO, error)
PatchLibraryElement(c context.Context, signedInUser identity.Requester, cmd model.PatchLibraryElementCommand, uid string) (model.LibraryElementDTO, error)
DeleteLibraryElement(c context.Context, signedInUser identity.Requester, uid string) (int64, error)
GetElement(c context.Context, signedInUser identity.Requester, cmd model.GetLibraryElementCommand) (model.LibraryElementDTO, error)
GetElementsForDashboard(c context.Context, dashboardID int64) (map[string]model.LibraryElementDTO, error)
ConnectElementsToDashboard(c context.Context, signedInUser identity.Requester, elementUIDs []string, dashboardID int64) error
DisconnectElementsFromDashboard(c context.Context, dashboardID int64) error
DeleteLibraryElementsInFolder(c context.Context, signedInUser identity.Requester, folderUID string) error
GetAllElements(c context.Context, signedInUser identity.Requester, query model.SearchLibraryElementsQuery) (model.LibraryElementSearchResult, error)
}
// LibraryElementService is the service for the Library Element feature.
type LibraryElementService struct {
Cfg *setting.Cfg
SQLStore db.DB
RouteRegister routing.RouteRegister
folderService folder.Service
dashboardsService dashboards.DashboardService
log log.Logger
features featuremgmt.FeatureToggles
AccessControl accesscontrol.AccessControl
k8sHandler *libraryElementsK8sHandler
}
var _ Service = (*LibraryElementService)(nil)
// GetElement gets an element from a UID.
func (l *LibraryElementService) GetElement(c context.Context, signedInUser identity.Requester, cmd model.GetLibraryElementCommand) (model.LibraryElementDTO, error) {
return l.getLibraryElementByUid(c, signedInUser, cmd)
}
// GetElementsForDashboard gets all connected elements for a specific dashboard.
func (l *LibraryElementService) GetElementsForDashboard(c context.Context, dashboardID int64) (map[string]model.LibraryElementDTO, error) {
return l.getElementsForDashboardID(c, dashboardID)
}
// ConnectElementsToDashboard connects elements to a specific dashboard.
func (l *LibraryElementService) ConnectElementsToDashboard(c context.Context, signedInUser identity.Requester, elementUIDs []string, dashboardID int64) error {
return l.connectElementsToDashboardID(c, signedInUser, elementUIDs, dashboardID)
}
// DisconnectElementsFromDashboard disconnects elements from a specific dashboard.
func (l *LibraryElementService) DisconnectElementsFromDashboard(c context.Context, dashboardID int64) error {
return l.disconnectElementsFromDashboardID(c, dashboardID)
}
// DeleteLibraryElementsInFolder deletes all elements for a specific folder.
func (l *LibraryElementService) DeleteLibraryElementsInFolder(c context.Context, signedInUser identity.Requester, folderUID string) error {
return l.deleteLibraryElementsInFolderUID(c, signedInUser, folderUID)
}
// GetAll gets all library elements with support to query filters.
func (l *LibraryElementService) GetAllElements(c context.Context, signedInUser identity.Requester, query model.SearchLibraryElementsQuery) (model.LibraryElementSearchResult, error) {
return l.getAllLibraryElements(c, signedInUser, query)
}
func (l *LibraryElementService) addUidToLibraryPanel(model []byte, newUid string) (json.RawMessage, error) {
var modelMap map[string]any
err := json.Unmarshal(model, &modelMap)
if err != nil {
return nil, err
}
if libraryPanel, ok := modelMap["libraryPanel"].(map[string]any); ok {
if uid, ok := libraryPanel["uid"]; ok && uid == "" {
libraryPanel["uid"] = newUid
}
}
updatedModel, err := json.Marshal(modelMap)
if err != nil {
return nil, err
}
return updatedModel, nil
}