diff --git a/changelog/mount-migration.txt b/changelog/mount-migration.txt new file mode 100644 index 000000000000..1e0eec36bd63 --- /dev/null +++ b/changelog/mount-migration.txt @@ -0,0 +1,3 @@ +```release-note:feature +**Mount Migration**: Vault supports moving secrets and auth mounts both within and across namespaces. +``` \ No newline at end of file diff --git a/vault/logical_system.go b/vault/logical_system.go index 84566349c138..9ca785d1849e 100644 --- a/vault/logical_system.go +++ b/vault/logical_system.go @@ -1201,6 +1201,13 @@ func (b *SystemBackend) handleRemount(ctx context.Context, req *logical.Request, logical.ErrInvalidRequest } + if strings.Contains(fromPath, " ") { + return logical.ErrorResponse("'from' path cannot contain whitespace"), logical.ErrInvalidRequest + } + if strings.Contains(toPath, " ") { + return logical.ErrorResponse("'to' path cannot contain whitespace"), logical.ErrInvalidRequest + } + fromPathDetails := b.Core.splitNamespaceAndMountFromPath(ns.Path, fromPath) toPathDetails := b.Core.splitNamespaceAndMountFromPath(ns.Path, toPath) diff --git a/vault/logical_system_test.go b/vault/logical_system_test.go index 5775a2b40ecf..4f889d7133f9 100644 --- a/vault/logical_system_test.go +++ b/vault/logical_system_test.go @@ -995,6 +995,38 @@ func TestSystemBackend_remount_nonPrintable(t *testing.T) { } } +func TestSystemBackend_remount_spacesInFromPath(t *testing.T) { + b := testSystemBackend(t) + + req := logical.TestRequest(t, logical.UpdateOperation, "remount") + req.Data["from"] = " foo / " + req.Data["to"] = "bar" + req.Data["config"] = structs.Map(MountConfig{}) + resp, err := b.HandleRequest(namespace.RootContext(nil), req) + if err != logical.ErrInvalidRequest { + t.Fatalf("err: %v", err) + } + if resp.Data["error"] != `'from' path cannot contain whitespace` { + t.Fatalf("bad: %v", resp) + } +} + +func TestSystemBackend_remount_spacesInToPath(t *testing.T) { + b := testSystemBackend(t) + + req := logical.TestRequest(t, logical.UpdateOperation, "remount") + req.Data["from"] = "foo" + req.Data["to"] = " bar / " + req.Data["config"] = structs.Map(MountConfig{}) + resp, err := b.HandleRequest(namespace.RootContext(nil), req) + if err != logical.ErrInvalidRequest { + t.Fatalf("err: %v", err) + } + if resp.Data["error"] != `'to' path cannot contain whitespace` { + t.Fatalf("bad: %v", resp) + } +} + func TestSystemBackend_leases(t *testing.T) { core, b, root := testCoreSystemBackend(t) diff --git a/website/content/docs/commands/auth/move.mdx b/website/content/docs/commands/auth/move.mdx index b61e01fd3cd3..e567d4d42be6 100644 --- a/website/content/docs/commands/auth/move.mdx +++ b/website/content/docs/commands/auth/move.mdx @@ -25,7 +25,7 @@ method.** Move the existing auth method at ns1/approle/ to ns2/new-approle/: ```shell-session -$ vault auth move ns1/approle/ ns2/new-approle/ +$ vault auth move ns1/auth/approle/ ns2/auth/new-approle/ ``` ## Usage