The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
grafana/pkg/services/dashboardimport/api/api.go

98 lines
3.3 KiB

package api
import (
"net/http"
"github.com/grafana/grafana/pkg/api/apierrors"
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/api/routing"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/middleware"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/services/accesscontrol"
acmiddleware "github.com/grafana/grafana/pkg/services/accesscontrol/middleware"
"github.com/grafana/grafana/pkg/services/dashboardimport"
"github.com/grafana/grafana/pkg/web"
)
type ImportDashboardAPI struct {
dashboardImportService dashboardimport.Service
quotaService QuotaService
schemaLoaderService SchemaLoaderService
pluginStore plugins.Store
ac accesscontrol.AccessControl
}
func New(dashboardImportService dashboardimport.Service, quotaService QuotaService,
schemaLoaderService SchemaLoaderService, pluginStore plugins.Store, ac accesscontrol.AccessControl) *ImportDashboardAPI {
return &ImportDashboardAPI{
dashboardImportService: dashboardImportService,
quotaService: quotaService,
schemaLoaderService: schemaLoaderService,
pluginStore: pluginStore,
ac: ac,
}
}
func (api *ImportDashboardAPI) RegisterAPIEndpoints(routeRegister routing.RouteRegister) {
authorize := acmiddleware.Middleware(api.ac)
routeRegister.Group("/api/dashboards", func(route routing.RouteRegister) {
route.Post(
"/import",
authorize(middleware.ReqSignedIn, accesscontrol.EvalPermission(accesscontrol.ActionDashboardsCreate)),
routing.Wrap(api.ImportDashboard),
)
}, middleware.ReqSignedIn)
}
func (api *ImportDashboardAPI) ImportDashboard(c *models.ReqContext) response.Response {
req := dashboardimport.ImportDashboardRequest{}
if err := web.Bind(c.Req, &req); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err)
}
if req.PluginId == "" && req.Dashboard == nil {
return response.Error(http.StatusUnprocessableEntity, "Dashboard must be set", nil)
}
limitReached, err := api.quotaService.QuotaReached(c, "dashboard")
if err != nil {
return response.Error(500, "failed to get quota", err)
}
if limitReached {
return response.Error(403, "Quota reached", nil)
}
trimDefaults := c.QueryBoolWithDefault("trimdefaults", true)
if trimDefaults && !api.schemaLoaderService.IsDisabled() {
req.Dashboard, err = api.schemaLoaderService.DashboardApplyDefaults(req.Dashboard)
if err != nil {
return response.Error(http.StatusInternalServerError, "Error while applying default value to the dashboard json", err)
}
}
req.User = c.SignedInUser
resp, err := api.dashboardImportService.ImportDashboard(c.Req.Context(), &req)
if err != nil {
return apierrors.ToDashboardErrorResponse(c.Req.Context(), api.pluginStore, err)
}
return response.JSON(http.StatusOK, resp)
}
type QuotaService interface {
QuotaReached(c *models.ReqContext, target string) (bool, error)
}
type quotaServiceFunc func(c *models.ReqContext, target string) (bool, error)
func (fn quotaServiceFunc) QuotaReached(c *models.ReqContext, target string) (bool, error) {
return fn(c, target)
}
type SchemaLoaderService interface {
IsDisabled() bool
DashboardApplyDefaults(input *simplejson.Json) (*simplejson.Json, error)
}