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:
Josh Hunt
2023-01-31 19:14:15 +00:00
committed by GitHub
parent 178f290f0c
commit 138575cbe9
10 changed files with 383 additions and 150 deletions
+135 -117
View File
@@ -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 {