mirror of
https://github.com/hashicorp/vault.git
synced 2026-04-02 04:11:19 +02:00
Merge remote-tracking branch 'remotes/from/ce/main'
This commit is contained in:
commit
fbf7f3bb12
3
changelog/_13260.txt
Normal file
3
changelog/_13260.txt
Normal 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
3
changelog/_13264.txt
Normal 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
6
go.mod
@ -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
12
go.sum
@ -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=
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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
|
||||
*/
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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,
|
||||
|
||||
13
ui/app/utils/constants/wizard.ts
Normal file
13
ui/app/utils/constants/wizard.ts
Normal 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;
|
||||
@ -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`) });
|
||||
});
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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');
|
||||
});
|
||||
|
||||
@ -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}`);
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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"]');
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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];
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user