diff --git a/ui/app/components/dashboard/quick-actions-card.hbs b/ui/app/components/dashboard/quick-actions-card.hbs
index 4c06e0316f..2e81fba965 100644
--- a/ui/app/components/dashboard/quick-actions-card.hbs
+++ b/ui/app/components/dashboard/quick-actions-card.hbs
@@ -97,7 +97,7 @@
@icon="chevron-right"
@iconPosition="trailing"
@text="Enable a secrets engine"
- @route="vault.cluster.settings.mount-secret-backend"
+ @route="vault.cluster.secrets.mounts"
/>
{{/if}}
diff --git a/ui/app/components/dashboard/secrets-engines-card.hbs b/ui/app/components/dashboard/secrets-engines-card.hbs
index 728c523c53..36f4553829 100644
--- a/ui/app/components/dashboard/secrets-engines-card.hbs
+++ b/ui/app/components/dashboard/secrets-engines-card.hbs
@@ -87,7 +87,7 @@
@icon="chevron-right"
@iconPosition="trailing"
@text="Enable a secrets engine"
- @route="vault.cluster.settings.mount-secret-backend"
+ @route="vault.cluster.secrets.mounts"
/>
{{/if}}
diff --git a/ui/app/components/secret-engine/list.hbs b/ui/app/components/secret-engine/list.hbs
index 96db6fe0ac..c94d1ded79 100644
--- a/ui/app/components/secret-engine/list.hbs
+++ b/ui/app/components/secret-engine/list.hbs
@@ -4,12 +4,7 @@
}}
-
+
diff --git a/ui/app/components/sidebar/nav/cluster.hbs b/ui/app/components/sidebar/nav/cluster.hbs
index da4c9dedbd..b2435eea86 100644
--- a/ui/app/components/sidebar/nav/cluster.hbs
+++ b/ui/app/components/sidebar/nav/cluster.hbs
@@ -9,7 +9,7 @@
diff --git a/ui/app/controllers/vault/cluster/secrets/mounts/index.js b/ui/app/controllers/vault/cluster/secrets/mounts/index.js
new file mode 100644
index 0000000000..7051a5afe7
--- /dev/null
+++ b/ui/app/controllers/vault/cluster/secrets/mounts/index.js
@@ -0,0 +1,37 @@
+/**
+ * Copyright (c) HashiCorp, Inc.
+ * SPDX-License-Identifier: BUSL-1.1
+ */
+
+import { service } from '@ember/service';
+import Controller from '@ember/controller';
+import { action } from '@ember/object';
+import { supportedSecretBackends } from 'vault/helpers/supported-secret-backends';
+import engineDisplayData from 'vault/helpers/engines-display-data';
+
+const SUPPORTED_BACKENDS = supportedSecretBackends();
+
+export default class SecretMountsController extends Controller {
+ @service router;
+
+ @action
+ onMountSuccess(type, path, useEngineRoute = false) {
+ let transition;
+ if (SUPPORTED_BACKENDS.includes(type)) {
+ const engineInfo = engineDisplayData(type);
+ if (useEngineRoute) {
+ transition = this.router.transitionTo(
+ `vault.cluster.secrets.backend.${engineInfo.engineRoute}`,
+ path
+ );
+ } else {
+ // For keymgmt, we need to land on provider tab by default using query params
+ const queryParams = engineInfo.type === 'keymgmt' ? { tab: 'provider' } : {};
+ transition = this.router.transitionTo('vault.cluster.secrets.backend.index', path, { queryParams });
+ }
+ } else {
+ transition = this.router.transitionTo('vault.cluster.secrets.backends');
+ }
+ return transition.followRedirects();
+ }
+}
diff --git a/ui/app/router.js b/ui/app/router.js
index b8b9bb64ab..b681781c7f 100644
--- a/ui/app/router.js
+++ b/ui/app/router.js
@@ -174,6 +174,10 @@ Router.map(function () {
});
});
this.route('secrets', function () {
+ this.route('mounts', function () {
+ // TODO: Revisit path on create once components are separated - should we specify selected type or just keep it generic as /create?
+ this.route('create', { path: '/:mount_type/create' });
+ });
this.route('backends', { path: '/' });
this.route('backend', { path: '/:backend' }, function () {
this.mount('kmip');
diff --git a/ui/app/routes/vault/cluster/secrets/mounts/index.ts b/ui/app/routes/vault/cluster/secrets/mounts/index.ts
new file mode 100644
index 0000000000..b3c83ff835
--- /dev/null
+++ b/ui/app/routes/vault/cluster/secrets/mounts/index.ts
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) HashiCorp, Inc.
+ * SPDX-License-Identifier: BUSL-1.1
+ */
+
+import Route from '@ember/routing/route';
+import { service } from '@ember/service';
+import SecretsEngineForm from 'vault/forms/secrets/engine';
+import Router from 'vault/router';
+
+import type { ModelFrom } from 'vault/vault/route';
+
+export type MountSecretBackendModel = ModelFrom;
+
+export default class VaultClusterSecretsMountsIndexRouter extends Route {
+ @service declare router: Router;
+
+ model() {
+ const defaults = {
+ config: { listing_visibility: false },
+ kv_config: {
+ max_versions: 0,
+ cas_required: false,
+ delete_version_after: undefined,
+ },
+ options: { version: 2 },
+ };
+ return new SecretsEngineForm(defaults, { isNew: true });
+ }
+}
diff --git a/ui/app/templates/vault/cluster/secrets/mounts/index.hbs b/ui/app/templates/vault/cluster/secrets/mounts/index.hbs
new file mode 100644
index 0000000000..0ecd0436a8
--- /dev/null
+++ b/ui/app/templates/vault/cluster/secrets/mounts/index.hbs
@@ -0,0 +1,7 @@
+{{!
+ Copyright (c) HashiCorp, Inc.
+ SPDX-License-Identifier: BUSL-1.1
+}}
+
+{{! TODO: Copied from existing component, to be replaced by new parent component in separate ticket - VAULT-37522 }}
+
\ No newline at end of file
diff --git a/ui/tests/acceptance/enterprise-transform-test.js b/ui/tests/acceptance/enterprise-transform-test.js
index d08f4b337f..ae88509a95 100644
--- a/ui/tests/acceptance/enterprise-transform-test.js
+++ b/ui/tests/acceptance/enterprise-transform-test.js
@@ -100,7 +100,7 @@ module('Acceptance | Enterprise | Transform secrets', function (hooks) {
});
test('it can create a transformation and add itself to the role attached', async function (assert) {
- await visit('/vault/settings/mount-secret-backend');
+ await visit('/vault/secrets/mounts');
const backend = `transform-${uuidv4()}`;
await click('[data-test-mount-type="transform"]');
await fillIn(GENERAL.inputByAttr('path'), backend);
@@ -152,7 +152,7 @@ module('Acceptance | Enterprise | Transform secrets', function (hooks) {
test('it can create a role and add itself to the transformation attached', async function (assert) {
const roleName = 'my-role';
- await visit('/vault/settings/mount-secret-backend');
+ await visit('/vault/secrets/mounts');
const backend = `transform-${uuidv4()}`;
await mountBackend('transform', backend);
// create transformation without role
@@ -192,7 +192,7 @@ module('Acceptance | Enterprise | Transform secrets', function (hooks) {
test('it adds a role to a transformation when added to a role', async function (assert) {
const roleName = 'role-test';
- await visit('/vault/settings/mount-secret-backend');
+ await visit('/vault/secrets/mounts');
const backend = `transform-${uuidv4()}`;
await mountBackend('transform', backend);
const transformation = await newTransformation(backend, 'b-transformation', true);
@@ -204,7 +204,7 @@ module('Acceptance | Enterprise | Transform secrets', function (hooks) {
test('it shows a message if an update fails after save', async function (assert) {
const roleName = 'role-remove';
- await visit('/vault/settings/mount-secret-backend');
+ await visit('/vault/secrets/mounts');
const backend = `transform-${uuidv4()}`;
await mountBackend('transform', backend);
// Create transformation
@@ -242,7 +242,7 @@ module('Acceptance | Enterprise | Transform secrets', function (hooks) {
test('it allows creation and edit of a template', async function (assert) {
const templateName = 'my-template';
- await visit('/vault/settings/mount-secret-backend');
+ await visit('/vault/secrets/mounts');
const backend = `transform-${uuidv4()}`;
await mountBackend('transform', backend);
await click('[data-test-secret-list-tab="Templates"]');
@@ -284,7 +284,7 @@ module('Acceptance | Enterprise | Transform secrets', function (hooks) {
test('it allows creation and edit of an alphabet', async function (assert) {
const alphabetName = 'vowels-only';
- await visit('/vault/settings/mount-secret-backend');
+ await visit('/vault/secrets/mounts');
const backend = `transform-${uuidv4()}`;
await mountBackend('transform', backend);
await click('[data-test-secret-list-tab="Alphabets"]');
diff --git a/ui/tests/acceptance/secrets/backend/aws/aws-configuration-test.js b/ui/tests/acceptance/secrets/backend/aws/aws-configuration-test.js
index 2f60a027ad..a7ecb9a8b3 100644
--- a/ui/tests/acceptance/secrets/backend/aws/aws-configuration-test.js
+++ b/ui/tests/acceptance/secrets/backend/aws/aws-configuration-test.js
@@ -55,7 +55,7 @@ module('Acceptance | aws | configuration', function (hooks) {
test('it should prompt configuration after mounting the aws engine', async function (assert) {
const path = `aws-${this.uid}`;
// in this test go through the full mount process. Bypass this step in later tests.
- await visit('/vault/settings/mount-secret-backend');
+ await visit('/vault/secrets/mounts');
await mountBackend('aws', path);
await click(SES.configTab);
assert.dom(GENERAL.emptyStateTitle).hasText('AWS not configured');
diff --git a/ui/tests/acceptance/secrets/backend/azure/azure-configuration-test.js b/ui/tests/acceptance/secrets/backend/azure/azure-configuration-test.js
index e49413a81c..3257b10543 100644
--- a/ui/tests/acceptance/secrets/backend/azure/azure-configuration-test.js
+++ b/ui/tests/acceptance/secrets/backend/azure/azure-configuration-test.js
@@ -41,7 +41,7 @@ module('Acceptance | Azure | configuration', function (hooks) {
test('it should prompt configuration after mounting the azure engine', async function (assert) {
const path = `azure-${this.uid}`;
- await visit('/vault/settings/mount-secret-backend');
+ await visit('/vault/secrets/mounts');
await mountBackend(this.type, path);
assert.strictEqual(
diff --git a/ui/tests/acceptance/secrets/backend/gcp/gcp-configuration-test.js b/ui/tests/acceptance/secrets/backend/gcp/gcp-configuration-test.js
index 32d4fd50f3..0235e4d6c1 100644
--- a/ui/tests/acceptance/secrets/backend/gcp/gcp-configuration-test.js
+++ b/ui/tests/acceptance/secrets/backend/gcp/gcp-configuration-test.js
@@ -42,7 +42,7 @@ module('Acceptance | GCP | configuration', function (hooks) {
});
test('it should prompt configuration after mounting the GCP engine', async function (assert) {
- await visit('/vault/settings/mount-secret-backend');
+ await visit('/vault/secrets/mounts');
await mountBackend(this.type, this.path);
assert.strictEqual(
diff --git a/ui/tests/acceptance/secrets/backend/ssh/configuration-test.js b/ui/tests/acceptance/secrets/backend/ssh/configuration-test.js
index 31676dbf94..87bc1663f4 100644
--- a/ui/tests/acceptance/secrets/backend/ssh/configuration-test.js
+++ b/ui/tests/acceptance/secrets/backend/ssh/configuration-test.js
@@ -30,7 +30,7 @@ module('Acceptance | ssh | configuration', function (hooks) {
test('it should prompt configuration after mounting ssh engine', async function (assert) {
const sshPath = `ssh-${this.uid}`;
// in this test go through the full mount process. Bypass this step in later tests.
- await visit('/vault/settings/mount-secret-backend');
+ await visit('/vault/secrets/mounts');
await mountBackend('ssh', sshPath);
await click(SES.configTab);
assert.dom(GENERAL.emptyStateTitle).hasText('SSH not configured');
diff --git a/ui/tests/acceptance/secrets/backend/totp/key-test.js b/ui/tests/acceptance/secrets/backend/totp/key-test.js
index b092725829..8b41b22b9d 100644
--- a/ui/tests/acceptance/secrets/backend/totp/key-test.js
+++ b/ui/tests/acceptance/secrets/backend/totp/key-test.js
@@ -56,7 +56,7 @@ module('Acceptance | totp key backend', function (hooks) {
await login();
// Setup TOTP engine
- await visit('/vault/settings/mount-secret-backend');
+ await visit('/vault/secrets/mounts');
await mountBackend('totp', this.mountPath);
});
diff --git a/ui/tests/acceptance/settings-test.js b/ui/tests/acceptance/settings-test.js
index 3d800cdfcb..7d88483237 100644
--- a/ui/tests/acceptance/settings-test.js
+++ b/ui/tests/acceptance/settings-test.js
@@ -28,13 +28,9 @@ module('Acceptance | secret engine mount settings', function (hooks) {
const path = `settings-path-${this.uid}`;
// mount unsupported backend
- await visit('/vault/settings/mount-secret-backend');
+ await visit('/vault/secrets/mounts');
- assert.strictEqual(
- currentURL(),
- '/vault/settings/mount-secret-backend',
- 'navigates to the mount secret backend page'
- );
+ assert.strictEqual(currentURL(), '/vault/secrets/mounts', 'navigates to the mount secret backend page');
await click(MOUNT_BACKEND_FORM.mountType(type));
await fillIn(GENERAL.inputByAttr('path'), path);
await click(GENERAL.button('Method Options'));
@@ -58,7 +54,7 @@ module('Acceptance | secret engine mount settings', function (hooks) {
const type = 'ldap';
const path = `ldap-${this.uid}`;
- await visit('/vault/settings/mount-secret-backend');
+ await visit('/vault/secrets/mounts');
await runCmd(mountEngineCmd(type, path), false);
await visit('/vault/secrets');
await selectChoose(GENERAL.searchSelect.trigger('filter-by-engine-name'), path);
@@ -77,7 +73,7 @@ module('Acceptance | secret engine mount settings', function (hooks) {
const type = 'ssh';
const path = `ssh-${this.uid}`;
- await visit('/vault/settings/mount-secret-backend');
+ await visit('/vault/secrets/mounts');
await runCmd(mountEngineCmd(type, path), false);
await visit('/vault/secrets');
await selectChoose(GENERAL.searchSelect.trigger('filter-by-engine-name'), path);
diff --git a/ui/tests/acceptance/settings/mount-secret-backend-test.js b/ui/tests/acceptance/settings/mount-secret-backend-test.js
index 2a0dfffbd8..6c60619194 100644
--- a/ui/tests/acceptance/settings/mount-secret-backend-test.js
+++ b/ui/tests/acceptance/settings/mount-secret-backend-test.js
@@ -60,7 +60,7 @@ module('Acceptance | settings/mount-secret-backend', function (hooks) {
const maxTTLHours = 300;
await page.visit();
- assert.strictEqual(currentRouteName(), 'vault.cluster.settings.mount-secret-backend');
+ assert.strictEqual(currentRouteName(), 'vault.cluster.secrets.mounts.index');
await click(MOUNT_BACKEND_FORM.mountType('kv'));
await fillIn(GENERAL.inputByAttr('path'), path);
await click(GENERAL.button('Method Options'));
@@ -81,11 +81,7 @@ module('Acceptance | settings/mount-secret-backend', function (hooks) {
await page.visit();
- assert.strictEqual(
- currentRouteName(),
- 'vault.cluster.settings.mount-secret-backend',
- 'navigates to mount page'
- );
+ assert.strictEqual(currentRouteName(), 'vault.cluster.secrets.mounts.index', 'navigates to mount page');
await click(MOUNT_BACKEND_FORM.mountType('kv'));
await fillIn(GENERAL.inputByAttr('path'), path);
await click(GENERAL.button('Method Options'));
@@ -100,7 +96,7 @@ module('Acceptance | settings/mount-secret-backend', function (hooks) {
test('it sets the max ttl after pki chosen, resets after', async function (assert) {
await page.visit();
- assert.strictEqual(currentRouteName(), 'vault.cluster.settings.mount-secret-backend');
+ assert.strictEqual(currentRouteName(), 'vault.cluster.secrets.mounts.index');
await click(MOUNT_BACKEND_FORM.mountType('pki'));
assert.dom('[data-test-input="config.max_lease_ttl"]').exists();
assert
@@ -131,7 +127,7 @@ module('Acceptance | settings/mount-secret-backend', function (hooks) {
await page.visit();
- assert.strictEqual(currentRouteName(), 'vault.cluster.settings.mount-secret-backend');
+ assert.strictEqual(currentRouteName(), 'vault.cluster.secrets.mounts.index');
await mountBackend('kv', path);
await page.secretList();
await settled();
@@ -139,7 +135,7 @@ module('Acceptance | settings/mount-secret-backend', function (hooks) {
await mountBackend('kv', path);
await waitFor('[data-test-message-error-description]');
assert.dom('[data-test-message-error-description]').containsText(`path is already in use at ${path}`);
- assert.strictEqual(currentRouteName(), 'vault.cluster.settings.mount-secret-backend');
+ assert.strictEqual(currentRouteName(), 'vault.cluster.secrets.mounts.index');
await page.secretList();
await settled();
@@ -361,7 +357,7 @@ module('Acceptance | settings/mount-secret-backend', function (hooks) {
);
await login(secretsAdminToken);
- await visit('/vault/settings/mount-secret-backend');
+ await visit('/vault/secrets/mounts');
await click(MOUNT_BACKEND_FORM.mountType(engine));
await fillIn(GENERAL.inputByAttr('path'), path);
await click(GENERAL.button('Method Options'));
diff --git a/ui/tests/pages/settings/mount-secret-backend.js b/ui/tests/pages/settings/mount-secret-backend.js
index daccb572f6..caf3c299de 100644
--- a/ui/tests/pages/settings/mount-secret-backend.js
+++ b/ui/tests/pages/settings/mount-secret-backend.js
@@ -8,7 +8,7 @@ import { settled } from '@ember/test-helpers';
import { mountBackend } from 'vault/tests/helpers/components/mount-backend-form-helpers';
export default create({
- visit: visitable('/vault/settings/mount-secret-backend'),
+ visit: visitable('/vault/secrets/mounts'),
version: fillable('[data-test-input="options.version"]'),
setMaxVersion: fillable('[data-test-input="kv_config.max_versions"]'),
maxTTLVal: fillable('[data-test-ttl-value="Max Lease TTL"]'),