diff --git a/changelog/20044.txt b/changelog/20044.txt new file mode 100644 index 000000000000..014e61b46743 --- /dev/null +++ b/changelog/20044.txt @@ -0,0 +1,4 @@ +```release-note:improvement +core: Add a `raft` sub-field to the `storage` and `ha_storage` details provided by the +`/sys/config/state/sanitized` endpoint in order to include the `max_entry_size`. +``` diff --git a/command/server/config.go b/command/server/config.go index d3f4d0755eb5..a9637f22477f 100644 --- a/command/server/config.go +++ b/command/server/config.go @@ -1133,23 +1133,39 @@ func (c *Config) Sanitized() map[string]interface{} { // Sanitize storage stanza if c.Storage != nil { + storageType := c.Storage.Type sanitizedStorage := map[string]interface{}{ - "type": c.Storage.Type, + "type": storageType, "redirect_addr": c.Storage.RedirectAddr, "cluster_addr": c.Storage.ClusterAddr, "disable_clustering": c.Storage.DisableClustering, } + + if storageType == "raft" { + sanitizedStorage["raft"] = map[string]interface{}{ + "max_entry_size": c.Storage.Config["max_entry_size"], + } + } + result["storage"] = sanitizedStorage } // Sanitize HA storage stanza if c.HAStorage != nil { + haStorageType := c.HAStorage.Type sanitizedHAStorage := map[string]interface{}{ - "type": c.HAStorage.Type, + "type": haStorageType, "redirect_addr": c.HAStorage.RedirectAddr, "cluster_addr": c.HAStorage.ClusterAddr, "disable_clustering": c.HAStorage.DisableClustering, } + + if haStorageType == "raft" { + sanitizedHAStorage["raft"] = map[string]interface{}{ + "max_entry_size": c.HAStorage.Config["max_entry_size"], + } + } + result["ha_storage"] = sanitizedHAStorage } diff --git a/http/sys_config_state_test.go b/http/sys_config_state_test.go index 08361af49339..5b5d9aac0dfa 100644 --- a/http/sys_config_state_test.go +++ b/http/sys_config_state_test.go @@ -6,70 +6,193 @@ import ( "testing" "github.com/go-test/deep" + "github.com/hashicorp/vault/command/server" + "github.com/hashicorp/vault/internalshared/configutil" "github.com/hashicorp/vault/vault" ) func TestSysConfigState_Sanitized(t *testing.T) { - var resp *http.Response + cases := []struct { + name string + storageConfig *server.Storage + haStorageConfig *server.Storage + expectedStorageOutput map[string]interface{} + expectedHAStorageOutput map[string]interface{} + }{ + { + name: "raft storage", + storageConfig: &server.Storage{ + Type: "raft", + RedirectAddr: "http://127.0.0.1:8200", + ClusterAddr: "http://127.0.0.1:8201", + DisableClustering: false, + Config: map[string]string{ + "path": "/storage/path/raft", + "node_id": "raft1", + "max_entry_size": "2097152", + }, + }, + haStorageConfig: nil, + expectedStorageOutput: map[string]interface{}{ + "type": "raft", + "redirect_addr": "http://127.0.0.1:8200", + "cluster_addr": "http://127.0.0.1:8201", + "disable_clustering": false, + "raft": map[string]interface{}{ + "max_entry_size": "2097152", + }, + }, + expectedHAStorageOutput: nil, + }, + { + name: "inmem storage, no HA storage", + storageConfig: &server.Storage{ + Type: "inmem", + RedirectAddr: "http://127.0.0.1:8200", + ClusterAddr: "http://127.0.0.1:8201", + DisableClustering: false, + }, + haStorageConfig: nil, + expectedStorageOutput: map[string]interface{}{ + "type": "inmem", + "redirect_addr": "http://127.0.0.1:8200", + "cluster_addr": "http://127.0.0.1:8201", + "disable_clustering": false, + }, + expectedHAStorageOutput: nil, + }, + { + name: "inmem storage, raft HA storage", + storageConfig: &server.Storage{ + Type: "inmem", + RedirectAddr: "http://127.0.0.1:8200", + ClusterAddr: "http://127.0.0.1:8201", + DisableClustering: false, + }, + haStorageConfig: &server.Storage{ + Type: "raft", + RedirectAddr: "http://127.0.0.1:8200", + ClusterAddr: "http://127.0.0.1:8201", + DisableClustering: false, + Config: map[string]string{ + "path": "/storage/path/raft", + "node_id": "raft1", + "max_entry_size": "2097152", + }, + }, + expectedStorageOutput: map[string]interface{}{ + "type": "inmem", + "redirect_addr": "http://127.0.0.1:8200", + "cluster_addr": "http://127.0.0.1:8201", + "disable_clustering": false, + }, + expectedHAStorageOutput: map[string]interface{}{ + "type": "raft", + "redirect_addr": "http://127.0.0.1:8200", + "cluster_addr": "http://127.0.0.1:8201", + "disable_clustering": false, + "raft": map[string]interface{}{ + "max_entry_size": "2097152", + }, + }, + }, + } - core, _, token := vault.TestCoreUnsealed(t) - ln, addr := TestServer(t, core) - defer ln.Close() - TestServerAuth(t, addr, token) + for _, tc := range cases { + tc := tc - resp = testHttpGet(t, token, addr+"/v1/sys/config/state/sanitized") - testResponseStatus(t, resp, 200) + t.Run(tc.name, func(t *testing.T) { + t.Parallel() - var actual map[string]interface{} - var expected map[string]interface{} + var resp *http.Response + confRaw := &server.Config{ + Storage: tc.storageConfig, + HAStorage: tc.haStorageConfig, + SharedConfig: &configutil.SharedConfig{ + Listeners: []*configutil.Listener{ + { + Type: "tcp", + Address: "127.0.0.1", + }, + }, + }, + } - configResp := map[string]interface{}{ - "api_addr": "", - "cache_size": json.Number("0"), - "cluster_addr": "", - "cluster_cipher_suites": "", - "cluster_name": "", - "default_lease_ttl": json.Number("0"), - "default_max_request_duration": json.Number("0"), - "disable_cache": false, - "disable_clustering": false, - "disable_indexing": false, - "disable_mlock": false, - "disable_performance_standby": false, - "disable_printable_check": false, - "disable_sealwrap": false, - "experiments": nil, - "raw_storage_endpoint": false, - "detect_deadlocks": "", - "introspection_endpoint": false, - "disable_sentinel_trace": false, - "enable_ui": false, - "log_format": "", - "log_level": "", - "max_lease_ttl": json.Number("0"), - "pid_file": "", - "plugin_directory": "", - "plugin_file_uid": json.Number("0"), - "plugin_file_permissions": json.Number("0"), - "enable_response_header_hostname": false, - "enable_response_header_raft_node_id": false, - "log_requests_level": "", - } + conf := &vault.CoreConfig{ + RawConfig: confRaw, + } - expected = map[string]interface{}{ - "lease_id": "", - "renewable": false, - "lease_duration": json.Number("0"), - "wrap_info": nil, - "warnings": nil, - "auth": nil, - "data": configResp, - } + core, _, token := vault.TestCoreUnsealedWithConfig(t, conf) + ln, addr := TestServer(t, core) + defer ln.Close() + TestServerAuth(t, addr, token) + + resp = testHttpGet(t, token, addr+"/v1/sys/config/state/sanitized") + testResponseStatus(t, resp, 200) + + var actual map[string]interface{} + var expected map[string]interface{} + + configResp := map[string]interface{}{ + "api_addr": "", + "cache_size": json.Number("0"), + "cluster_addr": "", + "cluster_cipher_suites": "", + "cluster_name": "", + "default_lease_ttl": json.Number("0"), + "default_max_request_duration": json.Number("0"), + "disable_cache": false, + "disable_clustering": false, + "disable_indexing": false, + "disable_mlock": false, + "disable_performance_standby": false, + "disable_printable_check": false, + "disable_sealwrap": false, + "experiments": nil, + "raw_storage_endpoint": false, + "detect_deadlocks": "", + "introspection_endpoint": false, + "disable_sentinel_trace": false, + "enable_ui": false, + "log_format": "", + "log_level": "", + "max_lease_ttl": json.Number("0"), + "pid_file": "", + "plugin_directory": "", + "plugin_file_uid": json.Number("0"), + "plugin_file_permissions": json.Number("0"), + "enable_response_header_hostname": false, + "enable_response_header_raft_node_id": false, + "log_requests_level": "", + "listeners": []interface{}{ + map[string]interface{}{ + "config": nil, + "type": "tcp", + }, + }, + "storage": tc.expectedStorageOutput, + } + + if tc.expectedHAStorageOutput != nil { + configResp["ha_storage"] = tc.expectedHAStorageOutput + } + + expected = map[string]interface{}{ + "lease_id": "", + "renewable": false, + "lease_duration": json.Number("0"), + "wrap_info": nil, + "warnings": nil, + "auth": nil, + "data": configResp, + } - testResponseBody(t, resp, &actual) - expected["request_id"] = actual["request_id"] + testResponseBody(t, resp, &actual) + expected["request_id"] = actual["request_id"] - if diff := deep.Equal(actual, expected); len(diff) > 0 { - t.Fatalf("bad mismatch response body: diff: %v", diff) + if diff := deep.Equal(actual, expected); len(diff) > 0 { + t.Fatalf("bad mismatch response body: diff: %v", diff) + } + }) } }