mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Config: Refactor frontend settings to struct (#61990)
* Config: Make frontend settings a struct rather than map remove frontend settings to setting package remove frontend settings struct to dtos package rearrange structs to avoid cycles rename getFrontendSettings fn omitempty fix login test fix middleware test * wip some enterprise types * cleanup, moved structs from enterprise * ci
This commit is contained in:
parent
178f290f0c
commit
138575cbe9
227
pkg/api/dtos/frontend_settings.go
Normal file
227
pkg/api/dtos/frontend_settings.go
Normal file
@ -0,0 +1,227 @@
|
||||
package dtos
|
||||
|
||||
import (
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
type FrontendSettingsAuthDTO struct {
|
||||
OAuthSkipOrgRoleUpdateSync bool `json:"OAuthSkipOrgRoleUpdateSync"`
|
||||
SAMLSkipOrgRoleSync bool `json:"SAMLSkipOrgRoleSync"`
|
||||
LDAPSkipOrgRoleSync bool `json:"LDAPSkipOrgRoleSync"`
|
||||
GoogleSkipOrgRoleSync bool `json:"GoogleSkipOrgRoleSync"`
|
||||
JWTAuthSkipOrgRoleSync bool `json:"JWTAuthSkipOrgRoleSync"`
|
||||
GrafanaComSkipOrgRoleSync bool `json:"GrafanaComSkipOrgRoleSync"`
|
||||
AzureADSkipOrgRoleSync bool `json:"AzureADSkipOrgRoleSync"`
|
||||
GithubSkipOrgRoleSync bool `json:"GithubSkipOrgRoleSync"`
|
||||
GitLabSkipOrgRoleSync bool `json:"GitLabSkipOrgRoleSync"`
|
||||
OktaSkipOrgRoleSync bool `json:"OktaSkipOrgRoleSync"`
|
||||
DisableSyncLock bool `json:"DisableSyncLock"`
|
||||
}
|
||||
|
||||
type FrontendSettingsBuildInfoDTO struct {
|
||||
HideVersion bool `json:"hideVersion"`
|
||||
Version string `json:"version"`
|
||||
Commit string `json:"commit"`
|
||||
Buildstamp int64 `json:"buildstamp"`
|
||||
Edition string `json:"edition"`
|
||||
LatestVersion string `json:"latestVersion"`
|
||||
HasUpdate bool `json:"hasUpdate"`
|
||||
Env string `json:"env"`
|
||||
}
|
||||
|
||||
type FrontendSettingsLicenseInfoDTO struct {
|
||||
Expiry int64 `json:"expiry"`
|
||||
StateInfo string `json:"stateInfo"`
|
||||
LicenseUrl string `json:"licenseUrl"`
|
||||
Edition string `json:"edition"`
|
||||
EnabledFeatures map[string]bool `json:"enabledFeatures"`
|
||||
|
||||
// Enterprise-only
|
||||
TrialExpiry *int64 `json:"trialExpiry,omitempty"`
|
||||
AppUrl *string `json:"appUrl,omitempty"`
|
||||
}
|
||||
|
||||
type FrontendSettingsAzureDTO struct {
|
||||
Cloud string `json:"cloud"`
|
||||
ManagedIdentityEnabled bool `json:"managedIdentityEnabled"`
|
||||
}
|
||||
|
||||
type FrontendSettingsCachingDTO struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
}
|
||||
|
||||
type FrontendSettingsRecordedQueriesDTO struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
}
|
||||
|
||||
type FrontendSettingsReportingDTO struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
}
|
||||
|
||||
type FrontendSettingsUnifiedAlertingDTO struct {
|
||||
MinInterval string `json:"minInterval"`
|
||||
}
|
||||
|
||||
type DashboardPreviewsSystemRequirements struct {
|
||||
Met bool `json:"met"`
|
||||
RequiredImageRendererPluginVersion string `json:"requiredImageRendererPluginVersion"`
|
||||
}
|
||||
|
||||
type DashboardPreviewsSetupConfig struct {
|
||||
SystemRequirements DashboardPreviewsSystemRequirements `json:"systemRequirements"`
|
||||
ThumbnailsExist bool `json:"thumbnailsExist"`
|
||||
}
|
||||
|
||||
// Enterprise-only
|
||||
type FrontendSettingsLicensingDTO struct {
|
||||
Slug *string `json:"slug,omitempty"`
|
||||
LimitBy *string `json:"limitBy,omitempty"`
|
||||
IncludedUsers *int64 `json:"includedUsers,omitempty"`
|
||||
LicenseExpiry *int64 `json:"licenseExpiry,omitempty"`
|
||||
LicenseExpiryWarnDays *int64 `json:"licenseExpiryWarnDays,omitempty"`
|
||||
TokenExpiry *int64 `json:"tokenExpiry,omitempty"`
|
||||
IsTrial *bool `json:"isTrial,omitempty"`
|
||||
TokenExpiryWarnDays *int64 `json:"tokenExpiryWarnDays,omitempty"`
|
||||
UsageBilling *bool `json:"usageBilling,omitempty"`
|
||||
ActiveAdminsAndEditors *int64 `json:"activeAdminsAndEditors,omitempty"`
|
||||
ActiveViewers *int64 `json:"activeViewers,omitempty"`
|
||||
ActiveUsers *int64 `json:"ActiveUsers,omitempty"`
|
||||
}
|
||||
|
||||
// Enterprise-only
|
||||
type FrontendSettingsFooterConfigItemDTO struct {
|
||||
Text string `json:"text"`
|
||||
Url string `json:"url"`
|
||||
Icon string `json:"icon"`
|
||||
Target string `json:"blank"`
|
||||
}
|
||||
|
||||
// Enterprise-only
|
||||
type FrontendSettingsPublicDashboardFooterConfigDTO struct {
|
||||
Hide bool `json:"hide"`
|
||||
Text string `json:"text"`
|
||||
Logo string `json:"logo"`
|
||||
Link string `json:"link"`
|
||||
}
|
||||
|
||||
// Enterprise-only
|
||||
type FrontendSettingsWhitelabelingDTO struct {
|
||||
Links []FrontendSettingsFooterConfigItemDTO `json:"links"`
|
||||
LoginTitle string `json:"loginTitle"`
|
||||
|
||||
AppTitle *string `json:"appTitle,omitempty"`
|
||||
LoginLogo *string `json:"loginLogo,omitempty"`
|
||||
MenuLogo *string `json:"menuLogo,omitempty"`
|
||||
LoginBackground *string `json:"loginBackground,omitempty"`
|
||||
LoginSubtitle *string `json:"loginSubtitle,omitempty"`
|
||||
LoginBoxBackground *string `json:"loginBoxBackground,omitempty"`
|
||||
LoadingLogo *string `json:"loadingLogo,omitempty"`
|
||||
PublicDashboardFooter *FrontendSettingsPublicDashboardFooterConfigDTO `json:"publicDashboardFooter,omitempty"` // PR TODO: type this properly
|
||||
}
|
||||
|
||||
type FrontendSettingsDTO struct {
|
||||
DefaultDatasource string `json:"defaultDatasource"`
|
||||
Datasources map[string]plugins.DataSourceDTO `json:"datasources"`
|
||||
MinRefreshInterval string `json:"minRefreshInterval"`
|
||||
Panels map[string]plugins.PanelDTO `json:"panels"`
|
||||
AppUrl string `json:"appUrl"`
|
||||
AppSubUrl string `json:"appSubUrl"`
|
||||
AllowOrgCreate bool `json:"allowOrgCreate"`
|
||||
AuthProxyEnabled bool `json:"authProxyEnabled"`
|
||||
LdapEnabled bool `json:"ldapEnabled"`
|
||||
JwtHeaderName string `json:"jwtHeaderName"`
|
||||
JwtUrlLogin bool `json:"jwtUrlLogin"`
|
||||
AlertingEnabled bool `json:"alertingEnabled"`
|
||||
AlertingErrorOrTimeout string `json:"alertingErrorOrTimeout"`
|
||||
AlertingNoDataOrNullValues string `json:"alertingNoDataOrNullValues"`
|
||||
AlertingMinInterval int64 `json:"alertingMinInterval"`
|
||||
LiveEnabled bool `json:"liveEnabled"`
|
||||
AutoAssignOrg bool `json:"autoAssignOrg"`
|
||||
|
||||
VerifyEmailEnabled bool `json:"verifyEmailEnabled"`
|
||||
SigV4AuthEnabled bool `json:"sigV4AuthEnabled"`
|
||||
AzureAuthEnabled bool `json:"azureAuthEnabled"`
|
||||
RbacEnabled bool `json:"rbacEnabled"`
|
||||
ExploreEnabled bool `json:"exploreEnabled"`
|
||||
HelpEnabled bool `json:"helpEnabled"`
|
||||
ProfileEnabled bool `json:"profileEnabled"`
|
||||
QueryHistoryEnabled bool `json:"queryHistoryEnabled"`
|
||||
|
||||
GoogleAnalyticsId string `json:"googleAnalyticsId"`
|
||||
GoogleAnalytics4Id string `json:"googleAnalytics4Id"`
|
||||
GoogleAnalytics4SendManualPageViews bool `json:"GoogleAnalytics4SendManualPageViews"`
|
||||
|
||||
RudderstackWriteKey string `json:"rudderstackWriteKey"`
|
||||
RudderstackDataPlaneUrl string `json:"rudderstackDataPlaneUrl"`
|
||||
RudderstackSdkUrl string `json:"rudderstackSdkUrl"`
|
||||
RudderstackConfigUrl string `json:"rudderstackConfigUrl"`
|
||||
|
||||
FeedbackLinksEnabled bool `json:"feedbackLinksEnabled"`
|
||||
ApplicationInsightsConnectionString string `json:"applicationInsightsConnectionString"`
|
||||
ApplicationInsightsEndpointUrl string `json:"applicationInsightsEndpointUrl"`
|
||||
DisableLoginForm bool `json:"disableLoginForm"`
|
||||
DisableUserSignUp bool `json:"disableUserSignUp"`
|
||||
LoginHint string `json:"loginHint"`
|
||||
PasswordHint string `json:"passwordHint"`
|
||||
ExternalUserMngInfo string `json:"externalUserMngInfo"`
|
||||
ExternalUserMngLinkUrl string `json:"externalUserMngLinkUrl"`
|
||||
ExternalUserMngLinkName string `json:"externalUserMngLinkName"`
|
||||
ViewersCanEdit bool `json:"viewersCanEdit"`
|
||||
AngularSupportEnabled bool `json:"angularSupportEnabled"`
|
||||
EditorsCanAdmin bool `json:"editorsCanAdmin"`
|
||||
DisableSanitizeHtml bool `json:"disableSanitizeHtml"`
|
||||
PluginsToPreload []*plugins.PreloadPlugin `json:"pluginsToPreload"`
|
||||
|
||||
Auth FrontendSettingsAuthDTO `json:"auth"`
|
||||
|
||||
BuildInfo FrontendSettingsBuildInfoDTO `json:"buildInfo"`
|
||||
|
||||
LicenseInfo FrontendSettingsLicenseInfoDTO `json:"licenseInfo"`
|
||||
|
||||
FeatureToggles map[string]bool `json:"featureToggles"`
|
||||
RendererAvailable bool `json:"rendererAvailable"`
|
||||
RendererVersion string `json:"rendererVersion"`
|
||||
SecretsManagerPluginEnabled bool `json:"secretsManagerPluginEnabled"`
|
||||
Http2Enabled bool `json:"http2Enabled"`
|
||||
Sentry setting.Sentry `json:"sentry"`
|
||||
GrafanaJavascriptAgent setting.GrafanaJavascriptAgent `json:"grafanaJavascriptAgent"`
|
||||
PluginCatalogURL string `json:"pluginCatalogURL"`
|
||||
PluginAdminEnabled bool `json:"pluginAdminEnabled"`
|
||||
PluginAdminExternalManageEnabled bool `json:"pluginAdminExternalManageEnabled"`
|
||||
PluginCatalogHiddenPlugins []string `json:"pluginCatalogHiddenPlugins"`
|
||||
ExpressionsEnabled bool `json:"expressionsEnabled"`
|
||||
AwsAllowedAuthProviders []string `json:"awsAllowedAuthProviders"`
|
||||
AwsAssumeRoleEnabled bool `json:"awsAssumeRoleEnabled"`
|
||||
SupportBundlesEnabled bool `json:"supportBundlesEnabled"`
|
||||
SnapshotEnabled bool `json:"snapshotEnabled"`
|
||||
|
||||
Azure FrontendSettingsAzureDTO `json:"azure"`
|
||||
|
||||
Caching FrontendSettingsCachingDTO `json:"caching"`
|
||||
RecordedQueries FrontendSettingsRecordedQueriesDTO `json:"recordedQueries"`
|
||||
Reporting FrontendSettingsReportingDTO `json:"reporting"`
|
||||
UnifiedAlertingEnabled bool `json:"unifiedAlertingEnabled"`
|
||||
UnifiedAlerting FrontendSettingsUnifiedAlertingDTO `json:"unifiedAlerting"`
|
||||
Oauth map[string]interface{} `json:"oauth"`
|
||||
SamlEnabled bool `json:"samlEnabled"`
|
||||
SamlName string `json:"samlName"`
|
||||
TokenExpirationDayLimit int `json:"tokenExpirationDayLimit"`
|
||||
|
||||
DashboardPreviews DashboardPreviewsSetupConfig `json:"dashboardPreviews,omitempty"`
|
||||
|
||||
GeomapDefaultBaseLayerConfig *map[string]interface{} `json:"geomapDefaultBaseLayerConfig,omitempty"`
|
||||
GeomapDisableCustomBaseLayer bool `json:"geomapDisableCustomBaseLayer"`
|
||||
|
||||
IsPublicDashboardView bool `json:"isPublicDashboardView"`
|
||||
|
||||
DateFormats setting.DateFormats `json:"dateFormats,omitempty"`
|
||||
|
||||
LoginError string `json:"loginError,omitempty"`
|
||||
|
||||
PluginsCDNBaseURL string `json:"pluginsCDNBaseURL,omitempty"`
|
||||
|
||||
// Enterprise
|
||||
Licensing *FrontendSettingsLicensingDTO `json:"licensing,omitempty"`
|
||||
Whitelabeling *FrontendSettingsWhitelabelingDTO `json:"whitelabeling,omitempty"`
|
||||
}
|
@ -9,7 +9,7 @@ import (
|
||||
|
||||
type IndexViewData struct {
|
||||
User *CurrentUser
|
||||
Settings map[string]interface{}
|
||||
Settings *FrontendSettingsDTO
|
||||
AppUrl string
|
||||
AppSubUrl string
|
||||
GoogleAnalyticsId string
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/grafana/grafana/pkg/api/dtos"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
|
||||
@ -20,7 +21,7 @@ import (
|
||||
)
|
||||
|
||||
func (hs *HTTPServer) GetFrontendSettings(c *contextmodel.ReqContext) {
|
||||
settings, err := hs.getFrontendSettingsMap(c)
|
||||
settings, err := hs.getFrontendSettings(c)
|
||||
if err != nil {
|
||||
c.JsonApiErr(400, "Failed to get frontend settings", err)
|
||||
return
|
||||
@ -29,8 +30,8 @@ func (hs *HTTPServer) GetFrontendSettings(c *contextmodel.ReqContext) {
|
||||
c.JSON(http.StatusOK, settings)
|
||||
}
|
||||
|
||||
// getFrontendSettingsMap returns a json object with all the settings needed for front end initialisation.
|
||||
func (hs *HTTPServer) getFrontendSettingsMap(c *contextmodel.ReqContext) (map[string]interface{}, error) {
|
||||
// getFrontendSettings returns a json object with all the settings needed for front end initialisation.
|
||||
func (hs *HTTPServer) getFrontendSettings(c *contextmodel.ReqContext) (*dtos.FrontendSettingsDTO, error) {
|
||||
enabledPlugins, err := hs.enabledPlugins(c.Req.Context(), c.OrgID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -97,121 +98,137 @@ func (hs *HTTPServer) getFrontendSettingsMap(c *contextmodel.ReqContext) (map[st
|
||||
hasAccess := accesscontrol.HasAccess(hs.AccessControl, c)
|
||||
secretsManagerPluginEnabled := kvstore.EvaluateRemoteSecretsPlugin(c.Req.Context(), hs.secretsPluginManager, hs.Cfg) == nil
|
||||
|
||||
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,
|
||||
"jwtHeaderName": hs.Cfg.JWTAuthHeaderName,
|
||||
"jwtUrlLogin": hs.Cfg.JWTAuthURLLogin,
|
||||
"alertingEnabled": setting.AlertingEnabled,
|
||||
"alertingErrorOrTimeout": setting.AlertingErrorOrTimeout,
|
||||
"alertingNoDataOrNullValues": setting.AlertingNoDataOrNullValues,
|
||||
"alertingMinInterval": setting.AlertingMinInterval,
|
||||
"liveEnabled": hs.Cfg.LiveMaxConnections != 0,
|
||||
"autoAssignOrg": setting.AutoAssignOrg,
|
||||
"verifyEmailEnabled": setting.VerifyEmailEnabled,
|
||||
"sigV4AuthEnabled": setting.SigV4AuthEnabled,
|
||||
"azureAuthEnabled": setting.AzureAuthEnabled,
|
||||
"rbacEnabled": hs.Cfg.RBACEnabled,
|
||||
"exploreEnabled": setting.ExploreEnabled,
|
||||
"helpEnabled": setting.HelpEnabled,
|
||||
"profileEnabled": setting.ProfileEnabled,
|
||||
"queryHistoryEnabled": hs.Cfg.QueryHistoryEnabled,
|
||||
"googleAnalyticsId": setting.GoogleAnalyticsId,
|
||||
"googleAnalytics4Id": setting.GoogleAnalytics4Id,
|
||||
"GoogleAnalytics4SendManualPageViews": setting.GoogleAnalytics4SendManualPageViews,
|
||||
"rudderstackWriteKey": setting.RudderstackWriteKey,
|
||||
"rudderstackDataPlaneUrl": setting.RudderstackDataPlaneUrl,
|
||||
"rudderstackSdkUrl": setting.RudderstackSdkUrl,
|
||||
"rudderstackConfigUrl": setting.RudderstackConfigUrl,
|
||||
"feedbackLinksEnabled": hs.Cfg.FeedbackLinksEnabled,
|
||||
"applicationInsightsConnectionString": hs.Cfg.ApplicationInsightsConnectionString,
|
||||
"applicationInsightsEndpointUrl": hs.Cfg.ApplicationInsightsEndpointUrl,
|
||||
"disableLoginForm": setting.DisableLoginForm,
|
||||
"disableUserSignUp": !setting.AllowUserSignUp,
|
||||
"loginHint": setting.LoginHint,
|
||||
"passwordHint": setting.PasswordHint,
|
||||
"externalUserMngInfo": setting.ExternalUserMngInfo,
|
||||
"externalUserMngLinkUrl": setting.ExternalUserMngLinkUrl,
|
||||
"externalUserMngLinkName": setting.ExternalUserMngLinkName,
|
||||
"viewersCanEdit": setting.ViewersCanEdit,
|
||||
"angularSupportEnabled": hs.Cfg.AngularSupportEnabled,
|
||||
"editorsCanAdmin": hs.Cfg.EditorsCanAdmin,
|
||||
"disableSanitizeHtml": hs.Cfg.DisableSanitizeHtml,
|
||||
"pluginsToPreload": pluginsToPreload,
|
||||
"auth": map[string]interface{}{
|
||||
"OAuthSkipOrgRoleUpdateSync": hs.Cfg.OAuthSkipOrgRoleUpdateSync,
|
||||
"SAMLSkipOrgRoleSync": hs.Cfg.SectionWithEnvOverrides("auth.saml").Key("skip_org_role_sync").MustBool(false),
|
||||
"LDAPSkipOrgRoleSync": hs.Cfg.LDAPSkipOrgRoleSync,
|
||||
"GithubSkipOrgRoleSync": hs.Cfg.GithubSkipOrgRoleSync,
|
||||
"GoogleSkipOrgRoleSync": hs.Cfg.GoogleSkipOrgRoleSync,
|
||||
"JWTAuthSkipOrgRoleSync": hs.Cfg.JWTAuthSkipOrgRoleSync,
|
||||
"GrafanaComSkipOrgRoleSync": hs.Cfg.GrafanaComSkipOrgRoleSync,
|
||||
"GitLabSkipOrgRoleSync": hs.Cfg.GitLabSkipOrgRoleSync,
|
||||
"AzureADSkipOrgRoleSync": hs.Cfg.AzureADSkipOrgRoleSync,
|
||||
"OktaSkipOrgRoleSync": hs.Cfg.OktaSkipOrgRoleSync,
|
||||
"DisableSyncLock": hs.Cfg.DisableSyncLock,
|
||||
frontendSettings := &dtos.FrontendSettingsDTO{
|
||||
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,
|
||||
JwtHeaderName: hs.Cfg.JWTAuthHeaderName,
|
||||
JwtUrlLogin: hs.Cfg.JWTAuthURLLogin,
|
||||
AlertingErrorOrTimeout: setting.AlertingErrorOrTimeout,
|
||||
AlertingNoDataOrNullValues: setting.AlertingNoDataOrNullValues,
|
||||
AlertingMinInterval: setting.AlertingMinInterval,
|
||||
LiveEnabled: hs.Cfg.LiveMaxConnections != 0,
|
||||
AutoAssignOrg: setting.AutoAssignOrg,
|
||||
VerifyEmailEnabled: setting.VerifyEmailEnabled,
|
||||
SigV4AuthEnabled: setting.SigV4AuthEnabled,
|
||||
AzureAuthEnabled: setting.AzureAuthEnabled,
|
||||
RbacEnabled: hs.Cfg.RBACEnabled,
|
||||
ExploreEnabled: setting.ExploreEnabled,
|
||||
HelpEnabled: setting.HelpEnabled,
|
||||
ProfileEnabled: setting.ProfileEnabled,
|
||||
QueryHistoryEnabled: hs.Cfg.QueryHistoryEnabled,
|
||||
GoogleAnalyticsId: setting.GoogleAnalyticsId,
|
||||
GoogleAnalytics4Id: setting.GoogleAnalytics4Id,
|
||||
GoogleAnalytics4SendManualPageViews: setting.GoogleAnalytics4SendManualPageViews,
|
||||
RudderstackWriteKey: setting.RudderstackWriteKey,
|
||||
RudderstackDataPlaneUrl: setting.RudderstackDataPlaneUrl,
|
||||
RudderstackSdkUrl: setting.RudderstackSdkUrl,
|
||||
RudderstackConfigUrl: setting.RudderstackConfigUrl,
|
||||
FeedbackLinksEnabled: hs.Cfg.FeedbackLinksEnabled,
|
||||
ApplicationInsightsConnectionString: hs.Cfg.ApplicationInsightsConnectionString,
|
||||
ApplicationInsightsEndpointUrl: hs.Cfg.ApplicationInsightsEndpointUrl,
|
||||
DisableLoginForm: setting.DisableLoginForm,
|
||||
DisableUserSignUp: !setting.AllowUserSignUp,
|
||||
LoginHint: setting.LoginHint,
|
||||
PasswordHint: setting.PasswordHint,
|
||||
ExternalUserMngInfo: setting.ExternalUserMngInfo,
|
||||
ExternalUserMngLinkUrl: setting.ExternalUserMngLinkUrl,
|
||||
ExternalUserMngLinkName: setting.ExternalUserMngLinkName,
|
||||
ViewersCanEdit: setting.ViewersCanEdit,
|
||||
AngularSupportEnabled: hs.Cfg.AngularSupportEnabled,
|
||||
EditorsCanAdmin: hs.Cfg.EditorsCanAdmin,
|
||||
DisableSanitizeHtml: hs.Cfg.DisableSanitizeHtml,
|
||||
PluginsToPreload: pluginsToPreload,
|
||||
DateFormats: hs.Cfg.DateFormats,
|
||||
|
||||
Auth: dtos.FrontendSettingsAuthDTO{
|
||||
OAuthSkipOrgRoleUpdateSync: hs.Cfg.OAuthSkipOrgRoleUpdateSync,
|
||||
SAMLSkipOrgRoleSync: hs.Cfg.SectionWithEnvOverrides("auth.saml").Key("skip_org_role_sync").MustBool(false),
|
||||
LDAPSkipOrgRoleSync: hs.Cfg.LDAPSkipOrgRoleSync,
|
||||
GoogleSkipOrgRoleSync: hs.Cfg.GoogleSkipOrgRoleSync,
|
||||
JWTAuthSkipOrgRoleSync: hs.Cfg.JWTAuthSkipOrgRoleSync,
|
||||
GrafanaComSkipOrgRoleSync: hs.Cfg.GrafanaComSkipOrgRoleSync,
|
||||
AzureADSkipOrgRoleSync: hs.Cfg.AzureADSkipOrgRoleSync,
|
||||
GithubSkipOrgRoleSync: hs.Cfg.GithubSkipOrgRoleSync,
|
||||
GitLabSkipOrgRoleSync: hs.Cfg.GitLabSkipOrgRoleSync,
|
||||
OktaSkipOrgRoleSync: hs.Cfg.OktaSkipOrgRoleSync,
|
||||
DisableSyncLock: hs.Cfg.DisableSyncLock,
|
||||
},
|
||||
"buildInfo": map[string]interface{}{
|
||||
"hideVersion": hideVersion,
|
||||
"version": version,
|
||||
"commit": commit,
|
||||
"buildstamp": buildstamp,
|
||||
"edition": hs.License.Edition(),
|
||||
"latestVersion": hs.grafanaUpdateChecker.LatestVersion(),
|
||||
"hasUpdate": hs.grafanaUpdateChecker.UpdateAvailable(),
|
||||
"env": setting.Env,
|
||||
|
||||
BuildInfo: dtos.FrontendSettingsBuildInfoDTO{
|
||||
HideVersion: hideVersion,
|
||||
Version: version,
|
||||
Commit: commit,
|
||||
Buildstamp: buildstamp,
|
||||
Edition: hs.License.Edition(),
|
||||
LatestVersion: hs.grafanaUpdateChecker.LatestVersion(),
|
||||
HasUpdate: hs.grafanaUpdateChecker.UpdateAvailable(),
|
||||
Env: setting.Env,
|
||||
},
|
||||
"licenseInfo": map[string]interface{}{
|
||||
"expiry": hs.License.Expiry(),
|
||||
"stateInfo": hs.License.StateInfo(),
|
||||
"licenseUrl": hs.License.LicenseURL(hasAccess(accesscontrol.ReqGrafanaAdmin, licensing.PageAccess)),
|
||||
"edition": hs.License.Edition(),
|
||||
"enabledFeatures": hs.License.EnabledFeatures(),
|
||||
|
||||
LicenseInfo: dtos.FrontendSettingsLicenseInfoDTO{
|
||||
Expiry: hs.License.Expiry(),
|
||||
StateInfo: hs.License.StateInfo(),
|
||||
LicenseUrl: hs.License.LicenseURL(hasAccess(accesscontrol.ReqGrafanaAdmin, licensing.PageAccess)),
|
||||
Edition: hs.License.Edition(),
|
||||
EnabledFeatures: hs.License.EnabledFeatures(),
|
||||
},
|
||||
"featureToggles": hs.Features.GetEnabled(c.Req.Context()),
|
||||
"rendererAvailable": hs.RenderService.IsAvailable(c.Req.Context()),
|
||||
"rendererVersion": hs.RenderService.Version(),
|
||||
"secretsManagerPluginEnabled": secretsManagerPluginEnabled,
|
||||
"http2Enabled": hs.Cfg.Protocol == setting.HTTP2Scheme,
|
||||
"sentry": hs.Cfg.Sentry,
|
||||
"grafanaJavascriptAgent": hs.Cfg.GrafanaJavascriptAgent,
|
||||
"pluginCatalogURL": hs.Cfg.PluginCatalogURL,
|
||||
"pluginAdminEnabled": hs.Cfg.PluginAdminEnabled,
|
||||
"pluginAdminExternalManageEnabled": hs.Cfg.PluginAdminEnabled && hs.Cfg.PluginAdminExternalManageEnabled,
|
||||
"pluginCatalogHiddenPlugins": hs.Cfg.PluginCatalogHiddenPlugins,
|
||||
"expressionsEnabled": hs.Cfg.ExpressionsEnabled,
|
||||
"awsAllowedAuthProviders": hs.Cfg.AWSAllowedAuthProviders,
|
||||
"awsAssumeRoleEnabled": hs.Cfg.AWSAssumeRoleEnabled,
|
||||
"supportBundlesEnabled": isSupportBundlesEnabled(hs),
|
||||
"azure": map[string]interface{}{
|
||||
"cloud": hs.Cfg.Azure.Cloud,
|
||||
"managedIdentityEnabled": hs.Cfg.Azure.ManagedIdentityEnabled,
|
||||
|
||||
FeatureToggles: hs.Features.GetEnabled(c.Req.Context()),
|
||||
RendererAvailable: hs.RenderService.IsAvailable(c.Req.Context()),
|
||||
RendererVersion: hs.RenderService.Version(),
|
||||
SecretsManagerPluginEnabled: secretsManagerPluginEnabled,
|
||||
Http2Enabled: hs.Cfg.Protocol == setting.HTTP2Scheme,
|
||||
Sentry: hs.Cfg.Sentry,
|
||||
GrafanaJavascriptAgent: hs.Cfg.GrafanaJavascriptAgent,
|
||||
PluginCatalogURL: hs.Cfg.PluginCatalogURL,
|
||||
PluginAdminEnabled: hs.Cfg.PluginAdminEnabled,
|
||||
PluginAdminExternalManageEnabled: hs.Cfg.PluginAdminEnabled && hs.Cfg.PluginAdminExternalManageEnabled,
|
||||
PluginCatalogHiddenPlugins: hs.Cfg.PluginCatalogHiddenPlugins,
|
||||
ExpressionsEnabled: hs.Cfg.ExpressionsEnabled,
|
||||
AwsAllowedAuthProviders: hs.Cfg.AWSAllowedAuthProviders,
|
||||
AwsAssumeRoleEnabled: hs.Cfg.AWSAssumeRoleEnabled,
|
||||
SupportBundlesEnabled: isSupportBundlesEnabled(hs),
|
||||
|
||||
Azure: dtos.FrontendSettingsAzureDTO{
|
||||
Cloud: hs.Cfg.Azure.Cloud,
|
||||
ManagedIdentityEnabled: hs.Cfg.Azure.ManagedIdentityEnabled,
|
||||
},
|
||||
"caching": map[string]bool{
|
||||
"enabled": hs.Cfg.SectionWithEnvOverrides("caching").Key("enabled").MustBool(true),
|
||||
|
||||
Caching: dtos.FrontendSettingsCachingDTO{
|
||||
Enabled: hs.Cfg.SectionWithEnvOverrides("caching").Key("enabled").MustBool(true),
|
||||
},
|
||||
"recordedQueries": map[string]bool{
|
||||
"enabled": hs.Cfg.SectionWithEnvOverrides("recorded_queries").Key("enabled").MustBool(true),
|
||||
RecordedQueries: dtos.FrontendSettingsRecordedQueriesDTO{
|
||||
Enabled: hs.Cfg.SectionWithEnvOverrides("recorded_queries").Key("enabled").MustBool(true),
|
||||
},
|
||||
"reporting": map[string]bool{
|
||||
"enabled": hs.Cfg.SectionWithEnvOverrides("reporting").Key("enabled").MustBool(true),
|
||||
Reporting: dtos.FrontendSettingsReportingDTO{
|
||||
Enabled: hs.Cfg.SectionWithEnvOverrides("reporting").Key("enabled").MustBool(true),
|
||||
},
|
||||
"unifiedAlertingEnabled": hs.Cfg.UnifiedAlerting.Enabled,
|
||||
"unifiedAlerting": map[string]interface{}{
|
||||
"minInterval": hs.Cfg.UnifiedAlerting.MinInterval.String(),
|
||||
|
||||
UnifiedAlerting: dtos.FrontendSettingsUnifiedAlertingDTO{
|
||||
MinInterval: hs.Cfg.UnifiedAlerting.MinInterval.String(),
|
||||
},
|
||||
"oauth": hs.getEnabledOAuthProviders(),
|
||||
"samlEnabled": hs.samlEnabled(),
|
||||
"samlName": hs.samlName(),
|
||||
"tokenExpirationDayLimit": hs.Cfg.SATokenExpirationDayLimit,
|
||||
"snapshotEnabled": hs.Cfg.SnapshotEnabled,
|
||||
|
||||
Oauth: hs.getEnabledOAuthProviders(),
|
||||
SamlEnabled: hs.samlEnabled(),
|
||||
SamlName: hs.samlName(),
|
||||
TokenExpirationDayLimit: hs.Cfg.SATokenExpirationDayLimit,
|
||||
|
||||
SnapshotEnabled: hs.Cfg.SnapshotEnabled,
|
||||
}
|
||||
|
||||
if hs.Cfg.UnifiedAlerting.Enabled != nil {
|
||||
frontendSettings.UnifiedAlertingEnabled = *hs.Cfg.UnifiedAlerting.Enabled
|
||||
}
|
||||
|
||||
if setting.AlertingEnabled != nil {
|
||||
frontendSettings.AlertingEnabled = *setting.AlertingEnabled
|
||||
}
|
||||
|
||||
if hs.pluginsCDNService != nil && hs.pluginsCDNService.IsEnabled() {
|
||||
@ -219,21 +236,22 @@ func (hs *HTTPServer) getFrontendSettingsMap(c *contextmodel.ReqContext) (map[st
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("plugins cdn base url: %w", err)
|
||||
}
|
||||
jsonObj["pluginsCDNBaseURL"] = cdnBaseURL
|
||||
frontendSettings.PluginsCDNBaseURL = cdnBaseURL
|
||||
}
|
||||
|
||||
if hs.ThumbService != nil {
|
||||
jsonObj["dashboardPreviews"] = hs.ThumbService.GetDashboardPreviewsSetupSettings(c)
|
||||
frontendSettings.DashboardPreviews = hs.ThumbService.GetDashboardPreviewsSetupSettings(c)
|
||||
}
|
||||
|
||||
if hs.Cfg.GeomapDefaultBaseLayerConfig != nil {
|
||||
jsonObj["geomapDefaultBaseLayerConfig"] = hs.Cfg.GeomapDefaultBaseLayerConfig
|
||||
}
|
||||
if !hs.Cfg.GeomapEnableCustomBaseLayers {
|
||||
jsonObj["geomapDisableCustomBaseLayer"] = true
|
||||
frontendSettings.GeomapDefaultBaseLayerConfig = &hs.Cfg.GeomapDefaultBaseLayerConfig
|
||||
}
|
||||
|
||||
return jsonObj, nil
|
||||
if !hs.Cfg.GeomapEnableCustomBaseLayers {
|
||||
frontendSettings.GeomapDisableCustomBaseLayer = true
|
||||
}
|
||||
|
||||
return frontendSettings, nil
|
||||
}
|
||||
|
||||
func isSupportBundlesEnabled(hs *HTTPServer) bool {
|
||||
|
@ -35,12 +35,12 @@ func (hs *HTTPServer) setIndexViewData(c *contextmodel.ReqContext) (*dtos.IndexV
|
||||
hasAccess := ac.HasAccess(hs.AccessControl, c)
|
||||
hasEditPerm := hasAccess(hs.editorInAnyFolder, ac.EvalAny(ac.EvalPermission(dashboards.ActionDashboardsCreate), ac.EvalPermission(dashboards.ActionFoldersCreate)))
|
||||
|
||||
settings, err := hs.getFrontendSettingsMap(c)
|
||||
settings, err := hs.getFrontendSettings(c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
settings["dateFormats"] = hs.Cfg.DateFormats
|
||||
settings.IsPublicDashboardView = c.IsPublicDashboardView
|
||||
|
||||
prefsQuery := pref.GetPreferenceWithDefaultsQuery{UserID: c.UserID, OrgID: c.OrgID, Teams: c.Teams}
|
||||
prefs, err := hs.preferenceService.GetWithDefaults(c.Req.Context(), &prefsQuery)
|
||||
@ -70,7 +70,7 @@ func (hs *HTTPServer) setIndexViewData(c *contextmodel.ReqContext) (*dtos.IndexV
|
||||
if c.IsRenderCall && !hs.Cfg.ServeFromSubPath {
|
||||
appURL = fmt.Sprintf("%s://localhost:%s", hs.Cfg.Protocol, hs.Cfg.HTTPPort)
|
||||
appSubURL = ""
|
||||
settings["appSubUrl"] = ""
|
||||
settings.AppSubUrl = ""
|
||||
}
|
||||
|
||||
navTree, err := hs.navTreeService.GetNavTree(c, hasEditPerm, prefs)
|
||||
@ -78,10 +78,6 @@ func (hs *HTTPServer) setIndexViewData(c *contextmodel.ReqContext) (*dtos.IndexV
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if c.IsPublicDashboardView {
|
||||
settings["isPublicDashboardView"] = true
|
||||
}
|
||||
|
||||
weekStart := ""
|
||||
if prefs.WeekStart != nil {
|
||||
weekStart = *prefs.WeekStart
|
||||
|
@ -100,7 +100,7 @@ func (hs *HTTPServer) LoginView(c *contextmodel.ReqContext) {
|
||||
// and the view should return immediately before attempting
|
||||
// to login again via OAuth and enter to a redirect loop
|
||||
cookies.DeleteCookie(c.Resp, loginErrorCookieName, hs.CookieOptionsFromCfg)
|
||||
viewData.Settings["loginError"] = loginError
|
||||
viewData.Settings.LoginError = loginError
|
||||
c.HTML(http.StatusOK, getViewIndex(), viewData)
|
||||
return
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ func fakeSetIndexViewData(t *testing.T) {
|
||||
setIndexViewData = func(*HTTPServer, *contextmodel.ReqContext) (*dtos.IndexViewData, error) {
|
||||
data := &dtos.IndexViewData{
|
||||
User: &dtos.CurrentUser{},
|
||||
Settings: map[string]interface{}{},
|
||||
Settings: &dtos.FrontendSettingsDTO{},
|
||||
NavTree: &navtree.NavTreeRoot{},
|
||||
}
|
||||
return data, nil
|
||||
|
@ -167,7 +167,7 @@ func TestMiddlewareContext(t *testing.T) {
|
||||
t.Log("Handler called")
|
||||
data := &dtos.IndexViewData{
|
||||
User: &dtos.CurrentUser{},
|
||||
Settings: map[string]interface{}{},
|
||||
Settings: &dtos.FrontendSettingsDTO{},
|
||||
NavTree: &navtree.NavTreeRoot{},
|
||||
}
|
||||
t.Log("Calling HTML", "data", data)
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/grafana/grafana/pkg/api/dtos"
|
||||
"github.com/grafana/grafana/pkg/api/response"
|
||||
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
|
||||
)
|
||||
@ -31,9 +32,9 @@ func (ds *dummyService) Enabled() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (ds *dummyService) GetDashboardPreviewsSetupSettings(c *contextmodel.ReqContext) dashboardPreviewsSetupConfig {
|
||||
return dashboardPreviewsSetupConfig{
|
||||
SystemRequirements: dashboardPreviewsSystemRequirements{
|
||||
func (ds *dummyService) GetDashboardPreviewsSetupSettings(c *contextmodel.ReqContext) dtos.DashboardPreviewsSetupConfig {
|
||||
return dtos.DashboardPreviewsSetupConfig{
|
||||
SystemRequirements: dtos.DashboardPreviewsSystemRequirements{
|
||||
Met: false,
|
||||
RequiredImageRendererPluginVersion: "",
|
||||
},
|
||||
|
@ -55,16 +55,6 @@ type crawlStatus struct {
|
||||
Last time.Time `json:"last,omitempty"`
|
||||
}
|
||||
|
||||
type dashboardPreviewsSystemRequirements struct {
|
||||
Met bool `json:"met"`
|
||||
RequiredImageRendererPluginVersion string `json:"requiredImageRendererPluginVersion"`
|
||||
}
|
||||
|
||||
type dashboardPreviewsSetupConfig struct {
|
||||
SystemRequirements dashboardPreviewsSystemRequirements `json:"systemRequirements"`
|
||||
ThumbnailsExist bool `json:"thumbnailsExist"`
|
||||
}
|
||||
|
||||
type ThumbnailKind string
|
||||
type ThumbnailState string
|
||||
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
|
||||
"github.com/segmentio/encoding/json"
|
||||
|
||||
"github.com/grafana/grafana/pkg/api/dtos"
|
||||
"github.com/grafana/grafana/pkg/api/response"
|
||||
"github.com/grafana/grafana/pkg/infra/db"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
@ -34,7 +35,7 @@ type Service interface {
|
||||
Run(ctx context.Context) error
|
||||
Enabled() bool
|
||||
GetImage(c *contextmodel.ReqContext)
|
||||
GetDashboardPreviewsSetupSettings(c *contextmodel.ReqContext) dashboardPreviewsSetupConfig
|
||||
GetDashboardPreviewsSetupSettings(c *contextmodel.ReqContext) dtos.DashboardPreviewsSetupConfig
|
||||
|
||||
// from dashboard page
|
||||
SetImage(c *contextmodel.ReqContext) // form post
|
||||
@ -319,44 +320,44 @@ func (hs *thumbService) hasAccessToPreview(c *contextmodel.ReqContext, res *Dash
|
||||
return true
|
||||
}
|
||||
|
||||
func (hs *thumbService) GetDashboardPreviewsSetupSettings(c *contextmodel.ReqContext) dashboardPreviewsSetupConfig {
|
||||
func (hs *thumbService) GetDashboardPreviewsSetupSettings(c *contextmodel.ReqContext) dtos.DashboardPreviewsSetupConfig {
|
||||
return hs.getDashboardPreviewsSetupSettings(c.Req.Context())
|
||||
}
|
||||
|
||||
func (hs *thumbService) getDashboardPreviewsSetupSettings(ctx context.Context) dashboardPreviewsSetupConfig {
|
||||
func (hs *thumbService) getDashboardPreviewsSetupSettings(ctx context.Context) dtos.DashboardPreviewsSetupConfig {
|
||||
systemRequirements := hs.getSystemRequirements(ctx)
|
||||
thumbnailsExist, err := hs.thumbnailRepo.doThumbnailsExist(ctx)
|
||||
|
||||
if err != nil {
|
||||
return dashboardPreviewsSetupConfig{
|
||||
return dtos.DashboardPreviewsSetupConfig{
|
||||
SystemRequirements: systemRequirements,
|
||||
ThumbnailsExist: false,
|
||||
}
|
||||
}
|
||||
|
||||
return dashboardPreviewsSetupConfig{
|
||||
return dtos.DashboardPreviewsSetupConfig{
|
||||
SystemRequirements: systemRequirements,
|
||||
ThumbnailsExist: thumbnailsExist,
|
||||
}
|
||||
}
|
||||
|
||||
func (hs *thumbService) getSystemRequirements(ctx context.Context) dashboardPreviewsSystemRequirements {
|
||||
func (hs *thumbService) getSystemRequirements(ctx context.Context) dtos.DashboardPreviewsSystemRequirements {
|
||||
res, err := hs.renderingService.HasCapability(ctx, rendering.ScalingDownImages)
|
||||
if err != nil {
|
||||
hs.log.Error("Error when verifying dashboard previews system requirements thumbnail", "err", err.Error())
|
||||
return dashboardPreviewsSystemRequirements{
|
||||
return dtos.DashboardPreviewsSystemRequirements{
|
||||
Met: false,
|
||||
}
|
||||
}
|
||||
|
||||
if !res.IsSupported {
|
||||
return dashboardPreviewsSystemRequirements{
|
||||
return dtos.DashboardPreviewsSystemRequirements{
|
||||
Met: false,
|
||||
RequiredImageRendererPluginVersion: res.SemverConstraint,
|
||||
}
|
||||
}
|
||||
|
||||
return dashboardPreviewsSystemRequirements{
|
||||
return dtos.DashboardPreviewsSystemRequirements{
|
||||
Met: true,
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user