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/api/frontendsettings.go

298 lines
8.3 KiB

package api
import (
"errors"
"strconv"
"github.com/grafana/grafana/pkg/models"
"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"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/setting"
)
func (hs *HTTPServer) getFSDataSources(c *models.ReqContext, enabledPlugins *plugins.EnabledPlugins) (map[string]interface{}, error) {
orgDataSources := make([]*models.DataSource, 0)
if c.OrgId != 0 {
query := models.GetDataSourcesQuery{OrgId: c.OrgId, DataSourceLimit: hs.Cfg.DataSourceLimit}
err := bus.Dispatch(&query)
if err != nil {
return nil, err
}
dsFilterQuery := models.DatasourcesPermissionFilterQuery{
User: c.SignedInUser,
Datasources: query.Result,
}
if err := bus.Dispatch(&dsFilterQuery); err != nil {
if !errors.Is(err, bus.ErrHandlerNotFound) {
return nil, err
}
orgDataSources = query.Result
} else {
orgDataSources = dsFilterQuery.Result
}
}
dataSources := make(map[string]interface{})
for _, ds := range orgDataSources {
url := ds.Url
if ds.Access == models.DS_ACCESS_PROXY {
url = "/api/datasources/proxy/" + strconv.FormatInt(ds.Id, 10)
}
dsMap := map[string]interface{}{
"id": ds.Id,
"uid": ds.Uid,
"type": ds.Type,
"name": ds.Name,
"url": url,
"isDefault": ds.IsDefault,
}
meta, exists := enabledPlugins.DataSources[ds.Type]
if !exists {
log.Errorf(3, "Could not find plugin definition for data source: %v", ds.Type)
10 years ago
continue
}
dsMap["meta"] = meta
jsonData := ds.JsonData
if jsonData == nil {
jsonData = simplejson.New()
}
dsMap["jsonData"] = jsonData
if ds.Access == models.DS_ACCESS_DIRECT {
if ds.BasicAuth {
dsMap["basicAuth"] = util.GetBasicAuthHeader(ds.BasicAuthUser, ds.DecryptedBasicAuthPassword())
}
if ds.WithCredentials {
dsMap["withCredentials"] = ds.WithCredentials
}
if ds.Type == models.DS_INFLUXDB_08 {
dsMap["username"] = ds.User
dsMap["password"] = ds.DecryptedPassword()
dsMap["url"] = url + "/db/" + ds.Database
}
if ds.Type == models.DS_INFLUXDB {
dsMap["username"] = ds.User
dsMap["password"] = ds.DecryptedPassword()
dsMap["url"] = url
}
}
if (ds.Type == models.DS_INFLUXDB) || (ds.Type == models.DS_ES) {
10 years ago
dsMap["database"] = ds.Database
}
if ds.Type == models.DS_PROMETHEUS {
// add unproxied server URL for link to Prometheus web UI
jsonData.Set("directUrl", ds.Url)
}
dataSources[ds.Name] = dsMap
}
// add data sources that are built in (meaning they are not added via data sources page, nor have any entry in
// the datasource table)
PluginManager: Make Plugins, Renderer and DataSources non-global (#31866) * PluginManager: Make Plugins and DataSources non-global Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix integration tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Replace outdated command Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * DashboardService: Ensure it gets constructed with necessary parameters Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix build Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * DashboardService: Ensure it gets constructed with necessary parameters Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove dead code Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove FocusConvey Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove dead code Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Undo interface changes Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Backend: Move tsdbifaces.RequestHandler to plugins.DataRequestHandler Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Rename to DataSourceCount Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Consolidate dashboard interfaces into one Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix dashboard integration tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
4 years ago
for _, ds := range hs.PluginManager.DataSources() {
if ds.BuiltIn {
dataSources[ds.Name] = map[string]interface{}{
"type": ds.Type,
"name": ds.Name,
PluginManager: Make Plugins, Renderer and DataSources non-global (#31866) * PluginManager: Make Plugins and DataSources non-global Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix integration tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Replace outdated command Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * DashboardService: Ensure it gets constructed with necessary parameters Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix build Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * DashboardService: Ensure it gets constructed with necessary parameters Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove dead code Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove FocusConvey Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove dead code Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Undo interface changes Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Backend: Move tsdbifaces.RequestHandler to plugins.DataRequestHandler Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Rename to DataSourceCount Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Consolidate dashboard interfaces into one Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix dashboard integration tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
4 years ago
"meta": hs.PluginManager.GetDataSource(ds.Id),
}
}
}
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 := hs.PluginManager.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 := hs.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
}
meta := dsM["meta"].(*plugins.DataSourcePlugin)
if meta.Preload {
pluginsToPreload = append(pluginsToPreload, meta.Module)
}
}
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,
"signature": panel.Signature,
}
}
hideVersion := hs.Cfg.AnonymousHideVersion && !c.IsSignedIn
version := setting.BuildVersion
commit := setting.BuildCommit
buildstamp := setting.BuildStamp
if hideVersion {
version = ""
commit = ""
buildstamp = 0
}
jsonObj := map[string]interface{}{
"defaultDatasource": defaultDS,
"datasources": dataSources,
"minRefreshInterval": setting.MinRefreshInterval,
"panels": panels,
"appUrl": hs.Cfg.AppURL,
"appSubUrl": hs.Cfg.AppSubURL,
"allowOrgCreate": (setting.AllowUserOrgCreate && c.IsSignedIn) || c.IsGrafanaAdmin,
"authProxyEnabled": setting.AuthProxyEnabled,
"ldapEnabled": hs.Cfg.LDAPEnabled,
"alertingEnabled": setting.AlertingEnabled,
"alertingErrorOrTimeout": setting.AlertingErrorOrTimeout,
"alertingNoDataOrNullValues": setting.AlertingNoDataOrNullValues,
"alertingMinInterval": setting.AlertingMinInterval,
"autoAssignOrg": setting.AutoAssignOrg,
"verifyEmailEnabled": setting.VerifyEmailEnabled,
"sigV4AuthEnabled": setting.SigV4AuthEnabled,
"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{}{
"hideVersion": hideVersion,
"version": version,
"commit": commit,
"buildstamp": buildstamp,
"edition": hs.License.Edition(),
PluginManager: Make Plugins, Renderer and DataSources non-global (#31866) * PluginManager: Make Plugins and DataSources non-global Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix integration tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Replace outdated command Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * DashboardService: Ensure it gets constructed with necessary parameters Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix build Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * DashboardService: Ensure it gets constructed with necessary parameters Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove dead code Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove FocusConvey Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove dead code Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Undo interface changes Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Backend: Move tsdbifaces.RequestHandler to plugins.DataRequestHandler Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Rename to DataSourceCount Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Consolidate dashboard interfaces into one Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix dashboard integration tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
4 years ago
"latestVersion": hs.PluginManager.GrafanaLatestVersion(),
"hasUpdate": hs.PluginManager.GrafanaHasUpdate(),
"env": setting.Env,
"isEnterprise": hs.License.HasValidLicense(),
},
"licenseInfo": map[string]interface{}{
"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(),
},
AWS: Add aws plugin configuration (#31312) * add new conf and make sure its passed to frontend * change auth provider name * goimports * fixed after feedback * more updates after feedback * Update docs/sources/administration/configuration.md Co-authored-by: Ursula Kallio <73951760+osg-grafana@users.noreply.github.com> * Update docs/sources/administration/configuration.md Co-authored-by: Ursula Kallio <73951760+osg-grafana@users.noreply.github.com> * Update docs/sources/administration/configuration.md Co-authored-by: Ursula Kallio <73951760+osg-grafana@users.noreply.github.com> * Update docs/sources/administration/configuration.md Co-authored-by: Ursula Kallio <73951760+osg-grafana@users.noreply.github.com> * Update docs/sources/administration/configuration.md Co-authored-by: Ursula Kallio <73951760+osg-grafana@users.noreply.github.com> * Update conf/sample.ini Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com> * Update docs/sources/administration/configuration.md Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com> * Update pkg/setting/setting.go Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com> * updates after pr feedback * Update conf/defaults.ini Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com> * Update conf/defaults.ini Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com> * Update conf/sample.ini Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com> Co-authored-by: Ursula Kallio <73951760+osg-grafana@users.noreply.github.com> Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com>
4 years ago
"featureToggles": hs.Cfg.FeatureToggles,
"rendererAvailable": hs.RenderService.IsAvailable(),
"http2Enabled": hs.Cfg.Protocol == setting.HTTP2Scheme,
"sentry": hs.Cfg.Sentry,
"marketplaceUrl": hs.Cfg.MarketplaceURL,
"expressionsEnabled": hs.Cfg.ExpressionsEnabled,
"awsAllowedAuthProviders": hs.Cfg.AWSAllowedAuthProviders,
"awsAssumeRoleEnabled": hs.Cfg.AWSAssumeRoleEnabled,
}
return jsonObj, nil
}
func getPanelSort(id string) int {
sort := 100
switch id {
case "graph":
sort = 1
case "timeseries":
sort = 2
case "barchart":
sort = 3
case "stat":
sort = 4
case "gauge":
sort = 5
case "bargauge":
sort = 6
case "table":
sort = 7
case "singlestat":
sort = 8
case "piechart":
sort = 9
PanelEdit: v8 Panel Edit UX (#32124) * Initial commit * Progress * Update * Progress * updates * Minor fix * fixed ts issue * fixed e2e tests * More explorations * Making progress * Panel options and field options unified * With nested categories * Starting to find something * fix paddings * Progress * Breakthrough ux layout * Progress * Updates * New way of composing options with search * added regex search * Refactoring to react note tree * Show overrides * Adding overrides radio button support * Added popular view * Separate stat/gauge/bargauge options into value options and display options * Initial work on getting library panels into viz picker flow * Fixed issues switching to panel library panel * Move search input put of LibraryPanelsView * Changing design again to have content inside boxes * Style updates * Refactoring to fix scroll issue * Option category naming * Fixed FilterInput issue * Updated snapshots * Fix padding * Updated viz picker design * Unify library panel an viz picker card * Updated card with delete action * Major refactoring back to an object model instead of searching and filtering react node tree * More refactoring * Show option category in label when searching * Nice logic for categories rendering when searching or when only child * Make getSuggestions more lazy for DataLinksEditor * Add missing repeat options and handle conditional options * Prepping options category to be more flexibly and control state from outside * Added option count to search result * Minor style tweak * Added button to close viz picker * Rewrote overrides to enable searching overrides * New search engine and tests * Searching overrides works * Hide radio buttons while searching * Added angular options back * Added memoize for all options so they are not rebuilt for every search key stroke * Added back support for category counters * Started unit test work * Refactoring and base popular options list * Initial update to e2e test, more coming to add e2e test for search features * Minor fix * Review updates * Fixing category open states * Unit test progress * Do not show visualization list mode radio button if library panels is not enabled * Use boolean * More unit tests * Increase library panels per page count and give search focus when switching list mode * field config change test and search test * Feedback updates * Minor tweaks * Minor refactorings * More minimal override collapse state
4 years ago
case "heatmap":
sort = 10
case "text":
sort = 11
case "alertlist":
sort = 12
case "dashlist":
PanelEdit: v8 Panel Edit UX (#32124) * Initial commit * Progress * Update * Progress * updates * Minor fix * fixed ts issue * fixed e2e tests * More explorations * Making progress * Panel options and field options unified * With nested categories * Starting to find something * fix paddings * Progress * Breakthrough ux layout * Progress * Updates * New way of composing options with search * added regex search * Refactoring to react note tree * Show overrides * Adding overrides radio button support * Added popular view * Separate stat/gauge/bargauge options into value options and display options * Initial work on getting library panels into viz picker flow * Fixed issues switching to panel library panel * Move search input put of LibraryPanelsView * Changing design again to have content inside boxes * Style updates * Refactoring to fix scroll issue * Option category naming * Fixed FilterInput issue * Updated snapshots * Fix padding * Updated viz picker design * Unify library panel an viz picker card * Updated card with delete action * Major refactoring back to an object model instead of searching and filtering react node tree * More refactoring * Show option category in label when searching * Nice logic for categories rendering when searching or when only child * Make getSuggestions more lazy for DataLinksEditor * Add missing repeat options and handle conditional options * Prepping options category to be more flexibly and control state from outside * Added option count to search result * Minor style tweak * Added button to close viz picker * Rewrote overrides to enable searching overrides * New search engine and tests * Searching overrides works * Hide radio buttons while searching * Added angular options back * Added memoize for all options so they are not rebuilt for every search key stroke * Added back support for category counters * Started unit test work * Refactoring and base popular options list * Initial update to e2e test, more coming to add e2e test for search features * Minor fix * Review updates * Fixing category open states * Unit test progress * Do not show visualization list mode radio button if library panels is not enabled * Use boolean * More unit tests * Increase library panels per page count and give search focus when switching list mode * field config change test and search test * Feedback updates * Minor tweaks * Minor refactorings * More minimal override collapse state
4 years ago
sort = 13
case "news":
sort = 14
}
return sort
}
func (hs *HTTPServer) GetFrontendSettings(c *models.ReqContext) {
settings, err := hs.getFrontendSettingsMap(c)
if err != nil {
c.JsonApiErr(400, "Failed to get frontend settings", err)
return
}
c.JSON(200, settings)
}