mirror of
https://github.com/grafana/grafana.git
synced 2025-07-31 18:42:27 +08:00
Dashboards: Make path to default dashboard configurable (#25595)
Closes #25463 Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com> Co-authored-by: Diana Payton <52059945+oddlittlebird@users.noreply.github.com>
This commit is contained in:
@ -234,6 +234,9 @@ versions_to_keep = 20
|
||||
# The interval string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
|
||||
min_refresh_interval = 5s
|
||||
|
||||
# Path to the default home dashboard. If this value is empty, then Grafana uses StaticRootPath + "dashboards/home.json"
|
||||
default_home_dashboard_path =
|
||||
|
||||
#################################### Users ###############################
|
||||
[users]
|
||||
# disable user signup / registration
|
||||
|
@ -233,6 +233,9 @@
|
||||
# The interval string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. 30s or 1m.
|
||||
;min_refresh_interval = 5s
|
||||
|
||||
# Path to the default home dashboard. If this value is empty, then Grafana uses StaticRootPath + "dashboards/home.json"
|
||||
;default_home_dashboard_path =
|
||||
|
||||
#################################### Users ###############################
|
||||
[users]
|
||||
# disable user signup / registration
|
||||
|
@ -525,6 +525,11 @@ Number dashboard versions to keep (per dashboard). Default: `20`, Minimum: `1`.
|
||||
This will restrict users to set the refresh interval of a dashboard lower than given interval. Per default this is 5 seconds.
|
||||
The interval string is a possibly signed sequence of decimal numbers, followed by a unit suffix (ms, s, m, h, d), e.g. `30s` or `1m`.
|
||||
|
||||
### default_home_dashboard_path
|
||||
|
||||
Path to the default home dashboard. If this value is empty, then Grafana uses StaticRootPath + "dashboards/home.json"
|
||||
|
||||
|
||||
## [dashboards.json]
|
||||
|
||||
> This have been replaced with dashboards [provisioning]({{< relref "../administration/provisioning" >}}) in 5.0+
|
||||
|
@ -298,7 +298,7 @@ func (hs *HTTPServer) registerRoutes() {
|
||||
dashboardRoute.Post("/calculate-diff", bind(dtos.CalculateDiffOptions{}), Wrap(CalculateDashboardDiff))
|
||||
|
||||
dashboardRoute.Post("/db", bind(models.SaveDashboardCommand{}), Wrap(hs.PostDashboard))
|
||||
dashboardRoute.Get("/home", Wrap(GetHomeDashboard))
|
||||
dashboardRoute.Get("/home", Wrap(hs.GetHomeDashboard))
|
||||
dashboardRoute.Get("/tags", GetDashboardTags)
|
||||
dashboardRoute.Post("/import", bind(dtos.ImportDashboardCommand{}), Wrap(ImportDashboard))
|
||||
|
||||
|
@ -19,7 +19,6 @@ import (
|
||||
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/services/guardian"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
)
|
||||
|
||||
@ -315,15 +314,16 @@ func dashboardSaveErrorToApiResponse(err error) Response {
|
||||
return Error(500, "Failed to save dashboard", err)
|
||||
}
|
||||
|
||||
func GetHomeDashboard(c *models.ReqContext) Response {
|
||||
// GetHomeDashboard returns the home dashboard.
|
||||
func (hs *HTTPServer) GetHomeDashboard(c *models.ReqContext) Response {
|
||||
prefsQuery := models.GetPreferencesWithDefaultsQuery{User: c.SignedInUser}
|
||||
if err := bus.Dispatch(&prefsQuery); err != nil {
|
||||
if err := hs.Bus.Dispatch(&prefsQuery); err != nil {
|
||||
return Error(500, "Failed to get preferences", err)
|
||||
}
|
||||
|
||||
if prefsQuery.Result.HomeDashboardId != 0 {
|
||||
slugQuery := models.GetDashboardRefByIdQuery{Id: prefsQuery.Result.HomeDashboardId}
|
||||
err := bus.Dispatch(&slugQuery)
|
||||
err := hs.Bus.Dispatch(&slugQuery)
|
||||
if err == nil {
|
||||
url := models.GetDashboardUrl(slugQuery.Result.Uid, slugQuery.Result.Slug)
|
||||
dashRedirect := dtos.DashboardRedirect{RedirectUri: url}
|
||||
@ -332,7 +332,11 @@ func GetHomeDashboard(c *models.ReqContext) Response {
|
||||
log.Warn("Failed to get slug from database, %s", err.Error())
|
||||
}
|
||||
|
||||
filePath := path.Join(setting.StaticRootPath, "dashboards/home.json")
|
||||
filePath := hs.Cfg.DefaultHomeDashboardPath
|
||||
if filePath == "" {
|
||||
filePath = path.Join(hs.Cfg.StaticRootPath, "dashboards/home.json")
|
||||
}
|
||||
|
||||
file, err := os.Open(filePath)
|
||||
if err != nil {
|
||||
return Error(500, "Failed to load home dashboard", err)
|
||||
|
@ -3,6 +3,7 @@ package api
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana/pkg/api/dtos"
|
||||
@ -13,10 +14,58 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
"github.com/grafana/grafana/pkg/services/provisioning"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func TestGetHomeDashboard(t *testing.T) {
|
||||
req := &models.ReqContext{SignedInUser: &models.SignedInUser{}}
|
||||
cfg := setting.NewCfg()
|
||||
cfg.StaticRootPath = "../../public/"
|
||||
|
||||
hs := &HTTPServer{Cfg: cfg, Bus: bus.New()}
|
||||
hs.Bus.AddHandler(func(query *models.GetPreferencesWithDefaultsQuery) error {
|
||||
query.Result = &models.Preferences{
|
||||
HomeDashboardId: 0,
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
defaultSetting string
|
||||
expectedDashboardPath string
|
||||
}{
|
||||
{name: "using default config", defaultSetting: "", expectedDashboardPath: "../../public/dashboards/home.json"},
|
||||
{name: "custom path", defaultSetting: "../../public/dashboards/default.json", expectedDashboardPath: "../../public/dashboards/default.json"},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
dash := dtos.DashboardFullWithMeta{}
|
||||
dash.Meta.IsHome = true
|
||||
dash.Meta.FolderTitle = "General"
|
||||
|
||||
homeDashJSON, err := ioutil.ReadFile(tc.expectedDashboardPath)
|
||||
require.NoError(t, err, "must be able to read expected dashboard file")
|
||||
hs.Cfg.DefaultHomeDashboardPath = tc.defaultSetting
|
||||
bytes, err := simplejson.NewJson(homeDashJSON)
|
||||
require.NoError(t, err, "must be able to encode file as JSON")
|
||||
|
||||
dash.Dashboard = bytes
|
||||
|
||||
b, err := json.Marshal(dash)
|
||||
require.NoError(t, err, "must be able to marshal object to JSON")
|
||||
|
||||
res := hs.GetHomeDashboard(req)
|
||||
nr, ok := res.(*NormalResponse)
|
||||
require.True(t, ok, "should return *NormalResponse")
|
||||
require.Equal(t, b, nr.body, "default home dashboard should equal content on disk")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// This tests three main scenarios.
|
||||
// If a user has access to execute an action on a dashboard:
|
||||
// 1. and the dashboard is in a folder which does not have an acl
|
||||
|
@ -227,6 +227,7 @@ type Cfg struct {
|
||||
AppUrl string
|
||||
AppSubUrl string
|
||||
ServeFromSubPath bool
|
||||
StaticRootPath string
|
||||
|
||||
// build
|
||||
BuildVersion string
|
||||
@ -272,6 +273,9 @@ type Cfg struct {
|
||||
DisableSanitizeHtml bool
|
||||
EnterpriseLicensePath string
|
||||
|
||||
// Dashboards
|
||||
DefaultHomeDashboardPath string
|
||||
|
||||
// Auth
|
||||
LoginCookieName string
|
||||
LoginMaxInactiveLifetimeDays int
|
||||
@ -699,6 +703,7 @@ func (cfg *Cfg) Load(args *CommandLineArgs) error {
|
||||
return err
|
||||
}
|
||||
StaticRootPath = makeAbsolute(staticRoot, HomePath)
|
||||
cfg.StaticRootPath = StaticRootPath
|
||||
|
||||
if err := cfg.validateStaticRootPath(); err != nil {
|
||||
return err
|
||||
@ -778,6 +783,8 @@ func (cfg *Cfg) Load(args *CommandLineArgs) error {
|
||||
return err
|
||||
}
|
||||
|
||||
cfg.DefaultHomeDashboardPath = dashboards.Key("default_home_dashboard_path").MustString("")
|
||||
|
||||
// read data source proxy white list
|
||||
DataProxyWhiteList = make(map[string]bool)
|
||||
securityStr, err := valueAsString(security, "data_source_proxy_whitelist", "")
|
||||
|
Reference in New Issue
Block a user