Propagate plugin execution dir to CreatePlugin (#2183)
* fix: Propagate plugin options to CreatePlugin Plugin options were previously only applied to the BuildPluginMap call, resulting in the plugin execution_dir variable being ineffective. Also add a test to verify functionality * fix: Support plugin execution_dir for all plugins Previously, only external host plugins would respect the plugin execution dir. Now, all uses of the embedded plugins respect the configuration.
This commit is contained in:
1 parent
5ef9496e0a
commit
d06ac0d370
5 files changed
+91
-1
No files matched your search
@@ -25,6 +25,11 @@ Canonical reference for changes, improvements, and bugfixes for Boundary.
|
||||
See Deprecations/Changes for some additional details.
|
||||
[PR](https://github.com/hashicorp/boundary/pull/2160).
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* The plugin execution_dir configuration parameter is now respected.
|
||||
[PR](https://github.com/hashicorp/boundary/pull/2183).
|
||||
|
||||
### Deprecations/Changes
|
||||
|
||||
* Targets: Removes support for `credential libraries` with respect to Target resources.
|
||||
|
||||
@@ -555,6 +555,7 @@ func (b *Server) SetupKMSes(ctx context.Context, ui cli.Ui, config *config.Confi
|
||||
configutil.WithPluginOptions(
|
||||
pluginutil.WithPluginsMap(kms_plugin_assets.BuiltinKmsPlugins()),
|
||||
pluginutil.WithPluginsFilesystem(kms_plugin_assets.KmsPluginPrefix, kms_plugin_assets.FileSystem()),
|
||||
pluginutil.WithPluginExecutionDirectory(config.Plugins.ExecutionDir),
|
||||
),
|
||||
configutil.WithLogger(pluginLogger.Named(kms.Type).With("purpose", purpose)),
|
||||
)
|
||||
|
||||
@@ -2,12 +2,17 @@ package controller
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/hashicorp/boundary/internal/cmd/base"
|
||||
"github.com/hashicorp/boundary/internal/cmd/config"
|
||||
"github.com/hashicorp/boundary/internal/iam"
|
||||
"github.com/hashicorp/boundary/internal/kms"
|
||||
"github.com/hashicorp/boundary/internal/types/scope"
|
||||
host_plugin_assets "github.com/hashicorp/boundary/plugins/host"
|
||||
"github.com/hashicorp/go-secure-stdlib/listenerutil"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
@@ -223,3 +228,39 @@ func TestControllerNewListenerConfig(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestController_NewPluginsConfig(t *testing.T) {
|
||||
require := require.New(t)
|
||||
testCtx := context.Background()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
tc := &TestController{
|
||||
t: t,
|
||||
ctx: ctx,
|
||||
cancel: cancel,
|
||||
opts: nil,
|
||||
}
|
||||
|
||||
initialConfig, err := config.DevController()
|
||||
require.NoError(err)
|
||||
tmpDir := t.TempDir()
|
||||
initialConfig.Plugins.ExecutionDir = tmpDir
|
||||
conf := TestControllerConfig(t, ctx, tc, &TestControllerOpts{Config: initialConfig})
|
||||
conf.EnabledPlugins = []base.EnabledPlugin{
|
||||
base.EnabledPluginHostAws,
|
||||
base.EnabledPluginHostAzure,
|
||||
}
|
||||
|
||||
_, err = New(testCtx, conf)
|
||||
require.NoError(err)
|
||||
|
||||
// Check that both plugins were written to the temp dir
|
||||
files, err := os.ReadDir(tmpDir)
|
||||
require.NoError(err)
|
||||
require.Len(files, 2)
|
||||
var pluginNames []string
|
||||
for _, file := range files {
|
||||
pluginNames = append(pluginNames, filepath.Base(file.Name()))
|
||||
}
|
||||
expectedPluginNames := []string{host_plugin_assets.HostPluginPrefix + "aws.gz", host_plugin_assets.HostPluginPrefix + "azure.gz"}
|
||||
require.Empty(cmp.Diff(expectedPluginNames, pluginNames))
|
||||
}
|
||||
@@ -60,7 +60,7 @@ func CreateHostPlugin(
|
||||
}
|
||||
|
||||
// Create the plugin and cleanup func
|
||||
plugClient, cleanup, err := pluginutil.CreatePlugin(pluginMap[pluginType])
|
||||
plugClient, cleanup, err := pluginutil.CreatePlugin(pluginMap[pluginType], opts.withPluginOptions...)
|
||||
if err != nil {
|
||||
return nil, cleanup, err
|
||||
}
|
||||
|
||||
@@ -3,17 +3,43 @@ package wrapper
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
wrapping "github.com/hashicorp/go-kms-wrapping/v2"
|
||||
configutil "github.com/hashicorp/go-secure-stdlib/configutil/v2"
|
||||
"github.com/hashicorp/go-secure-stdlib/pluginutil/v2"
|
||||
"github.com/hashicorp/go-secure-stdlib/strutil"
|
||||
"github.com/hashicorp/hcl"
|
||||
)
|
||||
|
||||
// pluginsConfig is used to pre-parse any plugins stanza
|
||||
// in the configuration file, so that we can use the correct
|
||||
// configuration when creating the KMS plugin for reading the
|
||||
// rest of the config.
|
||||
type pluginsConfig struct {
|
||||
Plugins struct {
|
||||
ExecutionDir string `hcl:"execution_dir"`
|
||||
} `hcl:"plugins"`
|
||||
}
|
||||
|
||||
func GetWrapperFromPath(ctx context.Context, path, purpose string, opt ...configutil.Option) (wrapping.Wrapper, func() error, error) {
|
||||
kmses, err := configutil.LoadConfigKMSes(path)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("Error parsing config file: %w", err)
|
||||
}
|
||||
hclBytes, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("Error reading config file: %w", err)
|
||||
}
|
||||
pluginsConfig, err := parsePluginsConfig(string(hclBytes))
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("Error parsing plugins stanza in config file: %w", err)
|
||||
}
|
||||
if pluginsConfig.Plugins.ExecutionDir != "" {
|
||||
// Note, this is safe to use because configutil.WithPluginOptions invocations
|
||||
// are additive with each other.
|
||||
opt = append(opt, configutil.WithPluginOptions(pluginutil.WithPluginExecutionDirectory(pluginsConfig.Plugins.ExecutionDir)))
|
||||
}
|
||||
|
||||
return getWrapper(ctx, kmses, purpose, opt...)
|
||||
}
|
||||
@@ -23,6 +49,15 @@ func GetWrapperFromHcl(ctx context.Context, inHcl, purpose string, opt ...config
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("Error parsing KMS HCL: %w", err)
|
||||
}
|
||||
pluginsConfig, err := parsePluginsConfig(inHcl)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("Error parsing plugins stanza in config file: %w", err)
|
||||
}
|
||||
if pluginsConfig.Plugins.ExecutionDir != "" {
|
||||
// Note, this is safe to use because configutil.WithPluginOptions invocations
|
||||
// are additive with each other.
|
||||
opt = append(opt, configutil.WithPluginOptions(pluginutil.WithPluginExecutionDirectory(pluginsConfig.Plugins.ExecutionDir)))
|
||||
}
|
||||
|
||||
return getWrapper(ctx, kmses, purpose, opt...)
|
||||
}
|
||||
@@ -54,3 +89,11 @@ func getWrapper(ctx context.Context, kmses []*configutil.KMS, purpose string, op
|
||||
|
||||
return wrapper, cleanup, nil
|
||||
}
|
||||
|
||||
func parsePluginsConfig(inHcl string) (*pluginsConfig, error) {
|
||||
var conf pluginsConfig
|
||||
if err := hcl.Decode(&conf, inHcl); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &conf, nil
|
||||
}
|
||||
Reference in new issue
Block a user