mirror of
https://github.com/hashicorp/vault.git
synced 2026-05-08 22:06:27 +02:00
* [VAULT-42686] UI: add playwright coverage for keymgmt binary tests * use test.step instead of comments * cleanup Co-authored-by: Shannon Roberts (Beagin) <beagins@users.noreply.github.com>
This commit is contained in:
parent
cd2c9b0304
commit
7f893c6ea3
136
ui/e2e/tests/superuser/keymgmt-mount-external.ent.spec.ts
Normal file
136
ui/e2e/tests/superuser/keymgmt-mount-external.ent.spec.ts
Normal file
@ -0,0 +1,136 @@
|
||||
/**
|
||||
* Copyright IBM Corp. 2016, 2025
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import { expect, test } from '@playwright/test';
|
||||
|
||||
const PINNED_PLUGIN_DATA = {
|
||||
data: {
|
||||
name: 'vault-plugin-secrets-keymgmt',
|
||||
type: 'secret',
|
||||
version: 'v0.17.0+ent',
|
||||
},
|
||||
};
|
||||
|
||||
const PLUGIN_CATALOG_DATA = {
|
||||
request_id: 'request_id',
|
||||
lease_id: '',
|
||||
renewable: false,
|
||||
lease_duration: 0,
|
||||
data: {
|
||||
detailed: [
|
||||
{
|
||||
builtin: true,
|
||||
deprecation_status: 'supported',
|
||||
name: 'keymgmt',
|
||||
type: 'secret',
|
||||
version: 'v0.18.1+builtin',
|
||||
},
|
||||
{
|
||||
builtin: false,
|
||||
name: 'vault-plugin-secrets-keymgmt',
|
||||
sha256: 'sha256',
|
||||
type: 'secret',
|
||||
version: '',
|
||||
},
|
||||
{
|
||||
builtin: false,
|
||||
name: 'vault-plugin-secrets-keymgmt',
|
||||
sha256: 'sha256',
|
||||
type: 'secret',
|
||||
version: 'v0.16.0+ent',
|
||||
},
|
||||
{
|
||||
builtin: false,
|
||||
name: 'vault-plugin-secrets-keymgmt',
|
||||
sha256: 'sha256',
|
||||
type: 'secret',
|
||||
version: 'v0.17.0+ent',
|
||||
},
|
||||
{
|
||||
builtin: false,
|
||||
name: 'vault-plugin-secrets-keymgmt',
|
||||
sha256: 'sha256',
|
||||
type: 'secret',
|
||||
version: 'v0.18.0+ent',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
test('mount external keymgmt workflow', async ({ page }) => {
|
||||
await test.step('mock the keymgmt pinned version response', async () => {
|
||||
await page.route('**v1/sys/plugins/pins/secret/vault-plugin-secrets-keymgmt', async (route) => {
|
||||
if (route.request().method() === 'GET') {
|
||||
await route.fulfill({
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
body: JSON.stringify(PINNED_PLUGIN_DATA),
|
||||
});
|
||||
} else {
|
||||
await route.continue();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
await test.step('mock the plugin catalog response to return builtin and external keymgmt plugins', async () => {
|
||||
await page.route('**v1/sys/plugins/catalog', async (route) => {
|
||||
if (route.request().method() === 'GET') {
|
||||
await route.fulfill({
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
body: JSON.stringify(PLUGIN_CATALOG_DATA),
|
||||
});
|
||||
} else {
|
||||
await route.continue();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
await page.goto('dashboard');
|
||||
|
||||
await test.step('navigate to enable Key Management engine', async () => {
|
||||
await page.getByRole('link', { name: 'Secrets', exact: true }).click();
|
||||
await page.getByRole('link', { name: 'Enable new engine' }).click();
|
||||
await page.getByLabel('Key Management - enabled').click();
|
||||
await page.getByRole('textbox', { name: 'Path' }).fill('keymgmt-external');
|
||||
});
|
||||
|
||||
await test.step('verify builtin and external plugin type options are visible', async () => {
|
||||
await expect(page.getByText('Built-in plugin Preregistered')).toBeVisible();
|
||||
await expect(page.getByText('External plugin External')).toBeVisible();
|
||||
await expect(page.getByText('Plugin version Required')).not.toBeVisible();
|
||||
});
|
||||
|
||||
await test.step('selecting external plugin type shows plugin version dropdown', async () => {
|
||||
await page.locator('label:nth-child(2) > .hds-form-radio-card__control-wrapper').click();
|
||||
await expect(page.getByText('Plugin version Required')).toBeVisible();
|
||||
await expect(page.getByLabel('Plugin version Required')).toContainText(
|
||||
'v0.17.0+ent (pinned) v0.16.0+ent v0.18.0+ent'
|
||||
);
|
||||
});
|
||||
|
||||
await test.step('pinned version is selected by default with no warning', async () => {
|
||||
await expect(page.getByLabel('Version differs from pinned')).not.toBeVisible();
|
||||
});
|
||||
|
||||
await test.step('selecting a non-pinned version shows a warning', async () => {
|
||||
await page.getByLabel('Plugin version Required').selectOption('v0.16.0+ent');
|
||||
await expect(page.getByLabel('Version differs from pinned')).toContainText(
|
||||
'You have selected v0.16.0+ent, but version v0.17.0+ent is pinned for this plugin. Enabling the engine with this version will override the pinned version for this mount.'
|
||||
);
|
||||
});
|
||||
|
||||
await test.step('re-selecting the pinned version clears the warning', async () => {
|
||||
await page.getByLabel('Plugin version Required').selectOption('v0.17.0+ent');
|
||||
await expect(page.getByLabel('Version differs from pinned')).not.toBeVisible();
|
||||
});
|
||||
|
||||
await test.step('enabling engine shows error with external plugin name', async () => {
|
||||
await page.getByRole('button', { name: 'Enable engine' }).click();
|
||||
await expect(page.getByLabel('Error')).toContainText(
|
||||
'plugin not found in the catalog: vault-plugin-secrets-keymgmt'
|
||||
);
|
||||
});
|
||||
});
|
||||
204
ui/e2e/tests/superuser/keymgmt-tune-external.ent.spec.ts
Normal file
204
ui/e2e/tests/superuser/keymgmt-tune-external.ent.spec.ts
Normal file
@ -0,0 +1,204 @@
|
||||
/**
|
||||
* Copyright IBM Corp. 2016, 2025
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import { expect, test } from '@playwright/test';
|
||||
|
||||
const PINNED_PLUGIN_DATA = {
|
||||
data: {
|
||||
name: 'vault-plugin-secrets-keymgmt',
|
||||
type: 'secret',
|
||||
version: 'v0.17.0+ent',
|
||||
},
|
||||
};
|
||||
|
||||
const PLUGIN_CATALOG_DATA = {
|
||||
request_id: 'request_id',
|
||||
lease_id: '',
|
||||
renewable: false,
|
||||
lease_duration: 0,
|
||||
data: {
|
||||
detailed: [
|
||||
{
|
||||
builtin: true,
|
||||
deprecation_status: 'supported',
|
||||
name: 'keymgmt',
|
||||
type: 'secret',
|
||||
version: 'v0.18.1+builtin',
|
||||
},
|
||||
{
|
||||
builtin: false,
|
||||
name: 'vault-plugin-secrets-keymgmt',
|
||||
sha256: 'sha256',
|
||||
type: 'secret',
|
||||
version: '',
|
||||
},
|
||||
{
|
||||
builtin: false,
|
||||
name: 'vault-plugin-secrets-keymgmt',
|
||||
sha256: 'sha256',
|
||||
type: 'secret',
|
||||
version: 'v0.16.0+ent',
|
||||
},
|
||||
{
|
||||
builtin: false,
|
||||
name: 'vault-plugin-secrets-keymgmt',
|
||||
sha256: 'sha256',
|
||||
type: 'secret',
|
||||
version: 'v0.17.0+ent',
|
||||
},
|
||||
{
|
||||
builtin: false,
|
||||
name: 'vault-plugin-secrets-keymgmt',
|
||||
sha256: 'sha256',
|
||||
type: 'secret',
|
||||
version: 'v0.18.0+ent',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
const KEYMGMT_EXTERNAL_MOUNT_DATA = {
|
||||
request_id: 'request_id',
|
||||
lease_id: '',
|
||||
renewable: false,
|
||||
lease_duration: 0,
|
||||
data: {
|
||||
accessor: 'vault-plugin-secrets-keymgmt_accessor',
|
||||
config: {
|
||||
default_lease_ttl: 2764800,
|
||||
force_no_cache: false,
|
||||
listing_visibility: 'hidden',
|
||||
max_lease_ttl: 2764800,
|
||||
},
|
||||
description: '',
|
||||
external_entropy_access: false,
|
||||
local: false,
|
||||
options: {},
|
||||
path: 'keymgmt-external/',
|
||||
plugin_version: 'v0.17.0+ent',
|
||||
running_plugin_version: 'v0.17.0+ent',
|
||||
running_sha256: 'sha256',
|
||||
seal_wrap: false,
|
||||
type: 'vault-plugin-secrets-keymgmt',
|
||||
uuid: 'uuid',
|
||||
},
|
||||
wrap_info: null,
|
||||
warnings: null,
|
||||
auth: null,
|
||||
mount_type: '',
|
||||
};
|
||||
|
||||
const UPDATED_KEYMGMT_EXTERNAL_MOUNT_DATA = {
|
||||
...KEYMGMT_EXTERNAL_MOUNT_DATA,
|
||||
data: {
|
||||
...KEYMGMT_EXTERNAL_MOUNT_DATA.data,
|
||||
plugin_version: 'v0.18.0+ent',
|
||||
running_plugin_version: 'v0.18.0+ent',
|
||||
},
|
||||
};
|
||||
|
||||
test('tune external keymgmt workflow', async ({ page }) => {
|
||||
await test.step('mock the keymgmt pinned version response', async () => {
|
||||
await page.route('**v1/sys/plugins/pins/secret/vault-plugin-secrets-keymgmt', async (route) => {
|
||||
if (route.request().method() === 'GET') {
|
||||
await route.fulfill({
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
body: JSON.stringify(PINNED_PLUGIN_DATA),
|
||||
});
|
||||
} else {
|
||||
await route.continue();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
await test.step('mock the plugin catalog response to return builtin and external keymgmt plugins', async () => {
|
||||
await page.route('**v1/sys/plugins/catalog', async (route) => {
|
||||
if (route.request().method() === 'GET') {
|
||||
await route.fulfill({
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
body: JSON.stringify(PLUGIN_CATALOG_DATA),
|
||||
});
|
||||
} else {
|
||||
await route.continue();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
await test.step('mock the keymgmt external mount response', async () => {
|
||||
await page.route('**/v1/sys/internal/ui/mounts/keymgmt-external', async (route) => {
|
||||
if (route.request().method() === 'GET') {
|
||||
await route.fulfill({
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
body: JSON.stringify(KEYMGMT_EXTERNAL_MOUNT_DATA),
|
||||
});
|
||||
} else {
|
||||
await route.continue();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
await test.step('mock the initial keymgmt external tunde response', async () => {
|
||||
await page.route('**/v1/sys/mounts/keymgmt-external/tune', async (route) => {
|
||||
if (route.request().method() === 'POST') {
|
||||
await route.fulfill({
|
||||
status: 204,
|
||||
contentType: 'application/json',
|
||||
});
|
||||
} else {
|
||||
await route.continue();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
await page.goto('dashboard');
|
||||
|
||||
await test.step("navigate to the external keymgmt mount's general settings page", async () => {
|
||||
await page.goto('secrets-engines/keymgmt-external/list');
|
||||
await page.getByRole('button', { name: 'Manage' }).click();
|
||||
await page.getByRole('link', { name: 'Configure' }).click();
|
||||
await expect(page.getByRole('heading', { level: 1 })).toContainText('keymgmt-external configuration');
|
||||
await expect(page.getByRole('link', { name: 'General settings' })).toBeVisible();
|
||||
await expect(page.getByRole('paragraph').nth(2)).toContainText('vault-plugin-secrets-keymgmt');
|
||||
await expect(page.getByRole('paragraph').nth(3)).toContainText('v0.17.0+ent (Pinned)');
|
||||
});
|
||||
|
||||
await test.step('verify that selecting an unpinned version shows the override message', async () => {
|
||||
await page.getByLabel('Update version to:').selectOption('v0.16.0+ent');
|
||||
await expect(page.getByLabel('Override pinned version')).toContainText(
|
||||
'You have selected v0.16.0+ent, but version v0.17.0+ent is pinned for this plugin. Updating to this version will override the pinned version for this mount.'
|
||||
);
|
||||
});
|
||||
|
||||
await test.step('reset the version selection and verify that the override message goes away', async () => {
|
||||
await page.getByLabel('Update version to:').selectOption('');
|
||||
await expect(page.getByLabel('Override pinned version')).not.toBeVisible();
|
||||
});
|
||||
|
||||
await test.step('verify that selecting an unpinned version shows the override message', async () => {
|
||||
await page.getByLabel('Update version to:').selectOption('v0.18.0+ent');
|
||||
await expect(page.getByLabel('Override pinned version')).toContainText(
|
||||
'You have selected v0.18.0+ent, but version v0.17.0+ent is pinned for this plugin. Updating to this version will override the pinned version for this mount.'
|
||||
);
|
||||
});
|
||||
|
||||
await test.step('mock updated mount response after tuning with a new plugin version', async () => {
|
||||
await page.route('**/v1/sys/internal/ui/mounts/keymgmt-external', async (route) => {
|
||||
if (route.request().method() === 'GET') {
|
||||
await route.fulfill({
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
body: JSON.stringify(UPDATED_KEYMGMT_EXTERNAL_MOUNT_DATA),
|
||||
});
|
||||
} else {
|
||||
await route.continue();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
await page.getByRole('button', { name: 'Save changes' }).click();
|
||||
});
|
||||
86
ui/e2e/tests/superuser/keymgmt.spec.ts
Normal file
86
ui/e2e/tests/superuser/keymgmt.spec.ts
Normal file
@ -0,0 +1,86 @@
|
||||
/**
|
||||
* Copyright IBM Corp. 2016, 2025
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import { expect, test } from '@playwright/test';
|
||||
|
||||
test('keymgmt workflow', async ({ page }) => {
|
||||
await test.step('mock the distribution response', async () => {
|
||||
await page.route('**/v1/keymgmt-builtin/kms/test-provider/key/test-key', async (route) => {
|
||||
if (route.request().method() === 'PUT') {
|
||||
await route.fulfill({
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
});
|
||||
} else {
|
||||
await route.continue();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
await page.goto('dashboard');
|
||||
|
||||
await test.step('enable Key Management secrets engine', async () => {
|
||||
await page.getByRole('link', { name: 'Secrets', exact: true }).click();
|
||||
await page.getByRole('link', { name: 'Enable new engine' }).click();
|
||||
await page.getByLabel('Key Management - enabled').click();
|
||||
await page.getByRole('textbox', { name: 'Path' }).fill('keymgmt-builtin');
|
||||
await page.getByRole('button', { name: 'Method Options' }).click();
|
||||
await page.getByRole('textbox', { name: 'Description' }).fill('This is a keymgmt mount.');
|
||||
await page.getByRole('checkbox', { name: 'Local' }).check();
|
||||
await page.getByRole('button', { name: 'Enable engine' }).click();
|
||||
|
||||
await expect(page.getByText('Success', { exact: true })).toBeVisible();
|
||||
await expect(
|
||||
page.getByText('Successfully mounted the keymgmt secrets engine at keymgmt-builtin')
|
||||
).toBeVisible();
|
||||
await page.getByRole('button', { name: 'Dismiss' }).click();
|
||||
});
|
||||
|
||||
await test.step('create a provider', async () => {
|
||||
await page.getByRole('link', { name: 'Create provider' }).click();
|
||||
await page.getByLabel('Type').selectOption('azurekeyvault');
|
||||
await page.getByRole('textbox', { name: 'Provider name' }).fill('test-provider');
|
||||
await page.getByRole('textbox', { name: 'Key Vault instance name' }).fill('keyvault-name');
|
||||
await page.getByRole('textbox', { name: 'client_id' }).fill('a0454cd1-e28e-405e-bc50-7477fa8a00b7');
|
||||
await page.getByRole('textbox', { name: 'client_secret' }).fill('eR%HizuCVEpAKgeaUEx');
|
||||
await page.getByRole('textbox', { name: 'tenant_id' }).fill('cd4bf224-d114-4f96-9bbc-b8f45751c43f');
|
||||
await page.getByRole('button', { name: 'Create provider' }).click();
|
||||
|
||||
await expect(page.locator('span').filter({ hasText: 'test-provider' })).toBeVisible();
|
||||
await expect(page.getByText('Azure Key Vault')).toBeVisible();
|
||||
await expect(page.getByText('keyvault-name')).toBeVisible();
|
||||
await expect(page.getByText('None')).toBeVisible();
|
||||
});
|
||||
|
||||
await test.step('create a key', async () => {
|
||||
await page.getByRole('link', { name: 'Keys' }).click();
|
||||
await page.getByRole('link', { name: 'Create key' }).click();
|
||||
await page.getByRole('textbox', { name: 'Key name' }).fill('test-key');
|
||||
await page.getByRole('checkbox', { name: 'Allow deletion' }).check();
|
||||
await page.getByRole('button', { name: 'Create key' }).click();
|
||||
|
||||
await expect(page.locator('section')).toContainText('test-key');
|
||||
await expect(page.locator('section')).toContainText('rsa-2048');
|
||||
await expect(page.locator('section')).toContainText('Yes');
|
||||
});
|
||||
|
||||
await test.step('distribute key to provider', async () => {
|
||||
await page.getByLabel('toolbar actions').getByRole('button', { name: 'Distribute key' }).click();
|
||||
await page.getByText('Search').click();
|
||||
await page.getByRole('option', { name: 'test-provider' }).click();
|
||||
await page.getByText('Encrypt').click();
|
||||
await page.getByText('Decrypt').click();
|
||||
await page.getByText('Sign').click();
|
||||
await page.getByText('Verify').click();
|
||||
await page.getByText('Wrap', { exact: true }).click();
|
||||
await page.getByText('Unwrap').click();
|
||||
await page.getByRole('radio', { name: 'HSM' }).check();
|
||||
await page.getByRole('button', { name: 'Distribute key' }).click();
|
||||
|
||||
await expect(page.getByText('Success', { exact: true })).toBeVisible();
|
||||
await expect(page.getByText('Successfully distributed key test-key to test-provider')).toBeVisible();
|
||||
await page.getByRole('button', { name: 'Dismiss' }).click();
|
||||
});
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user