UI: Moving settings/mount-backend-form to secrets/mounts (#8975) (#8998)

* adding route and replacing old route usage

* adding comments

* updating secrets tests to new route

Co-authored-by: Dan Rivera <dan.rivera@hashicorp.com>
This commit is contained in:
Vault Automation 2025-08-28 15:57:24 -06:00 committed by GitHub
parent 5f8575db48
commit bfd2e54d39
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 104 additions and 39 deletions

View file

@ -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"
/>
</EmptyState>
{{/if}}

View file

@ -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"
/>
</EmptyState>
{{/if}}

View file

@ -4,12 +4,7 @@
}}
<div class="top-right-absolute has-top-margin-s">
<Hds::Button
@text="Enable new engine"
@icon="plus"
@route="vault.cluster.settings.mount-secret-backend"
data-test-enable-engine
/>
<Hds::Button @text="Enable new engine" @icon="plus" @route="vault.cluster.secrets.mounts" data-test-enable-engine />
</div>
<Toolbar>
<ToolbarFilters>

View file

@ -9,7 +9,7 @@
<Nav.Link @route="vault.cluster.dashboard" @text="Dashboard" data-test-sidebar-nav-link="Dashboard" />
<Nav.Link
@route="vault.cluster.secrets"
@current-when="vault.cluster.secrets vault.cluster.settings.mount-secret-backend vault.cluster.secrets.backend.configuration.edit"
@current-when="vault.cluster.secrets vault.cluster.secrets.mounts vault.cluster.secrets.backend.configuration.edit"
@text="Secrets Engines"
data-test-sidebar-nav-link="Secrets Engines"
/>

View file

@ -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();
}
}

View file

@ -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');

View file

@ -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<VaultClusterSecretsMountsIndexRouter>;
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 });
}
}

View file

@ -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 }}
<MountBackendForm @mountModel={{this.model}} @mountCategory="secret" @onMountSuccess={{action "onMountSuccess"}} />

View file

@ -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"]');

View file

@ -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');

View file

@ -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(

View file

@ -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(

View file

@ -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');

View file

@ -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);
});

View file

@ -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);

View file

@ -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'));

View file

@ -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"]'),