mirror of
				https://github.com/optim-enterprises-bv/vault.git
				synced 2025-10-31 02:28:09 +00:00 
			
		
		
		
	Make cubbyhole local instead of replicated. (#2397)
This doesn't really change behavior, just what it looks like in the UX. However, it does make tests more complicated. Most were fixed by adding a sorting function, which is generally useful anyways.
This commit is contained in:
		| @@ -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) | ||||
|   | ||||
| @@ -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, | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -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: ".*", | ||||
|   | ||||
| @@ -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") | ||||
|   | ||||
| @@ -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) { | ||||
|   | ||||
| @@ -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() | ||||
|   | ||||
| @@ -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) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Jeff Mitchell
					Jeff Mitchell