Files
grafana/pkg/api/frontendsettings.go
lfroment 72628c8ea0 Dashboard: Adds support for a global minimum dashboard refresh interval (#19416)
This feature would provide a way for administrators to limit the minimum 
dashboard refresh interval globally.
Filters out the refresh intervals available in the time picker that are lower 
than the set minimum refresh interval in the configuration .ini file
Adds the minimum refresh interval as available in the time picker.
If the user tries to enter a refresh interval that is lower than the minimum 
in the URL, defaults to the minimum interval.
When trying to update the JSON via the API, rejects the update if the 
dashboard's refresh interval is lower than the minimum.
When trying to update a dashboard via provisioning having a lower 
refresh interval than the minimum, defaults to the minimum interval 
and logs a warning. 

Fixes #3356

Co-authored-by: Marcus Efraimsson <marcus.efraimsson@gmail.com>
2020-02-28 14:32:01 +01:00

259 lines
6.8 KiB
Go

package api
import (
"strconv"
"github.com/grafana/grafana/pkg/services/rendering"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/util"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/infra/log"
m "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/setting"
)
// getFrontendSettingsMap returns a json object with all the settings needed for front end initialisation.
func (hs *HTTPServer) getFrontendSettingsMap(c *m.ReqContext) (map[string]interface{}, error) {
orgDataSources := make([]*m.DataSource, 0)
if c.OrgId != 0 {
query := m.GetDataSourcesQuery{OrgId: c.OrgId}
err := bus.Dispatch(&query)
if err != nil {
return nil, err
}
dsFilterQuery := m.DatasourcesPermissionFilterQuery{
User: c.SignedInUser,
Datasources: query.Result,
}
if err := bus.Dispatch(&dsFilterQuery); err != nil {
if err != bus.ErrHandlerNotFound {
return nil, err
}
orgDataSources = query.Result
} else {
orgDataSources = dsFilterQuery.Result
}
}
datasources := make(map[string]interface{})
var defaultDatasource string
enabledPlugins, err := plugins.GetEnabledPlugins(c.OrgId)
if err != nil {
return nil, err
}
pluginsToPreload := []string{}
for _, app := range enabledPlugins.Apps {
if app.Preload {
pluginsToPreload = append(pluginsToPreload, app.Module)
}
}
for _, ds := range orgDataSources {
url := ds.Url
if ds.Access == m.DS_ACCESS_PROXY {
url = "/api/datasources/proxy/" + strconv.FormatInt(ds.Id, 10)
}
var dsMap = map[string]interface{}{
"id": ds.Id,
"type": ds.Type,
"name": ds.Name,
"url": url,
}
meta, exists := enabledPlugins.DataSources[ds.Type]
if !exists {
log.Error(3, "Could not find plugin definition for data source: %v", ds.Type)
continue
}
if meta.Preload {
pluginsToPreload = append(pluginsToPreload, meta.Module)
}
dsMap["meta"] = meta
if ds.IsDefault {
defaultDatasource = ds.Name
}
jsonData := ds.JsonData
if jsonData == nil {
jsonData = simplejson.New()
}
dsMap["jsonData"] = jsonData
if ds.Access == m.DS_ACCESS_DIRECT {
if ds.BasicAuth {
dsMap["basicAuth"] = util.GetBasicAuthHeader(ds.BasicAuthUser, ds.DecryptedBasicAuthPassword())
}
if ds.WithCredentials {
dsMap["withCredentials"] = ds.WithCredentials
}
if ds.Type == m.DS_INFLUXDB_08 {
dsMap["username"] = ds.User
dsMap["password"] = ds.DecryptedPassword()
dsMap["url"] = url + "/db/" + ds.Database
}
if ds.Type == m.DS_INFLUXDB {
dsMap["username"] = ds.User
dsMap["password"] = ds.DecryptedPassword()
dsMap["url"] = url
}
}
if (ds.Type == m.DS_INFLUXDB) || (ds.Type == m.DS_ES) {
dsMap["database"] = ds.Database
}
if ds.Type == m.DS_PROMETHEUS {
// add unproxied server URL for link to Prometheus web UI
jsonData.Set("directUrl", ds.Url)
}
datasources[ds.Name] = dsMap
}
// add datasources that are built in (meaning they are not added via data sources page, nor have any entry in datasource table)
for _, ds := range plugins.DataSources {
if ds.BuiltIn {
datasources[ds.Name] = map[string]interface{}{
"type": ds.Type,
"name": ds.Name,
"meta": plugins.DataSources[ds.Id],
}
}
}
if defaultDatasource == "" {
defaultDatasource = "-- Grafana --"
}
panels := map[string]interface{}{}
for _, panel := range enabledPlugins.Panels {
if panel.State == plugins.PluginStateAlpha && !hs.Cfg.PluginsEnableAlpha {
continue
}
if panel.Preload {
pluginsToPreload = append(pluginsToPreload, panel.Module)
}
panels[panel.Id] = map[string]interface{}{
"module": panel.Module,
"baseUrl": panel.BaseUrl,
"name": panel.Name,
"id": panel.Id,
"info": panel.Info,
"hideFromList": panel.HideFromList,
"sort": getPanelSort(panel.Id),
"skipDataQuery": panel.SkipDataQuery,
"state": panel.State,
}
}
jsonObj := map[string]interface{}{
"defaultDatasource": defaultDatasource,
"datasources": datasources,
"minRefreshInterval": setting.MinRefreshInterval,
"panels": panels,
"appSubUrl": setting.AppSubUrl,
"allowOrgCreate": (setting.AllowUserOrgCreate && c.IsSignedIn) || c.IsGrafanaAdmin,
"authProxyEnabled": setting.AuthProxyEnabled,
"ldapEnabled": setting.LDAPEnabled,
"alertingEnabled": setting.AlertingEnabled,
"alertingErrorOrTimeout": setting.AlertingErrorOrTimeout,
"alertingNoDataOrNullValues": setting.AlertingNoDataOrNullValues,
"alertingMinInterval": setting.AlertingMinInterval,
"autoAssignOrg": setting.AutoAssignOrg,
"verfiyEmailEnabled": setting.VerifyEmailEnabled,
"exploreEnabled": setting.ExploreEnabled,
"googleAnalyticsId": setting.GoogleAnalyticsId,
"disableLoginForm": setting.DisableLoginForm,
"disableUserSignUp": !setting.AllowUserSignUp,
"loginHint": setting.LoginHint,
"passwordHint": setting.PasswordHint,
"externalUserMngInfo": setting.ExternalUserMngInfo,
"externalUserMngLinkUrl": setting.ExternalUserMngLinkUrl,
"externalUserMngLinkName": setting.ExternalUserMngLinkName,
"viewersCanEdit": setting.ViewersCanEdit,
"editorsCanAdmin": hs.Cfg.EditorsCanAdmin,
"disableSanitizeHtml": hs.Cfg.DisableSanitizeHtml,
"pluginsToPreload": pluginsToPreload,
"buildInfo": map[string]interface{}{
"version": setting.BuildVersion,
"commit": setting.BuildCommit,
"buildstamp": setting.BuildStamp,
"edition": hs.License.Edition(),
"latestVersion": plugins.GrafanaLatestVersion,
"hasUpdate": plugins.GrafanaHasUpdate,
"env": setting.Env,
"isEnterprise": hs.License.HasValidLicense(),
},
"licenseInfo": map[string]interface{}{
"hasLicense": hs.License.HasLicense(),
"expiry": hs.License.Expiry(),
"stateInfo": hs.License.StateInfo(),
"licenseUrl": hs.License.LicenseURL(c.SignedInUser),
},
"featureToggles": hs.Cfg.FeatureToggles,
"phantomJSRenderer": rendering.IsPhantomJSEnabled,
}
return jsonObj, nil
}
func getPanelSort(id string) int {
sort := 100
switch id {
case "graph":
sort = 1
case "stat":
sort = 2
case "gauge":
sort = 3
case "bargauge":
sort = 4
case "table":
sort = 5
case "singlestat":
sort = 6
case "text":
sort = 7
case "heatmap":
sort = 8
case "alertlist":
sort = 9
case "dashlist":
sort = 10
case "news":
sort = 10
}
return sort
}
func (hs *HTTPServer) GetFrontendSettings(c *m.ReqContext) {
settings, err := hs.getFrontendSettingsMap(c)
if err != nil {
c.JsonApiErr(400, "Failed to get frontend settings", err)
return
}
c.JSON(200, settings)
}