mirror of
https://github.com/grafana/grafana.git
synced 2025-02-11 16:15:42 -06:00
156 lines
4.9 KiB
Go
156 lines
4.9 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/grafana/grafana/pkg/api/routing"
|
|
"github.com/grafana/grafana/pkg/components/simplejson"
|
|
"github.com/grafana/grafana/pkg/models"
|
|
"github.com/grafana/grafana/pkg/plugins"
|
|
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
|
"github.com/grafana/grafana/pkg/services/dashboardimport"
|
|
"github.com/grafana/grafana/pkg/services/dashboardimport/api"
|
|
"github.com/grafana/grafana/pkg/services/dashboardimport/utils"
|
|
"github.com/grafana/grafana/pkg/services/dashboards"
|
|
"github.com/grafana/grafana/pkg/services/folder"
|
|
"github.com/grafana/grafana/pkg/services/librarypanels"
|
|
"github.com/grafana/grafana/pkg/services/plugindashboards"
|
|
"github.com/grafana/grafana/pkg/services/quota"
|
|
)
|
|
|
|
func ProvideService(routeRegister routing.RouteRegister,
|
|
quotaService quota.Service,
|
|
pluginDashboardService plugindashboards.Service, pluginStore plugins.Store,
|
|
libraryPanelService librarypanels.Service, dashboardService dashboards.DashboardService,
|
|
ac accesscontrol.AccessControl, folderService folder.Service,
|
|
) *ImportDashboardService {
|
|
s := &ImportDashboardService{
|
|
pluginDashboardService: pluginDashboardService,
|
|
dashboardService: dashboardService,
|
|
libraryPanelService: libraryPanelService,
|
|
folderService: folderService,
|
|
}
|
|
|
|
dashboardImportAPI := api.New(s, quotaService, pluginStore, ac)
|
|
dashboardImportAPI.RegisterAPIEndpoints(routeRegister)
|
|
|
|
return s
|
|
}
|
|
|
|
type ImportDashboardService struct {
|
|
pluginDashboardService plugindashboards.Service
|
|
dashboardService dashboards.DashboardService
|
|
libraryPanelService librarypanels.Service
|
|
folderService folder.Service
|
|
}
|
|
|
|
func (s *ImportDashboardService) ImportDashboard(ctx context.Context, req *dashboardimport.ImportDashboardRequest) (*dashboardimport.ImportDashboardResponse, error) {
|
|
var draftDashboard *models.Dashboard
|
|
if req.PluginId != "" {
|
|
loadReq := &plugindashboards.LoadPluginDashboardRequest{
|
|
PluginID: req.PluginId,
|
|
Reference: req.Path,
|
|
}
|
|
if resp, err := s.pluginDashboardService.LoadPluginDashboard(ctx, loadReq); err != nil {
|
|
return nil, err
|
|
} else {
|
|
draftDashboard = resp.Dashboard
|
|
}
|
|
} else {
|
|
draftDashboard = models.NewDashboardFromJson(req.Dashboard)
|
|
}
|
|
|
|
evaluator := utils.NewDashTemplateEvaluator(draftDashboard.Data, req.Inputs)
|
|
generatedDash, err := evaluator.Eval()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Maintain backwards compatibility by transforming array of library elements to map
|
|
libraryElements := generatedDash.Get("__elements")
|
|
libElementsArr, err := libraryElements.Array()
|
|
if err == nil {
|
|
elementMap := map[string]interface{}{}
|
|
for _, el := range libElementsArr {
|
|
libElement := simplejson.NewFromAny(el)
|
|
elementMap[libElement.Get("uid").MustString()] = el
|
|
}
|
|
libraryElements = simplejson.NewFromAny(elementMap)
|
|
}
|
|
|
|
// No need to keep these in the stored dashboard JSON
|
|
generatedDash.Del("__elements")
|
|
generatedDash.Del("__inputs")
|
|
generatedDash.Del("__requires")
|
|
|
|
// here we need to get FolderId from FolderUID if it present in the request, if both exist, FolderUID would overwrite FolderID
|
|
if req.FolderUid != "" {
|
|
folder, err := s.folderService.Get(ctx, &folder.GetFolderQuery{
|
|
OrgID: req.User.OrgID,
|
|
UID: &req.FolderUid,
|
|
SignedInUser: req.User,
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
req.FolderId = folder.ID
|
|
} else {
|
|
folder, err := s.folderService.Get(ctx, &folder.GetFolderQuery{
|
|
ID: &req.FolderId,
|
|
OrgID: req.User.OrgID,
|
|
SignedInUser: req.User,
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
req.FolderUid = folder.UID
|
|
}
|
|
|
|
saveCmd := models.SaveDashboardCommand{
|
|
Dashboard: generatedDash,
|
|
OrgId: req.User.OrgID,
|
|
UserId: req.User.UserID,
|
|
Overwrite: req.Overwrite,
|
|
PluginId: req.PluginId,
|
|
FolderId: req.FolderId,
|
|
}
|
|
|
|
dto := &dashboards.SaveDashboardDTO{
|
|
OrgId: saveCmd.OrgId,
|
|
Dashboard: saveCmd.GetDashboardModel(),
|
|
Overwrite: saveCmd.Overwrite,
|
|
User: req.User,
|
|
}
|
|
|
|
savedDashboard, err := s.dashboardService.ImportDashboard(ctx, dto)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
err = s.libraryPanelService.ImportLibraryPanelsForDashboard(ctx, req.User, libraryElements, generatedDash.Get("panels").MustArray(), req.FolderId)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
err = s.libraryPanelService.ConnectLibraryPanelsForDashboard(ctx, req.User, savedDashboard)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &dashboardimport.ImportDashboardResponse{
|
|
UID: savedDashboard.Uid,
|
|
PluginId: req.PluginId,
|
|
Title: savedDashboard.Title,
|
|
Path: req.Path,
|
|
Revision: savedDashboard.Data.Get("revision").MustInt64(1),
|
|
FolderId: savedDashboard.FolderId,
|
|
FolderUID: req.FolderUid,
|
|
ImportedUri: "db/" + savedDashboard.Slug,
|
|
ImportedUrl: savedDashboard.GetUrl(),
|
|
ImportedRevision: savedDashboard.Data.Get("revision").MustInt64(1),
|
|
Imported: true,
|
|
DashboardId: savedDashboard.Id,
|
|
Slug: savedDashboard.Slug,
|
|
}, nil
|
|
}
|