From 21e64a1f1583b015ce67f3a0fdca6aa0aa34f712 Mon Sep 17 00:00:00 2001 From: Thy Ton Date: Mon, 22 Jan 2024 23:29:32 -0800 Subject: [PATCH 01/15] fix plugin register cli error on unfound oci images --- vault/logical_system.go | 5 +- vault/plugincatalog/plugin_catalog.go | 36 ++++++++----- vault/plugincatalog/plugin_catalog_test.go | 59 +++++++++++++++++----- 3 files changed, 72 insertions(+), 28 deletions(-) diff --git a/vault/logical_system.go b/vault/logical_system.go index 3441911f8c38..6004dde6f481 100644 --- a/vault/logical_system.go +++ b/vault/logical_system.go @@ -590,7 +590,10 @@ func (b *SystemBackend) handlePluginCatalogUpdate(ctx context.Context, _ *logica Sha256: sha256Bytes, }) if err != nil { - if errors.Is(err, plugincatalog.ErrPluginNotFound) || strings.HasPrefix(err.Error(), "plugin version mismatch") { + if errors.Is(err, plugincatalog.ErrPluginNotFound) || + errors.Is(err, plugincatalog.ErrPluginVersionMismatch) || + errors.Is(err, plugincatalog.ErrAllBackendPluginLoadsFailed) || + errors.Is(err, plugincatalog.ErrAllDatabasePluginLoadsFailed) { return logical.ErrorResponse(err.Error()), nil } return nil, err diff --git a/vault/plugincatalog/plugin_catalog.go b/vault/plugincatalog/plugin_catalog.go index 2c39009df7d3..7f80c71fbedd 100644 --- a/vault/plugincatalog/plugin_catalog.go +++ b/vault/plugincatalog/plugin_catalog.go @@ -34,10 +34,13 @@ import ( ) var ( - ErrDirectoryNotConfigured = errors.New("could not set plugin, plugin directory is not configured") - ErrPluginNotFound = errors.New("plugin not found in the catalog") - ErrPluginConnectionNotFound = errors.New("plugin connection not found for client") - ErrPluginBadType = errors.New("unable to determine plugin type") + ErrDirectoryNotConfigured = errors.New("could not set plugin, plugin directory is not configured") + ErrPluginNotFound = errors.New("plugin not found in the catalog") + ErrPluginConnectionNotFound = errors.New("plugin connection not found for client") + ErrPluginBadType = errors.New("unable to determine plugin type") + ErrPluginVersionMismatch = errors.New("plugin version mismatch") + ErrAllBackendPluginLoadsFailed = errors.New("failed to dispense all backend plugins v4 through v5") + ErrAllDatabasePluginLoadsFailed = errors.New("failed to load all database plugins v4 through v5") ) // PluginCatalog keeps a record of plugins known to vault. External plugins need @@ -585,7 +588,7 @@ func (c *PluginCatalog) getBackendRunningVersion(ctx context.Context, pluginRunn } return logical.EmptyPluginVersion, nil } - merr = multierror.Append(merr, fmt.Errorf("failed to dispense plugin as backend v5: %w", err)) + merr = multierror.Append(merr, err) } c.logger.Debug("failed to dispense v5 backend plugin", "name", pluginRunner.Name, "error", err) config.AutoMTLS = false @@ -593,9 +596,9 @@ func (c *PluginCatalog) getBackendRunningVersion(ctx context.Context, pluginRunn // attempt to run as a v4 backend plugin client, err = backendplugin.NewPluginClient(ctx, c.wrapper, pluginRunner, log.NewNullLogger(), true) if err != nil { - merr = multierror.Append(merr, fmt.Errorf("failed to dispense v4 backend plugin: %w", err)) - c.logger.Debug("failed to dispense v4 backend plugin", "name", pluginRunner.Name, "error", merr) - return logical.EmptyPluginVersion, merr.ErrorOrNil() + merr = multierror.Append(merr, err) + c.logger.Debug("failed to dispense v4 backend plugin", "name", pluginRunner.Name, "error", err) + return logical.EmptyPluginVersion, fmt.Errorf("%w: %s", ErrAllBackendPluginLoadsFailed, merr) } c.logger.Debug("successfully dispensed v4 backend plugin", "name", pluginRunner.Name) defer client.Cleanup(ctx) @@ -650,7 +653,7 @@ func (c *PluginCatalog) getDatabaseRunningVersion(ctx context.Context, pluginRun } return logical.EmptyPluginVersion, nil } - merr = multierror.Append(merr, fmt.Errorf("failed to load plugin as database v5: %w", err)) + merr = multierror.Append(merr, err) c.logger.Debug("attempting to load database plugin as v4", "name", pluginRunner.Name) v4Client, err := v4.NewPluginClient(ctx, c.wrapper, pluginRunner, log.NewNullLogger(), true) @@ -669,8 +672,9 @@ func (c *PluginCatalog) getDatabaseRunningVersion(ctx context.Context, pluginRun return logical.EmptyPluginVersion, nil } - merr = multierror.Append(merr, fmt.Errorf("failed to load plugin as database v4: %w", err)) - return logical.EmptyPluginVersion, merr + + merr = multierror.Append(merr, err) + return logical.EmptyPluginVersion, fmt.Errorf("%w: %s", ErrAllDatabasePluginLoadsFailed, merr) } // isDatabasePlugin returns an error if the plugin is not a database plugin. @@ -963,16 +967,20 @@ func (c *PluginCatalog) setInternal(ctx context.Context, plugin pluginutil.SetPl } if versionErr != nil { c.logger.Warn("Error determining plugin version", "error", versionErr) + if errors.Is(versionErr, ErrAllBackendPluginLoadsFailed) || errors.Is(versionErr, ErrAllDatabasePluginLoadsFailed) { + return nil, versionErr + } } else if plugin.Version != "" && runningVersion.Version != "" && plugin.Version != runningVersion.Version { - c.logger.Warn("Plugin self-reported version did not match requested version", "plugin", plugin.Name, "requestedVersion", plugin.Version, "reportedVersion", runningVersion.Version) - return nil, fmt.Errorf("plugin version mismatch: %s reported version (%s) did not match requested version (%s)", plugin.Name, runningVersion.Version, plugin.Version) + c.logger.Warn("Plugin self-reported version did not match requested version", + "plugin", plugin.Name, "requestedVersion", plugin.Version, "reportedVersion", runningVersion.Version) + return nil, fmt.Errorf("%w: %s reported version (%s) did not match requested version (%s)", + ErrPluginVersionMismatch, plugin.Name, runningVersion.Version, plugin.Version) } else if plugin.Version == "" && runningVersion.Version != "" { plugin.Version = runningVersion.Version _, err := semver.NewVersion(plugin.Version) if err != nil { return nil, fmt.Errorf("plugin self-reported version %q is not a valid semantic version: %w", plugin.Version, err) } - } entry := &pluginutil.PluginRunner{ diff --git a/vault/plugincatalog/plugin_catalog_test.go b/vault/plugincatalog/plugin_catalog_test.go index 9704a3742656..705287e05316 100644 --- a/vault/plugincatalog/plugin_catalog_test.go +++ b/vault/plugincatalog/plugin_catalog_test.go @@ -8,6 +8,7 @@ import ( "crypto/sha256" "encoding/hex" "encoding/json" + "errors" "fmt" "io/ioutil" "os" @@ -1007,9 +1008,18 @@ func TestExternalPluginInContainer_GetBackendTypeVersion(t *testing.T) { t.Skip("Running plugins in containers is only supported on linux") } + pluginTypeLoadsFailedErrMap := map[consts.PluginType]error{ + consts.PluginTypeCredential: ErrAllBackendPluginLoadsFailed, + consts.PluginTypeSecrets: ErrAllBackendPluginLoadsFailed, + consts.PluginTypeDatabase: ErrAllBackendPluginLoadsFailed, + } + pluginCatalog := testPluginCatalog(t) + var testCases []struct { + plugin pluginhelpers.TestPlugin + expectedErr error + } - var plugins []pluginhelpers.TestPlugin for _, pluginType := range []consts.PluginType{ consts.PluginTypeCredential, consts.PluginTypeSecrets, @@ -1017,21 +1027,38 @@ func TestExternalPluginInContainer_GetBackendTypeVersion(t *testing.T) { } { plugin := pluginhelpers.CompilePlugin(t, pluginType, "v1.2.3", pluginCatalog.directory) plugin.Image, plugin.ImageSha256 = pluginhelpers.BuildPluginContainerImage(t, plugin, pluginCatalog.directory) - plugins = append(plugins, plugin) + + testCases = append(testCases, + struct { + plugin pluginhelpers.TestPlugin + expectedErr error + }{ + plugin: plugin, + expectedErr: nil, + }) + + plugin.Image += "-will-not-be-found" + testCases = append(testCases, struct { + plugin pluginhelpers.TestPlugin + expectedErr error + }{ + plugin: plugin, + expectedErr: pluginTypeLoadsFailedErrMap[plugin.Typ], + }) } - for _, plugin := range plugins { - t.Run(plugin.Typ.String(), func(t *testing.T) { + for _, tc := range testCases { + t.Run(tc.plugin.Typ.String(), func(t *testing.T) { for _, ociRuntime := range []string{"runc", "runsc"} { t.Run(ociRuntime, func(t *testing.T) { if _, err := exec.LookPath(ociRuntime); err != nil { t.Skipf("Skipping test as %s not found on path", ociRuntime) } - shaBytes, _ := hex.DecodeString(plugin.ImageSha256) + shaBytes, _ := hex.DecodeString(tc.plugin.ImageSha256) entry := &pluginutil.PluginRunner{ - Name: plugin.Name, - OCIImage: plugin.Image, + Name: tc.plugin.Name, + OCIImage: tc.plugin.Image, Args: nil, Sha256: shaBytes, Builtin: false, @@ -1043,16 +1070,22 @@ func TestExternalPluginInContainer_GetBackendTypeVersion(t *testing.T) { var version logical.PluginVersion var err error - if plugin.Typ == consts.PluginTypeDatabase { + if tc.plugin.Typ == consts.PluginTypeDatabase { version, err = pluginCatalog.getDatabaseRunningVersion(context.Background(), entry) } else { version, err = pluginCatalog.getBackendRunningVersion(context.Background(), entry) } - if err != nil { - t.Fatal(err) - } - if version.Version != plugin.Version { - t.Errorf("Expected to get version %v but got %v", plugin.Version, version.Version) + + if tc.expectedErr == nil { + if err != nil { + t.Fatalf("Expected successful get backend type version but got: %v", err) + } + if version.Version != tc.plugin.Version { + t.Errorf("Expected to get version %v but got %v", tc.plugin.Version, version.Version) + } + + } else if !errors.Is(err, tc.expectedErr) { + t.Errorf("Expected to get err %s but got %s", tc.expectedErr, err) } }) } From 16bf7f5d08d2194a53ebfdce1d1dc74cfe075163 Mon Sep 17 00:00:00 2001 From: Thy Ton Date: Mon, 22 Jan 2024 23:58:23 -0800 Subject: [PATCH 02/15] unwrap error before creating logical error response on all plugin loads failed --- vault/logical_system.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/vault/logical_system.go b/vault/logical_system.go index 6004dde6f481..1a3d9bf008d8 100644 --- a/vault/logical_system.go +++ b/vault/logical_system.go @@ -591,11 +591,15 @@ func (b *SystemBackend) handlePluginCatalogUpdate(ctx context.Context, _ *logica }) if err != nil { if errors.Is(err, plugincatalog.ErrPluginNotFound) || - errors.Is(err, plugincatalog.ErrPluginVersionMismatch) || - errors.Is(err, plugincatalog.ErrAllBackendPluginLoadsFailed) || - errors.Is(err, plugincatalog.ErrAllDatabasePluginLoadsFailed) { + errors.Is(err, plugincatalog.ErrPluginVersionMismatch) { return logical.ErrorResponse(err.Error()), nil } + + if errors.Is(err, plugincatalog.ErrAllBackendPluginLoadsFailed) || + errors.Is(err, plugincatalog.ErrAllDatabasePluginLoadsFailed) { + return logical.ErrorResponse(errors.Unwrap(err).Error()), nil + } + return nil, err } From aa2f8412f7699714e0693b3c3d49e5efe1952370 Mon Sep 17 00:00:00 2001 From: Thy Ton Date: Tue, 23 Jan 2024 08:30:01 -0800 Subject: [PATCH 03/15] return all loads failed err when oci image is specified --- vault/logical_system.go | 4 ++-- vault/plugincatalog/plugin_catalog.go | 27 ++++++++++++++-------- vault/plugincatalog/plugin_catalog_test.go | 6 ++--- 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/vault/logical_system.go b/vault/logical_system.go index 1a3d9bf008d8..d38f738322f9 100644 --- a/vault/logical_system.go +++ b/vault/logical_system.go @@ -595,8 +595,8 @@ func (b *SystemBackend) handlePluginCatalogUpdate(ctx context.Context, _ *logica return logical.ErrorResponse(err.Error()), nil } - if errors.Is(err, plugincatalog.ErrAllBackendPluginLoadsFailed) || - errors.Is(err, plugincatalog.ErrAllDatabasePluginLoadsFailed) { + if errors.Is(err, plugincatalog.ErrAllContainerizedBackendPluginLoadsFailed) || + errors.Is(err, plugincatalog.ErrAllContainerizedDatabasePluginLoadsFailed) { return logical.ErrorResponse(errors.Unwrap(err).Error()), nil } diff --git a/vault/plugincatalog/plugin_catalog.go b/vault/plugincatalog/plugin_catalog.go index 7f80c71fbedd..8a7de13020b0 100644 --- a/vault/plugincatalog/plugin_catalog.go +++ b/vault/plugincatalog/plugin_catalog.go @@ -34,13 +34,13 @@ import ( ) var ( - ErrDirectoryNotConfigured = errors.New("could not set plugin, plugin directory is not configured") - ErrPluginNotFound = errors.New("plugin not found in the catalog") - ErrPluginConnectionNotFound = errors.New("plugin connection not found for client") - ErrPluginBadType = errors.New("unable to determine plugin type") - ErrPluginVersionMismatch = errors.New("plugin version mismatch") - ErrAllBackendPluginLoadsFailed = errors.New("failed to dispense all backend plugins v4 through v5") - ErrAllDatabasePluginLoadsFailed = errors.New("failed to load all database plugins v4 through v5") + ErrDirectoryNotConfigured = errors.New("could not set plugin, plugin directory is not configured") + ErrPluginNotFound = errors.New("plugin not found in the catalog") + ErrPluginConnectionNotFound = errors.New("plugin connection not found for client") + ErrPluginBadType = errors.New("unable to determine plugin type") + ErrPluginVersionMismatch = errors.New("plugin version mismatch") + ErrAllContainerizedBackendPluginLoadsFailed = errors.New("failed to dispense all containerized backend plugins v4 through v5") + ErrAllContainerizedDatabasePluginLoadsFailed = errors.New("failed to load all containerized database plugins v4 through v5") ) // PluginCatalog keeps a record of plugins known to vault. External plugins need @@ -598,7 +598,10 @@ func (c *PluginCatalog) getBackendRunningVersion(ctx context.Context, pluginRunn if err != nil { merr = multierror.Append(merr, err) c.logger.Debug("failed to dispense v4 backend plugin", "name", pluginRunner.Name, "error", err) - return logical.EmptyPluginVersion, fmt.Errorf("%w: %s", ErrAllBackendPluginLoadsFailed, merr) + if pluginRunner.OCIImage != "" { + return logical.EmptyPluginVersion, fmt.Errorf("%w: %s", ErrAllContainerizedBackendPluginLoadsFailed, merr) + } + return logical.EmptyPluginVersion, merr.ErrorOrNil() } c.logger.Debug("successfully dispensed v4 backend plugin", "name", pluginRunner.Name) defer client.Cleanup(ctx) @@ -674,7 +677,11 @@ func (c *PluginCatalog) getDatabaseRunningVersion(ctx context.Context, pluginRun } merr = multierror.Append(merr, err) - return logical.EmptyPluginVersion, fmt.Errorf("%w: %s", ErrAllDatabasePluginLoadsFailed, merr) + if pluginRunner.OCIImage != "" { + return logical.EmptyPluginVersion, fmt.Errorf("%w: %s", ErrAllContainerizedDatabasePluginLoadsFailed, merr) + } + + return logical.EmptyPluginVersion, merr.ErrorOrNil() } // isDatabasePlugin returns an error if the plugin is not a database plugin. @@ -967,7 +974,7 @@ func (c *PluginCatalog) setInternal(ctx context.Context, plugin pluginutil.SetPl } if versionErr != nil { c.logger.Warn("Error determining plugin version", "error", versionErr) - if errors.Is(versionErr, ErrAllBackendPluginLoadsFailed) || errors.Is(versionErr, ErrAllDatabasePluginLoadsFailed) { + if errors.Is(versionErr, ErrAllContainerizedBackendPluginLoadsFailed) || errors.Is(versionErr, ErrAllContainerizedDatabasePluginLoadsFailed) { return nil, versionErr } } else if plugin.Version != "" && runningVersion.Version != "" && plugin.Version != runningVersion.Version { diff --git a/vault/plugincatalog/plugin_catalog_test.go b/vault/plugincatalog/plugin_catalog_test.go index 705287e05316..08667532f648 100644 --- a/vault/plugincatalog/plugin_catalog_test.go +++ b/vault/plugincatalog/plugin_catalog_test.go @@ -1009,9 +1009,9 @@ func TestExternalPluginInContainer_GetBackendTypeVersion(t *testing.T) { } pluginTypeLoadsFailedErrMap := map[consts.PluginType]error{ - consts.PluginTypeCredential: ErrAllBackendPluginLoadsFailed, - consts.PluginTypeSecrets: ErrAllBackendPluginLoadsFailed, - consts.PluginTypeDatabase: ErrAllBackendPluginLoadsFailed, + consts.PluginTypeCredential: ErrAllContainerizedBackendPluginLoadsFailed, + consts.PluginTypeSecrets: ErrAllContainerizedBackendPluginLoadsFailed, + consts.PluginTypeDatabase: ErrAllContainerizedBackendPluginLoadsFailed, } pluginCatalog := testPluginCatalog(t) From f2cee44fcd2c7b18dc08d16cb7b7d0976a60d668 Mon Sep 17 00:00:00 2001 From: Thy Ton Date: Tue, 23 Jan 2024 09:54:18 -0800 Subject: [PATCH 04/15] add another t.Run for expected err --- .../pluginhelpers/pluginhelpers.go | 4 +- vault/external_plugin_container_test.go | 10 +- .../plugin/external_plugin_test.go | 24 ++-- vault/plugincatalog/plugin_catalog_test.go | 114 ++++++++++-------- 4 files changed, 86 insertions(+), 66 deletions(-) diff --git a/helper/testhelpers/pluginhelpers/pluginhelpers.go b/helper/testhelpers/pluginhelpers/pluginhelpers.go index 40035fc59f38..4b3be92835a2 100644 --- a/helper/testhelpers/pluginhelpers/pluginhelpers.go +++ b/helper/testhelpers/pluginhelpers/pluginhelpers.go @@ -26,7 +26,7 @@ var ( type TestPlugin struct { Name string - Typ consts.PluginType + Type consts.PluginType Version string FileName string Sha256 string @@ -142,7 +142,7 @@ func CompilePlugin(t testing.T, typ consts.PluginType, pluginVersion string, plu } return TestPlugin{ Name: pluginName, - Typ: typ, + Type: typ, Version: pluginVersion, FileName: path.Base(pluginPath), Sha256: fmt.Sprintf("%x", sha.Sum(nil)), diff --git a/vault/external_plugin_container_test.go b/vault/external_plugin_container_test.go index b77545372c61..75e072a3c516 100644 --- a/vault/external_plugin_container_test.go +++ b/vault/external_plugin_container_test.go @@ -48,7 +48,7 @@ func TestExternalPluginInContainer_MountAndUnmount(t *testing.T) { }) for _, plugin := range plugins { - t.Run(plugin.Typ.String(), func(t *testing.T) { + t.Run(plugin.Type.String(), func(t *testing.T) { t.Run("default runtime", func(t *testing.T) { if _, err := exec.LookPath("runsc"); err != nil { t.Skip("Skipping test as runsc not found on path") @@ -85,13 +85,13 @@ func mountAndUnmountContainerPlugin_WithRuntime(t *testing.T, c *Core, plugin pl if ociRuntime != "" { registerPluginRuntime(t, c.systemBackend, ociRuntime, rootless) } - registerContainerPlugin(t, c.systemBackend, plugin.Name, plugin.Typ.String(), "1.0.0", plugin.ImageSha256, plugin.Image, ociRuntime) + registerContainerPlugin(t, c.systemBackend, plugin.Name, plugin.Type.String(), "1.0.0", plugin.ImageSha256, plugin.Image, ociRuntime) - mountPlugin(t, c.systemBackend, plugin.Name, plugin.Typ, "v1.0.0", "") + mountPlugin(t, c.systemBackend, plugin.Name, plugin.Type, "v1.0.0", "") routeRequest := func(expectMatch bool) { pluginPath := "foo/bar" - if plugin.Typ == consts.PluginTypeCredential { + if plugin.Type == consts.PluginTypeCredential { pluginPath = "auth/foo/bar" } match := c.router.MatchingMount(namespace.RootContext(context.Background()), pluginPath) @@ -104,7 +104,7 @@ func mountAndUnmountContainerPlugin_WithRuntime(t *testing.T, c *Core, plugin pl } routeRequest(true) - unmountPlugin(t, c.systemBackend, plugin.Typ, "foo") + unmountPlugin(t, c.systemBackend, plugin.Type, "foo") routeRequest(false) } diff --git a/vault/external_tests/plugin/external_plugin_test.go b/vault/external_tests/plugin/external_plugin_test.go index 1e78cf0be148..2fe8942cc79d 100644 --- a/vault/external_tests/plugin/external_plugin_test.go +++ b/vault/external_tests/plugin/external_plugin_test.go @@ -131,7 +131,7 @@ func testRegisterAndEnable(t *testing.T, client *api.Client, plugin pluginhelper t.Helper() if err := client.Sys().RegisterPlugin(&api.RegisterPluginInput{ Name: plugin.Name, - Type: api.PluginType(plugin.Typ), + Type: api.PluginType(plugin.Type), Command: plugin.Name, SHA256: plugin.Sha256, Version: plugin.Version, @@ -139,7 +139,7 @@ func testRegisterAndEnable(t *testing.T, client *api.Client, plugin pluginhelper t.Fatal(err) } - switch plugin.Typ { + switch plugin.Type { case consts.PluginTypeSecrets: if err := client.Sys().Mount(plugin.Name, &api.MountInput{ Type: plugin.Name, @@ -304,7 +304,7 @@ func TestExternalPlugin_AuthMethod(t *testing.T) { // Register if err := client.Sys().RegisterPlugin(&api.RegisterPluginInput{ Name: plugin.Name, - Type: api.PluginType(plugin.Typ), + Type: api.PluginType(plugin.Type), Command: plugin.Name, SHA256: plugin.Sha256, Version: plugin.Version, @@ -403,7 +403,7 @@ func TestExternalPlugin_AuthMethod(t *testing.T) { // Deregister if err := client.Sys().DeregisterPlugin(&api.DeregisterPluginInput{ Name: plugin.Name, - Type: api.PluginType(plugin.Typ), + Type: api.PluginType(plugin.Type), Version: plugin.Version, }); err != nil { t.Fatal(err) @@ -478,7 +478,7 @@ func TestExternalPlugin_AuthMethodReload(t *testing.T) { // Deregister if err := client.Sys().DeregisterPlugin(&api.DeregisterPluginInput{ Name: plugin.Name, - Type: api.PluginType(plugin.Typ), + Type: api.PluginType(plugin.Type), Version: plugin.Version, }); err != nil { t.Fatal(err) @@ -498,7 +498,7 @@ func TestExternalPlugin_SecretsEngine(t *testing.T) { // Register if err := client.Sys().RegisterPlugin(&api.RegisterPluginInput{ Name: plugin.Name, - Type: api.PluginType(plugin.Typ), + Type: api.PluginType(plugin.Type), Command: plugin.Name, SHA256: plugin.Sha256, Version: plugin.Version, @@ -558,7 +558,7 @@ func TestExternalPlugin_SecretsEngine(t *testing.T) { // Deregister if err := client.Sys().DeregisterPlugin(&api.DeregisterPluginInput{ Name: plugin.Name, - Type: api.PluginType(plugin.Typ), + Type: api.PluginType(plugin.Type), Version: plugin.Version, }); err != nil { t.Fatal(err) @@ -624,7 +624,7 @@ func TestExternalPlugin_SecretsEngineReload(t *testing.T) { // Deregister if err := client.Sys().DeregisterPlugin(&api.DeregisterPluginInput{ Name: plugin.Name, - Type: api.PluginType(plugin.Typ), + Type: api.PluginType(plugin.Type), Version: plugin.Version, }); err != nil { t.Fatal(err) @@ -760,7 +760,7 @@ func TestExternalPlugin_Database(t *testing.T) { // Deregister if err := client.Sys().DeregisterPlugin(&api.DeregisterPluginInput{ Name: plugin.Name, - Type: api.PluginType(plugin.Typ), + Type: api.PluginType(plugin.Type), Version: plugin.Version, }); err != nil { t.Fatal(err) @@ -848,7 +848,7 @@ func TestExternalPlugin_DatabaseReload(t *testing.T) { // Deregister if err := client.Sys().DeregisterPlugin(&api.DeregisterPluginInput{ Name: plugin.Name, - Type: api.PluginType(plugin.Typ), + Type: api.PluginType(plugin.Type), Version: plugin.Version, }); err != nil { t.Fatal(err) @@ -944,7 +944,7 @@ func TestExternalPlugin_AuditEnabled_ShouldLogPluginMetadata_Auth(t *testing.T) // Deregister if err := client.Sys().DeregisterPlugin(&api.DeregisterPluginInput{ Name: plugin.Name, - Type: api.PluginType(plugin.Typ), + Type: api.PluginType(plugin.Type), Version: plugin.Version, }); err != nil { t.Fatal(err) @@ -1017,7 +1017,7 @@ func TestExternalPlugin_AuditEnabled_ShouldLogPluginMetadata_Secret(t *testing.T // Deregister if err := client.Sys().DeregisterPlugin(&api.DeregisterPluginInput{ Name: plugin.Name, - Type: api.PluginType(plugin.Typ), + Type: api.PluginType(plugin.Type), Version: plugin.Version, }); err != nil { t.Fatal(err) diff --git a/vault/plugincatalog/plugin_catalog_test.go b/vault/plugincatalog/plugin_catalog_test.go index 08667532f648..46f8fabbeea1 100644 --- a/vault/plugincatalog/plugin_catalog_test.go +++ b/vault/plugincatalog/plugin_catalog_test.go @@ -713,7 +713,7 @@ func TestPluginCatalog_ErrDirectoryNotConfigured(t *testing.T) { Type: consts.PluginTypeDatabase, OCIImage: image, }) - if err != nil { + if err == nil { t.Fatal(err) } // Check we can get it back ok. @@ -1008,16 +1008,29 @@ func TestExternalPluginInContainer_GetBackendTypeVersion(t *testing.T) { t.Skip("Running plugins in containers is only supported on linux") } - pluginTypeLoadsFailedErrMap := map[consts.PluginType]error{ - consts.PluginTypeCredential: ErrAllContainerizedBackendPluginLoadsFailed, - consts.PluginTypeSecrets: ErrAllContainerizedBackendPluginLoadsFailed, - consts.PluginTypeDatabase: ErrAllContainerizedBackendPluginLoadsFailed, + type expectedErr struct { + err error + name string + } + pluginTypeLoadsFailedErrMap := map[consts.PluginType]expectedErr{ + consts.PluginTypeCredential: { + err: ErrAllContainerizedBackendPluginLoadsFailed, + name: "all containerized backend plugin loads failed", + }, + consts.PluginTypeSecrets: { + err: ErrAllContainerizedBackendPluginLoadsFailed, + name: "all containerized backend plugin loads failed", + }, + consts.PluginTypeDatabase: { + err: ErrAllContainerizedDatabasePluginLoadsFailed, + name: "all containerized database plugin loads failed", + }, } pluginCatalog := testPluginCatalog(t) var testCases []struct { plugin pluginhelpers.TestPlugin - expectedErr error + expectedErr *expectedErr } for _, pluginType := range []consts.PluginType{ @@ -1031,64 +1044,71 @@ func TestExternalPluginInContainer_GetBackendTypeVersion(t *testing.T) { testCases = append(testCases, struct { plugin pluginhelpers.TestPlugin - expectedErr error + expectedErr *expectedErr }{ plugin: plugin, expectedErr: nil, }) plugin.Image += "-will-not-be-found" + err := pluginTypeLoadsFailedErrMap[plugin.Type] testCases = append(testCases, struct { plugin pluginhelpers.TestPlugin - expectedErr error + expectedErr *expectedErr }{ plugin: plugin, - expectedErr: pluginTypeLoadsFailedErrMap[plugin.Typ], + expectedErr: &err, }) } for _, tc := range testCases { - t.Run(tc.plugin.Typ.String(), func(t *testing.T) { - for _, ociRuntime := range []string{"runc", "runsc"} { - t.Run(ociRuntime, func(t *testing.T) { - if _, err := exec.LookPath(ociRuntime); err != nil { - t.Skipf("Skipping test as %s not found on path", ociRuntime) - } - - shaBytes, _ := hex.DecodeString(tc.plugin.ImageSha256) - entry := &pluginutil.PluginRunner{ - Name: tc.plugin.Name, - OCIImage: tc.plugin.Image, - Args: nil, - Sha256: shaBytes, - Builtin: false, - Runtime: ociRuntime, - RuntimeConfig: &pluginruntimeutil.PluginRuntimeConfig{ - OCIRuntime: ociRuntime, - }, - } - - var version logical.PluginVersion - var err error - if tc.plugin.Typ == consts.PluginTypeDatabase { - version, err = pluginCatalog.getDatabaseRunningVersion(context.Background(), entry) - } else { - version, err = pluginCatalog.getBackendRunningVersion(context.Background(), entry) - } - - if tc.expectedErr == nil { - if err != nil { - t.Fatalf("Expected successful get backend type version but got: %v", err) + t.Run(tc.plugin.Type.String(), func(t *testing.T) { + expectedErrTestName := "nil err" + if tc.expectedErr != nil { + expectedErrTestName = tc.expectedErr.name + } + t.Run(expectedErrTestName, func(t *testing.T) { + for _, ociRuntime := range []string{"runc", "runsc"} { + t.Run(ociRuntime, func(t *testing.T) { + if _, err := exec.LookPath(ociRuntime); err != nil { + t.Skipf("Skipping test as %s not found on path", ociRuntime) + } + + shaBytes, _ := hex.DecodeString(tc.plugin.ImageSha256) + entry := &pluginutil.PluginRunner{ + Name: tc.plugin.Name, + OCIImage: tc.plugin.Image, + Args: nil, + Sha256: shaBytes, + Builtin: false, + Runtime: ociRuntime, + RuntimeConfig: &pluginruntimeutil.PluginRuntimeConfig{ + OCIRuntime: ociRuntime, + }, } - if version.Version != tc.plugin.Version { - t.Errorf("Expected to get version %v but got %v", tc.plugin.Version, version.Version) + + var version logical.PluginVersion + var err error + if tc.plugin.Type == consts.PluginTypeDatabase { + version, err = pluginCatalog.getDatabaseRunningVersion(context.Background(), entry) + } else { + version, err = pluginCatalog.getBackendRunningVersion(context.Background(), entry) } - } else if !errors.Is(err, tc.expectedErr) { - t.Errorf("Expected to get err %s but got %s", tc.expectedErr, err) - } - }) - } + if tc.expectedErr == nil { + if err != nil { + t.Fatalf("Expected successful get backend type version but got: %v", err) + } + if version.Version != tc.plugin.Version { + t.Errorf("Expected to get version %v but got %v", tc.plugin.Version, version.Version) + } + + } else if !errors.Is(err, tc.expectedErr.err) { + t.Errorf("Expected to get err %s but got %s", tc.expectedErr.err, err) + } + }) + } + }) }) } } From 501b42bb839e114302ff96940568c42a4f574e75 Mon Sep 17 00:00:00 2001 From: Thy Ton Date: Wed, 31 Jan 2024 16:22:11 -0800 Subject: [PATCH 05/15] fix plugincatalog test failures --- vault/plugincatalog/plugin_catalog_test.go | 23 +++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/vault/plugincatalog/plugin_catalog_test.go b/vault/plugincatalog/plugin_catalog_test.go index 46f8fabbeea1..eb23a6a8268b 100644 --- a/vault/plugincatalog/plugin_catalog_test.go +++ b/vault/plugincatalog/plugin_catalog_test.go @@ -707,13 +707,15 @@ func TestPluginCatalog_ErrDirectoryNotConfigured(t *testing.T) { }, "set container plugin": func(t *testing.T) { // Should never error. - const image = "does-not-exist" + plugin := pluginhelpers.CompilePlugin(t, consts.PluginTypeDatabase, "", tempDir) + plugin.Image, plugin.ImageSha256 = pluginhelpers.BuildPluginContainerImage(t, plugin, tempDir) + err := catalog.Set(context.Background(), pluginutil.SetPluginInput{ Name: "container", Type: consts.PluginTypeDatabase, - OCIImage: image, + OCIImage: plugin.Image, }) - if err == nil { + if err != nil { t.Fatal(err) } // Check we can get it back ok. @@ -721,8 +723,8 @@ func TestPluginCatalog_ErrDirectoryNotConfigured(t *testing.T) { if err != nil { t.Fatal(err) } - if p.OCIImage != image { - t.Fatalf("Expected %s, got %s", image, p.OCIImage) + if p.OCIImage != plugin.Image { + t.Fatalf("Expected %s, got %s", plugin.Image, p.OCIImage) } // Make sure we can still get builtins too _, err = catalog.Get(context.Background(), "mysql-database-plugin", consts.PluginTypeDatabase, "") @@ -752,19 +754,22 @@ func TestPluginCatalog_ErrDirectoryNotConfigured(t *testing.T) { // specified. func TestRuntimeConfigPopulatedIfSpecified(t *testing.T) { pluginCatalog := testPluginCatalog(t) - const image = "does-not-exist" + + plugin := pluginhelpers.CompilePlugin(t, consts.PluginTypeDatabase, "", pluginCatalog.directory) + plugin.Image, plugin.ImageSha256 = pluginhelpers.BuildPluginContainerImage(t, plugin, pluginCatalog.directory) + const runtime = "custom-runtime" err := pluginCatalog.Set(context.Background(), pluginutil.SetPluginInput{ Name: "container", Type: consts.PluginTypeDatabase, - OCIImage: image, + OCIImage: plugin.Image, Runtime: runtime, }) if err == nil { t.Fatal("specified runtime doesn't exist yet, should have failed") } - const ociRuntime = "some-other-oci-runtime" + const ociRuntime = "runsc" err = pluginCatalog.runtimeCatalog.Set(context.Background(), &pluginruntimeutil.PluginRuntimeConfig{ Name: runtime, Type: consts.PluginRuntimeTypeContainer, @@ -778,7 +783,7 @@ func TestRuntimeConfigPopulatedIfSpecified(t *testing.T) { err = pluginCatalog.Set(context.Background(), pluginutil.SetPluginInput{ Name: "container", Type: consts.PluginTypeDatabase, - OCIImage: image, + OCIImage: plugin.Image, Runtime: runtime, }) if err != nil { From d69e5bbad05278fd2fbc4ce970b802e6fc9d86ac Mon Sep 17 00:00:00 2001 From: Thy Ton Date: Wed, 31 Jan 2024 17:52:16 -0800 Subject: [PATCH 06/15] make fmt --- vault/external_tests/plugin/external_plugin_test.go | 1 - vault/plugincatalog/plugin_catalog.go | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/vault/external_tests/plugin/external_plugin_test.go b/vault/external_tests/plugin/external_plugin_test.go index d3a03fa78222..08d263911ae4 100644 --- a/vault/external_tests/plugin/external_plugin_test.go +++ b/vault/external_tests/plugin/external_plugin_test.go @@ -483,7 +483,6 @@ func TestExternalPlugin_SecretsEngine(t *testing.T) { // Register testRegisterVersion(t, client, plugin, plugin.Version) - // define a group of parallel tests so we wait for their execution before // continuing on to cleanup // see: https://go.dev/blog/subtests diff --git a/vault/plugincatalog/plugin_catalog.go b/vault/plugincatalog/plugin_catalog.go index 815dfcdd4a64..e6101b052817 100644 --- a/vault/plugincatalog/plugin_catalog.go +++ b/vault/plugincatalog/plugin_catalog.go @@ -38,10 +38,10 @@ var ( ErrPluginNotFound = errors.New("plugin not found in the catalog") ErrPluginConnectionNotFound = errors.New("plugin connection not found for client") ErrPluginBadType = errors.New("unable to determine plugin type") - ErrPinnedVersion = errors.New("cannot delete a pinned version") + ErrPinnedVersion = errors.New("cannot delete a pinned version") ErrPluginVersionMismatch = errors.New("plugin version mismatch") ErrAllContainerizedBackendPluginLoadsFailed = errors.New("failed to dispense all containerized backend plugins v4 through v5") - ErrAllContainerizedDatabasePluginLoadsFailed = errors.New("failed to load all containerized database plugins v4 through v5" + ErrAllContainerizedDatabasePluginLoadsFailed = errors.New("failed to load all containerized database plugins v4 through v5") ) // PluginCatalog keeps a record of plugins known to vault. External plugins need From fde0a3bda5dea6b799bb2e0c7115269707d17ff9 Mon Sep 17 00:00:00 2001 From: Thy Ton Date: Wed, 31 Jan 2024 19:52:06 -0800 Subject: [PATCH 07/15] fix acceptance test TestSystemBackend_PluginCatalog_ContainerCRUD failures --- vault/logical_system_test.go | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/vault/logical_system_test.go b/vault/logical_system_test.go index 03d2a313f158..d953f05311eb 100644 --- a/vault/logical_system_test.go +++ b/vault/logical_system_test.go @@ -31,6 +31,7 @@ import ( "github.com/hashicorp/vault/helper/namespace" "github.com/hashicorp/vault/helper/random" "github.com/hashicorp/vault/helper/testhelpers/corehelpers" + "github.com/hashicorp/vault/helper/testhelpers/pluginhelpers" "github.com/hashicorp/vault/helper/versions" "github.com/hashicorp/vault/internalshared/configutil" "github.com/hashicorp/vault/sdk/framework" @@ -3888,18 +3889,25 @@ func TestSystemBackend_PluginCatalog_ContainerCRUD(t *testing.T) { }) b := c.systemBackend + latestPlugin := pluginhelpers.CompilePlugin(t, consts.PluginTypeDatabase, "", c.pluginDirectory) + latestPlugin.Image, latestPlugin.ImageSha256 = pluginhelpers.BuildPluginContainerImage(t, latestPlugin, c.pluginDirectory) + + const pluginVersion = "v1.0.0" + pluginV100 := pluginhelpers.CompilePlugin(t, consts.PluginTypeDatabase, pluginVersion, c.pluginDirectory) + pluginV100.Image, pluginV100.ImageSha256 = pluginhelpers.BuildPluginContainerImage(t, pluginV100, c.pluginDirectory) + for name, tc := range map[string]struct { in, expected map[string]any }{ "minimal": { in: map[string]any{ - "oci_image": "foo-image", - "sha256": hex.EncodeToString([]byte{'1'}), + "oci_image": latestPlugin.Image, + "sha_256": latestPlugin.ImageSha256, }, expected: map[string]interface{}{ "name": "test-plugin", - "oci_image": "foo-image", - "sha256": "31", + "oci_image": latestPlugin.Image, + "sha256": latestPlugin.ImageSha256, "command": "", "args": []string{}, "builtin": false, @@ -3908,21 +3916,21 @@ func TestSystemBackend_PluginCatalog_ContainerCRUD(t *testing.T) { }, "fully specified": { in: map[string]any{ - "oci_image": "foo-image", - "sha256": hex.EncodeToString([]byte{'1'}), - "command": "foo-command", + "oci_image": pluginV100.Image, + "sha256": pluginV100.ImageSha256, + "command": "plugin", "args": []string{"--a=1"}, - "version": "v1.0.0", + "version": pluginVersion, "env": []string{"X=2"}, }, expected: map[string]interface{}{ "name": "test-plugin", - "oci_image": "foo-image", - "sha256": "31", - "command": "foo-command", + "oci_image": pluginV100.Image, + "sha256": pluginV100.ImageSha256, + "command": "plugin", "args": []string{"--a=1"}, "builtin": false, - "version": "v1.0.0", + "version": pluginVersion, }, }, } { From 30e2259378e534ee87aa80d85b3cf9f338db8b0a Mon Sep 17 00:00:00 2001 From: Thy Ton Date: Wed, 31 Jan 2024 21:06:21 -0800 Subject: [PATCH 08/15] fix TestSystemBackend_pluginRuntime_CannotDeleteRuntimeWithReferencingPlugins acceptance test failures --- vault/logical_system_test.go | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/vault/logical_system_test.go b/vault/logical_system_test.go index d953f05311eb..7b8b10ca46d9 100644 --- a/vault/logical_system_test.go +++ b/vault/logical_system_test.go @@ -6706,24 +6706,24 @@ func TestSystemBackend_pluginRuntime_CannotDeleteRuntimeWithReferencingPlugins(t }) b := c.systemBackend + const runtime = "custom-runtime" + const ociRuntime = "runsc" conf := pluginruntimeutil.PluginRuntimeConfig{ - Name: "foo", - Type: consts.PluginRuntimeTypeContainer, - OCIRuntime: "some-oci-runtime", - CgroupParent: "/cpulimit/", - CPU: 1, - Memory: 10000, + Name: runtime, + Type: consts.PluginRuntimeTypeContainer, + OCIRuntime: ociRuntime, } // Register the plugin runtime req := logical.TestRequest(t, logical.UpdateOperation, fmt.Sprintf("plugins/runtimes/catalog/%s/%s", conf.Type.String(), conf.Name)) req.Data = map[string]interface{}{ - "oci_runtime": conf.OCIRuntime, - "cgroup_parent": conf.CgroupParent, - "cpu_nanos": conf.CPU, - "memory_bytes": conf.Memory, + "oci_runtime": conf.OCIRuntime, } + const pluginVersion = "v1.16.0" + plugin := pluginhelpers.CompilePlugin(t, consts.PluginTypeDatabase, pluginVersion, c.pluginDirectory) + plugin.Image, plugin.ImageSha256 = pluginhelpers.BuildPluginContainerImage(t, plugin, c.pluginDirectory) + resp, err := b.HandleRequest(namespace.RootContext(nil), req) if err != nil { t.Fatalf("err: %v %#v", err, resp) @@ -6734,18 +6734,17 @@ func TestSystemBackend_pluginRuntime_CannotDeleteRuntimeWithReferencingPlugins(t // Register the plugin referencing the runtime. req = logical.TestRequest(t, logical.UpdateOperation, "plugins/catalog/database/test-plugin") - req.Data["version"] = "v0.16.0" - req.Data["sha_256"] = hex.EncodeToString([]byte{'1'}) - req.Data["command"] = "" - req.Data["oci_image"] = "hashicorp/vault-plugin-auth-jwt" - req.Data["runtime"] = "foo" + req.Data["version"] = pluginVersion + req.Data["sha_256"] = plugin.ImageSha256 + req.Data["oci_image"] = plugin.Image + req.Data["runtime"] = runtime resp, err = b.HandleRequest(namespace.RootContext(nil), req) if err != nil || resp.Error() != nil { t.Fatalf("err: %v %v", err, resp.Error()) } // Expect to fail to delete the plugin runtime - req = logical.TestRequest(t, logical.DeleteOperation, "plugins/runtimes/catalog/container/foo") + req = logical.TestRequest(t, logical.DeleteOperation, fmt.Sprintf("plugins/runtimes/catalog/container/%s", runtime)) resp, err = b.HandleRequest(namespace.RootContext(nil), req) if resp == nil || !resp.IsError() || resp.Error() == nil { t.Errorf("expected logical error but got none, resp: %#v", resp) @@ -6756,14 +6755,14 @@ func TestSystemBackend_pluginRuntime_CannotDeleteRuntimeWithReferencingPlugins(t // Delete the plugin. req = logical.TestRequest(t, logical.DeleteOperation, "plugins/catalog/database/test-plugin") - req.Data["version"] = "v0.16.0" + req.Data["version"] = pluginVersion resp, err = b.HandleRequest(namespace.RootContext(nil), req) if err != nil || resp.Error() != nil { t.Fatalf("err: %v %v", err, resp.Error()) } // This time deleting the runtime should work. - req = logical.TestRequest(t, logical.DeleteOperation, "plugins/runtimes/catalog/container/foo") + req = logical.TestRequest(t, logical.DeleteOperation, fmt.Sprintf("plugins/runtimes/catalog/container/%s", runtime)) resp, err = b.HandleRequest(namespace.RootContext(nil), req) if err != nil || resp.Error() != nil { t.Fatalf("err: %v %v", err, resp.Error()) From 44f87936df0880cde5344b6807ad33e35145c336 Mon Sep 17 00:00:00 2001 From: Thy Ton Date: Wed, 31 Jan 2024 21:31:10 -0800 Subject: [PATCH 09/15] revert changing field name --- .../pluginhelpers/pluginhelpers.go | 4 ++-- vault/external_plugin_container_test.go | 10 +++++----- .../plugin/external_plugin_test.go | 20 +++++++++---------- vault/plugincatalog/plugin_catalog_test.go | 6 +++--- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/helper/testhelpers/pluginhelpers/pluginhelpers.go b/helper/testhelpers/pluginhelpers/pluginhelpers.go index 4b3be92835a2..40035fc59f38 100644 --- a/helper/testhelpers/pluginhelpers/pluginhelpers.go +++ b/helper/testhelpers/pluginhelpers/pluginhelpers.go @@ -26,7 +26,7 @@ var ( type TestPlugin struct { Name string - Type consts.PluginType + Typ consts.PluginType Version string FileName string Sha256 string @@ -142,7 +142,7 @@ func CompilePlugin(t testing.T, typ consts.PluginType, pluginVersion string, plu } return TestPlugin{ Name: pluginName, - Type: typ, + Typ: typ, Version: pluginVersion, FileName: path.Base(pluginPath), Sha256: fmt.Sprintf("%x", sha.Sum(nil)), diff --git a/vault/external_plugin_container_test.go b/vault/external_plugin_container_test.go index 4f8f2c92ce10..5bca8b9eb98c 100644 --- a/vault/external_plugin_container_test.go +++ b/vault/external_plugin_container_test.go @@ -61,7 +61,7 @@ func TestExternalPluginInContainer_MountAndUnmount(t *testing.T) { }) for _, plugin := range plugins { - t.Run(plugin.Type.String(), func(t *testing.T) { + t.Run(plugin.Typ.String(), func(t *testing.T) { t.Run("default runtime", func(t *testing.T) { if _, err := exec.LookPath("runsc"); err != nil { t.Skip("Skipping test as runsc not found on path") @@ -98,9 +98,9 @@ func mountAndUnmountContainerPlugin_WithRuntime(t *testing.T, c *TestClusterCore if ociRuntime != "" { registerPluginRuntime(t, c.systemBackend, ociRuntime, rootless) } - registerContainerPlugin(t, c.systemBackend, plugin.Name, plugin.Type.String(), "1.0.0", plugin.ImageSha256, plugin.Image, ociRuntime) + registerContainerPlugin(t, c.systemBackend, plugin.Name, plugin.Typ.String(), "1.0.0", plugin.ImageSha256, plugin.Image, ociRuntime) - mountPlugin(t, c.systemBackend, plugin.Name, plugin.Type, "v1.0.0", "") + mountPlugin(t, c.systemBackend, plugin.Name, plugin.Typ, "v1.0.0", "") expectTmpdirEntries := func(expected int) { t.Helper() @@ -116,7 +116,7 @@ func mountAndUnmountContainerPlugin_WithRuntime(t *testing.T, c *TestClusterCore routeRequest := func(expectMatch bool) { pluginPath := "foo/bar" - if plugin.Type == consts.PluginTypeCredential { + if plugin.Typ == consts.PluginTypeCredential { pluginPath = "auth/foo/bar" } match := c.router.MatchingMount(namespace.RootContext(context.Background()), pluginPath) @@ -129,7 +129,7 @@ func mountAndUnmountContainerPlugin_WithRuntime(t *testing.T, c *TestClusterCore } routeRequest(true) - unmountPlugin(t, c.systemBackend, plugin.Type, "foo") + unmountPlugin(t, c.systemBackend, plugin.Typ, "foo") routeRequest(false) expectTmpdirEntries(0) } diff --git a/vault/external_tests/plugin/external_plugin_test.go b/vault/external_tests/plugin/external_plugin_test.go index 08d263911ae4..83d1d477fafd 100644 --- a/vault/external_tests/plugin/external_plugin_test.go +++ b/vault/external_tests/plugin/external_plugin_test.go @@ -109,7 +109,7 @@ func testRegisterVersion(t *testing.T, client *api.Client, plugin pluginhelpers. t.Helper() if err := client.Sys().RegisterPlugin(&api.RegisterPluginInput{ Name: plugin.Name, - Type: api.PluginType(plugin.Type), + Type: api.PluginType(plugin.Typ), Command: plugin.Name, SHA256: plugin.Sha256, Version: version, @@ -120,7 +120,7 @@ func testRegisterVersion(t *testing.T, client *api.Client, plugin pluginhelpers. func testEnableVersion(t *testing.T, client *api.Client, plugin pluginhelpers.TestPlugin, version string) { t.Helper() - switch plugin.Type { + switch plugin.Typ { case consts.PluginTypeSecrets: if err := client.Sys().Mount(plugin.Name, &api.MountInput{ Type: plugin.Name, @@ -388,7 +388,7 @@ func TestExternalPlugin_AuthMethod(t *testing.T) { // Deregister if err := client.Sys().DeregisterPlugin(&api.DeregisterPluginInput{ Name: plugin.Name, - Type: api.PluginType(plugin.Type), + Type: api.PluginType(plugin.Typ), Version: plugin.Version, }); err != nil { t.Fatal(err) @@ -463,7 +463,7 @@ func TestExternalPlugin_AuthMethodReload(t *testing.T) { // Deregister if err := client.Sys().DeregisterPlugin(&api.DeregisterPluginInput{ Name: plugin.Name, - Type: api.PluginType(plugin.Type), + Type: api.PluginType(plugin.Typ), Version: plugin.Version, }); err != nil { t.Fatal(err) @@ -535,7 +535,7 @@ func TestExternalPlugin_SecretsEngine(t *testing.T) { // Deregister if err := client.Sys().DeregisterPlugin(&api.DeregisterPluginInput{ Name: plugin.Name, - Type: api.PluginType(plugin.Type), + Type: api.PluginType(plugin.Typ), Version: plugin.Version, }); err != nil { t.Fatal(err) @@ -601,7 +601,7 @@ func TestExternalPlugin_SecretsEngineReload(t *testing.T) { // Deregister if err := client.Sys().DeregisterPlugin(&api.DeregisterPluginInput{ Name: plugin.Name, - Type: api.PluginType(plugin.Type), + Type: api.PluginType(plugin.Typ), Version: plugin.Version, }); err != nil { t.Fatal(err) @@ -729,7 +729,7 @@ func TestExternalPlugin_Database(t *testing.T) { // Deregister if err := client.Sys().DeregisterPlugin(&api.DeregisterPluginInput{ Name: plugin.Name, - Type: api.PluginType(plugin.Type), + Type: api.PluginType(plugin.Typ), Version: plugin.Version, }); err != nil { t.Fatal(err) @@ -809,7 +809,7 @@ func TestExternalPlugin_DatabaseReload(t *testing.T) { // Deregister if err := client.Sys().DeregisterPlugin(&api.DeregisterPluginInput{ Name: plugin.Name, - Type: api.PluginType(plugin.Type), + Type: api.PluginType(plugin.Typ), Version: plugin.Version, }); err != nil { t.Fatal(err) @@ -906,7 +906,7 @@ func TestExternalPlugin_AuditEnabled_ShouldLogPluginMetadata_Auth(t *testing.T) // Deregister if err := client.Sys().DeregisterPlugin(&api.DeregisterPluginInput{ Name: plugin.Name, - Type: api.PluginType(plugin.Type), + Type: api.PluginType(plugin.Typ), Version: plugin.Version, }); err != nil { t.Fatal(err) @@ -980,7 +980,7 @@ func TestExternalPlugin_AuditEnabled_ShouldLogPluginMetadata_Secret(t *testing.T // Deregister if err := client.Sys().DeregisterPlugin(&api.DeregisterPluginInput{ Name: plugin.Name, - Type: api.PluginType(plugin.Type), + Type: api.PluginType(plugin.Typ), Version: plugin.Version, }); err != nil { t.Fatal(err) diff --git a/vault/plugincatalog/plugin_catalog_test.go b/vault/plugincatalog/plugin_catalog_test.go index 64aeea31e729..199d7f24bb8b 100644 --- a/vault/plugincatalog/plugin_catalog_test.go +++ b/vault/plugincatalog/plugin_catalog_test.go @@ -1079,7 +1079,7 @@ func TestExternalPluginInContainer_GetBackendTypeVersion(t *testing.T) { }) plugin.Image += "-will-not-be-found" - err := pluginTypeLoadsFailedErrMap[plugin.Type] + err := pluginTypeLoadsFailedErrMap[plugin.Typ] testCases = append(testCases, struct { plugin pluginhelpers.TestPlugin expectedErr *expectedErr @@ -1090,7 +1090,7 @@ func TestExternalPluginInContainer_GetBackendTypeVersion(t *testing.T) { } for _, tc := range testCases { - t.Run(tc.plugin.Type.String(), func(t *testing.T) { + t.Run(tc.plugin.Typ.String(), func(t *testing.T) { expectedErrTestName := "nil err" if tc.expectedErr != nil { expectedErrTestName = tc.expectedErr.name @@ -1117,7 +1117,7 @@ func TestExternalPluginInContainer_GetBackendTypeVersion(t *testing.T) { var version logical.PluginVersion var err error - if tc.plugin.Type == consts.PluginTypeDatabase { + if tc.plugin.Typ == consts.PluginTypeDatabase { version, err = pluginCatalog.getDatabaseRunningVersion(context.Background(), entry) } else { version, err = pluginCatalog.getBackendRunningVersion(context.Background(), entry) From c5163c1f657720540f91c7e4797aae3df86d9f98 Mon Sep 17 00:00:00 2001 From: Thy Ton Date: Wed, 31 Jan 2024 22:18:48 -0800 Subject: [PATCH 10/15] merge 2 sentinel errors to unable to run containerized plugin --- vault/logical_system.go | 3 +- vault/plugincatalog/plugin_catalog.go | 21 +++++++------ vault/plugincatalog/plugin_catalog_test.go | 35 +++++----------------- 3 files changed, 19 insertions(+), 40 deletions(-) diff --git a/vault/logical_system.go b/vault/logical_system.go index fc477f189be4..245fc3bf24a2 100644 --- a/vault/logical_system.go +++ b/vault/logical_system.go @@ -597,8 +597,7 @@ func (b *SystemBackend) handlePluginCatalogUpdate(ctx context.Context, _ *logica return logical.ErrorResponse(err.Error()), nil } - if errors.Is(err, plugincatalog.ErrAllContainerizedBackendPluginLoadsFailed) || - errors.Is(err, plugincatalog.ErrAllContainerizedDatabasePluginLoadsFailed) { + if errors.Is(err, plugincatalog.ErrContainerizedPluginUnableToRun) { return logical.ErrorResponse(errors.Unwrap(err).Error()), nil } diff --git a/vault/plugincatalog/plugin_catalog.go b/vault/plugincatalog/plugin_catalog.go index e6101b052817..0173f0995dc3 100644 --- a/vault/plugincatalog/plugin_catalog.go +++ b/vault/plugincatalog/plugin_catalog.go @@ -34,14 +34,13 @@ import ( ) var ( - ErrDirectoryNotConfigured = errors.New("could not set plugin, plugin directory is not configured") - ErrPluginNotFound = errors.New("plugin not found in the catalog") - ErrPluginConnectionNotFound = errors.New("plugin connection not found for client") - ErrPluginBadType = errors.New("unable to determine plugin type") - ErrPinnedVersion = errors.New("cannot delete a pinned version") - ErrPluginVersionMismatch = errors.New("plugin version mismatch") - ErrAllContainerizedBackendPluginLoadsFailed = errors.New("failed to dispense all containerized backend plugins v4 through v5") - ErrAllContainerizedDatabasePluginLoadsFailed = errors.New("failed to load all containerized database plugins v4 through v5") + ErrDirectoryNotConfigured = errors.New("could not set plugin, plugin directory is not configured") + ErrPluginNotFound = errors.New("plugin not found in the catalog") + ErrPluginConnectionNotFound = errors.New("plugin connection not found for client") + ErrPluginBadType = errors.New("unable to determine plugin type") + ErrPinnedVersion = errors.New("cannot delete a pinned version") + ErrPluginVersionMismatch = errors.New("plugin version mismatch") + ErrContainerizedPluginUnableToRun = errors.New("unable to run containerized plugin") ) // PluginCatalog keeps a record of plugins known to vault. External plugins need @@ -606,7 +605,7 @@ func (c *PluginCatalog) getBackendRunningVersion(ctx context.Context, pluginRunn merr = multierror.Append(merr, err) c.logger.Debug("failed to dispense v4 backend plugin", "name", pluginRunner.Name, "error", err) if pluginRunner.OCIImage != "" { - return logical.EmptyPluginVersion, fmt.Errorf("%w: %s", ErrAllContainerizedBackendPluginLoadsFailed, merr) + return logical.EmptyPluginVersion, fmt.Errorf("%w: %s", ErrContainerizedPluginUnableToRun, merr) } return logical.EmptyPluginVersion, merr.ErrorOrNil() } @@ -685,7 +684,7 @@ func (c *PluginCatalog) getDatabaseRunningVersion(ctx context.Context, pluginRun merr = multierror.Append(merr, err) if pluginRunner.OCIImage != "" { - return logical.EmptyPluginVersion, fmt.Errorf("%w: %s", ErrAllContainerizedDatabasePluginLoadsFailed, merr) + return logical.EmptyPluginVersion, fmt.Errorf("%w: %s", ErrContainerizedPluginUnableToRun, merr) } return logical.EmptyPluginVersion, merr.ErrorOrNil() @@ -986,7 +985,7 @@ func (c *PluginCatalog) setInternal(ctx context.Context, plugin pluginutil.SetPl } if versionErr != nil { c.logger.Warn("Error determining plugin version", "error", versionErr) - if errors.Is(versionErr, ErrAllContainerizedBackendPluginLoadsFailed) || errors.Is(versionErr, ErrAllContainerizedDatabasePluginLoadsFailed) { + if errors.Is(versionErr, ErrContainerizedPluginUnableToRun) { return nil, versionErr } } else if plugin.Version != "" && runningVersion.Version != "" && plugin.Version != runningVersion.Version { diff --git a/vault/plugincatalog/plugin_catalog_test.go b/vault/plugincatalog/plugin_catalog_test.go index 199d7f24bb8b..e31ef2657732 100644 --- a/vault/plugincatalog/plugin_catalog_test.go +++ b/vault/plugincatalog/plugin_catalog_test.go @@ -1036,29 +1036,10 @@ func TestExternalPluginInContainer_GetBackendTypeVersion(t *testing.T) { t.Skip("Running plugins in containers is only supported on linux") } - type expectedErr struct { - err error - name string - } - pluginTypeLoadsFailedErrMap := map[consts.PluginType]expectedErr{ - consts.PluginTypeCredential: { - err: ErrAllContainerizedBackendPluginLoadsFailed, - name: "all containerized backend plugin loads failed", - }, - consts.PluginTypeSecrets: { - err: ErrAllContainerizedBackendPluginLoadsFailed, - name: "all containerized backend plugin loads failed", - }, - consts.PluginTypeDatabase: { - err: ErrAllContainerizedDatabasePluginLoadsFailed, - name: "all containerized database plugin loads failed", - }, - } - pluginCatalog := testPluginCatalog(t) var testCases []struct { plugin pluginhelpers.TestPlugin - expectedErr *expectedErr + expectedErr error } for _, pluginType := range []consts.PluginType{ @@ -1072,20 +1053,19 @@ func TestExternalPluginInContainer_GetBackendTypeVersion(t *testing.T) { testCases = append(testCases, struct { plugin pluginhelpers.TestPlugin - expectedErr *expectedErr + expectedErr error }{ plugin: plugin, expectedErr: nil, }) plugin.Image += "-will-not-be-found" - err := pluginTypeLoadsFailedErrMap[plugin.Typ] testCases = append(testCases, struct { plugin pluginhelpers.TestPlugin - expectedErr *expectedErr + expectedErr error }{ plugin: plugin, - expectedErr: &err, + expectedErr: ErrContainerizedPluginUnableToRun, }) } @@ -1093,8 +1073,9 @@ func TestExternalPluginInContainer_GetBackendTypeVersion(t *testing.T) { t.Run(tc.plugin.Typ.String(), func(t *testing.T) { expectedErrTestName := "nil err" if tc.expectedErr != nil { - expectedErrTestName = tc.expectedErr.name + expectedErrTestName = tc.expectedErr.Error() } + t.Run(expectedErrTestName, func(t *testing.T) { for _, ociRuntime := range []string{"runc", "runsc"} { t.Run(ociRuntime, func(t *testing.T) { @@ -1131,8 +1112,8 @@ func TestExternalPluginInContainer_GetBackendTypeVersion(t *testing.T) { t.Errorf("Expected to get version %v but got %v", tc.plugin.Version, version.Version) } - } else if !errors.Is(err, tc.expectedErr.err) { - t.Errorf("Expected to get err %s but got %s", tc.expectedErr.err, err) + } else if !errors.Is(err, tc.expectedErr) { + t.Errorf("Expected to get err %s but got %s", tc.expectedErr, err) } }) } From 048d91bdebddaa3819f4b2278f1522d49962d323 Mon Sep 17 00:00:00 2001 From: Thy Ton Date: Fri, 9 Feb 2024 11:02:42 -0800 Subject: [PATCH 11/15] Update vault/logical_system.go Co-authored-by: Tom Proctor --- vault/logical_system.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vault/logical_system.go b/vault/logical_system.go index 245fc3bf24a2..0b0610c0e93d 100644 --- a/vault/logical_system.go +++ b/vault/logical_system.go @@ -598,7 +598,7 @@ func (b *SystemBackend) handlePluginCatalogUpdate(ctx context.Context, _ *logica } if errors.Is(err, plugincatalog.ErrContainerizedPluginUnableToRun) { - return logical.ErrorResponse(errors.Unwrap(err).Error()), nil + return logical.ErrorResponse(err.Error()), nil } return nil, err From 8fa6f109e13db998a0968f99fa8842015cb7b5a2 Mon Sep 17 00:00:00 2001 From: Thy Ton Date: Fri, 9 Feb 2024 11:38:02 -0800 Subject: [PATCH 12/15] Update vault/plugincatalog/plugin_catalog.go Co-authored-by: Tom Proctor --- vault/plugincatalog/plugin_catalog.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vault/plugincatalog/plugin_catalog.go b/vault/plugincatalog/plugin_catalog.go index 0173f0995dc3..f23417b640ac 100644 --- a/vault/plugincatalog/plugin_catalog.go +++ b/vault/plugincatalog/plugin_catalog.go @@ -989,7 +989,7 @@ func (c *PluginCatalog) setInternal(ctx context.Context, plugin pluginutil.SetPl return nil, versionErr } } else if plugin.Version != "" && runningVersion.Version != "" && plugin.Version != runningVersion.Version { - c.logger.Warn("Plugin self-reported version did not match requested version", + c.logger.Error("Plugin self-reported version did not match requested version", "plugin", plugin.Name, "requestedVersion", plugin.Version, "reportedVersion", runningVersion.Version) return nil, fmt.Errorf("%w: %s reported version (%s) did not match requested version (%s)", ErrPluginVersionMismatch, plugin.Name, runningVersion.Version, plugin.Version) From 7b890898b7a0a699e422841685f8c8b15f5f5734 Mon Sep 17 00:00:00 2001 From: Thy Ton Date: Fri, 9 Feb 2024 11:43:52 -0800 Subject: [PATCH 13/15] rename error and using %w verb for merr --- vault/logical_system.go | 7 ++----- vault/plugincatalog/plugin_catalog.go | 20 ++++++++++---------- vault/plugincatalog/plugin_catalog_test.go | 2 +- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/vault/logical_system.go b/vault/logical_system.go index 0b0610c0e93d..43f74a677abc 100644 --- a/vault/logical_system.go +++ b/vault/logical_system.go @@ -593,11 +593,8 @@ func (b *SystemBackend) handlePluginCatalogUpdate(ctx context.Context, _ *logica }) if err != nil { if errors.Is(err, plugincatalog.ErrPluginNotFound) || - errors.Is(err, plugincatalog.ErrPluginVersionMismatch) { - return logical.ErrorResponse(err.Error()), nil - } - - if errors.Is(err, plugincatalog.ErrContainerizedPluginUnableToRun) { + errors.Is(err, plugincatalog.ErrPluginVersionMismatch) || + errors.Is(err, plugincatalog.ErrPluginUnableToRun) { return logical.ErrorResponse(err.Error()), nil } diff --git a/vault/plugincatalog/plugin_catalog.go b/vault/plugincatalog/plugin_catalog.go index 0173f0995dc3..4208c9f9b420 100644 --- a/vault/plugincatalog/plugin_catalog.go +++ b/vault/plugincatalog/plugin_catalog.go @@ -34,13 +34,13 @@ import ( ) var ( - ErrDirectoryNotConfigured = errors.New("could not set plugin, plugin directory is not configured") - ErrPluginNotFound = errors.New("plugin not found in the catalog") - ErrPluginConnectionNotFound = errors.New("plugin connection not found for client") - ErrPluginBadType = errors.New("unable to determine plugin type") - ErrPinnedVersion = errors.New("cannot delete a pinned version") - ErrPluginVersionMismatch = errors.New("plugin version mismatch") - ErrContainerizedPluginUnableToRun = errors.New("unable to run containerized plugin") + ErrDirectoryNotConfigured = errors.New("could not set plugin, plugin directory is not configured") + ErrPluginNotFound = errors.New("plugin not found in the catalog") + ErrPluginConnectionNotFound = errors.New("plugin connection not found for client") + ErrPluginBadType = errors.New("unable to determine plugin type") + ErrPinnedVersion = errors.New("cannot delete a pinned version") + ErrPluginVersionMismatch = errors.New("plugin version mismatch") + ErrPluginUnableToRun = errors.New("unable to run plugin") ) // PluginCatalog keeps a record of plugins known to vault. External plugins need @@ -605,7 +605,7 @@ func (c *PluginCatalog) getBackendRunningVersion(ctx context.Context, pluginRunn merr = multierror.Append(merr, err) c.logger.Debug("failed to dispense v4 backend plugin", "name", pluginRunner.Name, "error", err) if pluginRunner.OCIImage != "" { - return logical.EmptyPluginVersion, fmt.Errorf("%w: %s", ErrContainerizedPluginUnableToRun, merr) + return logical.EmptyPluginVersion, fmt.Errorf("%w: %w", ErrPluginUnableToRun, merr.ErrorOrNil()) } return logical.EmptyPluginVersion, merr.ErrorOrNil() } @@ -684,7 +684,7 @@ func (c *PluginCatalog) getDatabaseRunningVersion(ctx context.Context, pluginRun merr = multierror.Append(merr, err) if pluginRunner.OCIImage != "" { - return logical.EmptyPluginVersion, fmt.Errorf("%w: %s", ErrContainerizedPluginUnableToRun, merr) + return logical.EmptyPluginVersion, fmt.Errorf("%w: %w", ErrPluginUnableToRun, merr.ErrorOrNil()) } return logical.EmptyPluginVersion, merr.ErrorOrNil() @@ -985,7 +985,7 @@ func (c *PluginCatalog) setInternal(ctx context.Context, plugin pluginutil.SetPl } if versionErr != nil { c.logger.Warn("Error determining plugin version", "error", versionErr) - if errors.Is(versionErr, ErrContainerizedPluginUnableToRun) { + if errors.Is(versionErr, ErrPluginUnableToRun) { return nil, versionErr } } else if plugin.Version != "" && runningVersion.Version != "" && plugin.Version != runningVersion.Version { diff --git a/vault/plugincatalog/plugin_catalog_test.go b/vault/plugincatalog/plugin_catalog_test.go index e31ef2657732..898005b70e11 100644 --- a/vault/plugincatalog/plugin_catalog_test.go +++ b/vault/plugincatalog/plugin_catalog_test.go @@ -1065,7 +1065,7 @@ func TestExternalPluginInContainer_GetBackendTypeVersion(t *testing.T) { expectedErr error }{ plugin: plugin, - expectedErr: ErrContainerizedPluginUnableToRun, + expectedErr: ErrPluginUnableToRun, }) } From e3c5e67b365624d33d09b50871ffdc52c3094eb2 Mon Sep 17 00:00:00 2001 From: Thy Ton Date: Fri, 9 Feb 2024 13:37:27 -0800 Subject: [PATCH 14/15] skip containized plugin test if not run on linux --- vault/logical_system_test.go | 17 ++++------- vault/plugincatalog/plugin_catalog_test.go | 33 ++++++++++++---------- 2 files changed, 24 insertions(+), 26 deletions(-) diff --git a/vault/logical_system_test.go b/vault/logical_system_test.go index 7b8b10ca46d9..d294e96165d7 100644 --- a/vault/logical_system_test.go +++ b/vault/logical_system_test.go @@ -3880,6 +3880,10 @@ func TestSystemBackend_PluginCatalogPins_CRUD(t *testing.T) { // TestSystemBackend_PluginCatalog_ContainerCRUD tests that plugins registered // with oci_image set get recorded properly in the catalog. func TestSystemBackend_PluginCatalog_ContainerCRUD(t *testing.T) { + if runtime.GOOS != "linux" { + t.Skip("Containerized plugins only supported on Linux") + } + sym, err := filepath.EvalSymlinks(os.TempDir()) if err != nil { t.Fatalf("error: %v", err) @@ -3943,15 +3947,6 @@ func TestSystemBackend_PluginCatalog_ContainerCRUD(t *testing.T) { resp, err := b.HandleRequest(namespace.RootContext(nil), req) - // We should get a nice error back from the API if we're not on linux, but - // that's all we can test on non-linux. - if runtime.GOOS != "linux" { - if err != nil || resp.Error() == nil { - t.Fatalf("err: %v %v", err, resp.Error()) - } - return - } - if err != nil || resp.Error() != nil { t.Fatalf("err: %v %v", err, resp.Error()) } @@ -6695,7 +6690,7 @@ func TestGetSealBackendStatus(t *testing.T) { func TestSystemBackend_pluginRuntime_CannotDeleteRuntimeWithReferencingPlugins(t *testing.T) { if runtime.GOOS != "linux" { - t.Skip("Currently plugincontainer only supports linux") + t.Skip("Containerized plugins only supported on Linux") } sym, err := filepath.EvalSymlinks(os.TempDir()) if err != nil { @@ -6707,7 +6702,7 @@ func TestSystemBackend_pluginRuntime_CannotDeleteRuntimeWithReferencingPlugins(t b := c.systemBackend const runtime = "custom-runtime" - const ociRuntime = "runsc" + const ociRuntime = "runc" conf := pluginruntimeutil.PluginRuntimeConfig{ Name: runtime, Type: consts.PluginRuntimeTypeContainer, diff --git a/vault/plugincatalog/plugin_catalog_test.go b/vault/plugincatalog/plugin_catalog_test.go index 898005b70e11..89696612ecd8 100644 --- a/vault/plugincatalog/plugin_catalog_test.go +++ b/vault/plugincatalog/plugin_catalog_test.go @@ -729,6 +729,10 @@ func TestPluginCatalog_ErrDirectoryNotConfigured(t *testing.T) { } }, "set container plugin": func(t *testing.T) { + if runtime.GOOS != "linux" { + t.Skip("Containerized plugins only supported on Linux") + } + // Should never error. plugin := pluginhelpers.CompilePlugin(t, consts.PluginTypeDatabase, "", tempDir) plugin.Image, plugin.ImageSha256 = pluginhelpers.BuildPluginContainerImage(t, plugin, tempDir) @@ -776,6 +780,10 @@ func TestPluginCatalog_ErrDirectoryNotConfigured(t *testing.T) { // are returned with their container runtime config populated if it was // specified. func TestRuntimeConfigPopulatedIfSpecified(t *testing.T) { + if runtime.GOOS != "linux" { + t.Skip("Containerized plugins only supported on Linux") + } + pluginCatalog := testPluginCatalog(t) plugin := pluginhelpers.CompilePlugin(t, consts.PluginTypeDatabase, "", pluginCatalog.directory) @@ -792,7 +800,7 @@ func TestRuntimeConfigPopulatedIfSpecified(t *testing.T) { t.Fatal("specified runtime doesn't exist yet, should have failed") } - const ociRuntime = "runsc" + const ociRuntime = "runc" err = pluginCatalog.runtimeCatalog.Set(context.Background(), &pluginruntimeutil.PluginRuntimeConfig{ Name: runtime, Type: consts.PluginRuntimeTypeContainer, @@ -1033,14 +1041,16 @@ func TestExternalPlugin_getBackendTypeVersion(t *testing.T) { func TestExternalPluginInContainer_GetBackendTypeVersion(t *testing.T) { if runtime.GOOS != "linux" { - t.Skip("Running plugins in containers is only supported on linux") + t.Skip("Containerized plugins only supported on Linux") } pluginCatalog := testPluginCatalog(t) - var testCases []struct { + + type testCase struct { plugin pluginhelpers.TestPlugin expectedErr error } + var testCases []testCase for _, pluginType := range []consts.PluginType{ consts.PluginTypeCredential, @@ -1050,20 +1060,13 @@ func TestExternalPluginInContainer_GetBackendTypeVersion(t *testing.T) { plugin := pluginhelpers.CompilePlugin(t, pluginType, "v1.2.3", pluginCatalog.directory) plugin.Image, plugin.ImageSha256 = pluginhelpers.BuildPluginContainerImage(t, plugin, pluginCatalog.directory) - testCases = append(testCases, - struct { - plugin pluginhelpers.TestPlugin - expectedErr error - }{ - plugin: plugin, - expectedErr: nil, - }) + testCases = append(testCases, testCase{ + plugin: plugin, + expectedErr: nil, + }) plugin.Image += "-will-not-be-found" - testCases = append(testCases, struct { - plugin pluginhelpers.TestPlugin - expectedErr error - }{ + testCases = append(testCases, testCase{ plugin: plugin, expectedErr: ErrPluginUnableToRun, }) From c4be808ed19d843abaa83274ff46603a6c9ad775 Mon Sep 17 00:00:00 2001 From: Thy Ton Date: Fri, 9 Feb 2024 13:44:01 -0800 Subject: [PATCH 15/15] add 24990 changelog --- changelog/24990.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 changelog/24990.txt diff --git a/changelog/24990.txt b/changelog/24990.txt new file mode 100644 index 000000000000..8079a4605c50 --- /dev/null +++ b/changelog/24990.txt @@ -0,0 +1,3 @@ +```release-note:bug +cli: fixes plugin register CLI failure to error when plugin image doesn't exist +``` \ No newline at end of file