| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | package api | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2021-11-02 20:42:55 +08:00
										 |  |  | 	"context" | 
					
						
							| 
									
										
										
										
											2024-01-04 15:00:07 +08:00
										 |  |  | 	"crypto/sha256" | 
					
						
							| 
									
										
										
										
											2023-01-27 22:08:17 +08:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2024-01-04 15:00:07 +08:00
										 |  |  | 	"hash" | 
					
						
							| 
									
										
										
										
											2022-04-15 20:01:58 +08:00
										 |  |  | 	"net/http" | 
					
						
							| 
									
										
										
										
											2023-11-02 00:17:38 +08:00
										 |  |  | 	"slices" | 
					
						
							| 
									
										
										
										
											2024-01-04 15:00:07 +08:00
										 |  |  | 	"sort" | 
					
						
							| 
									
										
										
										
											2023-04-28 00:20:37 +08:00
										 |  |  | 	"strings" | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-01 03:14:15 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/api/dtos" | 
					
						
							| 
									
										
										
										
											2024-01-04 15:00:07 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/api/webassets" | 
					
						
							| 
									
										
										
										
											2023-12-15 17:58:08 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/login/social" | 
					
						
							| 
									
										
										
										
											2015-02-28 05:29:00 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/plugins" | 
					
						
							| 
									
										
										
										
											2021-10-05 21:54:26 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/accesscontrol" | 
					
						
							| 
									
										
										
										
											2025-01-10 00:44:16 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/authn" | 
					
						
							| 
									
										
										
										
											2023-01-27 15:50:36 +08:00
										 |  |  | 	contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model" | 
					
						
							| 
									
										
										
										
											2022-06-28 00:23:15 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/datasources" | 
					
						
							| 
									
										
										
										
											2023-05-22 20:34:41 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/featuremgmt" | 
					
						
							| 
									
										
										
										
											2023-12-05 23:13:31 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/folder" | 
					
						
							| 
									
										
										
										
											2022-03-16 21:37:19 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/licensing" | 
					
						
							| 
									
										
										
										
											2023-03-08 00:22:30 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsettings" | 
					
						
							| 
									
										
										
										
											2023-09-11 19:59:24 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore" | 
					
						
							| 
									
										
										
										
											2015-02-05 17:37:13 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/setting" | 
					
						
							| 
									
										
										
										
											2021-10-05 21:54:26 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/tsdb/grafanads" | 
					
						
							|  |  |  | 	"github.com/grafana/grafana/pkg/util" | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-25 17:50:03 +08:00
										 |  |  | // GetBootdataAPI returns the same data we currently have rendered into index.html
 | 
					
						
							|  |  |  | // NOTE: this should not be added to the public API docs, and is useful for a transition
 | 
					
						
							|  |  |  | // towards a fully static index.html -- this will likely be replaced with multiple calls
 | 
					
						
							|  |  |  | func (hs *HTTPServer) GetBootdata(c *contextmodel.ReqContext) { | 
					
						
							|  |  |  | 	data, err := hs.setIndexViewData(c) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		c.Handle(hs.Cfg, http.StatusInternalServerError, "Failed to get settings", err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	c.JSON(http.StatusOK, data) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-04 15:00:07 +08:00
										 |  |  | // Returns a file that is easy to check for changes
 | 
					
						
							|  |  |  | // Any changes to the file means we should refresh the frontend
 | 
					
						
							|  |  |  | func (hs *HTTPServer) GetFrontendAssets(c *contextmodel.ReqContext) { | 
					
						
							| 
									
										
										
										
											2024-08-06 09:17:39 +08:00
										 |  |  | 	c, span := hs.injectSpan(c, "api.GetFrontendAssets") | 
					
						
							|  |  |  | 	defer span.End() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-04 15:00:07 +08:00
										 |  |  | 	hash := sha256.New() | 
					
						
							|  |  |  | 	keys := map[string]any{} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// BuildVersion
 | 
					
						
							|  |  |  | 	hash.Reset() | 
					
						
							|  |  |  | 	_, _ = hash.Write([]byte(setting.BuildVersion)) | 
					
						
							|  |  |  | 	_, _ = hash.Write([]byte(setting.BuildCommit)) | 
					
						
							|  |  |  | 	keys["version"] = fmt.Sprintf("%x", hash.Sum(nil)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Plugin configs
 | 
					
						
							|  |  |  | 	plugins := []string{} | 
					
						
							|  |  |  | 	for _, p := range hs.pluginStore.Plugins(c.Req.Context()) { | 
					
						
							|  |  |  | 		plugins = append(plugins, fmt.Sprintf("%s@%s", p.Name, p.Info.Version)) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	keys["plugins"] = sortedHash(plugins, hash) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Feature flags
 | 
					
						
							|  |  |  | 	enabled := []string{} | 
					
						
							|  |  |  | 	for flag, set := range hs.Features.GetEnabled(c.Req.Context()) { | 
					
						
							|  |  |  | 		if set { | 
					
						
							|  |  |  | 			enabled = append(enabled, flag) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	keys["flags"] = sortedHash(enabled, hash) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Assets
 | 
					
						
							|  |  |  | 	hash.Reset() | 
					
						
							| 
									
										
										
										
											2025-04-26 05:07:43 +08:00
										 |  |  | 	dto, err := webassets.GetWebAssets(c.Req.Context(), hs.Cfg, hs.License) | 
					
						
							| 
									
										
										
										
											2024-01-04 15:00:07 +08:00
										 |  |  | 	if err == nil && dto != nil { | 
					
						
							|  |  |  | 		_, _ = hash.Write([]byte(dto.ContentDeliveryURL)) | 
					
						
							|  |  |  | 		_, _ = hash.Write([]byte(dto.Dark)) | 
					
						
							|  |  |  | 		_, _ = hash.Write([]byte(dto.Light)) | 
					
						
							|  |  |  | 		for _, f := range dto.JSFiles { | 
					
						
							|  |  |  | 			_, _ = hash.Write([]byte(f.FilePath)) | 
					
						
							|  |  |  | 			_, _ = hash.Write([]byte(f.Integrity)) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	keys["assets"] = fmt.Sprintf("%x", hash.Sum(nil)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	c.JSON(http.StatusOK, keys) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func sortedHash(vals []string, hash hash.Hash) string { | 
					
						
							|  |  |  | 	hash.Reset() | 
					
						
							|  |  |  | 	sort.Strings(vals) | 
					
						
							|  |  |  | 	for _, v := range vals { | 
					
						
							|  |  |  | 		_, _ = hash.Write([]byte(v)) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return fmt.Sprintf("%x", hash.Sum(nil)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-27 15:50:36 +08:00
										 |  |  | func (hs *HTTPServer) GetFrontendSettings(c *contextmodel.ReqContext) { | 
					
						
							| 
									
										
										
										
											2023-02-01 03:14:15 +08:00
										 |  |  | 	settings, err := hs.getFrontendSettings(c) | 
					
						
							| 
									
										
										
										
											2022-03-19 03:49:13 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		c.JsonApiErr(400, "Failed to get frontend settings", err) | 
					
						
							|  |  |  | 		return | 
					
						
							| 
									
										
										
										
											2015-08-17 02:52:30 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-02-28 16:46:37 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-15 20:01:58 +08:00
										 |  |  | 	c.JSON(http.StatusOK, settings) | 
					
						
							| 
									
										
										
										
											2020-09-08 04:10:06 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-01 03:14:15 +08:00
										 |  |  | // getFrontendSettings returns a json object with all the settings needed for front end initialisation.
 | 
					
						
							| 
									
										
										
										
											2024-03-11 20:29:44 +08:00
										 |  |  | //
 | 
					
						
							|  |  |  | //nolint:gocyclo
 | 
					
						
							| 
									
										
										
										
											2023-02-01 03:14:15 +08:00
										 |  |  | func (hs *HTTPServer) getFrontendSettings(c *contextmodel.ReqContext) (*dtos.FrontendSettingsDTO, error) { | 
					
						
							| 
									
										
										
										
											2024-08-06 09:17:39 +08:00
										 |  |  | 	c, span := hs.injectSpan(c, "api.getFrontendSettings") | 
					
						
							|  |  |  | 	defer span.End() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-10 20:42:23 +08:00
										 |  |  | 	availablePlugins, err := hs.availablePlugins(c.Req.Context(), c.GetOrgID()) | 
					
						
							| 
									
										
										
										
											2020-09-08 04:10:06 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-02-25 17:00:21 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-08 00:20:05 +08:00
										 |  |  | 	apps := make(map[string]*plugins.AppDTO, 0) | 
					
						
							| 
									
										
										
										
											2023-06-08 18:21:19 +08:00
										 |  |  | 	for _, ap := range availablePlugins[plugins.TypeApp] { | 
					
						
							| 
									
										
										
										
											2024-09-09 17:38:35 +08:00
										 |  |  | 		apps[ap.Plugin.ID] = hs.newAppDTO( | 
					
						
							|  |  |  | 			c.Req.Context(), | 
					
						
							| 
									
										
										
										
											2023-02-08 00:20:05 +08:00
										 |  |  | 			ap.Plugin, | 
					
						
							|  |  |  | 			ap.Settings, | 
					
						
							|  |  |  | 		) | 
					
						
							| 
									
										
										
										
											2020-09-08 04:10:06 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-08 00:20:05 +08:00
										 |  |  | 	dataSources, err := hs.getFSDataSources(c, availablePlugins) | 
					
						
							| 
									
										
										
										
											2020-09-08 04:10:06 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	defaultDS := "-- Grafana --" | 
					
						
							|  |  |  | 	for n, ds := range dataSources { | 
					
						
							| 
									
										
										
										
											2021-12-14 18:16:13 +08:00
										 |  |  | 		if ds.IsDefault { | 
					
						
							| 
									
										
										
										
											2020-09-08 04:10:06 +08:00
										 |  |  | 			defaultDS = n | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-14 18:16:13 +08:00
										 |  |  | 	panels := make(map[string]plugins.PanelDTO) | 
					
						
							| 
									
										
										
										
											2023-06-08 18:21:19 +08:00
										 |  |  | 	for _, ap := range availablePlugins[plugins.TypePanel] { | 
					
						
							| 
									
										
										
										
											2023-02-08 00:20:05 +08:00
										 |  |  | 		panel := ap.Plugin | 
					
						
							| 
									
										
										
										
											2023-06-08 18:21:19 +08:00
										 |  |  | 		if panel.State == plugins.ReleaseStateAlpha && !hs.Cfg.PluginsEnableAlpha { | 
					
						
							| 
									
										
										
										
											2018-10-09 23:47:43 +08:00
										 |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-15 04:50:27 +08:00
										 |  |  | 		if panel.ID == "datagrid" && !hs.Features.IsEnabled(c.Req.Context(), featuremgmt.FlagEnableDatagridEditing) { | 
					
						
							| 
									
										
										
										
											2023-05-22 20:34:41 +08:00
										 |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-14 18:16:13 +08:00
										 |  |  | 		panels[panel.ID] = plugins.PanelDTO{ | 
					
						
							| 
									
										
										
										
											2024-09-09 17:38:35 +08:00
										 |  |  | 			ID:              panel.ID, | 
					
						
							|  |  |  | 			Name:            panel.Name, | 
					
						
							|  |  |  | 			AliasIDs:        panel.AliasIDs, | 
					
						
							|  |  |  | 			Info:            panel.Info, | 
					
						
							|  |  |  | 			Module:          panel.Module, | 
					
						
							| 
									
										
										
										
											2024-10-04 20:55:09 +08:00
										 |  |  | 			ModuleHash:      hs.pluginAssets.ModuleHash(c.Req.Context(), panel), | 
					
						
							| 
									
										
										
										
											2024-09-09 17:38:35 +08:00
										 |  |  | 			BaseURL:         panel.BaseURL, | 
					
						
							|  |  |  | 			SkipDataQuery:   panel.SkipDataQuery, | 
					
						
							|  |  |  | 			HideFromList:    panel.HideFromList, | 
					
						
							|  |  |  | 			ReleaseState:    string(panel.State), | 
					
						
							|  |  |  | 			Signature:       string(panel.Signature), | 
					
						
							|  |  |  | 			Sort:            getPanelSort(panel.ID), | 
					
						
							|  |  |  | 			Angular:         panel.Angular, | 
					
						
							|  |  |  | 			LoadingStrategy: hs.pluginAssets.LoadingStrategy(c.Req.Context(), panel), | 
					
						
							| 
									
										
										
										
											2025-03-31 12:38:38 +08:00
										 |  |  | 			Translations:    panel.Translations, | 
					
						
							| 
									
										
										
										
											2015-11-21 20:46:18 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-13 17:46:27 +08:00
										 |  |  | 	hideVersion := hs.Cfg.Anonymous.HideVersion && !c.IsSignedIn | 
					
						
							| 
									
										
										
										
											2020-06-17 13:39:50 +08:00
										 |  |  | 	version := setting.BuildVersion | 
					
						
							|  |  |  | 	commit := setting.BuildCommit | 
					
						
							| 
									
										
										
										
											2024-03-16 00:39:13 +08:00
										 |  |  | 	commitShort := getShortCommitHash(setting.BuildCommit, 10) | 
					
						
							| 
									
										
										
										
											2020-06-17 13:39:50 +08:00
										 |  |  | 	buildstamp := setting.BuildStamp | 
					
						
							| 
									
										
										
										
											2024-03-16 00:39:13 +08:00
										 |  |  | 	versionString := fmt.Sprintf(`%s v%s (%s)`, setting.ApplicationName, version, commitShort) | 
					
						
							| 
									
										
										
										
											2020-06-17 13:39:50 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if hideVersion { | 
					
						
							|  |  |  | 		version = "" | 
					
						
							| 
									
										
										
										
											2024-03-16 00:39:13 +08:00
										 |  |  | 		versionString = setting.ApplicationName | 
					
						
							| 
									
										
										
										
											2020-06-17 13:39:50 +08:00
										 |  |  | 		commit = "" | 
					
						
							| 
									
										
										
										
											2024-03-16 00:39:13 +08:00
										 |  |  | 		commitShort = "" | 
					
						
							| 
									
										
										
										
											2020-06-17 13:39:50 +08:00
										 |  |  | 		buildstamp = 0 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-05 21:54:26 +08:00
										 |  |  | 	hasAccess := accesscontrol.HasAccess(hs.AccessControl, c) | 
					
						
							| 
									
										
										
										
											2023-04-28 00:20:37 +08:00
										 |  |  | 	trustedTypesDefaultPolicyEnabled := (hs.Cfg.CSPEnabled && strings.Contains(hs.Cfg.CSPTemplate, "require-trusted-types-for")) || (hs.Cfg.CSPReportOnlyEnabled && strings.Contains(hs.Cfg.CSPReportOnlyTemplate, "require-trusted-types-for")) | 
					
						
							| 
									
										
										
										
											2024-03-25 23:43:28 +08:00
										 |  |  | 	isCloudMigrationTarget := hs.Features.IsEnabled(c.Req.Context(), featuremgmt.FlagOnPremToCloudMigrations) && hs.Cfg.CloudMigration.IsTarget | 
					
						
							| 
									
										
										
										
											2024-10-17 17:18:30 +08:00
										 |  |  | 	featureToggles := hs.Features.GetEnabled(c.Req.Context()) | 
					
						
							|  |  |  | 	// this is needed for backwards compatibility with external plugins
 | 
					
						
							|  |  |  | 	// we should remove this once we can be sure that no external plugins rely on this
 | 
					
						
							|  |  |  | 	featureToggles["topnav"] = true | 
					
						
							| 
									
										
										
										
											2021-10-05 21:54:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-01 03:14:15 +08:00
										 |  |  | 	frontendSettings := &dtos.FrontendSettingsDTO{ | 
					
						
							|  |  |  | 		DefaultDatasource:                   defaultDS, | 
					
						
							|  |  |  | 		Datasources:                         dataSources, | 
					
						
							| 
									
										
										
										
											2024-01-23 19:36:22 +08:00
										 |  |  | 		MinRefreshInterval:                  hs.Cfg.MinRefreshInterval, | 
					
						
							| 
									
										
										
										
											2023-02-01 03:14:15 +08:00
										 |  |  | 		Panels:                              panels, | 
					
						
							| 
									
										
										
										
											2023-02-08 00:20:05 +08:00
										 |  |  | 		Apps:                                apps, | 
					
						
							| 
									
										
										
										
											2023-02-01 03:14:15 +08:00
										 |  |  | 		AppUrl:                              hs.Cfg.AppURL, | 
					
						
							|  |  |  | 		AppSubUrl:                           hs.Cfg.AppSubURL, | 
					
						
							| 
									
										
										
										
											2024-01-23 19:36:22 +08:00
										 |  |  | 		AllowOrgCreate:                      (hs.Cfg.AllowUserOrgCreate && c.IsSignedIn) || c.IsGrafanaAdmin, | 
					
						
							| 
									
										
										
										
											2024-03-01 18:31:06 +08:00
										 |  |  | 		AuthProxyEnabled:                    hs.Cfg.AuthProxy.Enabled, | 
					
						
							| 
									
										
										
										
											2023-03-23 01:41:59 +08:00
										 |  |  | 		LdapEnabled:                         hs.Cfg.LDAPAuthEnabled, | 
					
						
							| 
									
										
										
										
											2024-02-09 23:35:58 +08:00
										 |  |  | 		JwtHeaderName:                       hs.Cfg.JWTAuth.HeaderName, | 
					
						
							|  |  |  | 		JwtUrlLogin:                         hs.Cfg.JWTAuth.URLLogin, | 
					
						
							| 
									
										
										
										
											2023-02-01 03:14:15 +08:00
										 |  |  | 		LiveEnabled:                         hs.Cfg.LiveMaxConnections != 0, | 
					
						
							| 
									
										
										
										
											2025-03-21 00:26:09 +08:00
										 |  |  | 		LiveMessageSizeLimit:                hs.Cfg.LiveMessageSizeLimit, | 
					
						
							| 
									
										
										
										
											2023-02-27 17:23:38 +08:00
										 |  |  | 		AutoAssignOrg:                       hs.Cfg.AutoAssignOrg, | 
					
						
							| 
									
										
										
										
											2024-01-23 19:36:22 +08:00
										 |  |  | 		VerifyEmailEnabled:                  hs.Cfg.VerifyEmailEnabled, | 
					
						
							|  |  |  | 		SigV4AuthEnabled:                    hs.Cfg.SigV4AuthEnabled, | 
					
						
							|  |  |  | 		AzureAuthEnabled:                    hs.Cfg.AzureAuthEnabled, | 
					
						
							| 
									
										
										
										
											2023-09-05 18:04:39 +08:00
										 |  |  | 		RbacEnabled:                         true, | 
					
						
							| 
									
										
										
										
											2024-01-23 19:36:22 +08:00
										 |  |  | 		ExploreEnabled:                      hs.Cfg.ExploreEnabled, | 
					
						
							|  |  |  | 		HelpEnabled:                         hs.Cfg.HelpEnabled, | 
					
						
							|  |  |  | 		ProfileEnabled:                      hs.Cfg.ProfileEnabled, | 
					
						
							|  |  |  | 		NewsFeedEnabled:                     hs.Cfg.NewsFeedEnabled, | 
					
						
							| 
									
										
										
										
											2023-02-01 03:14:15 +08:00
										 |  |  | 		QueryHistoryEnabled:                 hs.Cfg.QueryHistoryEnabled, | 
					
						
							| 
									
										
										
										
											2023-02-21 18:19:07 +08:00
										 |  |  | 		GoogleAnalyticsId:                   hs.Cfg.GoogleAnalyticsID, | 
					
						
							|  |  |  | 		GoogleAnalytics4Id:                  hs.Cfg.GoogleAnalytics4ID, | 
					
						
							|  |  |  | 		GoogleAnalytics4SendManualPageViews: hs.Cfg.GoogleAnalytics4SendManualPageViews, | 
					
						
							|  |  |  | 		RudderstackWriteKey:                 hs.Cfg.RudderstackWriteKey, | 
					
						
							|  |  |  | 		RudderstackDataPlaneUrl:             hs.Cfg.RudderstackDataPlaneURL, | 
					
						
							|  |  |  | 		RudderstackSdkUrl:                   hs.Cfg.RudderstackSDKURL, | 
					
						
							|  |  |  | 		RudderstackConfigUrl:                hs.Cfg.RudderstackConfigURL, | 
					
						
							| 
									
										
										
										
											2023-10-23 20:43:33 +08:00
										 |  |  | 		RudderstackIntegrationsUrl:          hs.Cfg.RudderstackIntegrationsURL, | 
					
						
							| 
									
										
										
										
											2024-10-30 02:20:54 +08:00
										 |  |  | 		AnalyticsConsoleReporting:           hs.Cfg.FrontendAnalyticsConsoleReporting, | 
					
						
							| 
									
										
										
										
											2025-01-29 01:36:10 +08:00
										 |  |  | 		DashboardPerformanceMetrics:         hs.Cfg.DashboardPerformanceMetrics, | 
					
						
							| 
									
										
										
										
											2025-04-11 19:56:58 +08:00
										 |  |  | 		PanelSeriesLimit:                    hs.Cfg.PanelSeriesLimit, | 
					
						
							| 
									
										
										
										
											2023-02-01 03:14:15 +08:00
										 |  |  | 		FeedbackLinksEnabled:                hs.Cfg.FeedbackLinksEnabled, | 
					
						
							|  |  |  | 		ApplicationInsightsConnectionString: hs.Cfg.ApplicationInsightsConnectionString, | 
					
						
							|  |  |  | 		ApplicationInsightsEndpointUrl:      hs.Cfg.ApplicationInsightsEndpointUrl, | 
					
						
							| 
									
										
										
										
											2023-02-27 22:28:49 +08:00
										 |  |  | 		DisableLoginForm:                    hs.Cfg.DisableLoginForm, | 
					
						
							| 
									
										
										
										
											2024-01-23 19:36:22 +08:00
										 |  |  | 		DisableUserSignUp:                   !hs.Cfg.AllowUserSignUp, | 
					
						
							|  |  |  | 		LoginHint:                           hs.Cfg.LoginHint, | 
					
						
							|  |  |  | 		PasswordHint:                        hs.Cfg.PasswordHint, | 
					
						
							|  |  |  | 		ExternalUserMngInfo:                 hs.Cfg.ExternalUserMngInfo, | 
					
						
							|  |  |  | 		ExternalUserMngLinkUrl:              hs.Cfg.ExternalUserMngLinkUrl, | 
					
						
							|  |  |  | 		ExternalUserMngLinkName:             hs.Cfg.ExternalUserMngLinkName, | 
					
						
							| 
									
										
										
										
											2025-01-21 22:47:57 +08:00
										 |  |  | 		ExternalUserMngAnalytics:            hs.Cfg.ExternalUserMngAnalytics, | 
					
						
							|  |  |  | 		ExternalUserMngAnalyticsParams:      hs.Cfg.ExternalUserMngAnalyticsParams, | 
					
						
							| 
									
										
										
										
											2025-03-13 00:25:23 +08:00
										 |  |  | 		//nolint:staticcheck // ViewersCanEdit is deprecated but still used for backward compatibility
 | 
					
						
							|  |  |  | 		ViewersCanEdit:                   hs.Cfg.ViewersCanEdit, | 
					
						
							|  |  |  | 		DisableSanitizeHtml:              hs.Cfg.DisableSanitizeHtml, | 
					
						
							|  |  |  | 		TrustedTypesDefaultPolicyEnabled: trustedTypesDefaultPolicyEnabled, | 
					
						
							|  |  |  | 		CSPReportOnlyEnabled:             hs.Cfg.CSPReportOnlyEnabled, | 
					
						
							|  |  |  | 		DateFormats:                      hs.Cfg.DateFormats, | 
					
						
							|  |  |  | 		SecureSocksDSProxyEnabled:        hs.Cfg.SecureSocksDSProxy.Enabled && hs.Cfg.SecureSocksDSProxy.ShowUI, | 
					
						
							|  |  |  | 		EnableFrontendSandboxForPlugins:  hs.Cfg.EnableFrontendSandboxForPlugins, | 
					
						
							|  |  |  | 		PublicDashboardAccessToken:       c.PublicDashboardAccessToken, | 
					
						
							|  |  |  | 		PublicDashboardsEnabled:          hs.Cfg.PublicDashboardsEnabled, | 
					
						
							|  |  |  | 		CloudMigrationIsTarget:           isCloudMigrationTarget, | 
					
						
							|  |  |  | 		CloudMigrationPollIntervalMs:     int(hs.Cfg.CloudMigration.FrontendPollInterval.Milliseconds()), | 
					
						
							|  |  |  | 		SharedWithMeFolderUID:            folder.SharedWithMeFolderUID, | 
					
						
							|  |  |  | 		RootFolderUID:                    accesscontrol.GeneralFolderUID, | 
					
						
							|  |  |  | 		LocalFileSystemAvailable:         hs.Cfg.LocalFileSystemAvailable, | 
					
						
							|  |  |  | 		ReportingStaticContext:           hs.Cfg.ReportingStaticContext, | 
					
						
							|  |  |  | 		ExploreDefaultTimeOffset:         hs.Cfg.ExploreDefaultTimeOffset, | 
					
						
							|  |  |  | 		ExploreHideLogsDownload:          hs.Cfg.ExploreHideLogsDownload, | 
					
						
							| 
									
										
										
										
											2023-02-01 03:14:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-10 22:20:09 +08:00
										 |  |  | 		DefaultDatasourceManageAlertsUIToggle: hs.Cfg.DefaultDatasourceManageAlertsUIToggle, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-01 03:14:15 +08:00
										 |  |  | 		BuildInfo: dtos.FrontendSettingsBuildInfoDTO{ | 
					
						
							|  |  |  | 			HideVersion:   hideVersion, | 
					
						
							|  |  |  | 			Version:       version, | 
					
						
							| 
									
										
										
										
											2024-03-16 00:39:13 +08:00
										 |  |  | 			VersionString: versionString, | 
					
						
							| 
									
										
										
										
											2023-02-01 03:14:15 +08:00
										 |  |  | 			Commit:        commit, | 
					
						
							| 
									
										
										
										
											2024-03-16 00:39:13 +08:00
										 |  |  | 			CommitShort:   commitShort, | 
					
						
							| 
									
										
										
										
											2023-02-01 03:14:15 +08:00
										 |  |  | 			Buildstamp:    buildstamp, | 
					
						
							|  |  |  | 			Edition:       hs.License.Edition(), | 
					
						
							|  |  |  | 			LatestVersion: hs.grafanaUpdateChecker.LatestVersion(), | 
					
						
							|  |  |  | 			HasUpdate:     hs.grafanaUpdateChecker.UpdateAvailable(), | 
					
						
							| 
									
										
										
										
											2024-01-23 19:36:22 +08:00
										 |  |  | 			Env:           hs.Cfg.Env, | 
					
						
							| 
									
										
										
										
											2019-11-01 21:56:12 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2023-02-01 03:14:15 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		LicenseInfo: dtos.FrontendSettingsLicenseInfoDTO{ | 
					
						
							|  |  |  | 			Expiry:          hs.License.Expiry(), | 
					
						
							|  |  |  | 			StateInfo:       hs.License.StateInfo(), | 
					
						
							| 
									
										
										
										
											2023-05-30 21:39:09 +08:00
										 |  |  | 			LicenseUrl:      hs.License.LicenseURL(hasAccess(licensing.PageAccess)), | 
					
						
							| 
									
										
										
										
											2023-02-01 03:14:15 +08:00
										 |  |  | 			Edition:         hs.License.Edition(), | 
					
						
							|  |  |  | 			EnabledFeatures: hs.License.EnabledFeatures(), | 
					
						
							| 
									
										
										
										
											2015-01-05 17:46:58 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2023-02-01 03:14:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-17 17:18:30 +08:00
										 |  |  | 		FeatureToggles:                   featureToggles, | 
					
						
							| 
									
										
										
										
											2024-12-13 17:46:27 +08:00
										 |  |  | 		AnonymousEnabled:                 hs.Cfg.Anonymous.Enabled, | 
					
						
							|  |  |  | 		AnonymousDeviceLimit:             hs.Cfg.Anonymous.DeviceLimit, | 
					
						
							| 
									
										
										
										
											2023-02-01 03:14:15 +08:00
										 |  |  | 		RendererAvailable:                hs.RenderService.IsAvailable(c.Req.Context()), | 
					
						
							|  |  |  | 		RendererVersion:                  hs.RenderService.Version(), | 
					
						
							| 
									
										
										
										
											2024-02-26 20:27:34 +08:00
										 |  |  | 		RendererDefaultImageWidth:        hs.Cfg.RendererDefaultImageWidth, | 
					
						
							|  |  |  | 		RendererDefaultImageHeight:       hs.Cfg.RendererDefaultImageHeight, | 
					
						
							|  |  |  | 		RendererDefaultImageScale:        hs.Cfg.RendererDefaultImageScale, | 
					
						
							| 
									
										
										
										
											2023-02-01 03:14:15 +08:00
										 |  |  | 		Http2Enabled:                     hs.Cfg.Protocol == setting.HTTP2Scheme, | 
					
						
							|  |  |  | 		GrafanaJavascriptAgent:           hs.Cfg.GrafanaJavascriptAgent, | 
					
						
							|  |  |  | 		PluginCatalogURL:                 hs.Cfg.PluginCatalogURL, | 
					
						
							|  |  |  | 		PluginAdminEnabled:               hs.Cfg.PluginAdminEnabled, | 
					
						
							|  |  |  | 		PluginAdminExternalManageEnabled: hs.Cfg.PluginAdminEnabled && hs.Cfg.PluginAdminExternalManageEnabled, | 
					
						
							|  |  |  | 		PluginCatalogHiddenPlugins:       hs.Cfg.PluginCatalogHiddenPlugins, | 
					
						
							| 
									
										
										
										
											2024-07-29 18:18:43 +08:00
										 |  |  | 		PluginCatalogManagedPlugins:      hs.managedPluginsService.ManagedPlugins(c.Req.Context()), | 
					
						
							| 
									
										
										
										
											2024-08-21 22:11:55 +08:00
										 |  |  | 		PluginCatalogPreinstalledPlugins: hs.Cfg.PreinstallPlugins, | 
					
						
							| 
									
										
										
										
											2023-02-01 03:14:15 +08:00
										 |  |  | 		ExpressionsEnabled:               hs.Cfg.ExpressionsEnabled, | 
					
						
							|  |  |  | 		AwsAllowedAuthProviders:          hs.Cfg.AWSAllowedAuthProviders, | 
					
						
							|  |  |  | 		AwsAssumeRoleEnabled:             hs.Cfg.AWSAssumeRoleEnabled, | 
					
						
							|  |  |  | 		SupportBundlesEnabled:            isSupportBundlesEnabled(hs), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Azure: dtos.FrontendSettingsAzureDTO{ | 
					
						
							| 
									
										
										
										
											2024-03-20 00:32:24 +08:00
										 |  |  | 			Cloud:                                  hs.Cfg.Azure.Cloud, | 
					
						
							| 
									
										
										
										
											2024-05-04 18:17:51 +08:00
										 |  |  | 			Clouds:                                 hs.Cfg.Azure.CustomClouds(), | 
					
						
							| 
									
										
										
										
											2024-03-20 00:32:24 +08:00
										 |  |  | 			ManagedIdentityEnabled:                 hs.Cfg.Azure.ManagedIdentityEnabled, | 
					
						
							|  |  |  | 			WorkloadIdentityEnabled:                hs.Cfg.Azure.WorkloadIdentityEnabled, | 
					
						
							|  |  |  | 			UserIdentityEnabled:                    hs.Cfg.Azure.UserIdentityEnabled, | 
					
						
							|  |  |  | 			UserIdentityFallbackCredentialsEnabled: hs.Cfg.Azure.UserIdentityFallbackCredentialsEnabled, | 
					
						
							| 
									
										
										
										
											2024-07-17 03:08:51 +08:00
										 |  |  | 			AzureEntraPasswordCredentialsEnabled:   hs.Cfg.Azure.AzureEntraPasswordCredentialsEnabled, | 
					
						
							| 
									
										
										
										
											2021-05-12 22:23:37 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2023-02-01 03:14:15 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		Caching: dtos.FrontendSettingsCachingDTO{ | 
					
						
							|  |  |  | 			Enabled: hs.Cfg.SectionWithEnvOverrides("caching").Key("enabled").MustBool(true), | 
					
						
							| 
									
										
										
										
											2021-05-27 01:27:28 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2023-02-01 03:14:15 +08:00
										 |  |  | 		RecordedQueries: dtos.FrontendSettingsRecordedQueriesDTO{ | 
					
						
							|  |  |  | 			Enabled: hs.Cfg.SectionWithEnvOverrides("recorded_queries").Key("enabled").MustBool(true), | 
					
						
							| 
									
										
										
										
											2021-11-18 05:45:05 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2023-02-01 03:14:15 +08:00
										 |  |  | 		Reporting: dtos.FrontendSettingsReportingDTO{ | 
					
						
							|  |  |  | 			Enabled: hs.Cfg.SectionWithEnvOverrides("reporting").Key("enabled").MustBool(true), | 
					
						
							| 
									
										
										
										
											2022-03-23 04:30:45 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2023-11-09 18:53:20 +08:00
										 |  |  | 		Analytics: dtos.FrontendSettingsAnalyticsDTO{ | 
					
						
							|  |  |  | 			Enabled: hs.Cfg.SectionWithEnvOverrides("analytics").Key("enabled").MustBool(true), | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2023-02-01 03:14:15 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		UnifiedAlerting: dtos.FrontendSettingsUnifiedAlertingDTO{ | 
					
						
							|  |  |  | 			MinInterval: hs.Cfg.UnifiedAlerting.MinInterval.String(), | 
					
						
							| 
									
										
										
										
											2022-08-01 21:01:14 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2023-02-01 03:14:15 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		Oauth:                   hs.getEnabledOAuthProviders(), | 
					
						
							|  |  |  | 		SamlEnabled:             hs.samlEnabled(), | 
					
						
							|  |  |  | 		SamlName:                hs.samlName(), | 
					
						
							|  |  |  | 		TokenExpirationDayLimit: hs.Cfg.SATokenExpirationDayLimit, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		SnapshotEnabled: hs.Cfg.SnapshotEnabled, | 
					
						
							| 
									
										
										
										
											2023-04-28 14:23:08 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		SqlConnectionLimits: dtos.FrontendSettingsSqlConnectionLimitsDTO{ | 
					
						
							|  |  |  | 			MaxOpenConns:    hs.Cfg.SqlDatasourceMaxOpenConnsDefault, | 
					
						
							|  |  |  | 			MaxIdleConns:    hs.Cfg.SqlDatasourceMaxIdleConnsDefault, | 
					
						
							|  |  |  | 			ConnMaxLifetime: hs.Cfg.SqlDatasourceMaxConnLifetimeDefault, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2023-02-01 03:14:15 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-24 15:28:11 +08:00
										 |  |  | 	if hs.Cfg.UnifiedAlerting.StateHistory.Enabled { | 
					
						
							|  |  |  | 		frontendSettings.UnifiedAlerting.AlertStateHistoryBackend = hs.Cfg.UnifiedAlerting.StateHistory.Backend | 
					
						
							| 
									
										
										
										
											2023-05-25 21:09:44 +08:00
										 |  |  | 		frontendSettings.UnifiedAlerting.AlertStateHistoryPrimary = hs.Cfg.UnifiedAlerting.StateHistory.MultiPrimary | 
					
						
							| 
									
										
										
										
											2023-04-24 15:28:11 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-26 16:59:45 +08:00
										 |  |  | 	frontendSettings.UnifiedAlerting.RecordingRulesEnabled = hs.Cfg.UnifiedAlerting.RecordingRules.Enabled | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-01 03:14:15 +08:00
										 |  |  | 	if hs.Cfg.UnifiedAlerting.Enabled != nil { | 
					
						
							|  |  |  | 		frontendSettings.UnifiedAlertingEnabled = *hs.Cfg.UnifiedAlerting.Enabled | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-15 17:58:08 +08:00
										 |  |  | 	// It returns false if the provider is not enabled or the skip org role sync is false.
 | 
					
						
							|  |  |  | 	parseSkipOrgRoleSyncEnabled := func(info *social.OAuthInfo) bool { | 
					
						
							|  |  |  | 		if info == nil { | 
					
						
							|  |  |  | 			return false | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return info.SkipOrgRoleSync | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	oauthProviders := hs.SocialService.GetOAuthInfoProviders() | 
					
						
							|  |  |  | 	frontendSettings.Auth = dtos.FrontendSettingsAuthDTO{ | 
					
						
							| 
									
										
										
										
											2024-03-07 15:56:48 +08:00
										 |  |  | 		AuthProxyEnableLoginToken:     hs.Cfg.AuthProxy.EnableLoginToken, | 
					
						
							|  |  |  | 		SAMLSkipOrgRoleSync:           hs.Cfg.SAMLSkipOrgRoleSync, | 
					
						
							|  |  |  | 		LDAPSkipOrgRoleSync:           hs.Cfg.LDAPSkipOrgRoleSync, | 
					
						
							|  |  |  | 		JWTAuthSkipOrgRoleSync:        hs.Cfg.JWTAuth.SkipOrgRoleSync, | 
					
						
							|  |  |  | 		GoogleSkipOrgRoleSync:         parseSkipOrgRoleSyncEnabled(oauthProviders[social.GoogleProviderName]), | 
					
						
							|  |  |  | 		GrafanaComSkipOrgRoleSync:     parseSkipOrgRoleSyncEnabled(oauthProviders[social.GrafanaComProviderName]), | 
					
						
							|  |  |  | 		GenericOAuthSkipOrgRoleSync:   parseSkipOrgRoleSyncEnabled(oauthProviders[social.GenericOAuthProviderName]), | 
					
						
							|  |  |  | 		AzureADSkipOrgRoleSync:        parseSkipOrgRoleSyncEnabled(oauthProviders[social.AzureADProviderName]), | 
					
						
							|  |  |  | 		GithubSkipOrgRoleSync:         parseSkipOrgRoleSyncEnabled(oauthProviders[social.GitHubProviderName]), | 
					
						
							|  |  |  | 		GitLabSkipOrgRoleSync:         parseSkipOrgRoleSyncEnabled(oauthProviders[social.GitlabProviderName]), | 
					
						
							|  |  |  | 		OktaSkipOrgRoleSync:           parseSkipOrgRoleSyncEnabled(oauthProviders[social.OktaProviderName]), | 
					
						
							|  |  |  | 		DisableLogin:                  hs.Cfg.DisableLogin, | 
					
						
							|  |  |  | 		BasicAuthStrongPasswordPolicy: hs.Cfg.BasicAuthStrongPasswordPolicy, | 
					
						
							| 
									
										
										
										
											2025-03-11 19:03:10 +08:00
										 |  |  | 		DisableSignoutMenu:            hs.Cfg.DisableSignoutMenu, | 
					
						
							| 
									
										
										
										
											2025-01-10 00:44:16 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if hs.Cfg.PasswordlessMagicLinkAuth.Enabled && hs.Features.IsEnabled(c.Req.Context(), featuremgmt.FlagPasswordlessMagicLinkAuthentication) { | 
					
						
							|  |  |  | 		hasEnabledProviders := hs.samlEnabled() || hs.authnService.IsClientEnabled(authn.ClientLDAP) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if !hasEnabledProviders { | 
					
						
							|  |  |  | 			oauthInfos := hs.SocialService.GetOAuthInfoProviders() | 
					
						
							|  |  |  | 			for _, provider := range oauthInfos { | 
					
						
							|  |  |  | 				if provider.Enabled { | 
					
						
							|  |  |  | 					hasEnabledProviders = true | 
					
						
							|  |  |  | 					break | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if !hasEnabledProviders { | 
					
						
							|  |  |  | 			frontendSettings.Auth.PasswordlessEnabled = true | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2023-12-15 17:58:08 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-27 22:08:17 +08:00
										 |  |  | 	if hs.pluginsCDNService != nil && hs.pluginsCDNService.IsEnabled() { | 
					
						
							|  |  |  | 		cdnBaseURL, err := hs.pluginsCDNService.BaseURL() | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return nil, fmt.Errorf("plugins cdn base url: %w", err) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2023-02-01 03:14:15 +08:00
										 |  |  | 		frontendSettings.PluginsCDNBaseURL = cdnBaseURL | 
					
						
							| 
									
										
										
										
											2023-01-27 22:08:17 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-22 04:48:20 +08:00
										 |  |  | 	if hs.Cfg.GeomapDefaultBaseLayerConfig != nil { | 
					
						
							| 
									
										
										
										
											2023-02-01 03:14:15 +08:00
										 |  |  | 		frontendSettings.GeomapDefaultBaseLayerConfig = &hs.Cfg.GeomapDefaultBaseLayerConfig | 
					
						
							| 
									
										
										
										
											2021-07-22 04:48:20 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-02-01 03:14:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-22 04:48:20 +08:00
										 |  |  | 	if !hs.Cfg.GeomapEnableCustomBaseLayers { | 
					
						
							| 
									
										
										
										
											2023-02-01 03:14:15 +08:00
										 |  |  | 		frontendSettings.GeomapDisableCustomBaseLayer = true | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-14 12:34:09 +08:00
										 |  |  | 	// Set the kubernetes namespace
 | 
					
						
							| 
									
										
										
										
											2025-04-10 20:42:23 +08:00
										 |  |  | 	frontendSettings.Namespace = hs.namespacer(c.OrgID) | 
					
						
							| 
									
										
										
										
											2023-11-14 12:34:09 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-05 23:41:19 +08:00
										 |  |  | 	// experimental scope features
 | 
					
						
							|  |  |  | 	if hs.Features.IsEnabled(c.Req.Context(), featuremgmt.FlagScopeFilters) { | 
					
						
							|  |  |  | 		frontendSettings.ListScopesEndpoint = hs.Cfg.ScopesListScopesURL | 
					
						
							|  |  |  | 		frontendSettings.ListDashboardScopesEndpoint = hs.Cfg.ScopesListDashboardsURL | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-01 03:14:15 +08:00
										 |  |  | 	return frontendSettings, nil | 
					
						
							| 
									
										
										
										
											2014-12-29 20:36:08 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2015-02-18 21:06:44 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-24 00:23:20 +08:00
										 |  |  | func isSupportBundlesEnabled(hs *HTTPServer) bool { | 
					
						
							| 
									
										
										
										
											2023-02-10 17:12:04 +08:00
										 |  |  | 	return hs.Cfg.SectionWithEnvOverrides("support_bundles").Key("enabled").MustBool(true) | 
					
						
							| 
									
										
										
										
											2023-01-24 00:23:20 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-16 00:39:13 +08:00
										 |  |  | func getShortCommitHash(commitHash string, maxLength int) string { | 
					
						
							|  |  |  | 	if len(commitHash) > maxLength { | 
					
						
							|  |  |  | 		return commitHash[:maxLength] | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return commitHash | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-08 00:20:05 +08:00
										 |  |  | func (hs *HTTPServer) getFSDataSources(c *contextmodel.ReqContext, availablePlugins AvailablePlugins) (map[string]plugins.DataSourceDTO, error) { | 
					
						
							| 
									
										
										
										
											2024-08-06 09:17:39 +08:00
										 |  |  | 	c, span := hs.injectSpan(c, "api.getFSDataSources") | 
					
						
							|  |  |  | 	defer span.End() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-28 00:23:15 +08:00
										 |  |  | 	orgDataSources := make([]*datasources.DataSource, 0) | 
					
						
							| 
									
										
										
										
											2025-04-10 20:42:23 +08:00
										 |  |  | 	if c.GetOrgID() != 0 { | 
					
						
							|  |  |  | 		query := datasources.GetDataSourcesQuery{OrgID: c.GetOrgID(), DataSourceLimit: hs.Cfg.DataSourceLimit} | 
					
						
							| 
									
										
										
										
											2023-02-09 22:49:44 +08:00
										 |  |  | 		dataSources, err := hs.DataSourcesService.GetDataSources(c.Req.Context(), &query) | 
					
						
							| 
									
										
										
										
											2022-03-19 03:49:13 +08:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return nil, err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-26 02:56:02 +08:00
										 |  |  | 		if c.IsPublicDashboardView() { | 
					
						
							| 
									
										
										
										
											2022-10-19 03:44:33 +08:00
										 |  |  | 			// If RBAC is enabled, it will filter out all datasources for a public user, so we need to skip it
 | 
					
						
							| 
									
										
										
										
											2023-02-09 22:49:44 +08:00
										 |  |  | 			orgDataSources = dataSources | 
					
						
							| 
									
										
										
										
											2022-10-19 03:44:33 +08:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2024-09-10 17:19:02 +08:00
										 |  |  | 			filtered, err := hs.dsGuardian.New(c.SignedInUser.OrgID, c.SignedInUser).FilterDatasourcesByReadPermissions(dataSources) | 
					
						
							| 
									
										
										
										
											2022-10-19 03:44:33 +08:00
										 |  |  | 			if err != nil { | 
					
						
							|  |  |  | 				return nil, err | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			orgDataSources = filtered | 
					
						
							| 
									
										
										
										
											2022-03-19 03:49:13 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	dataSources := make(map[string]plugins.DataSourceDTO) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for _, ds := range orgDataSources { | 
					
						
							| 
									
										
										
										
											2023-02-03 00:22:43 +08:00
										 |  |  | 		url := ds.URL | 
					
						
							| 
									
										
										
										
											2022-03-19 03:49:13 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-28 00:23:15 +08:00
										 |  |  | 		if ds.Access == datasources.DS_ACCESS_PROXY { | 
					
						
							| 
									
										
										
										
											2023-02-03 00:22:43 +08:00
										 |  |  | 			url = "/api/datasources/proxy/uid/" + ds.UID | 
					
						
							| 
									
										
										
										
											2022-03-19 03:49:13 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		dsDTO := plugins.DataSourceDTO{ | 
					
						
							| 
									
										
										
										
											2024-07-04 22:44:19 +08:00
										 |  |  | 			ID:         ds.ID, | 
					
						
							|  |  |  | 			UID:        ds.UID, | 
					
						
							|  |  |  | 			Type:       ds.Type, | 
					
						
							|  |  |  | 			Name:       ds.Name, | 
					
						
							|  |  |  | 			URL:        url, | 
					
						
							|  |  |  | 			IsDefault:  ds.IsDefault, | 
					
						
							|  |  |  | 			Access:     string(ds.Access), | 
					
						
							|  |  |  | 			ReadOnly:   ds.ReadOnly, | 
					
						
							|  |  |  | 			APIVersion: ds.APIVersion, | 
					
						
							| 
									
										
										
										
											2022-03-19 03:49:13 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-08 18:21:19 +08:00
										 |  |  | 		ap, exists := availablePlugins.Get(plugins.TypeDataSource, ds.Type) | 
					
						
							| 
									
										
										
										
											2022-03-19 03:49:13 +08:00
										 |  |  | 		if !exists { | 
					
						
							|  |  |  | 			c.Logger.Error("Could not find plugin definition for data source", "datasource_type", ds.Type) | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2023-02-08 00:20:05 +08:00
										 |  |  | 		plugin := ap.Plugin | 
					
						
							| 
									
										
										
										
											2023-06-03 01:46:12 +08:00
										 |  |  | 		dsDTO.Type = plugin.ID | 
					
						
							| 
									
										
										
										
											2022-03-19 03:49:13 +08:00
										 |  |  | 		dsDTO.Preload = plugin.Preload | 
					
						
							|  |  |  | 		dsDTO.Module = plugin.Module | 
					
						
							|  |  |  | 		dsDTO.PluginMeta = &plugins.PluginMetaDTO{ | 
					
						
							| 
									
										
										
										
											2024-08-30 18:03:44 +08:00
										 |  |  | 			JSONData:                  plugin.JSONData, | 
					
						
							|  |  |  | 			Signature:                 plugin.Signature, | 
					
						
							|  |  |  | 			Module:                    plugin.Module, | 
					
						
							| 
									
										
										
										
											2024-10-04 20:55:09 +08:00
										 |  |  | 			ModuleHash:                hs.pluginAssets.ModuleHash(c.Req.Context(), plugin), | 
					
						
							| 
									
										
										
										
											2024-08-30 18:03:44 +08:00
										 |  |  | 			BaseURL:                   plugin.BaseURL, | 
					
						
							|  |  |  | 			Angular:                   plugin.Angular, | 
					
						
							|  |  |  | 			MultiValueFilterOperators: plugin.MultiValueFilterOperators, | 
					
						
							| 
									
										
										
										
											2024-09-09 17:38:35 +08:00
										 |  |  | 			LoadingStrategy:           hs.pluginAssets.LoadingStrategy(c.Req.Context(), plugin), | 
					
						
							| 
									
										
										
										
											2025-03-31 12:38:38 +08:00
										 |  |  | 			Translations:              plugin.Translations, | 
					
						
							| 
									
										
										
										
											2022-03-19 03:49:13 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if ds.JsonData == nil { | 
					
						
							| 
									
										
										
										
											2023-08-30 23:46:47 +08:00
										 |  |  | 			dsDTO.JSONData = make(map[string]any) | 
					
						
							| 
									
										
										
										
											2022-03-19 03:49:13 +08:00
										 |  |  | 		} else { | 
					
						
							|  |  |  | 			dsDTO.JSONData = ds.JsonData.MustMap() | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-28 00:23:15 +08:00
										 |  |  | 		if ds.Access == datasources.DS_ACCESS_DIRECT { | 
					
						
							| 
									
										
										
										
											2022-03-19 03:49:13 +08:00
										 |  |  | 			if ds.BasicAuth { | 
					
						
							| 
									
										
										
										
											2022-04-26 00:57:45 +08:00
										 |  |  | 				password, err := hs.DataSourcesService.DecryptedBasicAuthPassword(c.Req.Context(), ds) | 
					
						
							|  |  |  | 				if err != nil { | 
					
						
							|  |  |  | 					return nil, err | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-19 03:49:13 +08:00
										 |  |  | 				dsDTO.BasicAuth = util.GetBasicAuthHeader( | 
					
						
							|  |  |  | 					ds.BasicAuthUser, | 
					
						
							| 
									
										
										
										
											2022-04-26 00:57:45 +08:00
										 |  |  | 					password, | 
					
						
							| 
									
										
										
										
											2022-03-19 03:49:13 +08:00
										 |  |  | 				) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if ds.WithCredentials { | 
					
						
							|  |  |  | 				dsDTO.WithCredentials = ds.WithCredentials | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-28 00:23:15 +08:00
										 |  |  | 			if ds.Type == datasources.DS_INFLUXDB_08 { | 
					
						
							| 
									
										
										
										
											2022-04-26 00:57:45 +08:00
										 |  |  | 				password, err := hs.DataSourcesService.DecryptedPassword(c.Req.Context(), ds) | 
					
						
							|  |  |  | 				if err != nil { | 
					
						
							|  |  |  | 					return nil, err | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-19 03:49:13 +08:00
										 |  |  | 				dsDTO.Username = ds.User | 
					
						
							| 
									
										
										
										
											2022-04-26 00:57:45 +08:00
										 |  |  | 				dsDTO.Password = password | 
					
						
							| 
									
										
										
										
											2022-03-19 03:49:13 +08:00
										 |  |  | 				dsDTO.URL = url + "/db/" + ds.Database | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-28 00:23:15 +08:00
										 |  |  | 			if ds.Type == datasources.DS_INFLUXDB { | 
					
						
							| 
									
										
										
										
											2022-04-26 00:57:45 +08:00
										 |  |  | 				password, err := hs.DataSourcesService.DecryptedPassword(c.Req.Context(), ds) | 
					
						
							|  |  |  | 				if err != nil { | 
					
						
							|  |  |  | 					return nil, err | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-19 03:49:13 +08:00
										 |  |  | 				dsDTO.Username = ds.User | 
					
						
							| 
									
										
										
										
											2022-04-26 00:57:45 +08:00
										 |  |  | 				dsDTO.Password = password | 
					
						
							| 
									
										
										
										
											2022-03-19 03:49:13 +08:00
										 |  |  | 				dsDTO.URL = url | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-07 00:28:52 +08:00
										 |  |  | 		// Update `jsonData.database` for outdated provisioned SQL datasources created WITHOUT the `jsonData` object in their configuration.
 | 
					
						
							|  |  |  | 		// In these cases, the `Database` value is defined (if at all) on the root level of the provisioning config object.
 | 
					
						
							|  |  |  | 		// This is done for easier warning/error checking on the front end.
 | 
					
						
							|  |  |  | 		if (ds.Type == datasources.DS_MSSQL) || (ds.Type == datasources.DS_MYSQL) || (ds.Type == datasources.DS_POSTGRES) { | 
					
						
							|  |  |  | 			// Only update if the value isn't already assigned.
 | 
					
						
							|  |  |  | 			if dsDTO.JSONData["database"] == nil || dsDTO.JSONData["database"] == "" { | 
					
						
							|  |  |  | 				dsDTO.JSONData["database"] = ds.Database | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-28 00:23:15 +08:00
										 |  |  | 		if (ds.Type == datasources.DS_INFLUXDB) || (ds.Type == datasources.DS_ES) { | 
					
						
							| 
									
										
										
										
											2022-03-19 03:49:13 +08:00
										 |  |  | 			dsDTO.Database = ds.Database | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-11 03:49:11 +08:00
										 |  |  | 		if ds.Type == datasources.DS_PROMETHEUS || ds.Type == datasources.DS_AMAZON_PROMETHEUS || ds.Type == datasources.DS_AZURE_PROMETHEUS { | 
					
						
							| 
									
										
										
										
											2022-03-19 03:49:13 +08:00
										 |  |  | 			// add unproxied server URL for link to Prometheus web UI
 | 
					
						
							| 
									
										
										
										
											2023-02-03 00:22:43 +08:00
										 |  |  | 			ds.JsonData.Set("directUrl", ds.URL) | 
					
						
							| 
									
										
										
										
											2022-03-19 03:49:13 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		dataSources[ds.Name] = dsDTO | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// add data sources that are built in (meaning they are not added via data sources page, nor have any entry in
 | 
					
						
							|  |  |  | 	// the datasource table)
 | 
					
						
							| 
									
										
										
										
											2023-06-08 18:21:19 +08:00
										 |  |  | 	for _, ds := range hs.pluginStore.Plugins(c.Req.Context(), plugins.TypeDataSource) { | 
					
						
							| 
									
										
										
										
											2022-03-19 03:49:13 +08:00
										 |  |  | 		if ds.BuiltIn { | 
					
						
							|  |  |  | 			dto := plugins.DataSourceDTO{ | 
					
						
							|  |  |  | 				Type:     string(ds.Type), | 
					
						
							|  |  |  | 				Name:     ds.Name, | 
					
						
							| 
									
										
										
										
											2023-08-30 23:46:47 +08:00
										 |  |  | 				JSONData: make(map[string]any), | 
					
						
							| 
									
										
										
										
											2022-03-19 03:49:13 +08:00
										 |  |  | 				PluginMeta: &plugins.PluginMetaDTO{ | 
					
						
							|  |  |  | 					JSONData:  ds.JSONData, | 
					
						
							|  |  |  | 					Signature: ds.Signature, | 
					
						
							|  |  |  | 					Module:    ds.Module, | 
					
						
							| 
									
										
										
										
											2024-10-04 20:55:09 +08:00
										 |  |  | 					// ModuleHash: hs.pluginAssets.ModuleHash(c.Req.Context(), ds),
 | 
					
						
							| 
									
										
										
										
											2025-03-31 12:38:38 +08:00
										 |  |  | 					BaseURL:      ds.BaseURL, | 
					
						
							|  |  |  | 					Angular:      ds.Angular, | 
					
						
							|  |  |  | 					Translations: ds.Translations, | 
					
						
							| 
									
										
										
										
											2022-03-19 03:49:13 +08:00
										 |  |  | 				}, | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if ds.Name == grafanads.DatasourceName { | 
					
						
							|  |  |  | 				dto.ID = grafanads.DatasourceID | 
					
						
							|  |  |  | 				dto.UID = grafanads.DatasourceUID | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			dataSources[ds.Name] = dto | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return dataSources, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-09 17:38:35 +08:00
										 |  |  | func (hs *HTTPServer) newAppDTO(ctx context.Context, plugin pluginstore.Plugin, settings pluginsettings.InfoDTO) *plugins.AppDTO { | 
					
						
							| 
									
										
										
										
											2023-02-08 00:20:05 +08:00
										 |  |  | 	app := &plugins.AppDTO{ | 
					
						
							| 
									
										
										
										
											2024-09-09 17:38:35 +08:00
										 |  |  | 		ID:              plugin.ID, | 
					
						
							|  |  |  | 		Version:         plugin.Info.Version, | 
					
						
							|  |  |  | 		Path:            plugin.Module, | 
					
						
							|  |  |  | 		Preload:         false, | 
					
						
							|  |  |  | 		Angular:         plugin.Angular, | 
					
						
							|  |  |  | 		LoadingStrategy: hs.pluginAssets.LoadingStrategy(ctx, plugin), | 
					
						
							| 
									
										
										
										
											2024-10-04 14:41:26 +08:00
										 |  |  | 		Extensions:      plugin.Extensions, | 
					
						
							|  |  |  | 		Dependencies:    plugin.Dependencies, | 
					
						
							| 
									
										
										
										
											2024-10-04 20:55:09 +08:00
										 |  |  | 		ModuleHash:      hs.pluginAssets.ModuleHash(ctx, plugin), | 
					
						
							| 
									
										
										
										
											2025-03-31 12:38:38 +08:00
										 |  |  | 		Translations:    plugin.Translations, | 
					
						
							| 
									
										
										
										
											2023-02-08 00:20:05 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if settings.Enabled { | 
					
						
							| 
									
										
										
										
											2023-02-08 21:41:49 +08:00
										 |  |  | 		app.Preload = plugin.Preload | 
					
						
							| 
									
										
										
										
											2023-02-08 00:20:05 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return app | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-26 23:42:39 +08:00
										 |  |  | func getPanelSort(id string) int { | 
					
						
							|  |  |  | 	sort := 100 | 
					
						
							|  |  |  | 	switch id { | 
					
						
							| 
									
										
										
										
											2021-01-11 00:41:20 +08:00
										 |  |  | 	case "timeseries": | 
					
						
							| 
									
										
										
										
											2021-05-05 19:19:14 +08:00
										 |  |  | 		sort = 1 | 
					
						
							| 
									
										
										
										
											2021-05-03 22:49:09 +08:00
										 |  |  | 	case "barchart": | 
					
						
							| 
									
										
										
										
											2021-05-05 19:19:14 +08:00
										 |  |  | 		sort = 2 | 
					
						
							| 
									
										
										
										
											2021-05-03 22:49:09 +08:00
										 |  |  | 	case "stat": | 
					
						
							| 
									
										
										
										
											2021-05-05 19:19:14 +08:00
										 |  |  | 		sort = 3 | 
					
						
							| 
									
										
										
										
											2021-05-03 22:49:09 +08:00
										 |  |  | 	case "gauge": | 
					
						
							| 
									
										
										
										
											2021-05-05 19:19:14 +08:00
										 |  |  | 		sort = 4 | 
					
						
							| 
									
										
										
										
											2021-05-03 22:49:09 +08:00
										 |  |  | 	case "bargauge": | 
					
						
							| 
									
										
										
										
											2021-05-05 19:19:14 +08:00
										 |  |  | 		sort = 5 | 
					
						
							| 
									
										
										
										
											2021-05-03 22:49:09 +08:00
										 |  |  | 	case "table": | 
					
						
							| 
									
										
										
										
											2021-05-05 19:19:14 +08:00
										 |  |  | 		sort = 6 | 
					
						
							| 
									
										
										
										
											2021-05-03 22:49:09 +08:00
										 |  |  | 	case "singlestat": | 
					
						
							| 
									
										
										
										
											2021-05-05 19:19:14 +08:00
										 |  |  | 		sort = 7 | 
					
						
							| 
									
										
										
										
											2021-05-03 22:49:09 +08:00
										 |  |  | 	case "piechart": | 
					
						
							| 
									
										
										
										
											2021-05-05 19:19:14 +08:00
										 |  |  | 		sort = 8 | 
					
						
							| 
									
										
										
										
											2021-05-18 04:00:04 +08:00
										 |  |  | 	case "state-timeline": | 
					
						
							| 
									
										
										
										
											2019-02-16 04:33:36 +08:00
										 |  |  | 		sort = 9 | 
					
						
							| 
									
										
										
										
											2021-03-25 15:33:13 +08:00
										 |  |  | 	case "heatmap": | 
					
						
							| 
									
										
										
										
											2020-01-17 16:43:17 +08:00
										 |  |  | 		sort = 10 | 
					
						
							| 
									
										
										
										
											2021-05-30 02:24:14 +08:00
										 |  |  | 	case "status-history": | 
					
						
							| 
									
										
										
										
											2021-01-11 00:41:20 +08:00
										 |  |  | 		sort = 11 | 
					
						
							| 
									
										
										
										
											2021-05-20 23:36:20 +08:00
										 |  |  | 	case "histogram": | 
					
						
							| 
									
										
										
										
											2021-01-11 00:41:20 +08:00
										 |  |  | 		sort = 12 | 
					
						
							| 
									
										
										
										
											2021-05-20 23:36:20 +08:00
										 |  |  | 	case "graph": | 
					
						
							| 
									
										
										
										
											2021-03-25 15:33:13 +08:00
										 |  |  | 		sort = 13 | 
					
						
							| 
									
										
										
										
											2021-05-20 23:36:20 +08:00
										 |  |  | 	case "text": | 
					
						
							| 
									
										
										
										
											2021-05-03 22:49:09 +08:00
										 |  |  | 		sort = 14 | 
					
						
							| 
									
										
										
										
											2021-05-20 23:36:20 +08:00
										 |  |  | 	case "alertlist": | 
					
						
							| 
									
										
										
										
											2021-05-05 19:19:14 +08:00
										 |  |  | 		sort = 15 | 
					
						
							| 
									
										
										
										
											2021-05-20 23:36:20 +08:00
										 |  |  | 	case "dashlist": | 
					
						
							| 
									
										
										
										
											2021-05-18 04:00:04 +08:00
										 |  |  | 		sort = 16 | 
					
						
							| 
									
										
										
										
											2021-05-20 23:36:20 +08:00
										 |  |  | 	case "news": | 
					
						
							|  |  |  | 		sort = 17 | 
					
						
							| 
									
										
										
										
											2016-10-26 23:42:39 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return sort | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-08 00:20:05 +08:00
										 |  |  | type availablePluginDTO struct { | 
					
						
							| 
									
										
										
										
											2023-09-11 19:59:24 +08:00
										 |  |  | 	Plugin   pluginstore.Plugin | 
					
						
							| 
									
										
										
										
											2023-02-08 00:20:05 +08:00
										 |  |  | 	Settings pluginsettings.InfoDTO | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // AvailablePlugins represents a mapping from plugin types (panel, data source, etc.) to plugin IDs to plugins
 | 
					
						
							| 
									
										
										
										
											2021-11-17 19:04:22 +08:00
										 |  |  | // For example ["panel"] -> ["piechart"] -> {pie chart plugin DTO}
 | 
					
						
							| 
									
										
										
										
											2023-02-08 00:20:05 +08:00
										 |  |  | type AvailablePlugins map[plugins.Type]map[string]*availablePluginDTO | 
					
						
							| 
									
										
										
										
											2021-11-01 17:53:33 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-08 00:20:05 +08:00
										 |  |  | func (ap AvailablePlugins) Get(pluginType plugins.Type, pluginID string) (*availablePluginDTO, bool) { | 
					
						
							| 
									
										
										
										
											2023-06-03 01:46:12 +08:00
										 |  |  | 	p, exists := ap[pluginType][pluginID] | 
					
						
							|  |  |  | 	if exists { | 
					
						
							|  |  |  | 		return p, true | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	for _, p = range ap[pluginType] { | 
					
						
							| 
									
										
										
										
											2023-09-29 23:20:37 +08:00
										 |  |  | 		if p.Plugin.ID == pluginID || slices.Contains(p.Plugin.AliasIDs, pluginID) { | 
					
						
							| 
									
										
										
										
											2023-06-03 01:46:12 +08:00
										 |  |  | 			return p, true | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-11-01 17:53:33 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-02-08 00:20:05 +08:00
										 |  |  | 	return nil, false | 
					
						
							| 
									
										
										
										
											2021-11-01 17:53:33 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-08 00:20:05 +08:00
										 |  |  | func (hs *HTTPServer) availablePlugins(ctx context.Context, orgID int64) (AvailablePlugins, error) { | 
					
						
							| 
									
										
										
										
											2024-08-06 09:17:39 +08:00
										 |  |  | 	ctx, span := hs.tracer.Start(ctx, "api.availablePlugins") | 
					
						
							|  |  |  | 	defer span.End() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-08 00:20:05 +08:00
										 |  |  | 	ap := make(AvailablePlugins) | 
					
						
							| 
									
										
										
										
											2021-11-01 17:53:33 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-02 20:42:55 +08:00
										 |  |  | 	pluginSettingMap, err := hs.pluginSettings(ctx, orgID) | 
					
						
							| 
									
										
										
										
											2021-11-01 17:53:33 +08:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2023-02-08 00:20:05 +08:00
										 |  |  | 		return ap, err | 
					
						
							| 
									
										
										
										
											2021-11-01 17:53:33 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-08 00:20:05 +08:00
										 |  |  | 	apps := make(map[string]*availablePluginDTO) | 
					
						
							| 
									
										
										
										
											2023-06-08 18:21:19 +08:00
										 |  |  | 	for _, app := range hs.pluginStore.Plugins(ctx, plugins.TypeApp) { | 
					
						
							| 
									
										
										
										
											2023-02-08 00:20:05 +08:00
										 |  |  | 		if s, exists := pluginSettingMap[app.ID]; exists { | 
					
						
							|  |  |  | 			app.Pinned = s.Pinned | 
					
						
							|  |  |  | 			apps[app.ID] = &availablePluginDTO{ | 
					
						
							|  |  |  | 				Plugin:   app, | 
					
						
							|  |  |  | 				Settings: *s, | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2021-11-01 17:53:33 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-06-08 18:21:19 +08:00
										 |  |  | 	ap[plugins.TypeApp] = apps | 
					
						
							| 
									
										
										
										
											2021-11-01 17:53:33 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-08 00:20:05 +08:00
										 |  |  | 	dataSources := make(map[string]*availablePluginDTO) | 
					
						
							| 
									
										
										
										
											2023-06-08 18:21:19 +08:00
										 |  |  | 	for _, ds := range hs.pluginStore.Plugins(ctx, plugins.TypeDataSource) { | 
					
						
							| 
									
										
										
										
											2023-02-08 00:20:05 +08:00
										 |  |  | 		if s, exists := pluginSettingMap[ds.ID]; exists { | 
					
						
							|  |  |  | 			dataSources[ds.ID] = &availablePluginDTO{ | 
					
						
							|  |  |  | 				Plugin:   ds, | 
					
						
							|  |  |  | 				Settings: *s, | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2021-11-01 17:53:33 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-06-08 18:21:19 +08:00
										 |  |  | 	ap[plugins.TypeDataSource] = dataSources | 
					
						
							| 
									
										
										
										
											2021-11-01 17:53:33 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-08 00:20:05 +08:00
										 |  |  | 	panels := make(map[string]*availablePluginDTO) | 
					
						
							| 
									
										
										
										
											2023-06-08 18:21:19 +08:00
										 |  |  | 	for _, p := range hs.pluginStore.Plugins(ctx, plugins.TypePanel) { | 
					
						
							| 
									
										
										
										
											2023-02-08 00:20:05 +08:00
										 |  |  | 		if s, exists := pluginSettingMap[p.ID]; exists { | 
					
						
							|  |  |  | 			panels[p.ID] = &availablePluginDTO{ | 
					
						
							|  |  |  | 				Plugin:   p, | 
					
						
							|  |  |  | 				Settings: *s, | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2021-11-01 17:53:33 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-06-08 18:21:19 +08:00
										 |  |  | 	ap[plugins.TypePanel] = panels | 
					
						
							| 
									
										
										
										
											2021-11-01 17:53:33 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-08 00:20:05 +08:00
										 |  |  | 	return ap, nil | 
					
						
							| 
									
										
										
										
											2021-11-01 17:53:33 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-21 18:20:11 +08:00
										 |  |  | func (hs *HTTPServer) pluginSettings(ctx context.Context, orgID int64) (map[string]*pluginsettings.InfoDTO, error) { | 
					
						
							| 
									
										
										
										
											2024-08-06 09:17:39 +08:00
										 |  |  | 	ctx, span := hs.tracer.Start(ctx, "api.pluginSettings") | 
					
						
							|  |  |  | 	defer span.End() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-21 18:20:11 +08:00
										 |  |  | 	pluginSettings := make(map[string]*pluginsettings.InfoDTO) | 
					
						
							| 
									
										
										
										
											2021-11-01 17:53:33 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-05 22:07:53 +08:00
										 |  |  | 	// fill settings from database
 | 
					
						
							| 
									
										
										
										
											2022-03-19 03:49:13 +08:00
										 |  |  | 	if pss, err := hs.PluginSettings.GetPluginSettings(ctx, &pluginsettings.GetArgs{OrgID: orgID}); err != nil { | 
					
						
							| 
									
										
										
										
											2021-11-05 22:07:53 +08:00
										 |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		for _, ps := range pss { | 
					
						
							| 
									
										
										
										
											2022-03-19 03:49:13 +08:00
										 |  |  | 			pluginSettings[ps.PluginID] = ps | 
					
						
							| 
									
										
										
										
											2021-11-05 22:07:53 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-11-01 17:53:33 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-05 22:07:53 +08:00
										 |  |  | 	// fill settings from app plugins
 | 
					
						
							| 
									
										
										
										
											2023-06-08 18:21:19 +08:00
										 |  |  | 	for _, plugin := range hs.pluginStore.Plugins(ctx, plugins.TypeApp) { | 
					
						
							| 
									
										
										
										
											2021-11-05 22:07:53 +08:00
										 |  |  | 		// ignore settings that already exist
 | 
					
						
							|  |  |  | 		if _, exists := pluginSettings[plugin.ID]; exists { | 
					
						
							| 
									
										
										
										
											2021-11-01 17:53:33 +08:00
										 |  |  | 			continue | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-05 22:07:53 +08:00
										 |  |  | 		// add new setting which is enabled depending on if AutoEnabled: true
 | 
					
						
							| 
									
										
										
										
											2022-09-21 18:20:11 +08:00
										 |  |  | 		pluginSetting := &pluginsettings.InfoDTO{ | 
					
						
							|  |  |  | 			PluginID:      plugin.ID, | 
					
						
							|  |  |  | 			OrgID:         orgID, | 
					
						
							|  |  |  | 			Enabled:       plugin.AutoEnabled, | 
					
						
							|  |  |  | 			Pinned:        plugin.AutoEnabled, | 
					
						
							| 
									
										
										
										
											2024-12-16 21:51:04 +08:00
										 |  |  | 			AutoEnabled:   plugin.AutoEnabled, | 
					
						
							| 
									
										
										
										
											2022-09-21 18:20:11 +08:00
										 |  |  | 			PluginVersion: plugin.Info.Version, | 
					
						
							| 
									
										
										
										
											2021-11-01 17:53:33 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-05 22:07:53 +08:00
										 |  |  | 		pluginSettings[plugin.ID] = pluginSetting | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// fill settings from all remaining plugins (including potential app child plugins)
 | 
					
						
							| 
									
										
										
										
											2021-11-17 19:04:22 +08:00
										 |  |  | 	for _, plugin := range hs.pluginStore.Plugins(ctx) { | 
					
						
							| 
									
										
										
										
											2021-11-05 22:07:53 +08:00
										 |  |  | 		// ignore settings that already exist
 | 
					
						
							|  |  |  | 		if _, exists := pluginSettings[plugin.ID]; exists { | 
					
						
							|  |  |  | 			continue | 
					
						
							| 
									
										
										
										
											2021-11-01 17:53:33 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-05 22:07:53 +08:00
										 |  |  | 		// add new setting which is enabled by default
 | 
					
						
							| 
									
										
										
										
											2022-09-21 18:20:11 +08:00
										 |  |  | 		pluginSetting := &pluginsettings.InfoDTO{ | 
					
						
							|  |  |  | 			PluginID:      plugin.ID, | 
					
						
							|  |  |  | 			OrgID:         orgID, | 
					
						
							|  |  |  | 			Enabled:       true, | 
					
						
							|  |  |  | 			Pinned:        false, | 
					
						
							|  |  |  | 			PluginVersion: plugin.Info.Version, | 
					
						
							| 
									
										
										
										
											2021-11-05 22:07:53 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-11-01 17:53:33 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-05 22:07:53 +08:00
										 |  |  | 		// if plugin is included in an app, check app settings
 | 
					
						
							|  |  |  | 		if plugin.IncludedInAppID != "" { | 
					
						
							|  |  |  | 			// app child plugins are disabled unless app is enabled
 | 
					
						
							|  |  |  | 			pluginSetting.Enabled = false | 
					
						
							|  |  |  | 			if p, exists := pluginSettings[plugin.IncludedInAppID]; exists { | 
					
						
							|  |  |  | 				pluginSetting.Enabled = p.Enabled | 
					
						
							| 
									
										
										
										
											2021-11-01 17:53:33 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-11-05 22:07:53 +08:00
										 |  |  | 		pluginSettings[plugin.ID] = pluginSetting | 
					
						
							| 
									
										
										
										
											2021-11-01 17:53:33 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-05 22:07:53 +08:00
										 |  |  | 	return pluginSettings, nil | 
					
						
							| 
									
										
										
										
											2021-11-01 17:53:33 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2022-11-15 17:50:37 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-30 23:46:47 +08:00
										 |  |  | func (hs *HTTPServer) getEnabledOAuthProviders() map[string]any { | 
					
						
							|  |  |  | 	providers := make(map[string]any) | 
					
						
							| 
									
										
										
										
											2022-11-15 17:50:37 +08:00
										 |  |  | 	for key, oauth := range hs.SocialService.GetOAuthInfoProviders() { | 
					
						
							|  |  |  | 		providers[key] = map[string]string{ | 
					
						
							|  |  |  | 			"name": oauth.Name, | 
					
						
							|  |  |  | 			"icon": oauth.Icon, | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return providers | 
					
						
							|  |  |  | } |