Merge remote-tracking branch 'remotes/from/ce/main'

This commit is contained in:
hc-github-team-secure-vault-core 2026-03-20 20:05:24 +00:00
commit fbf7f3bb12
29 changed files with 100 additions and 77 deletions

3
changelog/_13260.txt Normal file
View File

@ -0,0 +1,3 @@
```release-note:change
secrets/openldap: Update plugin to [v0.18.0](https://github.com/hashicorp/vault-plugin-secrets-openldap/releases/tag/v0.18.0)
```

3
changelog/_13264.txt Normal file
View File

@ -0,0 +1,3 @@
```release-note:change
secrets/kv: Update plugin to [v0.26.2](https://github.com/hashicorp/vault-plugin-secrets-kv/releases/tag/v0.26.2)
```

6
go.mod
View File

@ -159,13 +159,13 @@ require (
github.com/hashicorp/vault-plugin-database-snowflake v0.16.0
github.com/hashicorp/vault-plugin-secrets-ad v0.22.1
github.com/hashicorp/vault-plugin-secrets-alicloud v0.22.1
github.com/hashicorp/vault-plugin-secrets-azure v0.23.0
github.com/hashicorp/vault-plugin-secrets-azure v0.25.0
github.com/hashicorp/vault-plugin-secrets-gcp v0.23.0
github.com/hashicorp/vault-plugin-secrets-gcpkms v0.23.0
github.com/hashicorp/vault-plugin-secrets-kubernetes v0.13.1
github.com/hashicorp/vault-plugin-secrets-kv v0.25.0
github.com/hashicorp/vault-plugin-secrets-kv v0.26.2
github.com/hashicorp/vault-plugin-secrets-mongodbatlas v0.17.1
github.com/hashicorp/vault-plugin-secrets-openldap v0.17.0
github.com/hashicorp/vault-plugin-secrets-openldap v0.18.0
github.com/hashicorp/vault-plugin-secrets-terraform v0.14.1
github.com/hashicorp/vault-testing-stepwise v0.3.3
github.com/hashicorp/vault/api v1.22.0

12
go.sum
View File

@ -869,20 +869,20 @@ github.com/hashicorp/vault-plugin-secrets-ad v0.22.1 h1:Wqp6I0gSOI3kf3TK3JJeylDC
github.com/hashicorp/vault-plugin-secrets-ad v0.22.1/go.mod h1:xERfc+dNwlLEefQDcjhhhHPTJLs9komReccRKMsDoAs=
github.com/hashicorp/vault-plugin-secrets-alicloud v0.22.1 h1:6JvSoeYU+tRSnc0eGNz+1ttFK8gfIqw/sXHme4h6CRY=
github.com/hashicorp/vault-plugin-secrets-alicloud v0.22.1/go.mod h1:2tiBfbs4TXU1mHg7oJUThSac4mzRdnBOmt6ZBmfkV8o=
github.com/hashicorp/vault-plugin-secrets-azure v0.23.0 h1:oetvEJqXP+2jGM9CfT/LjpJyuViNKdjPKFbDIkRdaPo=
github.com/hashicorp/vault-plugin-secrets-azure v0.23.0/go.mod h1:QkmR0rnexjc330oUzoiuXFsA6OnxmI56h4jnDb1PKbY=
github.com/hashicorp/vault-plugin-secrets-azure v0.25.0 h1:IYIGfFiw3ICLfVlF+YlPztthbc5pMaT3SwVr27VjERw=
github.com/hashicorp/vault-plugin-secrets-azure v0.25.0/go.mod h1:S4E5R3RVpGWnzR0bDGDwpV0HlyNsMAIcuYuNlgWv2zo=
github.com/hashicorp/vault-plugin-secrets-gcp v0.23.0 h1:hqZlxS4Ya0DBt+FutW6z6tSEdnwHFusY49x7TLKVrAw=
github.com/hashicorp/vault-plugin-secrets-gcp v0.23.0/go.mod h1:OmRHszxWAV9MTwFeQKDQmrpRw9q+RMp1vohCuhkkr1k=
github.com/hashicorp/vault-plugin-secrets-gcpkms v0.23.0 h1:gXFfSYVpebgklMeLxWfMrBHOZJ5EdJtM80ir0NZNdMM=
github.com/hashicorp/vault-plugin-secrets-gcpkms v0.23.0/go.mod h1:YdDoi8TIpbJ4lljL3fISJmZQxZqmJfHMdzxCS33pjBc=
github.com/hashicorp/vault-plugin-secrets-kubernetes v0.13.1 h1:ug+5nibS3AulD3ElaQeD42N0VJsTUwTRVPgJSj0ovvM=
github.com/hashicorp/vault-plugin-secrets-kubernetes v0.13.1/go.mod h1:t34JjbPLaLrhvwb7iKmvW9y72o7ZhxGfN0Q3yClsV8Y=
github.com/hashicorp/vault-plugin-secrets-kv v0.25.0 h1:5Xx8Hub0nAoFLIHZ4d9tMpPG+MACHXLzed5i7hViKTk=
github.com/hashicorp/vault-plugin-secrets-kv v0.25.0/go.mod h1:Xy3wQwAJxhVZweR2DXBrEgk1erkWKNrhYcuD4Gy4ACo=
github.com/hashicorp/vault-plugin-secrets-kv v0.26.2 h1:5ruO7aTfQqOKIuC+G6hXQbBKXZ6sPGDA3s2oCtyGtdU=
github.com/hashicorp/vault-plugin-secrets-kv v0.26.2/go.mod h1:VRZ9QtAibng01WsVj95vpF0oiEDuDTpBp2PSjxYyARI=
github.com/hashicorp/vault-plugin-secrets-mongodbatlas v0.17.1 h1:WezfLs6aH9MOWLux1XJ/8Z2kJncVQWRHJ1hKfXIjRKg=
github.com/hashicorp/vault-plugin-secrets-mongodbatlas v0.17.1/go.mod h1:3mLTbgTz8GShAf81IFT0WdKAUjJoIMg/qmucHJfHiD8=
github.com/hashicorp/vault-plugin-secrets-openldap v0.17.0 h1:GpgYcuBL66zzFLkf143Q3zFr//BF/4jX/EXXy9wDUOM=
github.com/hashicorp/vault-plugin-secrets-openldap v0.17.0/go.mod h1:UPWSw0hYY37sC4MeeoG9G8jN88DYi3L4MeJjRauhaBI=
github.com/hashicorp/vault-plugin-secrets-openldap v0.18.0 h1:m2OlgzCKFlBP+/dpRMRsyu9gfwsWCWjJNRpU6UNgIE4=
github.com/hashicorp/vault-plugin-secrets-openldap v0.18.0/go.mod h1:HO9g8SO9blk3ayPBaHA0dIo4YgpASSkY7fy2DEY57bI=
github.com/hashicorp/vault-plugin-secrets-terraform v0.14.1 h1:okWkXeDbTElc1tA2TzPsNV5yEa1fcttXZFMIKn2fVQk=
github.com/hashicorp/vault-plugin-secrets-terraform v0.14.1/go.mod h1:FjgfSW1exgLCnc2ALi6CKwux2NMuqiAzKf/hMPm6WWU=
github.com/hashicorp/vault-testing-stepwise v0.3.3 h1:/PQhXpJln7UQf3NJmG61ucAxsvttd+a0kb5NKW01iIA=

View File

@ -9,7 +9,7 @@ import { tracked } from '@glimmer/tracking';
import Component from '@glimmer/component';
import { dropTask } from 'ember-concurrency';
import sortObjects from 'vault/utils/sort-objects';
import { WIZARD_ID } from '../wizard/methods/methods-wizard';
import { WIZARD_ID_MAP } from 'vault/utils/constants/wizard';
import type ApiService from 'vault/services/api';
import type FlashMessageService from 'vault/services/flash-messages';
@ -46,7 +46,7 @@ export default class PageAuthMethodsComponent extends Component<Args> {
@tracked methodToDisable: AuthMethodResource | null = null;
@tracked shouldRenderIntroModal = false;
wizardId = WIZARD_ID;
wizardId = WIZARD_ID_MAP.authMethods;
// list returned by getter is sorted in template
get authMethodList() {
@ -95,7 +95,7 @@ export default class PageAuthMethodsComponent extends Component<Args> {
get showContent() {
// Show when the 1) wizard is not shown OR 2) wizard intro modal is shown
// This ensures the wizard intro modal is shown on top of the list view and the background content is not blank behind the modal
return !this.showWizard || (this.shouldRenderIntroModal && this.wizard.isIntroVisible(WIZARD_ID));
return !this.showWizard || (this.shouldRenderIntroModal && this.wizard.isIntroVisible(this.wizardId));
}
get showIntroButton() {

View File

@ -8,7 +8,7 @@ import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking';
import Component from '@glimmer/component';
import keys from 'core/utils/keys';
import { WIZARD_ID } from 'vault/components/wizard/namespaces/namespace-wizard';
import { WIZARD_ID_MAP } from 'vault/utils/constants/wizard';
import errorMessage from 'vault/utils/error-message';
import type ApiService from 'vault/services/api';
@ -62,6 +62,8 @@ export default class PageNamespacesComponent extends Component<Args> {
@tracked showSetupAlert = false;
@tracked shouldRenderIntroModal = false;
wizardId = WIZARD_ID_MAP.namespace;
constructor(owner: unknown, args: Args) {
super(owner, args);
this.query = this.args.model.pageFilter || '';
@ -91,13 +93,13 @@ export default class PageNamespacesComponent extends Component<Args> {
// Show header and breadcrumbs when viewing the intro page or during the list view.
// Do not show during Guided Start as that has its own header
get showPageHeader() {
return !this.showWizard || this.wizard.isIntroVisible(WIZARD_ID);
return !this.showWizard || this.wizard.isIntroVisible(this.wizardId);
}
get showContent() {
// Show when the 1) wizard is not shown OR 2) wizard intro modal is shown
// This ensures the wizard intro modal is shown on top of the list view and the background content is not blank behind the modal
return !this.showWizard || (this.shouldRenderIntroModal && this.wizard.isIntroVisible(WIZARD_ID));
return !this.showWizard || (this.shouldRenderIntroModal && this.wizard.isIntroVisible(this.wizardId));
}
get showIntroButton() {
@ -106,7 +108,7 @@ export default class PageNamespacesComponent extends Component<Args> {
get showWizard() {
// Show when there are no existing namespaces and it is not in a dismissed state
return !this.wizard.isDismissed(WIZARD_ID) && !this.hasNamespaces;
return !this.wizard.isDismissed(this.wizardId) && !this.hasNamespaces;
}
@action
@ -162,7 +164,7 @@ export default class PageNamespacesComponent extends Component<Args> {
@action
showIntroPage() {
// Reset the wizard dismissal state to allow re-entering the wizard
this.wizard.reset(WIZARD_ID);
this.wizard.reset(this.wizardId);
this.shouldRenderIntroModal = true;
}

View File

@ -7,7 +7,7 @@ import { service } from '@ember/service';
import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking';
import Component from '@glimmer/component';
import { WIZARD_ID } from 'vault/components/wizard/acl-policies/acl-wizard';
import { WIZARD_ID_MAP } from 'vault/utils/constants/wizard';
import errorMessage from 'vault/utils/error-message';
import { PolicyTypes } from 'core/utils/code-generators/policy';
@ -39,6 +39,8 @@ export default class PagePoliciesComponent extends Component<Args> {
@tracked policyToDelete = null;
@tracked shouldRenderIntroModal = false;
wizardId = WIZARD_ID_MAP.aclPolicy;
constructor(owner: unknown, args: Args) {
super(owner, args);
this.filter = this.args.filter || '';
@ -97,7 +99,7 @@ export default class PagePoliciesComponent extends Component<Args> {
get showContent() {
// Show when the 1) wizard is not shown OR 2) wizard intro modal is shown
// This ensures the wizard intro modal is shown on top of the list view and the background content is not blank behind the modal
return !this.showWizard || (this.shouldRenderIntroModal && this.wizard.isIntroVisible(WIZARD_ID));
return !this.showWizard || (this.shouldRenderIntroModal && this.wizard.isIntroVisible(this.wizardId));
}
get showIntroButton() {
@ -108,7 +110,7 @@ export default class PagePoliciesComponent extends Component<Args> {
get showWizard() {
if (this.args.policyType !== PolicyTypes.ACL) return false;
// Use total instead of filtered total to avoid flashing wizard when filtering with no results
return !this.wizard.isDismissed(WIZARD_ID) && this.hasOnlyDefaultPolicies;
return !this.wizard.isDismissed(this.wizardId) && this.hasOnlyDefaultPolicies;
}
@action
@ -151,7 +153,7 @@ export default class PagePoliciesComponent extends Component<Args> {
@action
showIntroPage() {
// Reset the wizard dismissal state to allow re-entering the wizard
this.wizard.reset(WIZARD_ID);
this.wizard.reset(this.wizardId);
this.shouldRenderIntroModal = true;
}

View File

@ -10,7 +10,7 @@ import { tracked } from '@glimmer/tracking';
import engineDisplayData from 'vault/helpers/engines-display-data';
import { ALL_ENGINES } from 'vault/utils/all-engines-metadata';
import { getEffectiveEngineType } from 'vault/utils/external-plugin-helpers';
import { WIZARD_ID } from '../wizard/secret-engines/secret-engines-wizard';
import { WIZARD_ID_MAP } from 'vault/utils/constants/wizard';
import type RouterService from '@ember/routing/router-service';
import type SecretsEngineResource from 'vault/resources/secrets/engine';
@ -48,7 +48,8 @@ export default class SecretEngineList extends Component<Args> {
@tracked versionSearchText = '';
@tracked shouldRenderIntroModal = false;
wizardId = WIZARD_ID;
wizardId = WIZARD_ID_MAP.secretEngines;
tableColumns = [
{
@ -198,7 +199,7 @@ export default class SecretEngineList extends Component<Args> {
get showContent() {
// Show when the 1) wizard is not shown OR 2) wizard intro modal is shown
// This ensures the wizard intro modal is shown on top of the list view and the background content is not blank behind the modal
return !this.showWizard || (this.shouldRenderIntroModal && this.wizard.isIntroVisible(WIZARD_ID));
return !this.showWizard || (this.shouldRenderIntroModal && this.wizard.isIntroVisible(this.wizardId));
}
get showIntroButton() {

View File

@ -6,6 +6,7 @@
import { service } from '@ember/service';
import { action } from '@ember/object';
import Component from '@glimmer/component';
import { WIZARD_ID_MAP } from 'vault/utils/constants/wizard';
import type WizardService from 'vault/services/wizard';
@ -14,12 +15,10 @@ interface Args {
onRefresh: CallableFunction;
}
export const WIZARD_ID = 'acl-policy';
export default class WizardNamespacesWizardComponent extends Component<Args> {
@service declare readonly wizard: WizardService;
wizardId = WIZARD_ID;
wizardId = WIZARD_ID_MAP.aclPolicy;
@action
async onDismiss() {

View File

@ -5,13 +5,15 @@
import { service } from '@ember/service';
import Component from '@glimmer/component';
import type WizardService from 'vault/services/wizard';
import type { WizardId } from 'vault/app-types';
interface Args {
/**
* The unique identifier for the wizard used for handling wizard dismissal and intro visibility state
*/
wizardId: string;
wizardId: WizardId;
/**
* Whether the intro page is in the default view or in modal view depending on how it is triggered
*/

View File

@ -6,6 +6,7 @@
import { service } from '@ember/service';
import { action } from '@ember/object';
import Component from '@glimmer/component';
import { WIZARD_ID_MAP } from 'vault/utils/constants/wizard';
import type WizardService from 'vault/services/wizard';
@ -14,11 +15,10 @@ interface Args {
onRefresh: CallableFunction;
}
export const WIZARD_ID = 'auth-methods';
export default class WizardMethodsWizardComponent extends Component<Args> {
@service declare readonly wizard: WizardService;
wizardId = WIZARD_ID;
wizardId = WIZARD_ID_MAP.authMethods;
@action
async onDismiss() {

View File

@ -9,6 +9,7 @@ import { tracked } from '@glimmer/tracking';
import Component from '@glimmer/component';
import { SecurityPolicy } from 'vault/components/wizard/namespaces/step-1';
import { CreationMethod } from 'vault/components/wizard/namespaces/step-3';
import { WIZARD_ID_MAP } from 'vault/utils/constants/wizard';
import type ApiService from 'vault/services/api';
import type Block from 'vault/components/wizard/namespaces/step-2';
@ -37,8 +38,6 @@ interface WizardState {
codeSnippet: string | null;
}
export const WIZARD_ID = 'namespace';
export default class WizardNamespacesWizardComponent extends Component<Args> {
@service declare readonly api: ApiService;
@service declare readonly router: RouterService;
@ -59,7 +58,7 @@ export default class WizardNamespacesWizardComponent extends Component<Args> {
methods = CreationMethod;
policy = SecurityPolicy;
wizardId = WIZARD_ID;
wizardId = WIZARD_ID_MAP.namespace;
// Whether the current step requirements have been met to proceed to the next step
get canProceed() {

View File

@ -6,6 +6,7 @@
import Component from '@glimmer/component';
import { service } from '@ember/service';
import { action } from '@ember/object';
import { WIZARD_ID_MAP } from 'vault/utils/constants/wizard';
import type ApiService from 'vault/services/api';
import type FlashMessageService from 'vault/services/flash-messages';
@ -17,15 +18,13 @@ interface Args {
onRefresh: CallableFunction;
}
export const WIZARD_ID = 'secret-engines';
export default class WizardSecretEnginesWizardComponent extends Component<Args> {
@service declare readonly api: ApiService;
@service declare readonly router: RouterService;
@service declare readonly flashMessages: FlashMessageService;
@service declare readonly wizard: WizardService;
wizardId = WIZARD_ID;
wizardId = WIZARD_ID_MAP.secretEngines;
@action
onDismiss() {

View File

@ -6,8 +6,9 @@
import Service from '@ember/service';
import { tracked } from '@glimmer/tracking';
import localStorage from 'vault/lib/local-storage';
import { DISMISSED_WIZARD_KEY } from 'vault/utils/constants/wizard';
const DISMISSED_WIZARD_KEY = 'dismissed-wizards';
import type { WizardId } from 'vault/app-types';
/**
* WizardService manages the state of wizards across the application,
@ -31,7 +32,7 @@ export default class WizardService extends Service {
* @param wizardId - The unique identifier for the wizard
* @returns true if the wizard has been dismissed, false otherwise
*/
isDismissed(wizardId: string): boolean {
isDismissed(wizardId: WizardId): boolean {
return this.dismissedWizards.includes(wizardId);
}
@ -39,7 +40,7 @@ export default class WizardService extends Service {
* Mark a wizard as dismissed
* @param wizardId - The unique identifier for the wizard to dismiss
*/
dismiss(wizardId: string): void {
dismiss(wizardId: WizardId): void {
// Only add if not already dismissed
if (!this.dismissedWizards.includes(wizardId)) {
this.dismissedWizards = [...this.dismissedWizards, wizardId];
@ -51,7 +52,7 @@ export default class WizardService extends Service {
* Clear the dismissed state for a specific wizard
* @param wizardId - The unique identifier for the wizard to reset
*/
reset(wizardId: string): void {
reset(wizardId: WizardId): void {
this.dismissedWizards = this.dismissedWizards.filter((id: string) => id !== wizardId);
localStorage.setItem(DISMISSED_WIZARD_KEY, this.dismissedWizards);
// Reset intro visibility when wizard is reset
@ -72,7 +73,7 @@ export default class WizardService extends Service {
* @param wizardId - The unique identifier for the wizard
* @returns true if the intro is visible, false otherwise (defaults to true if wizard not dismissed, false if dismissed)
*/
isIntroVisible(wizardId: string): boolean {
isIntroVisible(wizardId: WizardId): boolean {
// If intro visibility has been explicitly set, use that value
if (this.introVisibleState[wizardId] !== undefined) {
return this.introVisibleState[wizardId];
@ -87,7 +88,7 @@ export default class WizardService extends Service {
* @param wizardId - The unique identifier for the wizard
* @param visible - Whether the intro should be visible
*/
setIntroVisible(wizardId: string, visible: boolean): void {
setIntroVisible(wizardId: WizardId, visible: boolean): void {
this.introVisibleState = {
...this.introVisibleState,
[wizardId]: visible,

View File

@ -0,0 +1,13 @@
/**
* Copyright IBM Corp. 2016, 2025
* SPDX-License-Identifier: BUSL-1.1
*/
export const DISMISSED_WIZARD_KEY = 'dismissed-wizards';
export const WIZARD_ID_MAP = {
aclPolicy: 'acl-policy',
authMethods: 'auth-methods',
secretEngines: 'secret-engines',
namespace: 'namespace',
} as const;

View File

@ -7,6 +7,7 @@ import { test as base } from '@playwright/test';
import fs from 'fs';
import path from 'path';
import { USER_POLICY_MAP } from './policies';
import { DISMISSED_WIZARD_KEY, WIZARD_ID_MAP } from '../app/utils/constants/wizard';
export type UserSetupOptions = {
userType: string;
@ -21,6 +22,13 @@ export const setup = base.extend<UserSetupOptions>({
setup('initialize vault and setup user for testing', async ({ page, userType }) => {
// on fresh app load navigating to the root will land us on the initialize page
await page.goto('./');
// manually update dismissed wizards so that they don't have to be skipped in tests before persisting storage state;
await page.evaluate(
({ key, ids }) => {
localStorage.setItem(key, JSON.stringify(ids));
},
{ key: DISMISSED_WIZARD_KEY, ids: Object.values(WIZARD_ID_MAP) }
);
// initialize vault
await page.getByRole('spinbutton', { name: 'Key shares' }).fill('1');
await page.getByRole('spinbutton', { name: 'Key threshold' }).fill('1');
@ -68,7 +76,7 @@ setup('initialize vault and setup user for testing', async ({ page, userType })
await page.getByRole('button', { name: 'Sign in' }).click();
// wait for the dashboard to load to ensure login was successful
await page.waitForURL('**/dashboard');
// save the authenticated state to file
// subsequent tests can then reuse this session data
// save the localStorage state to file which includes the auth token and dismissed wizards
// subsequent tests can then reuse the session data
await page.context().storageState({ path: path.join(__dirname, `/tmp/${userType}-session.json`) });
});

View File

@ -12,11 +12,6 @@ test('filtering secrets engines workflow', async ({ page }) => {
await page.goto('dashboard');
await page.getByRole('link', { name: 'Secrets', exact: true }).click();
// skip intro page if it appears
if (await page.getByRole('button', { name: 'Skip' }).isVisible()) {
await page.getByRole('button', { name: 'Skip' }).click();
}
// enable transit
await page.getByRole('link', { name: 'Enable new engine' }).click();
await page.getByLabel('Transit - enabled engine type').click();

View File

@ -10,9 +10,6 @@ test('namespace workflow', async ({ page }) => {
// nav to namespaces and create a new namespace
await page.getByRole('link', { name: 'Access control' }).click();
await page.getByRole('link', { name: 'Namespaces' }).click();
// skip guided tour if it appears
await page.getByRole('button', { name: 'Skip' }).click();
await page.getByRole('link', { name: 'Create namespace' }).click();
await page.getByRole('textbox', { name: 'Path' }).fill('testNamespace');
await page.getByRole('button', { name: 'Save' }).click();

View File

@ -10,9 +10,6 @@ test('userpass workflow', async ({ page }) => {
await page.goto('dashboard');
await page.getByRole('link', { name: 'Access control' }).click();
await page.getByRole('link', { name: 'Authentication methods' }).click();
// dismiss intro page and click enable method in toolbar
await page.getByRole('button', { name: 'Skip' }).click();
await page.getByRole('link', { name: 'Enable new method' }).click();
// enable userpass auth method

View File

@ -13,7 +13,7 @@ import { GENERAL } from 'vault/tests/helpers/general-selectors';
import { mountAuthCmd, runCmd } from 'vault/tests/helpers/commands';
import { login } from 'vault/tests/helpers/auth/auth-helpers';
import { sanitizePath } from 'core/utils/sanitize-path';
import localStorage from 'vault/lib/local-storage';
import { WIZARD_ID_MAP } from 'vault/utils/constants/wizard';
const { searchSelect } = GENERAL;
@ -25,7 +25,7 @@ module('Acceptance | auth-methods list view', function (hooks) {
this.uid = uuidv4();
await login();
// dismiss wizard
localStorage.setItem('dismissed-wizards', ['auth-methods']);
this.owner.lookup('service:wizard').dismiss(WIZARD_ID_MAP.authMethods);
});
test('it navigates to auth method', async function (assert) {

View File

@ -9,15 +9,15 @@ import { setupApplicationTest } from 'ember-qunit';
import { login } from 'vault/tests/helpers/auth/auth-helpers';
import { GENERAL } from 'vault/tests/helpers/general-selectors';
import { createNS, deleteNS, runCmd } from 'vault/tests/helpers/commands';
import localStorage from 'vault/lib/local-storage';
import { WIZARD_ID_MAP } from 'vault/utils/constants/wizard';
module('Acceptance | Enterprise | /access/namespaces', function (hooks) {
setupApplicationTest(hooks);
hooks.beforeEach(async () => {
hooks.beforeEach(async function () {
await login();
// dismiss the wizard
localStorage.setItem('dismissed-wizards', ['namespace']);
this.owner.lookup('service:wizard').dismiss(WIZARD_ID_MAP.namespace);
// Go to the manage namespaces page
await visit('/vault/access/namespaces');
});

View File

@ -13,7 +13,7 @@ import { MANAGED_AUTH_BACKENDS } from 'vault/helpers/supported-managed-auth-back
import { deleteAuthCmd, mountAuthCmd, runCmd, createNS } from 'vault/tests/helpers/commands';
import { GENERAL } from 'vault/tests/helpers/general-selectors';
import { filterEnginesByMountCategory } from 'vault/utils/all-engines-metadata';
import localStorage from 'vault/lib/local-storage';
import { WIZARD_ID_MAP } from 'vault/utils/constants/wizard';
const SELECTORS = {
createUser: '[data-test-entity-create-link="user"]',
@ -27,7 +27,7 @@ module('Acceptance | auth backend list', function (hooks) {
hooks.beforeEach(async function () {
await login();
// dismiss wizard
localStorage.setItem('dismissed-wizards', ['auth-methods']);
this.owner.lookup('service:wizard').dismiss(WIZARD_ID_MAP.authMethods);
});
test('userpass secret backend', async function (assert) {
@ -158,7 +158,7 @@ module('Acceptance | auth backend list', function (hooks) {
await runCmd(createNS(ns), false);
await settled();
await loginNs(ns);
localStorage.setItem('dismissed-wizards', ['auth-methods']);
this.owner.lookup('service:wizard').dismiss(WIZARD_ID_MAP.authMethods);
// go directly to token configure route
await visit(`/vault/settings/auth/configure/token/options?namespace=${ns}`);

View File

@ -20,15 +20,15 @@ import { runCmd, createNSFromPaths, deleteNSFromPaths } from 'vault/tests/helper
import { login, loginNs, logout } from 'vault/tests/helpers/auth/auth-helpers';
import { AUTH_FORM } from 'vault/tests/helpers/auth/auth-form-selectors';
import { GENERAL } from 'vault/tests/helpers/general-selectors';
import localStorage from 'vault/lib/local-storage';
import { WIZARD_ID_MAP } from 'vault/utils/constants/wizard';
module('Acceptance | Enterprise | namespaces', function (hooks) {
setupApplicationTest(hooks);
hooks.beforeEach(async () => {
hooks.beforeEach(async function () {
await login();
// dismiss wizard
localStorage.setItem('dismissed-wizards', ['namespace']);
this.owner.lookup('service:wizard').dismiss(WIZARD_ID_MAP.namespace);
});
test('it focuses the search input field when user toggles namespace picker', async function (assert) {

View File

@ -21,7 +21,7 @@ import { login } from 'vault/tests/helpers/auth/auth-helpers';
import { runCmd } from 'vault/tests/helpers/commands';
import codemirror, { setCodeEditorValue } from 'vault/tests/helpers/codemirror';
import { GENERAL } from 'vault/tests/helpers/general-selectors';
import localStorage from 'vault/lib/local-storage';
import { WIZARD_ID_MAP } from 'vault/utils/constants/wizard';
const SELECT = {
policyByName: (name) => `[data-test-policy-link="${name}"]`,
@ -38,7 +38,7 @@ module('Acceptance | policies/acl', function (hooks) {
this.uid = uuidv4();
await login();
// dismiss wizard
localStorage.setItem('dismissed-wizards', ['acl-policy']);
this.owner.lookup('service:wizard').dismiss(WIZARD_ID_MAP.aclPolicy);
});
test('it lists default and root acls', async function (assert) {

View File

@ -8,7 +8,7 @@ import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { login } from 'vault/tests/helpers/auth/auth-helpers';
import { GENERAL } from 'vault/tests/helpers/general-selectors';
import localStorage from 'vault/lib/local-storage';
import { WIZARD_ID_MAP } from 'vault/utils/constants/wizard';
module('Acceptance | policies', function (hooks) {
setupApplicationTest(hooks);
@ -41,7 +41,7 @@ module('Acceptance | policies', function (hooks) {
test('it navigates to and from policy show page from sidebar', async function (assert) {
await visit('/vault/dashboard');
localStorage.setItem('dismissed-wizards', ['acl-policy']);
this.owner.lookup('service:wizard').dismiss(WIZARD_ID_MAP.aclPolicy);
await click(GENERAL.navLink('Access control'));
assert.strictEqual(currentURL(), '/vault/policies/acl', 'currentURL is /vault/policies/acl');
await waitFor('[data-test-component="navigate-input"]');

View File

@ -13,8 +13,8 @@ import { SECRET_ENGINE_SELECTORS as SES } from 'vault/tests/helpers/secret-engin
import { deleteEngineCmd, mountEngineCmd, runCmd } from 'vault/tests/helpers/commands';
import { login, loginNs } from 'vault/tests/helpers/auth/auth-helpers';
import page from 'vault/tests/pages/settings/mount-secret-backend';
import localStorage from 'vault/lib/local-storage';
import { setupMirage } from 'ember-cli-mirage/test-support';
import { WIZARD_ID_MAP } from 'vault/utils/constants/wizard';
module('Acceptance | secret-engine list view', function (hooks) {
setupApplicationTest(hooks);
@ -33,7 +33,7 @@ module('Acceptance | secret-engine list view', function (hooks) {
this.uid = uuidv4();
await login();
// dismiss wizard
localStorage.setItem('dismissed-wizards', ['secret-engines']);
this.owner.lookup('service:wizard').dismiss(WIZARD_ID_MAP.secretEngines);
});
// the new API service camelizes response keys, so this tests is to assert that does NOT happen when we re-implement it
@ -210,7 +210,7 @@ module('Acceptance | secret-engine list view', function (hooks) {
await runCmd([`write sys/namespaces/${this.namespace} -force`]);
await loginNs(this.namespace); // log into namespace with root token
// dismiss wizard
localStorage.setItem('dismissed-wizards', ['secret-engines']);
this.owner.lookup('service:wizard').dismiss(WIZARD_ID_MAP.secretEngines);
});
// Ember route models won't refresh within a namespace when this.router.transitionTo() is called

View File

@ -11,7 +11,7 @@ import { login } from 'vault/tests/helpers/auth/auth-helpers';
import modifyPassthroughResponse from 'vault/mirage/helpers/modify-passthrough-response';
import { setRunOptions } from 'ember-a11y-testing/test-support';
import { GENERAL } from 'vault/tests/helpers/general-selectors';
import localStorage from 'vault/lib/local-storage';
import { WIZARD_ID_MAP } from 'vault/utils/constants/wizard';
const link = (label) => `[data-test-sidebar-nav-link="${label}"]`;
const panel = (label) => `[data-test-sidebar-nav-panel="${label}"]`;
@ -34,7 +34,7 @@ module('Acceptance | sidebar navigation', function (hooks) {
});
await login();
// dismiss wizard
localStorage.setItem('dismissed-wizards', ['auth-methods']);
this.owner.lookup('service:wizard').dismiss(WIZARD_ID_MAP.authMethods);
});
test('it should navigate back to the dashboard when logo is clicked in app header', async function (assert) {

View File

@ -7,8 +7,7 @@ import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
import sinon from 'sinon';
import localStorage from 'vault/lib/local-storage';
const DISMISSED_WIZARD_KEY = 'dismissed-wizards';
import { DISMISSED_WIZARD_KEY } from 'vault/utils/constants/wizard';
module('Unit | Service | wizard', function (hooks) {
setupTest(hooks);

View File

@ -4,6 +4,7 @@
*/
import type EmberDataModel from 'ember-data/model'; // eslint-disable-line ember/use-ember-data-rfc-395-imports
import type Owner from '@ember/owner';
import type { WIZARD_ID_MAP } from 'vault/utils/constants/wizard';
// Type that comes back from expandAttributeMeta
export interface FormField {
@ -153,3 +154,5 @@ export interface SearchSelectOption {
export interface StringMap {
[key: string]: string;
}
export type WizardId = (typeof WIZARD_ID_MAP)[keyof typeof WIZARD_ID_MAP];