From bb9a3cb3982401e77c0d0db009c286bfcda406de Mon Sep 17 00:00:00 2001 From: Vault Automation Date: Wed, 7 Jan 2026 17:40:37 -0700 Subject: [PATCH] Copy ui: Add Configuration path for KV v2 secrets into main (#11585) (#11646) * Copy https://github.com/hashicorp/vault/pull/31679 into main * ui: Add Configuration path for KV v2 secrets * ui: Add Configuration metadata path for KV v2 secrets * rename changelog for ent repo --------- Co-authored-by: RamdaneBelkhir Co-authored-by: claire bontempo Co-authored-by: claire bontempo <68122737+hellobontempo@users.noreply.github.com> --- changelog/_11585.txt | 3 ++ ui/lib/kv/addon/components/kv-paths-card.hbs | 2 +- ui/lib/kv/addon/components/kv-paths-card.js | 10 ++++++ ...-v2-workflow-version-history-paths-test.js | 36 +++++++++++++++---- .../components/kv/kv-paths-card-test.js | 7 ++++ .../kv/page/kv-page-overview-test.js | 12 +++---- 6 files changed, 57 insertions(+), 13 deletions(-) create mode 100644 changelog/_11585.txt diff --git a/changelog/_11585.txt b/changelog/_11585.txt new file mode 100644 index 0000000000..f3fa711e1b --- /dev/null +++ b/changelog/_11585.txt @@ -0,0 +1,3 @@ +```release-note:improvement +ui: Add "Configuration path" and "Configuration metadata path" fields to KV v2 secret paths page showing paths without /v1/ prefix for use in policies, Vault Agent configurations, and other tools that reference the logical path. +``` diff --git a/ui/lib/kv/addon/components/kv-paths-card.hbs b/ui/lib/kv/addon/components/kv-paths-card.hbs index 66f34db3eb..ce74e81b44 100644 --- a/ui/lib/kv/addon/components/kv-paths-card.hbs +++ b/ui/lib/kv/addon/components/kv-paths-card.hbs @@ -9,7 +9,7 @@ {{#if @isCondensed}} - The paths to use when referring to this secret in API or CLI. + The paths to use when referring to this secret in API, policies, or CLI. {{/if}} diff --git a/ui/lib/kv/addon/components/kv-paths-card.js b/ui/lib/kv/addon/components/kv-paths-card.js index be3f9813e9..a1c1c881a3 100644 --- a/ui/lib/kv/addon/components/kv-paths-card.js +++ b/ui/lib/kv/addon/components/kv-paths-card.js @@ -39,6 +39,11 @@ export default class KvPathsCard extends Component { snippet: namespace ? `/v1/${encodePath(namespace)}/${data}` : `/v1/${data}`, text: 'Use this path when referring to this secret in the API.', }, + { + label: 'Configuration path', + snippet: namespace ? `${encodePath(namespace)}/${data}` : data, + text: 'Use this path in policies, Vault Agent configurations, and other tools that reference the logical path.', + }, { label: 'CLI path', snippet: namespace ? `-namespace=${namespace} ${cli}` : cli, @@ -52,6 +57,11 @@ export default class KvPathsCard extends Component { snippet: namespace ? `/v1/${encodePath(namespace)}/${metadata}` : `/v1/${metadata}`, text: `Use this path when referring to this secret's metadata in the API and permanent secret deletion.`, }, + { + label: 'Configuration metadata path', + snippet: namespace ? `${encodePath(namespace)}/${metadata}` : metadata, + text: 'Use this path in policies and other tools that reference the logical metadata path.', + }, ]), ]; } diff --git a/ui/tests/acceptance/secrets/backend/kv/kv-v2-workflow-version-history-paths-test.js b/ui/tests/acceptance/secrets/backend/kv/kv-v2-workflow-version-history-paths-test.js index ba794c297a..cdc152481b 100644 --- a/ui/tests/acceptance/secrets/backend/kv/kv-v2-workflow-version-history-paths-test.js +++ b/ui/tests/acceptance/secrets/backend/kv/kv-v2-workflow-version-history-paths-test.js @@ -91,12 +91,16 @@ module('Acceptance | kv-v2 workflow | version history, paths', function (hooks) `/vault/secrets-engines/${this.urlPath}/paths`, 'navigates to secret paths route' ); - assert.dom(PAGE.infoRow).exists({ count: 3 }, 'shows 3 rows of information'); + assert.dom(PAGE.infoRow).exists({ count: 5 }, 'shows 5 rows of information'); assert.dom(PAGE.infoRowValue('API path')).hasText(`/v1/${this.backend}/data/${this.secretPath}`); + assert.dom(PAGE.infoRowValue('Configuration path')).hasText(`${this.backend}/data/${this.secretPath}`); assert.dom(PAGE.infoRowValue('CLI path')).hasText(`-mount="${this.backend}" "${this.secretPath}"`); assert .dom(PAGE.infoRowValue('API path for metadata')) .hasText(`/v1/${this.backend}/metadata/${this.secretPath}`); + assert + .dom(PAGE.infoRowValue('Configuration metadata path')) + .hasText(`${this.backend}/metadata/${this.secretPath}`); }); }); @@ -117,12 +121,16 @@ module('Acceptance | kv-v2 workflow | version history, paths', function (hooks) `/vault/secrets-engines/${this.urlPath}/paths`, 'navigates to secret paths route' ); - assert.dom(PAGE.infoRow).exists({ count: 3 }, 'shows 3 rows of information'); + assert.dom(PAGE.infoRow).exists({ count: 5 }, 'shows 5 rows of information'); assert.dom(PAGE.infoRowValue('API path')).hasText(`/v1/${this.backend}/data/${this.secretPath}`); + assert.dom(PAGE.infoRowValue('Configuration path')).hasText(`${this.backend}/data/${this.secretPath}`); assert.dom(PAGE.infoRowValue('CLI path')).hasText(`-mount="${this.backend}" "${this.secretPath}"`); assert .dom(PAGE.infoRowValue('API path for metadata')) .hasText(`/v1/${this.backend}/metadata/${this.secretPath}`); + assert + .dom(PAGE.infoRowValue('Configuration metadata path')) + .hasText(`${this.backend}/metadata/${this.secretPath}`); }); }); @@ -143,12 +151,16 @@ module('Acceptance | kv-v2 workflow | version history, paths', function (hooks) `/vault/secrets-engines/${this.urlPath}/paths`, 'navigates to secret paths route' ); - assert.dom(PAGE.infoRow).exists({ count: 3 }, 'shows 3 rows of information'); + assert.dom(PAGE.infoRow).exists({ count: 5 }, 'shows 5 rows of information'); assert.dom(PAGE.infoRowValue('API path')).hasText(`/v1/${this.backend}/data/${this.secretPath}`); + assert.dom(PAGE.infoRowValue('Configuration path')).hasText(`${this.backend}/data/${this.secretPath}`); assert.dom(PAGE.infoRowValue('CLI path')).hasText(`-mount="${this.backend}" "${this.secretPath}"`); assert .dom(PAGE.infoRowValue('API path for metadata')) .hasText(`/v1/${this.backend}/metadata/${this.secretPath}`); + assert + .dom(PAGE.infoRowValue('Configuration metadata path')) + .hasText(`${this.backend}/metadata/${this.secretPath}`); }); }); @@ -191,12 +203,16 @@ module('Acceptance | kv-v2 workflow | version history, paths', function (hooks) `/vault/secrets-engines/${this.urlPath}/paths`, 'navigates to secret paths route' ); - assert.dom(PAGE.infoRow).exists({ count: 3 }, 'shows 3 rows of information'); + assert.dom(PAGE.infoRow).exists({ count: 5 }, 'shows 5 rows of information'); assert.dom(PAGE.infoRowValue('API path')).hasText(`/v1/${this.backend}/data/${this.secretPath}`); + assert.dom(PAGE.infoRowValue('Configuration path')).hasText(`${this.backend}/data/${this.secretPath}`); assert.dom(PAGE.infoRowValue('CLI path')).hasText(`-mount="${this.backend}" "${this.secretPath}"`); assert .dom(PAGE.infoRowValue('API path for metadata')) .hasText(`/v1/${this.backend}/metadata/${this.secretPath}`); + assert + .dom(PAGE.infoRowValue('Configuration metadata path')) + .hasText(`${this.backend}/metadata/${this.secretPath}`); }); }); @@ -217,12 +233,16 @@ module('Acceptance | kv-v2 workflow | version history, paths', function (hooks) `/vault/secrets-engines/${this.urlPath}/paths`, 'navigates to secret paths route' ); - assert.dom(PAGE.infoRow).exists({ count: 3 }, 'shows 3 rows of information'); + assert.dom(PAGE.infoRow).exists({ count: 5 }, 'shows 5 rows of information'); assert.dom(PAGE.infoRowValue('API path')).hasText(`/v1/${this.backend}/data/${this.secretPath}`); + assert.dom(PAGE.infoRowValue('Configuration path')).hasText(`${this.backend}/data/${this.secretPath}`); assert.dom(PAGE.infoRowValue('CLI path')).hasText(`-mount="${this.backend}" "${this.secretPath}"`); assert .dom(PAGE.infoRowValue('API path for metadata')) .hasText(`/v1/${this.backend}/metadata/${this.secretPath}`); + assert + .dom(PAGE.infoRowValue('Configuration metadata path')) + .hasText(`${this.backend}/metadata/${this.secretPath}`); }); }); @@ -301,12 +321,16 @@ path "${this.backend}/*" { `/vault/secrets-engines/${this.urlPath}/paths`, 'navigates to secret paths route' ); - assert.dom(PAGE.infoRow).exists({ count: 3 }, 'shows 3 rows of information'); + assert.dom(PAGE.infoRow).exists({ count: 5 }, 'shows 5 rows of information'); assert.dom(PAGE.infoRowValue('API path')).hasText(`/v1/${this.backend}/data/${this.secretPath}`); + assert.dom(PAGE.infoRowValue('Configuration path')).hasText(`${this.backend}/data/${this.secretPath}`); assert.dom(PAGE.infoRowValue('CLI path')).hasText(`-mount="${this.backend}" "${this.secretPath}"`); assert .dom(PAGE.infoRowValue('API path for metadata')) .hasText(`/v1/${this.backend}/metadata/${this.secretPath}`); + assert + .dom(PAGE.infoRowValue('Configuration metadata path')) + .hasText(`${this.backend}/metadata/${this.secretPath}`); }); }); }); diff --git a/ui/tests/integration/components/kv/kv-paths-card-test.js b/ui/tests/integration/components/kv/kv-paths-card-test.js index e3d3195445..d79063bf35 100644 --- a/ui/tests/integration/components/kv/kv-paths-card-test.js +++ b/ui/tests/integration/components/kv/kv-paths-card-test.js @@ -63,6 +63,7 @@ module('Integration | Component | kv-v2 | KvPathsCard', function (hooks) { const paths = [ { label: 'API path', expected: `/v1/${this.backend}/data/${this.path}` }, + { label: 'Configuration path', expected: `${this.backend}/data/${this.path}` }, { label: 'CLI path', expected: `-mount="${this.backend}" "${this.path}"` }, ]; for (const [index, path] of paths.entries()) { @@ -84,8 +85,10 @@ module('Integration | Component | kv-v2 | KvPathsCard', function (hooks) { test('it renders copyable paths', async function (assert) { const paths = [ { label: 'API path', expected: `/v1/${this.backend}/data/${this.path}` }, + { label: 'Configuration path', expected: `${this.backend}/data/${this.path}` }, { label: 'CLI path', expected: `-mount="${this.backend}" "${this.path}"` }, { label: 'API path for metadata', expected: `/v1/${this.backend}/metadata/${this.path}` }, + { label: 'Configuration metadata path', expected: `${this.backend}/metadata/${this.path}` }, ]; await this.renderComponent(); @@ -106,6 +109,10 @@ module('Integration | Component | kv-v2 | KvPathsCard', function (hooks) { label: 'API path', expected: `/v1/${backend}/data/${path}`, }, + { + label: 'Configuration path', + expected: `${backend}/data/${path}`, + }, { label: 'CLI path', expected: `-mount="${this.backend}" "${this.path}"` }, { label: 'API path for metadata', diff --git a/ui/tests/integration/components/kv/page/kv-page-overview-test.js b/ui/tests/integration/components/kv/page/kv-page-overview-test.js index 33a5a601fa..79f594788e 100644 --- a/ui/tests/integration/components/kv/page/kv-page-overview-test.js +++ b/ui/tests/integration/components/kv/page/kv-page-overview-test.js @@ -116,7 +116,7 @@ module('Integration | Component | kv-v2 | Page::Secret::Overview', function (hoo assert .dom(overviewCard.container('Paths')) .hasText( - `Paths The paths to use when referring to this secret in API or CLI. API path /v1/${this.backend}/data/${this.path} CLI path -mount="${this.backend}" "${this.path}"` + `Paths The paths to use when referring to this secret in API, policies, or CLI. API path /v1/${this.backend}/data/${this.path} Configuration path ${this.backend}/data/${this.path} CLI path -mount="${this.backend}" "${this.path}"` ); assert .dom(overviewCard.container('Subkeys')) @@ -162,7 +162,7 @@ module('Integration | Component | kv-v2 | Page::Secret::Overview', function (hoo assert .dom(overviewCard.container('Paths')) .hasText( - `Paths The paths to use when referring to this secret in API or CLI. API path /v1/${this.backend}/data/${this.path} CLI path -mount="${this.backend}" "${this.path}"` + `Paths The paths to use when referring to this secret in API, policies, or CLI. API path /v1/${this.backend}/data/${this.path} Configuration path ${this.backend}/data/${this.path} CLI path -mount="${this.backend}" "${this.path}"` ); assert .dom(overviewCard.container('Subkeys')) @@ -191,7 +191,7 @@ module('Integration | Component | kv-v2 | Page::Secret::Overview', function (hoo assert .dom(overviewCard.container('Paths')) .hasText( - `Paths The paths to use when referring to this secret in API or CLI. API path /v1/${this.backend}/data/${this.path} CLI path -mount="${this.backend}" "${this.path}"` + `Paths The paths to use when referring to this secret in API, policies, or CLI. API path /v1/${this.backend}/data/${this.path} Configuration path ${this.backend}/data/${this.path} CLI path -mount="${this.backend}" "${this.path}"` ); assert.dom(overviewCard.container('Subkeys')).doesNotExist(); }); @@ -206,7 +206,7 @@ module('Integration | Component | kv-v2 | Page::Secret::Overview', function (hoo assert .dom(overviewCard.container('Paths')) .hasText( - `Paths The paths to use when referring to this secret in API or CLI. API path /v1/${this.backend}/data/${this.path} CLI path -mount="${this.backend}" "${this.path}"` + `Paths The paths to use when referring to this secret in API, policies, or CLI. API path /v1/${this.backend}/data/${this.path} Configuration path ${this.backend}/data/${this.path} CLI path -mount="${this.backend}" "${this.path}"` ); }); }); @@ -250,7 +250,7 @@ module('Integration | Component | kv-v2 | Page::Secret::Overview', function (hoo assert .dom(overviewCard.container('Paths')) .hasText( - `Paths The paths to use when referring to this secret in API or CLI. API path /v1/${this.backend}/data/${this.path} CLI path -mount="${this.backend}" "${this.path}"` + `Paths The paths to use when referring to this secret in API, policies, or CLI. API path /v1/${this.backend}/data/${this.path} Configuration path ${this.backend}/data/${this.path} CLI path -mount="${this.backend}" "${this.path}"` ); }); @@ -326,7 +326,7 @@ module('Integration | Component | kv-v2 | Page::Secret::Overview', function (hoo assert .dom(overviewCard.container('Paths')) .hasText( - `Paths The paths to use when referring to this secret in API or CLI. API path /v1/${this.backend}/data/${this.path} CLI path -mount="${this.backend}" "${this.path}"` + `Paths The paths to use when referring to this secret in API, policies, or CLI. API path /v1/${this.backend}/data/${this.path} Configuration path ${this.backend}/data/${this.path} CLI path -mount="${this.backend}" "${this.path}"` ); });