2014-12-29 13:36:08 +01:00
|
|
|
package api
|
|
|
|
|
|
|
|
|
|
import (
|
2020-11-19 13:34:28 +01:00
|
|
|
"errors"
|
2014-12-29 13:36:08 +01:00
|
|
|
"strconv"
|
|
|
|
|
|
2020-03-04 12:57:20 +01:00
|
|
|
"github.com/grafana/grafana/pkg/models"
|
2020-01-30 17:35:32 +01:00
|
|
|
|
2019-05-10 02:37:43 -07:00
|
|
|
"github.com/grafana/grafana/pkg/components/simplejson"
|
2019-05-09 22:46:14 -07:00
|
|
|
"github.com/grafana/grafana/pkg/util"
|
|
|
|
|
|
2015-02-05 10:37:13 +01:00
|
|
|
"github.com/grafana/grafana/pkg/bus"
|
2019-05-13 14:45:54 +08:00
|
|
|
"github.com/grafana/grafana/pkg/infra/log"
|
2015-02-27 22:29:00 +01:00
|
|
|
"github.com/grafana/grafana/pkg/plugins"
|
2015-02-05 10:37:13 +01:00
|
|
|
"github.com/grafana/grafana/pkg/setting"
|
2014-12-29 13:36:08 +01:00
|
|
|
)
|
|
|
|
|
|
2020-09-07 22:10:06 +02:00
|
|
|
func getFSDataSources(c *models.ReqContext, enabledPlugins *plugins.EnabledPlugins) (map[string]interface{}, error) {
|
2020-03-04 12:57:20 +01:00
|
|
|
orgDataSources := make([]*models.DataSource, 0)
|
2014-12-29 13:36:08 +01:00
|
|
|
|
2015-03-11 17:34:11 +01:00
|
|
|
if c.OrgId != 0 {
|
2020-03-04 12:57:20 +01:00
|
|
|
query := models.GetDataSourcesQuery{OrgId: c.OrgId}
|
2014-12-29 13:36:08 +01:00
|
|
|
err := bus.Dispatch(&query)
|
|
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-04 12:57:20 +01:00
|
|
|
dsFilterQuery := models.DatasourcesPermissionFilterQuery{
|
2018-10-10 15:54:37 +02:00
|
|
|
User: c.SignedInUser,
|
|
|
|
|
Datasources: query.Result,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err := bus.Dispatch(&dsFilterQuery); err != nil {
|
2020-11-19 13:34:28 +01:00
|
|
|
if !errors.Is(err, bus.ErrHandlerNotFound) {
|
2018-10-10 15:54:37 +02:00
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
orgDataSources = query.Result
|
|
|
|
|
} else {
|
|
|
|
|
orgDataSources = dsFilterQuery.Result
|
|
|
|
|
}
|
2014-12-29 13:36:08 +01:00
|
|
|
}
|
|
|
|
|
|
2020-09-07 22:10:06 +02:00
|
|
|
dataSources := make(map[string]interface{})
|
2019-04-10 23:02:22 -07:00
|
|
|
|
2015-02-23 20:07:49 +01:00
|
|
|
for _, ds := range orgDataSources {
|
2014-12-29 13:36:08 +01:00
|
|
|
url := ds.Url
|
|
|
|
|
|
2020-03-04 12:57:20 +01:00
|
|
|
if ds.Access == models.DS_ACCESS_PROXY {
|
2016-09-23 12:29:53 +02:00
|
|
|
url = "/api/datasources/proxy/" + strconv.FormatInt(ds.Id, 10)
|
2014-12-29 13:36:08 +01:00
|
|
|
}
|
|
|
|
|
|
2020-09-07 22:10:06 +02:00
|
|
|
dsMap := map[string]interface{}{
|
|
|
|
|
"id": ds.Id,
|
|
|
|
|
"uid": ds.Uid,
|
|
|
|
|
"type": ds.Type,
|
|
|
|
|
"name": ds.Name,
|
|
|
|
|
"url": url,
|
|
|
|
|
"isDefault": ds.IsDefault,
|
2015-02-27 13:45:00 +01:00
|
|
|
}
|
|
|
|
|
|
2015-12-22 11:37:44 +01:00
|
|
|
meta, exists := enabledPlugins.DataSources[ds.Type]
|
2015-02-27 22:29:00 +01:00
|
|
|
if !exists {
|
2020-07-23 08:14:39 +02:00
|
|
|
log.Errorf(3, "Could not find plugin definition for data source: %v", ds.Type)
|
2015-03-27 14:23:23 +01:00
|
|
|
continue
|
2015-02-27 22:29:00 +01:00
|
|
|
}
|
|
|
|
|
dsMap["meta"] = meta
|
|
|
|
|
|
2019-05-10 02:37:43 -07:00
|
|
|
jsonData := ds.JsonData
|
|
|
|
|
if jsonData == nil {
|
|
|
|
|
jsonData = simplejson.New()
|
2015-05-20 18:29:20 +02:00
|
|
|
}
|
|
|
|
|
|
2019-05-10 02:37:43 -07:00
|
|
|
dsMap["jsonData"] = jsonData
|
|
|
|
|
|
2020-03-04 12:57:20 +01:00
|
|
|
if ds.Access == models.DS_ACCESS_DIRECT {
|
2015-03-02 09:58:35 +01:00
|
|
|
if ds.BasicAuth {
|
2019-04-15 11:11:17 +02:00
|
|
|
dsMap["basicAuth"] = util.GetBasicAuthHeader(ds.BasicAuthUser, ds.DecryptedBasicAuthPassword())
|
2015-03-02 09:58:35 +01:00
|
|
|
}
|
2015-12-09 12:37:08 +09:00
|
|
|
if ds.WithCredentials {
|
|
|
|
|
dsMap["withCredentials"] = ds.WithCredentials
|
|
|
|
|
}
|
2015-03-02 09:58:35 +01:00
|
|
|
|
2020-03-04 12:57:20 +01:00
|
|
|
if ds.Type == models.DS_INFLUXDB_08 {
|
2014-12-29 13:36:08 +01:00
|
|
|
dsMap["username"] = ds.User
|
2019-04-15 11:11:17 +02:00
|
|
|
dsMap["password"] = ds.DecryptedPassword()
|
2014-12-29 13:36:08 +01:00
|
|
|
dsMap["url"] = url + "/db/" + ds.Database
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-04 12:57:20 +01:00
|
|
|
if ds.Type == models.DS_INFLUXDB {
|
2015-02-25 18:43:44 +01:00
|
|
|
dsMap["username"] = ds.User
|
2019-04-15 11:11:17 +02:00
|
|
|
dsMap["password"] = ds.DecryptedPassword()
|
2015-02-25 18:43:44 +01:00
|
|
|
dsMap["url"] = url
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-04 12:57:20 +01:00
|
|
|
if (ds.Type == models.DS_INFLUXDB) || (ds.Type == models.DS_ES) {
|
2016-01-18 07:28:01 +01:00
|
|
|
dsMap["database"] = ds.Database
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-04 12:57:20 +01:00
|
|
|
if ds.Type == models.DS_PROMETHEUS {
|
2015-10-01 18:01:09 +02:00
|
|
|
// add unproxied server URL for link to Prometheus web UI
|
2019-05-10 02:37:43 -07:00
|
|
|
jsonData.Set("directUrl", ds.Url)
|
2015-10-01 18:01:09 +02:00
|
|
|
}
|
|
|
|
|
|
2020-09-07 22:10:06 +02:00
|
|
|
dataSources[ds.Name] = dsMap
|
2014-12-29 13:36:08 +01:00
|
|
|
}
|
|
|
|
|
|
2020-09-07 22:10:06 +02:00
|
|
|
// add data sources that are built in (meaning they are not added via data sources page, nor have any entry in
|
|
|
|
|
// the datasource table)
|
2017-04-11 13:47:53 -07:00
|
|
|
for _, ds := range plugins.DataSources {
|
2017-04-12 08:23:44 +02:00
|
|
|
if ds.BuiltIn {
|
2020-09-07 22:10:06 +02:00
|
|
|
dataSources[ds.Name] = map[string]interface{}{
|
2017-04-11 13:47:53 -07:00
|
|
|
"type": ds.Type,
|
|
|
|
|
"name": ds.Name,
|
|
|
|
|
"meta": plugins.DataSources[ds.Id],
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-08-16 20:52:30 +02:00
|
|
|
}
|
2015-02-28 09:46:37 +01:00
|
|
|
|
2020-09-07 22:10:06 +02:00
|
|
|
return dataSources, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// getFrontendSettingsMap returns a json object with all the settings needed for front end initialisation.
|
|
|
|
|
func (hs *HTTPServer) getFrontendSettingsMap(c *models.ReqContext) (map[string]interface{}, error) {
|
|
|
|
|
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)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dataSources, err := getFSDataSources(c, enabledPlugins)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
defaultDS := "-- Grafana --"
|
|
|
|
|
for n, ds := range dataSources {
|
|
|
|
|
dsM := ds.(map[string]interface{})
|
|
|
|
|
if isDefault, _ := dsM["isDefault"].(bool); isDefault {
|
|
|
|
|
defaultDS = n
|
|
|
|
|
}
|
|
|
|
|
delete(dsM, "isDefault")
|
|
|
|
|
|
|
|
|
|
meta := dsM["meta"].(*plugins.DataSourcePlugin)
|
|
|
|
|
if meta.Preload {
|
|
|
|
|
pluginsToPreload = append(pluginsToPreload, meta.Module)
|
|
|
|
|
}
|
2014-12-29 13:36:08 +01:00
|
|
|
}
|
|
|
|
|
|
2015-11-21 13:46:18 +01:00
|
|
|
panels := map[string]interface{}{}
|
2015-12-22 11:37:44 +01:00
|
|
|
for _, panel := range enabledPlugins.Panels {
|
2019-04-12 04:46:42 -07:00
|
|
|
if panel.State == plugins.PluginStateAlpha && !hs.Cfg.PluginsEnableAlpha {
|
2018-10-09 17:47:43 +02:00
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-10 23:02:22 -07:00
|
|
|
if panel.Preload {
|
|
|
|
|
pluginsToPreload = append(pluginsToPreload, panel.Module)
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-08 23:15:44 +01:00
|
|
|
panels[panel.Id] = map[string]interface{}{
|
2019-05-09 22:46:14 -07:00
|
|
|
"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,
|
2020-10-23 16:45:43 +02:00
|
|
|
"signature": panel.Signature,
|
2015-11-21 13:46:18 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-17 07:39:50 +02:00
|
|
|
hideVersion := hs.Cfg.AnonymousHideVersion && !c.IsSignedIn
|
|
|
|
|
version := setting.BuildVersion
|
|
|
|
|
commit := setting.BuildCommit
|
|
|
|
|
buildstamp := setting.BuildStamp
|
|
|
|
|
|
|
|
|
|
if hideVersion {
|
|
|
|
|
version = ""
|
|
|
|
|
commit = ""
|
|
|
|
|
buildstamp = 0
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-29 13:36:08 +01:00
|
|
|
jsonObj := map[string]interface{}{
|
2020-09-07 22:10:06 +02:00
|
|
|
"defaultDatasource": defaultDS,
|
|
|
|
|
"datasources": dataSources,
|
2020-02-28 14:32:01 +01:00
|
|
|
"minRefreshInterval": setting.MinRefreshInterval,
|
2018-09-06 11:20:38 +02:00
|
|
|
"panels": panels,
|
2020-06-16 16:33:44 +03:00
|
|
|
"appUrl": setting.AppUrl,
|
2018-09-06 11:20:38 +02:00
|
|
|
"appSubUrl": setting.AppSubUrl,
|
|
|
|
|
"allowOrgCreate": (setting.AllowUserOrgCreate && c.IsSignedIn) || c.IsGrafanaAdmin,
|
|
|
|
|
"authProxyEnabled": setting.AuthProxyEnabled,
|
2019-05-22 15:30:03 +03:00
|
|
|
"ldapEnabled": setting.LDAPEnabled,
|
2018-09-06 11:20:38 +02:00
|
|
|
"alertingEnabled": setting.AlertingEnabled,
|
|
|
|
|
"alertingErrorOrTimeout": setting.AlertingErrorOrTimeout,
|
|
|
|
|
"alertingNoDataOrNullValues": setting.AlertingNoDataOrNullValues,
|
2020-01-14 11:13:34 +02:00
|
|
|
"alertingMinInterval": setting.AlertingMinInterval,
|
2020-02-17 11:13:13 +01:00
|
|
|
"autoAssignOrg": setting.AutoAssignOrg,
|
2020-07-11 12:26:02 +05:30
|
|
|
"verifyEmailEnabled": setting.VerifyEmailEnabled,
|
2020-10-08 10:03:20 +02:00
|
|
|
"sigV4AuthEnabled": setting.SigV4AuthEnabled,
|
2018-09-06 11:20:38 +02:00
|
|
|
"exploreEnabled": setting.ExploreEnabled,
|
|
|
|
|
"googleAnalyticsId": setting.GoogleAnalyticsId,
|
|
|
|
|
"disableLoginForm": setting.DisableLoginForm,
|
2019-09-16 13:38:03 +02:00
|
|
|
"disableUserSignUp": !setting.AllowUserSignUp,
|
|
|
|
|
"loginHint": setting.LoginHint,
|
|
|
|
|
"passwordHint": setting.PasswordHint,
|
2018-09-06 11:20:38 +02:00
|
|
|
"externalUserMngInfo": setting.ExternalUserMngInfo,
|
|
|
|
|
"externalUserMngLinkUrl": setting.ExternalUserMngLinkUrl,
|
|
|
|
|
"externalUserMngLinkName": setting.ExternalUserMngLinkName,
|
2019-01-21 08:47:41 +01:00
|
|
|
"viewersCanEdit": setting.ViewersCanEdit,
|
2019-03-12 07:32:47 +01:00
|
|
|
"editorsCanAdmin": hs.Cfg.EditorsCanAdmin,
|
2019-01-22 11:56:35 +01:00
|
|
|
"disableSanitizeHtml": hs.Cfg.DisableSanitizeHtml,
|
2019-04-10 23:02:22 -07:00
|
|
|
"pluginsToPreload": pluginsToPreload,
|
2015-01-05 10:46:58 +01:00
|
|
|
"buildInfo": map[string]interface{}{
|
2020-06-17 07:39:50 +02:00
|
|
|
"hideVersion": hideVersion,
|
|
|
|
|
"version": version,
|
|
|
|
|
"commit": commit,
|
|
|
|
|
"buildstamp": buildstamp,
|
2020-01-27 09:24:44 +01:00
|
|
|
"edition": hs.License.Edition(),
|
2016-04-11 13:42:52 -04:00
|
|
|
"latestVersion": plugins.GrafanaLatestVersion,
|
|
|
|
|
"hasUpdate": plugins.GrafanaHasUpdate,
|
2016-05-17 15:00:48 +02:00
|
|
|
"env": setting.Env,
|
2019-11-01 14:56:12 +01:00
|
|
|
"isEnterprise": hs.License.HasValidLicense(),
|
|
|
|
|
},
|
|
|
|
|
"licenseInfo": map[string]interface{}{
|
2020-11-05 12:55:40 +02:00
|
|
|
"hasLicense": hs.License.HasLicense(),
|
|
|
|
|
"hasValidLicense": hs.License.HasValidLicense(),
|
|
|
|
|
"expiry": hs.License.Expiry(),
|
|
|
|
|
"stateInfo": hs.License.StateInfo(),
|
|
|
|
|
"licenseUrl": hs.License.LicenseURL(c.SignedInUser),
|
|
|
|
|
"edition": hs.License.Edition(),
|
2015-01-05 10:46:58 +01:00
|
|
|
},
|
2020-01-30 17:35:32 +01:00
|
|
|
"featureToggles": hs.Cfg.FeatureToggles,
|
2020-04-15 22:17:41 +02:00
|
|
|
"rendererAvailable": hs.RenderService.IsAvailable(),
|
2020-10-02 15:45:45 +02:00
|
|
|
"http2Enabled": hs.Cfg.Protocol == setting.HTTP2Scheme,
|
2020-11-12 13:29:43 +02:00
|
|
|
"sentry": hs.Cfg.Sentry,
|
2020-11-05 12:55:40 +02:00
|
|
|
"marketplaceUrl": hs.Cfg.MarketplaceURL,
|
2014-12-29 13:36:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return jsonObj, nil
|
|
|
|
|
}
|
2015-02-18 14:06:44 +01:00
|
|
|
|
2016-10-26 17:42:39 +02:00
|
|
|
func getPanelSort(id string) int {
|
|
|
|
|
sort := 100
|
|
|
|
|
switch id {
|
|
|
|
|
case "graph":
|
|
|
|
|
sort = 1
|
2020-01-17 09:43:17 +01:00
|
|
|
case "stat":
|
2016-10-26 17:42:39 +02:00
|
|
|
sort = 2
|
2018-12-17 17:54:40 +01:00
|
|
|
case "gauge":
|
2016-10-26 17:42:39 +02:00
|
|
|
sort = 3
|
2019-02-15 21:33:36 +01:00
|
|
|
case "bargauge":
|
2016-10-26 17:42:39 +02:00
|
|
|
sort = 4
|
2019-02-15 21:33:36 +01:00
|
|
|
case "table":
|
2016-10-26 17:42:39 +02:00
|
|
|
sort = 5
|
2020-01-17 09:43:17 +01:00
|
|
|
case "singlestat":
|
2016-10-26 17:42:39 +02:00
|
|
|
sort = 6
|
2020-01-17 09:43:17 +01:00
|
|
|
case "text":
|
2017-05-03 08:56:51 +02:00
|
|
|
sort = 7
|
2020-01-17 09:43:17 +01:00
|
|
|
case "heatmap":
|
2018-12-17 17:54:40 +01:00
|
|
|
sort = 8
|
2020-01-17 09:43:17 +01:00
|
|
|
case "alertlist":
|
2019-02-15 21:33:36 +01:00
|
|
|
sort = 9
|
2020-01-17 09:43:17 +01:00
|
|
|
case "dashlist":
|
|
|
|
|
sort = 10
|
|
|
|
|
case "news":
|
|
|
|
|
sort = 10
|
2016-10-26 17:42:39 +02:00
|
|
|
}
|
|
|
|
|
return sort
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-04 12:57:20 +01:00
|
|
|
func (hs *HTTPServer) GetFrontendSettings(c *models.ReqContext) {
|
2018-10-09 17:47:43 +02:00
|
|
|
settings, err := hs.getFrontendSettingsMap(c)
|
2015-02-18 14:06:44 +01:00
|
|
|
if err != nil {
|
|
|
|
|
c.JsonApiErr(400, "Failed to get frontend settings", err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
c.JSON(200, settings)
|
|
|
|
|
}
|