diff --git a/api/sys_mounts.go b/api/sys_mounts.go index 993a1b67bfea..354b1ee93465 100644 --- a/api/sys_mounts.go +++ b/api/sys_mounts.go @@ -159,6 +159,7 @@ type MountConfigInput struct { } type MountOutput struct { + UUID string `json:"uuid"` Type string `json:"type"` Description string `json:"description"` Accessor string `json:"accessor"` diff --git a/command/auth_list.go b/command/auth_list.go index d7032e87b525..48780efba321 100644 --- a/command/auth_list.go +++ b/command/auth_list.go @@ -143,7 +143,7 @@ func (c *AuthListCommand) detailedMounts(auths map[string]*api.AuthMount) []stri } } - out := []string{"Path | Plugin | Accessor | Default TTL | Max TTL | Token Type | Replication | Seal Wrap | Options | Description"} + out := []string{"Path | Plugin | Accessor | Default TTL | Max TTL | Token Type | Replication | Seal Wrap | Options | Description | UUID"} for _, path := range paths { mount := auths[path] @@ -160,7 +160,7 @@ func (c *AuthListCommand) detailedMounts(auths map[string]*api.AuthMount) []stri pluginName = mount.Config.PluginName } - out = append(out, fmt.Sprintf("%s | %s | %s | %s | %s | %s | %s | %t | %v | %s", + out = append(out, fmt.Sprintf("%s | %s | %s | %s | %s | %s | %s | %t | %v | %s | %s", path, pluginName, mount.Accessor, @@ -171,6 +171,7 @@ func (c *AuthListCommand) detailedMounts(auths map[string]*api.AuthMount) []stri mount.SealWrap, mount.Options, mount.Description, + mount.UUID, )) } diff --git a/command/secrets_list.go b/command/secrets_list.go index c88e2b286747..87a95fe5863a 100644 --- a/command/secrets_list.go +++ b/command/secrets_list.go @@ -143,7 +143,7 @@ func (c *SecretsListCommand) detailedMounts(mounts map[string]*api.MountOutput) } } - out := []string{"Path | Plugin | Accessor | Default TTL | Max TTL | Force No Cache | Replication | Seal Wrap | Options | Description"} + out := []string{"Path | Plugin | Accessor | Default TTL | Max TTL | Force No Cache | Replication | Seal Wrap | Options | Description | UUID "} for _, path := range paths { mount := mounts[path] @@ -160,7 +160,7 @@ func (c *SecretsListCommand) detailedMounts(mounts map[string]*api.MountOutput) pluginName = mount.Config.PluginName } - out = append(out, fmt.Sprintf("%s | %s | %s | %s | %s | %t | %s | %t | %v | %s", + out = append(out, fmt.Sprintf("%s | %s | %s | %s | %s | %t | %s | %t | %v | %s | %s", path, pluginName, mount.Accessor, @@ -171,6 +171,7 @@ func (c *SecretsListCommand) detailedMounts(mounts map[string]*api.MountOutput) mount.SealWrap, mount.Options, mount.Description, + mount.UUID, )) } diff --git a/http/handler_test.go b/http/handler_test.go index ff22b7fb73ff..2c4bc87a9706 100644 --- a/http/handler_test.go +++ b/http/handler_test.go @@ -4,7 +4,6 @@ import ( "context" "encoding/json" "errors" - "github.com/go-test/deep" "net/http" "net/http/httptest" "net/textproto" @@ -12,6 +11,8 @@ import ( "strings" "testing" + "github.com/go-test/deep" + cleanhttp "github.com/hashicorp/go-cleanhttp" "github.com/hashicorp/vault/helper/namespace" "github.com/hashicorp/vault/sdk/helper/consts" @@ -375,8 +376,14 @@ func TestSysMounts_headerAuth(t *testing.T) { if v.(map[string]interface{})["accessor"] == "" { t.Fatalf("no accessor from %s", k) } + if v.(map[string]interface{})["uuid"] == "" { + t.Fatalf("no uuid from %s", k) + } + expected[k].(map[string]interface{})["accessor"] = v.(map[string]interface{})["accessor"] + expected[k].(map[string]interface{})["uuid"] = v.(map[string]interface{})["uuid"] expected["data"].(map[string]interface{})[k].(map[string]interface{})["accessor"] = v.(map[string]interface{})["accessor"] + expected["data"].(map[string]interface{})[k].(map[string]interface{})["uuid"] = v.(map[string]interface{})["uuid"] } if diff := deep.Equal(actual, expected); len(diff) > 0 { diff --git a/http/sys_auth_test.go b/http/sys_auth_test.go index 33f631429814..e20f3fd10f02 100644 --- a/http/sys_auth_test.go +++ b/http/sys_auth_test.go @@ -62,8 +62,14 @@ func TestSysAuth(t *testing.T) { if v.(map[string]interface{})["accessor"] == "" { t.Fatalf("no accessor from %s", k) } + if v.(map[string]interface{})["uuid"] == "" { + t.Fatalf("no uuid from %s", k) + } + expected[k].(map[string]interface{})["accessor"] = v.(map[string]interface{})["accessor"] + expected[k].(map[string]interface{})["uuid"] = v.(map[string]interface{})["uuid"] expected["data"].(map[string]interface{})[k].(map[string]interface{})["accessor"] = v.(map[string]interface{})["accessor"] + expected["data"].(map[string]interface{})[k].(map[string]interface{})["uuid"] = v.(map[string]interface{})["uuid"] } if !reflect.DeepEqual(actual, expected) { @@ -156,8 +162,14 @@ func TestSysEnableAuth(t *testing.T) { if v.(map[string]interface{})["accessor"] == "" { t.Fatalf("no accessor from %s", k) } + if v.(map[string]interface{})["uuid"] == "" { + t.Fatalf("no uuid from %s", k) + } + expected[k].(map[string]interface{})["accessor"] = v.(map[string]interface{})["accessor"] + expected[k].(map[string]interface{})["uuid"] = v.(map[string]interface{})["uuid"] expected["data"].(map[string]interface{})[k].(map[string]interface{})["accessor"] = v.(map[string]interface{})["accessor"] + expected["data"].(map[string]interface{})[k].(map[string]interface{})["uuid"] = v.(map[string]interface{})["uuid"] } if diff := deep.Equal(actual, expected); diff != nil { @@ -227,8 +239,14 @@ func TestSysDisableAuth(t *testing.T) { if v.(map[string]interface{})["accessor"] == "" { t.Fatalf("no accessor from %s", k) } + if v.(map[string]interface{})["uuid"] == "" { + t.Fatalf("no uuid from %s", k) + } + expected[k].(map[string]interface{})["accessor"] = v.(map[string]interface{})["accessor"] + expected[k].(map[string]interface{})["uuid"] = v.(map[string]interface{})["uuid"] expected["data"].(map[string]interface{})[k].(map[string]interface{})["accessor"] = v.(map[string]interface{})["accessor"] + expected["data"].(map[string]interface{})[k].(map[string]interface{})["uuid"] = v.(map[string]interface{})["uuid"] } if diff := deep.Equal(actual, expected); diff != nil { diff --git a/http/sys_mount_test.go b/http/sys_mount_test.go index cddc18ce5b16..c4cc8850551f 100644 --- a/http/sys_mount_test.go +++ b/http/sys_mount_test.go @@ -2,10 +2,11 @@ package http import ( "encoding/json" - "github.com/go-test/deep" "reflect" "testing" + "github.com/go-test/deep" + "github.com/fatih/structs" "github.com/hashicorp/vault/vault" ) @@ -134,8 +135,13 @@ func TestSysMounts(t *testing.T) { if v.(map[string]interface{})["accessor"] == "" { t.Fatalf("no accessor from %s", k) } + if v.(map[string]interface{})["uuid"] == "" { + t.Fatalf("no uuid from %s", k) + } expected[k].(map[string]interface{})["accessor"] = v.(map[string]interface{})["accessor"] + expected[k].(map[string]interface{})["uuid"] = v.(map[string]interface{})["uuid"] expected["data"].(map[string]interface{})[k].(map[string]interface{})["accessor"] = v.(map[string]interface{})["accessor"] + expected["data"].(map[string]interface{})[k].(map[string]interface{})["uuid"] = v.(map[string]interface{})["uuid"] } if diff := deep.Equal(actual, expected); len(diff) > 0 { @@ -300,8 +306,13 @@ func TestSysMount(t *testing.T) { if v.(map[string]interface{})["accessor"] == "" { t.Fatalf("no accessor from %s", k) } + if v.(map[string]interface{})["uuid"] == "" { + t.Fatalf("no uuid from %s", k) + } expected[k].(map[string]interface{})["accessor"] = v.(map[string]interface{})["accessor"] + expected[k].(map[string]interface{})["uuid"] = v.(map[string]interface{})["uuid"] expected["data"].(map[string]interface{})[k].(map[string]interface{})["accessor"] = v.(map[string]interface{})["accessor"] + expected["data"].(map[string]interface{})[k].(map[string]interface{})["uuid"] = v.(map[string]interface{})["uuid"] } if diff := deep.Equal(actual, expected); len(diff) > 0 { @@ -486,8 +497,13 @@ func TestSysRemount(t *testing.T) { if v.(map[string]interface{})["accessor"] == "" { t.Fatalf("no accessor from %s", k) } + if v.(map[string]interface{})["uuid"] == "" { + t.Fatalf("no uuid from %s", k) + } expected[k].(map[string]interface{})["accessor"] = v.(map[string]interface{})["accessor"] + expected[k].(map[string]interface{})["uuid"] = v.(map[string]interface{})["uuid"] expected["data"].(map[string]interface{})[k].(map[string]interface{})["accessor"] = v.(map[string]interface{})["accessor"] + expected["data"].(map[string]interface{})[k].(map[string]interface{})["uuid"] = v.(map[string]interface{})["uuid"] } if !reflect.DeepEqual(actual, expected) { @@ -628,8 +644,13 @@ func TestSysUnmount(t *testing.T) { if v.(map[string]interface{})["accessor"] == "" { t.Fatalf("no accessor from %s", k) } + if v.(map[string]interface{})["uuid"] == "" { + t.Fatalf("no uuid from %s", k) + } expected[k].(map[string]interface{})["accessor"] = v.(map[string]interface{})["accessor"] + expected[k].(map[string]interface{})["uuid"] = v.(map[string]interface{})["uuid"] expected["data"].(map[string]interface{})[k].(map[string]interface{})["accessor"] = v.(map[string]interface{})["accessor"] + expected["data"].(map[string]interface{})[k].(map[string]interface{})["uuid"] = v.(map[string]interface{})["uuid"] } if diff := deep.Equal(actual, expected); len(diff) > 0 { @@ -876,8 +897,13 @@ func TestSysTuneMount(t *testing.T) { if v.(map[string]interface{})["accessor"] == "" { t.Fatalf("no accessor from %s", k) } + if v.(map[string]interface{})["uuid"] == "" { + t.Fatalf("no uuid from %s", k) + } expected[k].(map[string]interface{})["accessor"] = v.(map[string]interface{})["accessor"] + expected[k].(map[string]interface{})["uuid"] = v.(map[string]interface{})["uuid"] expected["data"].(map[string]interface{})[k].(map[string]interface{})["accessor"] = v.(map[string]interface{})["accessor"] + expected["data"].(map[string]interface{})[k].(map[string]interface{})["uuid"] = v.(map[string]interface{})["uuid"] } if diff := deep.Equal(actual, expected); len(diff) > 0 { @@ -1069,8 +1095,13 @@ func TestSysTuneMount(t *testing.T) { if v.(map[string]interface{})["accessor"] == "" { t.Fatalf("no accessor from %s", k) } + if v.(map[string]interface{})["uuid"] == "" { + t.Fatalf("no uuid from %s", k) + } expected[k].(map[string]interface{})["accessor"] = v.(map[string]interface{})["accessor"] + expected[k].(map[string]interface{})["uuid"] = v.(map[string]interface{})["uuid"] expected["data"].(map[string]interface{})[k].(map[string]interface{})["accessor"] = v.(map[string]interface{})["accessor"] + expected["data"].(map[string]interface{})[k].(map[string]interface{})["uuid"] = v.(map[string]interface{})["uuid"] } if diff := deep.Equal(actual, expected); len(diff) > 0 { diff --git a/vault/logical_system.go b/vault/logical_system.go index 5af7b69a8ba1..a0749b441c2d 100644 --- a/vault/logical_system.go +++ b/vault/logical_system.go @@ -661,6 +661,7 @@ func mountInfo(entry *MountEntry) map[string]interface{} { "local": entry.Local, "seal_wrap": entry.SealWrap, "options": entry.Options, + "uuid": entry.UUID, } entryConfig := map[string]interface{}{ "default_lease_ttl": int64(entry.Config.DefaultLeaseTTL.Seconds()), diff --git a/vault/logical_system_test.go b/vault/logical_system_test.go index f8f48ab0a27b..88ade571f846 100644 --- a/vault/logical_system_test.go +++ b/vault/logical_system_test.go @@ -153,6 +153,7 @@ func TestSystemBackend_mounts(t *testing.T) { "type": "kv", "description": "key/value secret storage", "accessor": resp.Data["secret/"].(map[string]interface{})["accessor"], + "uuid": resp.Data["secret/"].(map[string]interface{})["uuid"], "config": map[string]interface{}{ "default_lease_ttl": resp.Data["secret/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64), "max_lease_ttl": resp.Data["secret/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64), @@ -168,6 +169,7 @@ func TestSystemBackend_mounts(t *testing.T) { "type": "system", "description": "system endpoints used for control, policy and debugging", "accessor": resp.Data["sys/"].(map[string]interface{})["accessor"], + "uuid": resp.Data["sys/"].(map[string]interface{})["uuid"], "config": map[string]interface{}{ "default_lease_ttl": resp.Data["sys/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64), "max_lease_ttl": resp.Data["sys/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64), @@ -182,6 +184,7 @@ func TestSystemBackend_mounts(t *testing.T) { "description": "per-token private secret storage", "type": "cubbyhole", "accessor": resp.Data["cubbyhole/"].(map[string]interface{})["accessor"], + "uuid": resp.Data["cubbyhole/"].(map[string]interface{})["uuid"], "config": map[string]interface{}{ "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), @@ -195,6 +198,7 @@ func TestSystemBackend_mounts(t *testing.T) { "description": "identity store", "type": "identity", "accessor": resp.Data["identity/"].(map[string]interface{})["accessor"], + "uuid": resp.Data["identity/"].(map[string]interface{})["uuid"], "config": map[string]interface{}{ "default_lease_ttl": resp.Data["identity/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64), "max_lease_ttl": resp.Data["identity/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64), @@ -246,6 +250,7 @@ func TestSystemBackend_mount(t *testing.T) { "type": "kv", "description": "key/value secret storage", "accessor": resp.Data["secret/"].(map[string]interface{})["accessor"], + "uuid": resp.Data["secret/"].(map[string]interface{})["uuid"], "config": map[string]interface{}{ "default_lease_ttl": resp.Data["secret/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64), "max_lease_ttl": resp.Data["secret/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64), @@ -261,6 +266,7 @@ func TestSystemBackend_mount(t *testing.T) { "type": "system", "description": "system endpoints used for control, policy and debugging", "accessor": resp.Data["sys/"].(map[string]interface{})["accessor"], + "uuid": resp.Data["sys/"].(map[string]interface{})["uuid"], "config": map[string]interface{}{ "default_lease_ttl": resp.Data["sys/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64), "max_lease_ttl": resp.Data["sys/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64), @@ -275,6 +281,7 @@ func TestSystemBackend_mount(t *testing.T) { "description": "per-token private secret storage", "type": "cubbyhole", "accessor": resp.Data["cubbyhole/"].(map[string]interface{})["accessor"], + "uuid": resp.Data["cubbyhole/"].(map[string]interface{})["uuid"], "config": map[string]interface{}{ "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), @@ -288,6 +295,7 @@ func TestSystemBackend_mount(t *testing.T) { "description": "identity store", "type": "identity", "accessor": resp.Data["identity/"].(map[string]interface{})["accessor"], + "uuid": resp.Data["identity/"].(map[string]interface{})["uuid"], "config": map[string]interface{}{ "default_lease_ttl": resp.Data["identity/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64), "max_lease_ttl": resp.Data["identity/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64), @@ -301,6 +309,7 @@ func TestSystemBackend_mount(t *testing.T) { "description": "", "type": "kv", "accessor": resp.Data["prod/secret/"].(map[string]interface{})["accessor"], + "uuid": resp.Data["prod/secret/"].(map[string]interface{})["uuid"], "config": map[string]interface{}{ "default_lease_ttl": int64(2100), "max_lease_ttl": int64(2700), @@ -1441,6 +1450,7 @@ func TestSystemBackend_authTable(t *testing.T) { "type": "token", "description": "token based credentials", "accessor": resp.Data["token/"].(map[string]interface{})["accessor"], + "uuid": resp.Data["token/"].(map[string]interface{})["uuid"], "config": map[string]interface{}{ "default_lease_ttl": int64(0), "max_lease_ttl": int64(0), @@ -1494,6 +1504,7 @@ func TestSystemBackend_enableAuth(t *testing.T) { "type": "noop", "description": "", "accessor": resp.Data["foo/"].(map[string]interface{})["accessor"], + "uuid": resp.Data["foo/"].(map[string]interface{})["uuid"], "config": map[string]interface{}{ "default_lease_ttl": int64(2100), "max_lease_ttl": int64(2700), @@ -1508,6 +1519,7 @@ func TestSystemBackend_enableAuth(t *testing.T) { "type": "token", "description": "token based credentials", "accessor": resp.Data["token/"].(map[string]interface{})["accessor"], + "uuid": resp.Data["token/"].(map[string]interface{})["uuid"], "config": map[string]interface{}{ "default_lease_ttl": int64(0), "max_lease_ttl": int64(0), @@ -2270,6 +2282,7 @@ func TestSystemBackend_InternalUIMounts(t *testing.T) { "type": "kv", "description": "key/value secret storage", "accessor": resp.Data["secret"].(map[string]interface{})["secret/"].(map[string]interface{})["accessor"], + "uuid": resp.Data["secret"].(map[string]interface{})["secret/"].(map[string]interface{})["uuid"], "config": map[string]interface{}{ "default_lease_ttl": resp.Data["secret"].(map[string]interface{})["secret/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64), "max_lease_ttl": resp.Data["secret"].(map[string]interface{})["secret/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64), @@ -2285,6 +2298,7 @@ func TestSystemBackend_InternalUIMounts(t *testing.T) { "type": "system", "description": "system endpoints used for control, policy and debugging", "accessor": resp.Data["secret"].(map[string]interface{})["sys/"].(map[string]interface{})["accessor"], + "uuid": resp.Data["secret"].(map[string]interface{})["sys/"].(map[string]interface{})["uuid"], "config": map[string]interface{}{ "default_lease_ttl": resp.Data["secret"].(map[string]interface{})["sys/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64), "max_lease_ttl": resp.Data["secret"].(map[string]interface{})["sys/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64), @@ -2299,6 +2313,7 @@ func TestSystemBackend_InternalUIMounts(t *testing.T) { "description": "per-token private secret storage", "type": "cubbyhole", "accessor": resp.Data["secret"].(map[string]interface{})["cubbyhole/"].(map[string]interface{})["accessor"], + "uuid": resp.Data["secret"].(map[string]interface{})["cubbyhole/"].(map[string]interface{})["uuid"], "config": map[string]interface{}{ "default_lease_ttl": resp.Data["secret"].(map[string]interface{})["cubbyhole/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64), "max_lease_ttl": resp.Data["secret"].(map[string]interface{})["cubbyhole/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64), @@ -2312,6 +2327,7 @@ func TestSystemBackend_InternalUIMounts(t *testing.T) { "description": "identity store", "type": "identity", "accessor": resp.Data["secret"].(map[string]interface{})["identity/"].(map[string]interface{})["accessor"], + "uuid": resp.Data["secret"].(map[string]interface{})["identity/"].(map[string]interface{})["uuid"], "config": map[string]interface{}{ "default_lease_ttl": resp.Data["secret"].(map[string]interface{})["identity/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64), "max_lease_ttl": resp.Data["secret"].(map[string]interface{})["identity/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64), @@ -2334,6 +2350,7 @@ func TestSystemBackend_InternalUIMounts(t *testing.T) { "type": "token", "description": "token based credentials", "accessor": resp.Data["auth"].(map[string]interface{})["token/"].(map[string]interface{})["accessor"], + "uuid": resp.Data["auth"].(map[string]interface{})["token/"].(map[string]interface{})["uuid"], "local": false, "seal_wrap": false, }, diff --git a/vendor/github.com/hashicorp/vault/api/sys_mounts.go b/vendor/github.com/hashicorp/vault/api/sys_mounts.go index 993a1b67bfea..354b1ee93465 100644 --- a/vendor/github.com/hashicorp/vault/api/sys_mounts.go +++ b/vendor/github.com/hashicorp/vault/api/sys_mounts.go @@ -159,6 +159,7 @@ type MountConfigInput struct { } type MountOutput struct { + UUID string `json:"uuid"` Type string `json:"type"` Description string `json:"description"` Accessor string `json:"accessor"`