diff --git a/http/handler_test.go b/http/handler_test.go index beab922812..0cda837281 100644 --- a/http/handler_test.go +++ b/http/handler_test.go @@ -99,7 +99,7 @@ func TestSysMounts_headerAuth(t *testing.T) { "default_lease_ttl": json.Number("0"), "max_lease_ttl": json.Number("0"), }, - "local": false, + "local": true, }, }, "secret/": map[string]interface{}{ @@ -127,7 +127,7 @@ func TestSysMounts_headerAuth(t *testing.T) { "default_lease_ttl": json.Number("0"), "max_lease_ttl": json.Number("0"), }, - "local": false, + "local": true, }, } testResponseStatus(t, resp, 200) diff --git a/http/sys_mount_test.go b/http/sys_mount_test.go index f922299815..e84ee67914 100644 --- a/http/sys_mount_test.go +++ b/http/sys_mount_test.go @@ -51,7 +51,7 @@ func TestSysMounts(t *testing.T) { "default_lease_ttl": json.Number("0"), "max_lease_ttl": json.Number("0"), }, - "local": false, + "local": true, }, }, "secret/": map[string]interface{}{ @@ -79,7 +79,7 @@ func TestSysMounts(t *testing.T) { "default_lease_ttl": json.Number("0"), "max_lease_ttl": json.Number("0"), }, - "local": false, + "local": true, }, } testResponseStatus(t, resp, 200) @@ -147,7 +147,7 @@ func TestSysMount(t *testing.T) { "default_lease_ttl": json.Number("0"), "max_lease_ttl": json.Number("0"), }, - "local": false, + "local": true, }, }, "foo/": map[string]interface{}{ @@ -184,7 +184,7 @@ func TestSysMount(t *testing.T) { "default_lease_ttl": json.Number("0"), "max_lease_ttl": json.Number("0"), }, - "local": false, + "local": true, }, } testResponseStatus(t, resp, 200) @@ -274,7 +274,7 @@ func TestSysRemount(t *testing.T) { "default_lease_ttl": json.Number("0"), "max_lease_ttl": json.Number("0"), }, - "local": false, + "local": true, }, }, "bar/": map[string]interface{}{ @@ -311,7 +311,7 @@ func TestSysRemount(t *testing.T) { "default_lease_ttl": json.Number("0"), "max_lease_ttl": json.Number("0"), }, - "local": false, + "local": true, }, } testResponseStatus(t, resp, 200) @@ -373,7 +373,7 @@ func TestSysUnmount(t *testing.T) { "default_lease_ttl": json.Number("0"), "max_lease_ttl": json.Number("0"), }, - "local": false, + "local": true, }, }, "secret/": map[string]interface{}{ @@ -401,7 +401,7 @@ func TestSysUnmount(t *testing.T) { "default_lease_ttl": json.Number("0"), "max_lease_ttl": json.Number("0"), }, - "local": false, + "local": true, }, } testResponseStatus(t, resp, 200) @@ -469,7 +469,7 @@ func TestSysTuneMount(t *testing.T) { "default_lease_ttl": json.Number("0"), "max_lease_ttl": json.Number("0"), }, - "local": false, + "local": true, }, }, "foo/": map[string]interface{}{ @@ -506,7 +506,7 @@ func TestSysTuneMount(t *testing.T) { "default_lease_ttl": json.Number("0"), "max_lease_ttl": json.Number("0"), }, - "local": false, + "local": true, }, } testResponseStatus(t, resp, 200) @@ -595,7 +595,7 @@ func TestSysTuneMount(t *testing.T) { "default_lease_ttl": json.Number("0"), "max_lease_ttl": json.Number("0"), }, - "local": false, + "local": true, }, }, "foo/": map[string]interface{}{ @@ -632,7 +632,7 @@ func TestSysTuneMount(t *testing.T) { "default_lease_ttl": json.Number("0"), "max_lease_ttl": json.Number("0"), }, - "local": false, + "local": true, }, } diff --git a/vault/logical_cubbyhole.go b/vault/logical_cubbyhole.go index 697655538f..76353b0bed 100644 --- a/vault/logical_cubbyhole.go +++ b/vault/logical_cubbyhole.go @@ -16,12 +16,6 @@ func CubbyholeBackendFactory(conf *logical.BackendConfig) (logical.Backend, erro b.Backend = &framework.Backend{ Help: strings.TrimSpace(cubbyholeHelp), - PathsSpecial: &logical.Paths{ - LocalStorage: []string{ - "*", - }, - }, - Paths: []*framework.Path{ &framework.Path{ Pattern: ".*", diff --git a/vault/logical_cubbyhole_test.go b/vault/logical_cubbyhole_test.go index 79531d6e39..880011513f 100644 --- a/vault/logical_cubbyhole_test.go +++ b/vault/logical_cubbyhole_test.go @@ -10,18 +10,6 @@ import ( "github.com/hashicorp/vault/logical" ) -func TestCubbyholeBackend_RootPaths(t *testing.T) { - b := testCubbyholeBackend() - expected := []string{ - "*", - } - - actual := b.SpecialPaths().LocalStorage - if !reflect.DeepEqual(actual, expected) { - t.Fatalf("bad: %#v", actual) - } -} - func TestCubbyholeBackend_Write(t *testing.T) { b := testCubbyholeBackend() req := logical.TestRequest(t, logical.UpdateOperation, "foo") diff --git a/vault/logical_system_test.go b/vault/logical_system_test.go index ac9c7b4335..15f60a50c2 100644 --- a/vault/logical_system_test.go +++ b/vault/logical_system_test.go @@ -70,7 +70,7 @@ func TestSystemBackend_mounts(t *testing.T) { "default_lease_ttl": resp.Data["cubbyhole/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64), "max_lease_ttl": resp.Data["cubbyhole/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64), }, - "local": false, + "local": true, }, } if !reflect.DeepEqual(resp.Data, exp) { diff --git a/vault/mount.go b/vault/mount.go index a7e29a2a93..8ac952016f 100644 --- a/vault/mount.go +++ b/vault/mount.go @@ -5,6 +5,7 @@ import ( "encoding/json" "errors" "fmt" + "sort" "strings" "time" @@ -119,6 +120,15 @@ func (t *MountTable) remove(path string) *MountEntry { return nil } +// sortEntriesByPath sorts the entries in the table by path and returns the +// table; this is useful for tests +func (t *MountTable) sortEntriesByPath() *MountTable { + sort.Slice(t.Entries, func(i, j int) bool { + return t.Entries[i].Path < t.Entries[j].Path + }) + return t +} + // MountEntry is used to represent a mount table entry type MountEntry struct { Table string `json:"table"` // The table it belongs to @@ -733,6 +743,7 @@ func requiredMountTable() *MountTable { Type: "cubbyhole", Description: "per-token private secret storage", UUID: cubbyholeUUID, + Local: true, } sysUUID, err := uuid.GenerateUUID() diff --git a/vault/mount_test.go b/vault/mount_test.go index a00d379454..49f5f76d0d 100644 --- a/vault/mount_test.go +++ b/vault/mount_test.go @@ -37,7 +37,7 @@ func TestCore_DefaultMountTable(t *testing.T) { } // Verify matching mount tables - if !reflect.DeepEqual(c.mounts, c2.mounts) { + if !reflect.DeepEqual(c.mounts.sortEntriesByPath(), c2.mounts.sortEntriesByPath()) { t.Fatalf("mismatch: %v %v", c.mounts, c2.mounts) } } @@ -78,7 +78,7 @@ func TestCore_Mount(t *testing.T) { } // Verify matching mount tables - if !reflect.DeepEqual(c.mounts, c2.mounts) { + if !reflect.DeepEqual(c.mounts.sortEntriesByPath(), c2.mounts.sortEntriesByPath()) { t.Fatalf("mismatch: %v %v", c.mounts, c2.mounts) } } @@ -127,8 +127,8 @@ func TestCore_Mount_Local(t *testing.T) { if err := jsonutil.DecodeJSON(rawLocal.Value, localMountsTable); err != nil { t.Fatal(err) } - if len(localMountsTable.Entries) > 0 { - t.Fatalf("expected no entries in local mount table, got %#v", localMountsTable) + if len(localMountsTable.Entries) != 1 || localMountsTable.Entries[0].Type != "cubbyhole" { + t.Fatalf("expected only cubbyhole entry in local mount table, got %#v", localMountsTable) } c.mounts.Entries[1].Local = true @@ -147,7 +147,11 @@ func TestCore_Mount_Local(t *testing.T) { if err := jsonutil.DecodeJSON(rawLocal.Value, localMountsTable); err != nil { t.Fatal(err) } - if len(localMountsTable.Entries) != 1 { + // This requires some explanation: because we're directly munging the mount + // table, the table initially when core unseals contains cubbyhole as per + // above, but then we overwrite it with our own table with one local entry, + // so we should now only expect the noop2 entry + if len(localMountsTable.Entries) != 1 || localMountsTable.Entries[0].Path != "noop2/" { t.Fatalf("expected one entry in local mount table, got %#v", localMountsTable) } @@ -204,7 +208,7 @@ func TestCore_Unmount(t *testing.T) { } // Verify matching mount tables - if !reflect.DeepEqual(c.mounts, c2.mounts) { + if !reflect.DeepEqual(c.mounts.sortEntriesByPath(), c2.mounts.sortEntriesByPath()) { t.Fatalf("mismatch: %v %v", c.mounts, c2.mounts) } } @@ -483,6 +487,17 @@ func testCore_MountTable_UpgradeToTyped_Common( mt = c.auth } + // We filter out local entries here since the logic is rather dumb + // (straight JSON comparison) and doesn't seal well with the separate + // locations + newEntries := mt.Entries[:0] + for _, entry := range mt.Entries { + if !entry.Local { + newEntries = append(newEntries, entry) + } + } + mt.Entries = newEntries + // Save the expected table goodJson, err := json.Marshal(mt) if err != nil { @@ -577,22 +592,23 @@ func verifyDefaultTable(t *testing.T, table *MountTable) { if len(table.Entries) != 3 { t.Fatalf("bad: %v", table.Entries) } + table.sortEntriesByPath() for idx, entry := range table.Entries { switch idx { case 0: - if entry.Path != "secret/" { - t.Fatalf("bad: %v", entry) - } - if entry.Type != "generic" { - t.Fatalf("bad: %v", entry) - } - case 1: if entry.Path != "cubbyhole/" { t.Fatalf("bad: %v", entry) } if entry.Type != "cubbyhole" { t.Fatalf("bad: %v", entry) } + case 1: + if entry.Path != "secret/" { + t.Fatalf("bad: %v", entry) + } + if entry.Type != "generic" { + t.Fatalf("bad: %v", entry) + } case 2: if entry.Path != "sys/" { t.Fatalf("bad: %v", entry) @@ -611,5 +627,4 @@ func verifyDefaultTable(t *testing.T, table *MountTable) { t.Fatalf("bad: %v", entry) } } - }