KV: Update 'versioned' naming to 'v2' (#4293)
* Update 'versioned' naming to 'v2' * Make sure options are set * Fix description of auth flag * Review feedback
This commit is contained in:
parent
279810a6a6
commit
915e452c0d
@ -3,6 +3,7 @@ package command
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@ -29,6 +30,7 @@ type AuthEnableCommand struct {
|
||||
flagOptions map[string]string
|
||||
flagLocal bool
|
||||
flagSealWrap bool
|
||||
flagVersion int
|
||||
}
|
||||
|
||||
func (c *AuthEnableCommand) Synopsis() string {
|
||||
@ -160,6 +162,13 @@ func (c *AuthEnableCommand) Flags() *FlagSets {
|
||||
Usage: "Enable seal wrapping of critical values in the secrets engine.",
|
||||
})
|
||||
|
||||
f.IntVar(&IntVar{
|
||||
Name: "version",
|
||||
Target: &c.flagVersion,
|
||||
Default: 0,
|
||||
Usage: "Select the version of the auth method to run. Not supported by all auth methods.",
|
||||
})
|
||||
|
||||
return set
|
||||
}
|
||||
|
||||
@ -211,6 +220,13 @@ func (c *AuthEnableCommand) Run(args []string) int {
|
||||
// Append a trailing slash to indicate it's a path in output
|
||||
authPath = ensureTrailingSlash(authPath)
|
||||
|
||||
if c.flagVersion > 0 {
|
||||
if c.flagOptions == nil {
|
||||
c.flagOptions = make(map[string]string)
|
||||
}
|
||||
c.flagOptions["version"] = strconv.Itoa(c.flagVersion)
|
||||
}
|
||||
|
||||
authOpts := &api.EnableAuthOptions{
|
||||
Type: authType,
|
||||
Description: c.flagDescription,
|
||||
|
@ -77,7 +77,7 @@ func (c *KVEnableVersioningCommand) Run(args []string) int {
|
||||
|
||||
if err := client.Sys().TuneMount(mountPath, api.MountConfigInput{
|
||||
Options: map[string]string{
|
||||
"versioned": "true",
|
||||
"version": "2",
|
||||
},
|
||||
}); err != nil {
|
||||
c.UI.Error(fmt.Sprintf("Error tuning secrets engine %s: %s", mountPath, err))
|
||||
|
@ -18,7 +18,7 @@ func kvReadRequest(client *api.Client, path string, params map[string]string) (*
|
||||
if r.Headers == nil {
|
||||
r.Headers = http.Header{}
|
||||
}
|
||||
r.Headers.Add(consts.VaultKVCLIClientHeader, "v1")
|
||||
r.Headers.Add(consts.VaultKVCLIClientHeader, "v2")
|
||||
|
||||
for k, v := range params {
|
||||
r.Params.Set(k, v)
|
||||
@ -53,7 +53,7 @@ func kvListRequest(client *api.Client, path string) (*api.Secret, error) {
|
||||
if r.Headers == nil {
|
||||
r.Headers = http.Header{}
|
||||
}
|
||||
r.Headers.Add(consts.VaultKVCLIClientHeader, "v1")
|
||||
r.Headers.Add(consts.VaultKVCLIClientHeader, "v2")
|
||||
|
||||
// Set this for broader compatibility, but we use LIST above to be able to
|
||||
// handle the wrapping lookup function
|
||||
@ -89,7 +89,7 @@ func kvWriteRequest(client *api.Client, path string, data map[string]interface{}
|
||||
if r.Headers == nil {
|
||||
r.Headers = http.Header{}
|
||||
}
|
||||
r.Headers.Add(consts.VaultKVCLIClientHeader, "v1")
|
||||
r.Headers.Add(consts.VaultKVCLIClientHeader, "v2")
|
||||
if err := r.SetJSONBody(data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -127,7 +127,7 @@ func kvDeleteRequest(client *api.Client, path string) (*api.Secret, error) {
|
||||
if r.Headers == nil {
|
||||
r.Headers = http.Header{}
|
||||
}
|
||||
r.Headers.Add(consts.VaultKVCLIClientHeader, "v1")
|
||||
r.Headers.Add(consts.VaultKVCLIClientHeader, "v2")
|
||||
resp, err := client.RawRequest(r)
|
||||
if resp != nil {
|
||||
defer resp.Body.Close()
|
||||
|
@ -3,6 +3,7 @@ package command
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@ -30,6 +31,7 @@ type SecretsEnableCommand struct {
|
||||
flagOptions map[string]string
|
||||
flagLocal bool
|
||||
flagSealWrap bool
|
||||
flagVersion int
|
||||
}
|
||||
|
||||
func (c *SecretsEnableCommand) Synopsis() string {
|
||||
@ -177,6 +179,13 @@ func (c *SecretsEnableCommand) Flags() *FlagSets {
|
||||
Usage: "Enable seal wrapping of critical values in the secrets engine.",
|
||||
})
|
||||
|
||||
f.IntVar(&IntVar{
|
||||
Name: "version",
|
||||
Target: &c.flagVersion,
|
||||
Default: 0,
|
||||
Usage: "Select the version of the engine to run. Not supported by all engines.",
|
||||
})
|
||||
|
||||
return set
|
||||
}
|
||||
|
||||
@ -226,6 +235,13 @@ func (c *SecretsEnableCommand) Run(args []string) int {
|
||||
}
|
||||
}
|
||||
|
||||
if c.flagVersion > 0 {
|
||||
if c.flagOptions == nil {
|
||||
c.flagOptions = make(map[string]string)
|
||||
}
|
||||
c.flagOptions["version"] = strconv.Itoa(c.flagVersion)
|
||||
}
|
||||
|
||||
// Append a trailing slash to indicate it's a path in output
|
||||
mountPath = ensureTrailingSlash(mountPath)
|
||||
|
||||
|
@ -168,7 +168,7 @@ func TestSysMounts_headerAuth(t *testing.T) {
|
||||
},
|
||||
"local": false,
|
||||
"seal_wrap": false,
|
||||
"options": map[string]interface{}{"versioned": "true"},
|
||||
"options": map[string]interface{}{"version": "2"},
|
||||
},
|
||||
"sys/": map[string]interface{}{
|
||||
"description": "system endpoints used for control, policy and debugging",
|
||||
@ -221,7 +221,7 @@ func TestSysMounts_headerAuth(t *testing.T) {
|
||||
},
|
||||
"local": false,
|
||||
"seal_wrap": false,
|
||||
"options": map[string]interface{}{"versioned": "true"},
|
||||
"options": map[string]interface{}{"version": "2"},
|
||||
},
|
||||
"sys/": map[string]interface{}{
|
||||
"description": "system endpoints used for control, policy and debugging",
|
||||
|
@ -37,7 +37,7 @@ func TestSysMounts(t *testing.T) {
|
||||
},
|
||||
"local": false,
|
||||
"seal_wrap": false,
|
||||
"options": map[string]interface{}{"versioned": "true"},
|
||||
"options": map[string]interface{}{"version": "2"},
|
||||
},
|
||||
"sys/": map[string]interface{}{
|
||||
"description": "system endpoints used for control, policy and debugging",
|
||||
@ -90,7 +90,7 @@ func TestSysMounts(t *testing.T) {
|
||||
},
|
||||
"local": false,
|
||||
"seal_wrap": false,
|
||||
"options": map[string]interface{}{"versioned": "true"},
|
||||
"options": map[string]interface{}{"version": "2"},
|
||||
},
|
||||
"sys/": map[string]interface{}{
|
||||
"description": "system endpoints used for control, policy and debugging",
|
||||
@ -158,7 +158,7 @@ func TestSysMount(t *testing.T) {
|
||||
"type": "kv",
|
||||
"description": "foo",
|
||||
"options": map[string]string{
|
||||
"versioned": "true",
|
||||
"version": "2",
|
||||
},
|
||||
})
|
||||
testResponseStatus(t, resp, 204)
|
||||
@ -185,7 +185,7 @@ func TestSysMount(t *testing.T) {
|
||||
},
|
||||
"local": false,
|
||||
"seal_wrap": false,
|
||||
"options": map[string]interface{}{"versioned": "true"},
|
||||
"options": map[string]interface{}{"version": "2"},
|
||||
},
|
||||
"secret/": map[string]interface{}{
|
||||
"description": "key/value secret storage",
|
||||
@ -198,7 +198,7 @@ func TestSysMount(t *testing.T) {
|
||||
},
|
||||
"local": false,
|
||||
"seal_wrap": false,
|
||||
"options": map[string]interface{}{"versioned": "true"},
|
||||
"options": map[string]interface{}{"version": "2"},
|
||||
},
|
||||
"sys/": map[string]interface{}{
|
||||
"description": "system endpoints used for control, policy and debugging",
|
||||
@ -251,7 +251,7 @@ func TestSysMount(t *testing.T) {
|
||||
},
|
||||
"local": false,
|
||||
"seal_wrap": false,
|
||||
"options": map[string]interface{}{"versioned": "true"},
|
||||
"options": map[string]interface{}{"version": "2"},
|
||||
},
|
||||
"secret/": map[string]interface{}{
|
||||
"description": "key/value secret storage",
|
||||
@ -264,7 +264,7 @@ func TestSysMount(t *testing.T) {
|
||||
},
|
||||
"local": false,
|
||||
"seal_wrap": false,
|
||||
"options": map[string]interface{}{"versioned": "true"},
|
||||
"options": map[string]interface{}{"version": "2"},
|
||||
},
|
||||
"sys/": map[string]interface{}{
|
||||
"description": "system endpoints used for control, policy and debugging",
|
||||
@ -391,7 +391,7 @@ func TestSysRemount(t *testing.T) {
|
||||
},
|
||||
"local": false,
|
||||
"seal_wrap": false,
|
||||
"options": map[string]interface{}{"versioned": "true"},
|
||||
"options": map[string]interface{}{"version": "2"},
|
||||
},
|
||||
"sys/": map[string]interface{}{
|
||||
"description": "system endpoints used for control, policy and debugging",
|
||||
@ -457,7 +457,7 @@ func TestSysRemount(t *testing.T) {
|
||||
},
|
||||
"local": false,
|
||||
"seal_wrap": false,
|
||||
"options": map[string]interface{}{"versioned": "true"},
|
||||
"options": map[string]interface{}{"version": "2"},
|
||||
},
|
||||
"sys/": map[string]interface{}{
|
||||
"description": "system endpoints used for control, policy and debugging",
|
||||
@ -552,7 +552,7 @@ func TestSysUnmount(t *testing.T) {
|
||||
},
|
||||
"local": false,
|
||||
"seal_wrap": false,
|
||||
"options": map[string]interface{}{"versioned": "true"},
|
||||
"options": map[string]interface{}{"version": "2"},
|
||||
},
|
||||
"sys/": map[string]interface{}{
|
||||
"description": "system endpoints used for control, policy and debugging",
|
||||
@ -605,7 +605,7 @@ func TestSysUnmount(t *testing.T) {
|
||||
},
|
||||
"local": false,
|
||||
"seal_wrap": false,
|
||||
"options": map[string]interface{}{"versioned": "true"},
|
||||
"options": map[string]interface{}{"version": "2"},
|
||||
},
|
||||
"sys/": map[string]interface{}{
|
||||
"description": "system endpoints used for control, policy and debugging",
|
||||
@ -793,7 +793,7 @@ func TestSysTuneMount(t *testing.T) {
|
||||
},
|
||||
"local": false,
|
||||
"seal_wrap": false,
|
||||
"options": map[string]interface{}{"versioned": "true"},
|
||||
"options": map[string]interface{}{"version": "2"},
|
||||
},
|
||||
"sys/": map[string]interface{}{
|
||||
"description": "system endpoints used for control, policy and debugging",
|
||||
@ -859,7 +859,7 @@ func TestSysTuneMount(t *testing.T) {
|
||||
},
|
||||
"local": false,
|
||||
"seal_wrap": false,
|
||||
"options": map[string]interface{}{"versioned": "true"},
|
||||
"options": map[string]interface{}{"version": "2"},
|
||||
},
|
||||
"sys/": map[string]interface{}{
|
||||
"description": "system endpoints used for control, policy and debugging",
|
||||
@ -955,7 +955,7 @@ func TestSysTuneMount(t *testing.T) {
|
||||
// mark as versioned
|
||||
resp = testHttpPost(t, token, addr+"/v1/sys/mounts/foo/tune", map[string]interface{}{
|
||||
"options": map[string]string{
|
||||
"versioned": "true",
|
||||
"version": "2",
|
||||
},
|
||||
})
|
||||
testResponseStatus(t, resp, 200)
|
||||
@ -980,7 +980,7 @@ func TestSysTuneMount(t *testing.T) {
|
||||
},
|
||||
"local": false,
|
||||
"seal_wrap": false,
|
||||
"options": map[string]interface{}{"versioned": "true"},
|
||||
"options": map[string]interface{}{"version": "2"},
|
||||
},
|
||||
"secret/": map[string]interface{}{
|
||||
"description": "key/value secret storage",
|
||||
@ -993,7 +993,7 @@ func TestSysTuneMount(t *testing.T) {
|
||||
},
|
||||
"local": false,
|
||||
"seal_wrap": false,
|
||||
"options": map[string]interface{}{"versioned": "true"},
|
||||
"options": map[string]interface{}{"version": "2"},
|
||||
},
|
||||
"sys/": map[string]interface{}{
|
||||
"description": "system endpoints used for control, policy and debugging",
|
||||
@ -1046,7 +1046,7 @@ func TestSysTuneMount(t *testing.T) {
|
||||
},
|
||||
"local": false,
|
||||
"seal_wrap": false,
|
||||
"options": map[string]interface{}{"versioned": "true"},
|
||||
"options": map[string]interface{}{"version": "2"},
|
||||
},
|
||||
"secret/": map[string]interface{}{
|
||||
"description": "key/value secret storage",
|
||||
@ -1059,7 +1059,7 @@ func TestSysTuneMount(t *testing.T) {
|
||||
},
|
||||
"local": false,
|
||||
"seal_wrap": false,
|
||||
"options": map[string]interface{}{"versioned": "true"},
|
||||
"options": map[string]interface{}{"version": "2"},
|
||||
},
|
||||
"sys/": map[string]interface{}{
|
||||
"description": "system endpoints used for control, policy and debugging",
|
||||
@ -1131,12 +1131,12 @@ func TestSysTuneMount(t *testing.T) {
|
||||
"default_lease_ttl": json.Number("259196400"),
|
||||
"max_lease_ttl": json.Number("259200000"),
|
||||
"force_no_cache": false,
|
||||
"options": map[string]interface{}{"versioned": "true"},
|
||||
"options": map[string]interface{}{"version": "2"},
|
||||
},
|
||||
"default_lease_ttl": json.Number("259196400"),
|
||||
"max_lease_ttl": json.Number("259200000"),
|
||||
"force_no_cache": false,
|
||||
"options": map[string]interface{}{"versioned": "true"},
|
||||
"options": map[string]interface{}{"version": "2"},
|
||||
}
|
||||
|
||||
testResponseStatus(t, resp, 200)
|
||||
@ -1166,12 +1166,12 @@ func TestSysTuneMount(t *testing.T) {
|
||||
"default_lease_ttl": json.Number("40"),
|
||||
"max_lease_ttl": json.Number("80"),
|
||||
"force_no_cache": false,
|
||||
"options": map[string]interface{}{"versioned": "true"},
|
||||
"options": map[string]interface{}{"version": "2"},
|
||||
},
|
||||
"default_lease_ttl": json.Number("40"),
|
||||
"max_lease_ttl": json.Number("80"),
|
||||
"force_no_cache": false,
|
||||
"options": map[string]interface{}{"versioned": "true"},
|
||||
"options": map[string]interface{}{"version": "2"},
|
||||
}
|
||||
|
||||
testResponseStatus(t, resp, 200)
|
||||
@ -1263,14 +1263,14 @@ func TestSysTuneMount_nonHMACKeys(t *testing.T) {
|
||||
"force_no_cache": false,
|
||||
"audit_non_hmac_request_keys": []interface{}{"foo"},
|
||||
"audit_non_hmac_response_keys": []interface{}{"bar"},
|
||||
"options": map[string]interface{}{"versioned": "true"},
|
||||
"options": map[string]interface{}{"version": "2"},
|
||||
},
|
||||
"default_lease_ttl": json.Number("2764800"),
|
||||
"max_lease_ttl": json.Number("2764800"),
|
||||
"force_no_cache": false,
|
||||
"audit_non_hmac_request_keys": []interface{}{"foo"},
|
||||
"audit_non_hmac_response_keys": []interface{}{"bar"},
|
||||
"options": map[string]interface{}{"versioned": "true"},
|
||||
"options": map[string]interface{}{"version": "2"},
|
||||
}
|
||||
testResponseBody(t, resp, &actual)
|
||||
expected["request_id"] = actual["request_id"]
|
||||
@ -1305,12 +1305,12 @@ func TestSysTuneMount_nonHMACKeys(t *testing.T) {
|
||||
"default_lease_ttl": json.Number("2764800"),
|
||||
"max_lease_ttl": json.Number("2764800"),
|
||||
"force_no_cache": false,
|
||||
"options": map[string]interface{}{"versioned": "true"},
|
||||
"options": map[string]interface{}{"version": "2"},
|
||||
},
|
||||
"default_lease_ttl": json.Number("2764800"),
|
||||
"max_lease_ttl": json.Number("2764800"),
|
||||
"force_no_cache": false,
|
||||
"options": map[string]interface{}{"versioned": "true"},
|
||||
"options": map[string]interface{}{"version": "2"},
|
||||
}
|
||||
testResponseBody(t, resp, &actual)
|
||||
expected["request_id"] = actual["request_id"]
|
||||
@ -1341,12 +1341,12 @@ func TestSysTuneMount_listingVisibility(t *testing.T) {
|
||||
"default_lease_ttl": json.Number("2764800"),
|
||||
"max_lease_ttl": json.Number("2764800"),
|
||||
"force_no_cache": false,
|
||||
"options": map[string]interface{}{"versioned": "true"},
|
||||
"options": map[string]interface{}{"version": "2"},
|
||||
},
|
||||
"default_lease_ttl": json.Number("2764800"),
|
||||
"max_lease_ttl": json.Number("2764800"),
|
||||
"force_no_cache": false,
|
||||
"options": map[string]interface{}{"versioned": "true"},
|
||||
"options": map[string]interface{}{"version": "2"},
|
||||
}
|
||||
testResponseBody(t, resp, &actual)
|
||||
expected["request_id"] = actual["request_id"]
|
||||
@ -1377,13 +1377,13 @@ func TestSysTuneMount_listingVisibility(t *testing.T) {
|
||||
"max_lease_ttl": json.Number("2764800"),
|
||||
"force_no_cache": false,
|
||||
"listing_visibility": "unauth",
|
||||
"options": map[string]interface{}{"versioned": "true"},
|
||||
"options": map[string]interface{}{"version": "2"},
|
||||
},
|
||||
"default_lease_ttl": json.Number("2764800"),
|
||||
"max_lease_ttl": json.Number("2764800"),
|
||||
"force_no_cache": false,
|
||||
"listing_visibility": "unauth",
|
||||
"options": map[string]interface{}{"versioned": "true"},
|
||||
"options": map[string]interface{}{"version": "2"},
|
||||
}
|
||||
testResponseBody(t, resp, &actual)
|
||||
expected["request_id"] = actual["request_id"]
|
||||
@ -1419,13 +1419,13 @@ func TestSysTuneMount_passthroughRequestHeaders(t *testing.T) {
|
||||
"data": map[string]interface{}{
|
||||
"default_lease_ttl": json.Number("2764800"),
|
||||
"max_lease_ttl": json.Number("2764800"),
|
||||
"options": map[string]interface{}{"versioned": "true"},
|
||||
"options": map[string]interface{}{"version": "2"},
|
||||
"force_no_cache": false,
|
||||
"passthrough_request_headers": []interface{}{"X-Vault-Foo"},
|
||||
},
|
||||
"default_lease_ttl": json.Number("2764800"),
|
||||
"max_lease_ttl": json.Number("2764800"),
|
||||
"options": map[string]interface{}{"versioned": "true"},
|
||||
"options": map[string]interface{}{"version": "2"},
|
||||
"force_no_cache": false,
|
||||
"passthrough_request_headers": []interface{}{"X-Vault-Foo"},
|
||||
}
|
||||
@ -1457,12 +1457,12 @@ func TestSysTuneMount_passthroughRequestHeaders(t *testing.T) {
|
||||
"default_lease_ttl": json.Number("2764800"),
|
||||
"max_lease_ttl": json.Number("2764800"),
|
||||
"force_no_cache": false,
|
||||
"options": map[string]interface{}{"versioned": "true"},
|
||||
"options": map[string]interface{}{"version": "2"},
|
||||
},
|
||||
"default_lease_ttl": json.Number("2764800"),
|
||||
"max_lease_ttl": json.Number("2764800"),
|
||||
"force_no_cache": false,
|
||||
"options": map[string]interface{}{"versioned": "true"},
|
||||
"options": map[string]interface{}{"version": "2"},
|
||||
}
|
||||
testResponseBody(t, resp, &actual)
|
||||
expected["request_id"] = actual["request_id"]
|
||||
|
@ -1643,6 +1643,22 @@ func (b *SystemBackend) handleMount(ctx context.Context, req *logical.Request, d
|
||||
"plugin_name must be provided for plugin backend"),
|
||||
logical.ErrInvalidRequest
|
||||
}
|
||||
|
||||
case "kv-v1":
|
||||
// Alias KV v1
|
||||
logicalType = "kv"
|
||||
if options == nil {
|
||||
options = map[string]string{}
|
||||
}
|
||||
options["version"] = "1"
|
||||
|
||||
case "kv-v2":
|
||||
// Alias KV v2
|
||||
logicalType = "kv"
|
||||
if options == nil {
|
||||
options = map[string]string{}
|
||||
}
|
||||
options["version"] = "2"
|
||||
}
|
||||
|
||||
// Copy over the force no cache if set
|
||||
@ -1665,15 +1681,6 @@ func (b *SystemBackend) handleMount(ctx context.Context, req *logical.Request, d
|
||||
config.PassthroughRequestHeaders = apiConfig.PassthroughRequestHeaders
|
||||
}
|
||||
|
||||
// Alias versioned KV
|
||||
if logicalType == "vkv" {
|
||||
logicalType = "kv"
|
||||
if options == nil {
|
||||
options = map[string]string{}
|
||||
}
|
||||
options["versioned"] = "true"
|
||||
}
|
||||
|
||||
// Create the mount entry
|
||||
me := &MountEntry{
|
||||
Table: mountTableType,
|
||||
@ -2099,16 +2106,16 @@ func (b *SystemBackend) handleTuneWriteCommon(ctx context.Context, path string,
|
||||
b.Core.logger.Info("core: mount tuning of options", "path", path, "options", options)
|
||||
// Special case to make sure we can not disable versioning once it's
|
||||
// enabeled. If the vkv backend suports downgrading this can be removed.
|
||||
meVersioned, err := parseutil.ParseBool(mountEntry.Options["versioned"])
|
||||
meVersion, err := parseutil.ParseInt(mountEntry.Options["version"])
|
||||
if err != nil {
|
||||
return nil, errwrap.Wrapf("unable to parse mount entry: {{err}}", err)
|
||||
}
|
||||
optVersioned, err := parseutil.ParseBool(options["versioned"])
|
||||
optVersion, err := parseutil.ParseInt(options["version"])
|
||||
if err != nil {
|
||||
return handleError(errwrap.Wrapf("unable to parse options: {{err}}", err))
|
||||
}
|
||||
if meVersioned && !optVersioned {
|
||||
return logical.ErrorResponse("cannot disable versioning once it's enabled"), logical.ErrInvalidRequest
|
||||
if meVersion > optVersion {
|
||||
return logical.ErrorResponse(fmt.Sprintf("cannot downgrade mount from version %d", meVersion)), logical.ErrInvalidRequest
|
||||
}
|
||||
|
||||
oldVal := mountEntry.Options
|
||||
@ -2125,15 +2132,9 @@ func (b *SystemBackend) handleTuneWriteCommon(ctx context.Context, path string,
|
||||
return handleError(err)
|
||||
}
|
||||
|
||||
// Another special case to add a warning if we are going to be
|
||||
// upgrading.
|
||||
oldVersioned, err := parseutil.ParseBool(oldVal["versioned"])
|
||||
if err != nil {
|
||||
return nil, errwrap.Wrapf("unable to parse mount entry: {{err}}", err)
|
||||
}
|
||||
if !oldVersioned && optVersioned {
|
||||
if meVersion < optVersion {
|
||||
resp = &logical.Response{}
|
||||
resp.AddWarning("Uprading from non-versioned to versioned data. This backend will be unavailable for a brief period and will resume service shortly.")
|
||||
resp.AddWarning(fmt.Sprintf("Upgrading mount from version %d to version %d. This mount will be unavailable for a brief period and will resume service shortly.", meVersion, optVersion))
|
||||
}
|
||||
|
||||
// Reload the backend to kick off the upgrade process.
|
||||
|
@ -132,7 +132,7 @@ func TestSystemBackend_mounts(t *testing.T) {
|
||||
"local": false,
|
||||
"seal_wrap": false,
|
||||
"options": map[string]string{
|
||||
"versioned": "true",
|
||||
"version": "2",
|
||||
},
|
||||
},
|
||||
"sys/": map[string]interface{}{
|
||||
@ -195,7 +195,7 @@ func TestSystemBackend_mount(t *testing.T) {
|
||||
req.Data["local"] = true
|
||||
req.Data["seal_wrap"] = true
|
||||
req.Data["options"] = map[string]string{
|
||||
"versioned": "true",
|
||||
"version": "2",
|
||||
}
|
||||
|
||||
resp, err := b.HandleRequest(context.Background(), req)
|
||||
@ -228,7 +228,7 @@ func TestSystemBackend_mount(t *testing.T) {
|
||||
"local": false,
|
||||
"seal_wrap": false,
|
||||
"options": map[string]string{
|
||||
"versioned": "true",
|
||||
"version": "2",
|
||||
},
|
||||
},
|
||||
"sys/": map[string]interface{}{
|
||||
@ -286,7 +286,7 @@ func TestSystemBackend_mount(t *testing.T) {
|
||||
"local": true,
|
||||
"seal_wrap": true,
|
||||
"options": map[string]string{
|
||||
"versioned": "true",
|
||||
"version": "2",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -959,7 +959,7 @@ func (c *Core) defaultMountTable() *MountTable {
|
||||
Accessor: mountAccessor,
|
||||
BackendAwareUUID: bUUID,
|
||||
Options: map[string]string{
|
||||
"versioned": "true",
|
||||
"version": "2",
|
||||
},
|
||||
}
|
||||
table.Entries = append(table.Entries, kvMount)
|
||||
|
@ -8,10 +8,10 @@ description: |-
|
||||
|
||||
# KV Secrets Engine (API)
|
||||
|
||||
This backend can be run in one of two modes. Each of which have a distinct API.
|
||||
Choose the mode below you are running. For more information on the two modes see
|
||||
the [Vault kv documentation](/docs/secrets/kv/index.html).
|
||||
This backend can be run in one of two versions. Each of which have a distinct API.
|
||||
Choose the version below you are running. For more information on the KV secrets
|
||||
engine see the [Vault kv documentation](/docs/secrets/kv/index.html).
|
||||
|
||||
- [Normal KV API](/api/secret/kv/kv.html)
|
||||
- [KV Version 1 API](/api/secret/kv/kv-v1.html)
|
||||
|
||||
- [Versioned KV API](/api/secret/kv/versioned-kv.html)
|
||||
- [KV Version 2 API](/api/secret/kv/kv-v2.html)
|
||||
|
@ -1,12 +1,12 @@
|
||||
---
|
||||
layout: "api"
|
||||
page_title: "KV - Secrets Engines - HTTP API"
|
||||
sidebar_current: "docs-http-secret-kv-nonversioned"
|
||||
sidebar_current: "docs-http-secret-kv-v1"
|
||||
description: |-
|
||||
This is the API documentation for the Vault KV secrets engine.
|
||||
---
|
||||
|
||||
# KV Secrets Engine (API)
|
||||
# KV Secrets Engine - Version 1 (API)
|
||||
|
||||
This is the API documentation for the Vault KV secrets engine. For general
|
||||
information about the usage and operation of the kv secrets engine, please
|
@ -1,12 +1,12 @@
|
||||
---
|
||||
layout: "api"
|
||||
page_title: "KV - Secrets Engines - HTTP API"
|
||||
sidebar_current: "docs-http-secret-kv-versioned"
|
||||
sidebar_current: "docs-http-secret-kv-v2"
|
||||
description: |-
|
||||
This is the API documentation for the Vault KV secrets engine.
|
||||
---
|
||||
|
||||
# Versioned KV Secrets Engine (API)
|
||||
# KV Secrets Engine - Version 2 (API)
|
||||
|
||||
This is the API documentation for the Vault KV secrets engine while running in
|
||||
versioned mode. For general information about the usage and operation of the kv
|
||||
@ -19,7 +19,7 @@ possible to enable secrets engines at any location, please update your API calls
|
||||
accordingly.
|
||||
|
||||
|
||||
## Configure the Versioned K/V Backend
|
||||
## Configure the KV Engine
|
||||
|
||||
This path configures backend level settings that are applied to every key in the
|
||||
key-value store.
|
@ -14,7 +14,7 @@ modes. It can be a generic Key-Value store that stores one value for a key.
|
||||
Versioning can be enabled and a configurable number of versions for each key
|
||||
will be stored.
|
||||
|
||||
## Non-Versioned Mode
|
||||
## KV Version 1
|
||||
|
||||
When running the `kv` secrets backend non-versioned only the most recently
|
||||
written value for a key will be preserved. The benefits of non-versioned `kv`
|
||||
@ -23,15 +23,15 @@ is stored. Additionally, requests going to a backend configured this way will be
|
||||
more performant because for any given request there will be fewer storage calls
|
||||
and no locking.
|
||||
|
||||
More information about running in this mode can be found in the [K/V
|
||||
Docs](/docs/secrets/kv/kv.html)
|
||||
More information about running in this mode can be found in the [K/V Version 1
|
||||
Docs](/docs/secrets/kv/kv-v1.html)
|
||||
|
||||
## Versioned Mode
|
||||
## KV Version 2
|
||||
|
||||
When running the `kv` backend in versioned mode a key can retain a configurable
|
||||
number of versions. This defaults to 10 versions. The older versions' metadata
|
||||
and data can be retrieved. Additionally, Check-and-Set operations can be used to
|
||||
avoid overwritting data unintentionally.
|
||||
When running v2 of the `kv` backend a key can retain a configurable number of
|
||||
versions. This defaults to 10 versions. The older versions' metadata and data
|
||||
can be retrieved. Additionally, Check-and-Set operations can be used to avoid
|
||||
overwritting data unintentionally.
|
||||
|
||||
When a version is deleted the underlying data is not removed, rather it is
|
||||
marked as deleted. Deleted versions can be undeleted. To permanently remove a
|
||||
@ -40,5 +40,5 @@ versions and metadata for a key can be deleted by deleting on the metadata
|
||||
command or API endpoint. Each of these operations can be ACL'ed differently,
|
||||
restricting who has permissions to soft delete, undelete, or fully remove data.
|
||||
|
||||
More information about running in this mode can be found in the [Versioned K/V
|
||||
Docs](/docs/secrets/kv/versioned-kv.html)
|
||||
More information about running in this mode can be found in the [K/V Version 2
|
||||
Docs](/docs/secrets/kv/kv-v2.html)
|
||||
|
@ -1,12 +1,12 @@
|
||||
---
|
||||
layout: "docs"
|
||||
page_title: "KV - Secrets Engines"
|
||||
sidebar_current: "docs-secrets-kv-nonversioned"
|
||||
sidebar_current: "docs-secrets-kv-v1"
|
||||
description: |-
|
||||
The KV secrets engine can store arbitrary secrets.
|
||||
---
|
||||
|
||||
# KV Secrets Engine
|
||||
# KV Secrets Engine - Version 1
|
||||
|
||||
The `kv` secrets engine is used to store arbitrary secrets within the
|
||||
configured physical storage for Vault.
|
||||
@ -28,10 +28,10 @@ secret's path.
|
||||
|
||||
## Setup
|
||||
|
||||
To enable a non-versioned kv store:
|
||||
To enable a version 1 kv store:
|
||||
|
||||
```
|
||||
vault secrets enable kv
|
||||
vault secrets enable -version=1 kv
|
||||
```
|
||||
|
||||
## Usage
|
||||
@ -106,5 +106,5 @@ ttl 30m
|
||||
## API
|
||||
|
||||
The KV secrets engine has a full HTTP API. Please see the
|
||||
[KV secrets engine API](/api/secret/kv/kv.html) for more
|
||||
[KV secrets engine API](/api/secret/kv/kv-v1.html) for more
|
||||
details.
|
@ -1,12 +1,12 @@
|
||||
---
|
||||
layout: "docs"
|
||||
page_title: "KV - Secrets Engines"
|
||||
sidebar_current: "docs-secrets-kv-versioned"
|
||||
sidebar_current: "docs-secrets-kv-v2"
|
||||
description: |-
|
||||
The KV secrets engine can store arbitrary secrets.
|
||||
---
|
||||
|
||||
# Versioned KV Secrets Engine
|
||||
# KV Secrets Engine - Version 2
|
||||
|
||||
The `kv` secrets engine is used to store arbitrary secrets within the
|
||||
configured physical storage for Vault.
|
||||
@ -25,20 +25,20 @@ Most secrets engines must be configured in advance before they can perform their
|
||||
functions. These steps are usually completed by an operator or configuration
|
||||
management tool.
|
||||
|
||||
A versioned `kv` secrets engine can be enabled by:
|
||||
A v2 `kv` secrets engine can be enabled by:
|
||||
|
||||
```
|
||||
$ vault secrets enable vkv
|
||||
$ vault secrets enable -version=2 kv
|
||||
```
|
||||
|
||||
Additionally, the versioned `kv` secrets engine is enabled by default at the
|
||||
Additionally, the v2 `kv` secrets engine is enabled by default at the
|
||||
path `secret/`. It can be disabled, moved, or enabled multiple times at
|
||||
different paths. Each instance of the KV secrets engine is isolated and unique.
|
||||
|
||||
## Upgrading from Non-Versioned
|
||||
## Upgrading from Version 1
|
||||
|
||||
An existing non-versioned kv can be easily upgraded to a versioned key/value
|
||||
store with the CLI command:
|
||||
An existing version 1 kv can be easily upgraded to a version 2 KV store with the
|
||||
CLI command:
|
||||
|
||||
```
|
||||
$ vault kv enable-versioning secret/
|
||||
@ -51,7 +51,7 @@ or via the API:
|
||||
$ cat payload.json
|
||||
{
|
||||
"options": {
|
||||
"versioned": "true"
|
||||
"version": "2"
|
||||
}
|
||||
}
|
||||
|
||||
@ -68,13 +68,13 @@ process could take a long time, so plan accordingly.
|
||||
|
||||
## ACL Rules
|
||||
|
||||
The versioned kv store uses a prefixed API, which is different from the
|
||||
non-versioned store. Before upgrading from a non-versioned kv the ACL rules
|
||||
should be changed. Also different paths in the versioned API can be ACL'ed
|
||||
The version 2 kv store uses a prefixed API, which is different from the
|
||||
version 1 API. Before upgrading from a version 1 kv the ACL rules
|
||||
should be changed. Also different paths in the version 2 API can be ACL'ed
|
||||
differently.
|
||||
|
||||
Writing and reading versions are prefixed with the `data/` path. This policy
|
||||
that worked for the non-versioned kv:
|
||||
that worked for the version 1 kv:
|
||||
|
||||
```
|
||||
path "secret/dev/team-1/*" {
|
||||
@ -146,7 +146,7 @@ path "secret/metadata/dev/team-1/*" {
|
||||
}
|
||||
```
|
||||
|
||||
See the [API Specification](/api/secret/kv/versioned-kv.html) for more
|
||||
See the [API Specification](/api/secret/kv/kv-v2.html) for more
|
||||
information.
|
||||
|
||||
## Usage
|
||||
@ -381,5 +381,5 @@ See the commands below for more information:
|
||||
## API
|
||||
|
||||
The KV secrets engine has a full HTTP API. Please see the
|
||||
[KV secrets engine API](/api/secret/kv/versioned-kv.html) for more
|
||||
[KV secrets engine API](/api/secret/kv/kv-v2.html) for more
|
||||
details.
|
@ -59,11 +59,11 @@
|
||||
<li<%= sidebar_current("docs-http-secret-kv") %>>
|
||||
<a href="/api/secret/kv/index.html">Key/Value</a>
|
||||
<ul class="nav">
|
||||
<li<%= sidebar_current("docs-http-secret-kv-nonversioned") %>>
|
||||
<a href="/api/secret/kv/kv.html">K/V</a>
|
||||
<li<%= sidebar_current("docs-http-secret-kv-v1") %>>
|
||||
<a href="/api/secret/kv/kv-v1.html">K/V Version 1</a>
|
||||
</li>
|
||||
<li<%= sidebar_current("docs-http-secret-kv-versioned") %>>
|
||||
<a href="/api/secret/kv/versioned-kv.html">Versioned K/V</a>
|
||||
<li<%= sidebar_current("docs-http-secret-kv-v2") %>>
|
||||
<a href="/api/secret/kv/kv-v2.html">K/V Version 2</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
@ -397,11 +397,11 @@
|
||||
<li<%= sidebar_current("docs-secrets-kv") %>>
|
||||
<a href="/docs/secrets/kv/index.html">Key/Value</a>
|
||||
<ul class="nav">
|
||||
<li<%= sidebar_current("docs-secrets-kv-nonversioned") %>>
|
||||
<a href="/docs/secrets/kv/kv.html">K/V</a>
|
||||
<li<%= sidebar_current("docs-secrets-kv-v1") %>>
|
||||
<a href="/docs/secrets/kv/kv-v1.html">K/V Version 1</a>
|
||||
</li>
|
||||
<li<%= sidebar_current("docs-secrets-kv-versioned") %>>
|
||||
<a href="/docs/secrets/kv/versioned-kv.html">Versioned K/V</a>
|
||||
<li<%= sidebar_current("docs-secrets-kv-v2") %>>
|
||||
<a href="/docs/secrets/kv/kv-v2.html">K/V Version 2</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
Loading…
Reference in New Issue
Block a user