mirror of
https://github.com/grafana/grafana.git
synced 2024-11-21 16:38:03 -06:00
Plugins: Add forward_host_env_vars setting (#79333)
* Plugins: Add forward_host_env_vars_plugins setting * Renamed forward_host_env_vars_plugins to forward_host_env_vars * Add readPluginIDsList * refactoring * lint * Use util.SplitString
This commit is contained in:
parent
106903b549
commit
0d1d437c86
@ -1535,6 +1535,8 @@ disable_plugins =
|
||||
install_token =
|
||||
# Comma separated list of plugin ids for which angular deprecation UI should be disabled
|
||||
hide_angular_deprecation =
|
||||
# Comma separated list of plugin ids for which environment variables should be forwarded. Used only when feature flag pluginsSkipHostEnvVars is enabled.
|
||||
forward_host_env_vars =
|
||||
|
||||
#################################### Grafana Live ##########################################
|
||||
[live]
|
||||
|
@ -18,6 +18,7 @@ type Cfg struct {
|
||||
PluginSettings setting.PluginSettings
|
||||
PluginsAllowUnsigned []string
|
||||
DisablePlugins []string
|
||||
ForwardHostEnvVars []string
|
||||
|
||||
// AWS Plugin Auth
|
||||
AWSAllowedAuthProviders []string
|
||||
@ -52,7 +53,7 @@ type Cfg struct {
|
||||
func NewCfg(devMode bool, pluginsPath string, pluginSettings setting.PluginSettings, pluginsAllowUnsigned []string,
|
||||
awsAllowedAuthProviders []string, awsAssumeRoleEnabled bool, awsExternalId string, azure *azsettings.AzureSettings, secureSocksDSProxy setting.SecureSocksDSProxySettings,
|
||||
grafanaVersion string, logDatasourceRequests bool, pluginsCDNURLTemplate string, appURL string, appSubURL string, tracing Tracing, features plugins.FeatureToggles, angularSupportEnabled bool,
|
||||
grafanaComURL string, disablePlugins []string, hideAngularDeprecation []string) *Cfg {
|
||||
grafanaComURL string, disablePlugins []string, hideAngularDeprecation []string, forwardHostEnvVars []string) *Cfg {
|
||||
return &Cfg{
|
||||
log: log.New("plugin.cfg"),
|
||||
PluginsPath: pluginsPath,
|
||||
@ -75,5 +76,6 @@ func NewCfg(devMode bool, pluginsPath string, pluginSettings setting.PluginSetti
|
||||
Features: features,
|
||||
AngularSupportEnabled: angularSupportEnabled,
|
||||
HideAngularDeprecation: hideAngularDeprecation,
|
||||
ForwardHostEnvVars: forwardHostEnvVars,
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package bootstrap
|
||||
import (
|
||||
"context"
|
||||
"path"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/slugify"
|
||||
@ -157,12 +158,12 @@ func configureAppChildPlugin(cfg *config.Cfg, parent *plugins.Plugin, child *plu
|
||||
}
|
||||
|
||||
// SkipHostEnvVarsDecorateFunc returns a DecorateFunc that configures the SkipHostEnvVars field of the plugin.
|
||||
// It will be set to true if the FlagPluginsSkipHostEnvVars feature flag is set, and the plugin does not have
|
||||
// forward_host_env_vars = true in its plugin settings.
|
||||
// It will be set to true if the FlagPluginsSkipHostEnvVars feature flag is set, and the plugin is not present in the
|
||||
// ForwardHostEnvVars plugin ids list.
|
||||
func SkipHostEnvVarsDecorateFunc(cfg *config.Cfg) DecorateFunc {
|
||||
return func(_ context.Context, p *plugins.Plugin) (*plugins.Plugin, error) {
|
||||
p.SkipHostEnvVars = cfg.Features.IsEnabledGlobally(featuremgmt.FlagPluginsSkipHostEnvVars) &&
|
||||
cfg.PluginSettings[p.ID]["forward_host_env_vars"] != "true"
|
||||
!slices.Contains(cfg.ForwardHostEnvVars, p.ID)
|
||||
return p, nil
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,6 @@ import (
|
||||
"github.com/grafana/grafana/pkg/plugins/log"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager/fakes"
|
||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
func TestSetDefaultNavURL(t *testing.T) {
|
||||
@ -172,34 +171,34 @@ func TestSkipEnvVarsDecorateFunc(t *testing.T) {
|
||||
t.Run("plugin setting", func(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
pluginSettings setting.PluginSettings
|
||||
forwardHostEnvVars []string
|
||||
expSkipHostEnvVars bool
|
||||
}{
|
||||
{
|
||||
name: "forward_host_env_vars = false should set SkipHostEnvVars to true",
|
||||
pluginSettings: setting.PluginSettings{pluginID: map[string]string{"forward_host_env_vars": "false"}},
|
||||
name: "plugin id not present in forwardHostEnvVars should set SkipHostEnvVars to true (empty)",
|
||||
forwardHostEnvVars: []string{},
|
||||
expSkipHostEnvVars: true,
|
||||
},
|
||||
{
|
||||
name: "forward_host_env_vars = true should set SkipHostEnvVars to false",
|
||||
pluginSettings: setting.PluginSettings{pluginID: map[string]string{"forward_host_env_vars": "true"}},
|
||||
name: "plugin id not present in forwardHostEnvVars should set SkipHostEnvVars to true (other id)",
|
||||
forwardHostEnvVars: []string{"other-id", "yet-another-id"},
|
||||
expSkipHostEnvVars: true,
|
||||
},
|
||||
{
|
||||
name: "plugin id in forwardHostEnvVars should set SkipHostEnvVars to false (only)",
|
||||
forwardHostEnvVars: []string{pluginID},
|
||||
expSkipHostEnvVars: false,
|
||||
},
|
||||
{
|
||||
name: "invalid forward_host_env_vars should set SkipHostEnvVars to true",
|
||||
pluginSettings: setting.PluginSettings{pluginID: map[string]string{"forward_host_env_vars": "grilled cheese sandwich with bacon"}},
|
||||
expSkipHostEnvVars: true,
|
||||
},
|
||||
{
|
||||
name: "forward_host_env_vars absent should set SkipHostEnvVars to true",
|
||||
pluginSettings: setting.PluginSettings{pluginID: nil},
|
||||
expSkipHostEnvVars: true,
|
||||
name: "plugin id in forwardHostEnvVars should set SkipHostEnvVars to false (with other)",
|
||||
forwardHostEnvVars: []string{"a-plugin", pluginID, "other-id"},
|
||||
expSkipHostEnvVars: false,
|
||||
},
|
||||
} {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
f := SkipHostEnvVarsDecorateFunc(&config.Cfg{
|
||||
Features: featuremgmt.WithFeatures(featuremgmt.FlagPluginsSkipHostEnvVars),
|
||||
PluginSettings: tc.pluginSettings,
|
||||
Features: featuremgmt.WithFeatures(featuremgmt.FlagPluginsSkipHostEnvVars),
|
||||
ForwardHostEnvVars: tc.forwardHostEnvVars,
|
||||
})
|
||||
p, err := f(context.Background(), &plugins.Plugin{JSONData: plugins.JSONData{ID: pluginID}})
|
||||
require.NoError(t, err)
|
||||
|
@ -48,6 +48,7 @@ func ProvideConfig(settingProvider setting.Provider, grafanaCfg *setting.Cfg, fe
|
||||
grafanaCfg.GrafanaComURL,
|
||||
grafanaCfg.DisablePlugins,
|
||||
grafanaCfg.HideAngularDeprecation,
|
||||
grafanaCfg.ForwardHostEnvVars,
|
||||
), nil
|
||||
}
|
||||
|
||||
|
@ -248,6 +248,7 @@ type Cfg struct {
|
||||
DisablePlugins []string
|
||||
HideAngularDeprecation []string
|
||||
PluginInstallToken string
|
||||
ForwardHostEnvVars []string
|
||||
|
||||
PluginsCDNURLTemplate string
|
||||
PluginLogBackendRequests bool
|
||||
|
@ -4,6 +4,8 @@ import (
|
||||
"strings"
|
||||
|
||||
"gopkg.in/ini.v1"
|
||||
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
)
|
||||
|
||||
// PluginSettings maps plugin id to map of key/value settings.
|
||||
@ -33,40 +35,17 @@ func (cfg *Cfg) readPluginSettings(iniFile *ini.File) error {
|
||||
cfg.PluginSkipPublicKeyDownload = pluginsSection.Key("public_key_retrieval_disabled").MustBool(false)
|
||||
cfg.PluginForcePublicKeyDownload = pluginsSection.Key("public_key_retrieval_on_startup").MustBool(false)
|
||||
|
||||
pluginsAllowUnsigned := pluginsSection.Key("allow_loading_unsigned_plugins").MustString("")
|
||||
|
||||
for _, plug := range strings.Split(pluginsAllowUnsigned, ",") {
|
||||
plug = strings.TrimSpace(plug)
|
||||
cfg.PluginsAllowUnsigned = append(cfg.PluginsAllowUnsigned, plug)
|
||||
}
|
||||
|
||||
disablePlugins := pluginsSection.Key("disable_plugins").MustString("")
|
||||
for _, plug := range strings.Split(disablePlugins, ",") {
|
||||
plug = strings.TrimSpace(plug)
|
||||
if plug != "" {
|
||||
cfg.DisablePlugins = append(cfg.DisablePlugins, plug)
|
||||
}
|
||||
}
|
||||
|
||||
hideAngularDeprecation := pluginsSection.Key("hide_angular_deprecation").MustString("")
|
||||
for _, id := range strings.Split(hideAngularDeprecation, ",") {
|
||||
id = strings.TrimSpace(id)
|
||||
if id == "" {
|
||||
continue
|
||||
}
|
||||
cfg.HideAngularDeprecation = append(cfg.HideAngularDeprecation, id)
|
||||
}
|
||||
cfg.PluginsAllowUnsigned = util.SplitString(pluginsSection.Key("allow_loading_unsigned_plugins").MustString(""))
|
||||
cfg.DisablePlugins = util.SplitString(pluginsSection.Key("disable_plugins").MustString(""))
|
||||
cfg.HideAngularDeprecation = util.SplitString(pluginsSection.Key("hide_angular_deprecation").MustString(""))
|
||||
cfg.ForwardHostEnvVars = util.SplitString(pluginsSection.Key("forward_host_env_vars").MustString(""))
|
||||
|
||||
cfg.PluginCatalogURL = pluginsSection.Key("plugin_catalog_url").MustString("https://grafana.com/grafana/plugins/")
|
||||
cfg.PluginAdminEnabled = pluginsSection.Key("plugin_admin_enabled").MustBool(true)
|
||||
cfg.PluginAdminExternalManageEnabled = pluginsSection.Key("plugin_admin_external_manage_enabled").MustBool(false)
|
||||
catalogHiddenPlugins := pluginsSection.Key("plugin_catalog_hidden_plugins").MustString("")
|
||||
cfg.PluginCatalogHiddenPlugins = util.SplitString(pluginsSection.Key("plugin_catalog_hidden_plugins").MustString(""))
|
||||
|
||||
for _, plug := range strings.Split(catalogHiddenPlugins, ",") {
|
||||
plug = strings.TrimSpace(plug)
|
||||
cfg.PluginCatalogHiddenPlugins = append(cfg.PluginCatalogHiddenPlugins, plug)
|
||||
}
|
||||
// Pull disablep plugins from the catalog
|
||||
// Pull disabled plugins from the catalog
|
||||
cfg.PluginCatalogHiddenPlugins = append(cfg.PluginCatalogHiddenPlugins, cfg.DisablePlugins...)
|
||||
|
||||
// Plugins CDN settings
|
||||
|
@ -1,6 +1,7 @@
|
||||
package setting
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
@ -43,23 +44,55 @@ func TestPluginSettings(t *testing.T) {
|
||||
}
|
||||
|
||||
func Test_readPluginSettings(t *testing.T) {
|
||||
t.Run("should parse plugin ids", func(t *testing.T) {
|
||||
cfg := NewCfg()
|
||||
sec, err := cfg.Raw.NewSection("plugins")
|
||||
require.NoError(t, err)
|
||||
_, err = sec.NewKey("disable_plugins", "plugin1,plugin2")
|
||||
require.NoError(t, err)
|
||||
t.Run("should parse separated plugin ids", func(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
f func(ids ...string) string
|
||||
}{
|
||||
{
|
||||
name: "commas",
|
||||
f: func(ids ...string) string {
|
||||
return strings.Join(ids, ",")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "commas and a space",
|
||||
f: func(ids ...string) string {
|
||||
return strings.Join(ids, ", ")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "spaces",
|
||||
f: func(ids ...string) string {
|
||||
return strings.Join(ids, " ")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "json-like",
|
||||
f: func(ids ...string) string {
|
||||
return `["` + strings.Join(ids, `","`) + `"]`
|
||||
},
|
||||
},
|
||||
} {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
cfg := NewCfg()
|
||||
sec, err := cfg.Raw.NewSection("plugins")
|
||||
require.NoError(t, err)
|
||||
_, err = sec.NewKey("disable_plugins", tc.f("plugin1", "plugin2"))
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = sec.NewKey("plugin_catalog_hidden_plugins", "plugin3")
|
||||
require.NoError(t, err)
|
||||
_, err = sec.NewKey("plugin_catalog_hidden_plugins", tc.f("plugin3"))
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = sec.NewKey("hide_angular_deprecation", "a,b,c")
|
||||
require.NoError(t, err)
|
||||
_, err = sec.NewKey("hide_angular_deprecation", tc.f("a", "b", "c"))
|
||||
require.NoError(t, err)
|
||||
|
||||
err = cfg.readPluginSettings(cfg.Raw)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, []string{"plugin1", "plugin2"}, cfg.DisablePlugins)
|
||||
require.Equal(t, []string{"plugin3", "plugin1", "plugin2"}, cfg.PluginCatalogHiddenPlugins)
|
||||
require.Equal(t, []string{"a", "b", "c"}, cfg.HideAngularDeprecation)
|
||||
err = cfg.readPluginSettings(cfg.Raw)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, []string{"plugin1", "plugin2"}, cfg.DisablePlugins)
|
||||
require.Equal(t, []string{"plugin3", "plugin1", "plugin2"}, cfg.PluginCatalogHiddenPlugins)
|
||||
require.Equal(t, []string{"a", "b", "c"}, cfg.HideAngularDeprecation)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user