mirror of
https://github.com/hashicorp/vault.git
synced 2025-08-05 22:27:03 +02:00
UI: Fix externally mounted engine tooltip bug (#31382)
* adding clause for external plugin to tooltip * fixing mouseover event * fix check * pulling object out of list * fix used parameter * adding comments * fix * fixing tests * adding 1 more test * update tooltip func, remove excess params, update tests
This commit is contained in:
parent
3a37fe4cca
commit
c80c4b4180
@ -48,21 +48,7 @@
|
||||
<div>
|
||||
<div class="has-text-grey is-grid align-items-center linked-block-title">
|
||||
{{#if backend.icon}}
|
||||
<Hds::TooltipButton
|
||||
@text={{if
|
||||
backend.isSupportedBackend
|
||||
(concat
|
||||
(get (engines-display-data backend.type) "displayName")
|
||||
(if
|
||||
(eq backend.version 2)
|
||||
" version 2"
|
||||
(if (and (eq backend.version 1) (eq backend.type "kv")) " version 1" "")
|
||||
)
|
||||
)
|
||||
"The UI only supports configuration views for these secret engines. The CLI must be used to manage other engine resources."
|
||||
}}
|
||||
aria-label="Type of backend"
|
||||
>
|
||||
<Hds::TooltipButton aria-label="Type of backend" @text={{this.generateToolTipText backend}}>
|
||||
<Icon @name={{backend.icon}} class="has-text-grey-light" />
|
||||
</Hds::TooltipButton>
|
||||
{{/if}}
|
||||
@ -99,13 +85,15 @@
|
||||
@hasChevron={{false}}
|
||||
data-test-popup-menu-trigger
|
||||
/>
|
||||
<dd.Interactive
|
||||
@route={{backend.backendConfigurationLink}}
|
||||
@model={{backend.id}}
|
||||
data-test-popup-menu="view-configuration"
|
||||
>
|
||||
View configuration
|
||||
</dd.Interactive>
|
||||
{{#if (not-eq (get (engines-display-data backend.type) "type") "generic")}}
|
||||
<dd.Interactive
|
||||
@route={{backend.backendConfigurationLink}}
|
||||
@model={{backend.id}}
|
||||
data-test-popup-menu="view-configuration"
|
||||
>
|
||||
View configuration
|
||||
</dd.Interactive>
|
||||
{{/if}}
|
||||
{{#if (not-eq backend.type "cubbyhole")}}
|
||||
<dd.Interactive
|
||||
@color="critical"
|
||||
|
@ -13,6 +13,7 @@ import type FlashMessageService from 'vault/services/flash-messages';
|
||||
import type SecretsEngineResource from 'vault/resources/secrets/engine';
|
||||
import type ApiService from 'vault/services/api';
|
||||
import type RouterService from '@ember/routing/router-service';
|
||||
import engineDisplayData from 'vault/helpers/engines-display-data';
|
||||
|
||||
/**
|
||||
* @module SecretEngineList handles the display of the list of secret engines, including the filtering.
|
||||
@ -67,6 +68,28 @@ export default class SecretEngineList extends Component<Args> {
|
||||
return sortedBackends;
|
||||
}
|
||||
|
||||
generateToolTipText = (backend: SecretsEngineResource) => {
|
||||
const displayData = engineDisplayData(backend.type);
|
||||
|
||||
if (!displayData) {
|
||||
return;
|
||||
} else if (backend.isSupportedBackend) {
|
||||
if (backend.type === 'kv') {
|
||||
// If the backend is a KV engine, include the version in the tooltip.
|
||||
return `${displayData.displayName} version ${backend.version}`;
|
||||
} else {
|
||||
return `${displayData.displayName}`;
|
||||
}
|
||||
} else if (displayData.type === 'generic') {
|
||||
// If a mounted engine type doesn't match any known type, the type is returned as 'generic' and set this tooltip.
|
||||
// Handles issue when a user externally mounts an engine that doesn't follow the expected naming conventions for what's in the binary, despite being a valid engine.
|
||||
return 'This plugin is not supported by the UI. Please use the CLI to manage this engine.';
|
||||
} else {
|
||||
// If the engine type is recognized but not supported, we only show configuration view and set this tooltip.
|
||||
return 'The UI only supports configuration views for these secret engines. The CLI must be used to manage other engine resources.';
|
||||
}
|
||||
};
|
||||
|
||||
// Filtering & searching
|
||||
get secretEngineArrayByType() {
|
||||
const arrayOfAllEngineTypes = this.sortedDisplayableBackends.map((modelObject) => modelObject.engineType);
|
||||
|
@ -23,5 +23,15 @@ import { ALL_ENGINES } from 'vault/utils/all-engines-metadata';
|
||||
*/
|
||||
export default function engineDisplayData(methodType: string) {
|
||||
const engine = ALL_ENGINES?.find((t) => t.type === methodType);
|
||||
if (!engine && methodType) {
|
||||
// Fallback to a generic engine if no match found but type is provided
|
||||
return {
|
||||
displayName: 'Generic plugin',
|
||||
type: 'generic',
|
||||
glyph: 'lock',
|
||||
mountCategory: ['secret', 'auth'],
|
||||
};
|
||||
}
|
||||
|
||||
return engine;
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import { click, fillIn, currentRouteName, visit, currentURL, triggerEvent } from '@ember/test-helpers';
|
||||
import { click, fillIn, currentRouteName, visit, currentURL } from '@ember/test-helpers';
|
||||
import { selectChoose } from 'ember-power-select/test-support';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupApplicationTest } from 'ember-qunit';
|
||||
@ -86,57 +86,6 @@ module('Acceptance | secret-engine list view', function (hooks) {
|
||||
await runCmd(deleteEngineCmd('aws'));
|
||||
});
|
||||
|
||||
test('hovering over the icon of an unsupported engine shows unsupported tooltip', async function (assert) {
|
||||
await visit('/vault/secrets');
|
||||
await page.enableEngine();
|
||||
await click(MOUNT_BACKEND_FORM.mountType('nomad'));
|
||||
await click(GENERAL.submitButton);
|
||||
|
||||
await selectChoose(GENERAL.searchSelect.trigger('filter-by-engine-type'), 'nomad');
|
||||
|
||||
await triggerEvent('.hds-tooltip-button', 'mouseenter');
|
||||
assert
|
||||
.dom('.hds-tooltip-container')
|
||||
.hasText(
|
||||
'The UI only supports configuration views for these secret engines. The CLI must be used to manage other engine resources.',
|
||||
'shows tooltip text for unsupported engine'
|
||||
);
|
||||
// cleanup
|
||||
await runCmd(deleteEngineCmd('nomad'));
|
||||
});
|
||||
|
||||
test('hovering over the icon of a supported engine shows engine name', async function (assert) {
|
||||
await visit('/vault/secrets');
|
||||
await page.enableEngine();
|
||||
await click(MOUNT_BACKEND_FORM.mountType('ssh'));
|
||||
await click(GENERAL.submitButton);
|
||||
await click(GENERAL.breadcrumbLink('Secrets'));
|
||||
|
||||
await selectChoose(GENERAL.searchSelect.trigger('filter-by-engine-type'), 'ssh');
|
||||
await triggerEvent('.hds-tooltip-button', 'mouseenter');
|
||||
assert.dom('.hds-tooltip-container').hasText('SSH', 'shows tooltip for SSH without version');
|
||||
|
||||
// cleanup
|
||||
await runCmd(deleteEngineCmd('ssh'));
|
||||
});
|
||||
|
||||
test('hovering over the icon of a kv engine shows engine name and version', async function (assert) {
|
||||
await visit('/vault/secrets');
|
||||
|
||||
await page.enableEngine();
|
||||
await click(MOUNT_BACKEND_FORM.mountType('kv'));
|
||||
await fillIn(GENERAL.inputByAttr('path'), `kv-${this.uid}`);
|
||||
await click(GENERAL.submitButton);
|
||||
await click(GENERAL.breadcrumbLink('Secrets'));
|
||||
|
||||
await selectChoose(GENERAL.searchSelect.trigger('filter-by-engine-name'), `kv-${this.uid}`);
|
||||
await triggerEvent('.hds-tooltip-button', 'mouseenter');
|
||||
assert.dom('.hds-tooltip-container').hasText('KV version 2', 'shows tooltip for kv version 2');
|
||||
|
||||
// cleanup
|
||||
await runCmd(deleteEngineCmd('kv'));
|
||||
});
|
||||
|
||||
test('enterprise: cannot view list without permissions inside a namespace', async function (assert) {
|
||||
this.namespace = `ns-${this.uid}`;
|
||||
const enginePath1 = `kv-t1-${this.uid}`;
|
||||
|
@ -5,14 +5,14 @@
|
||||
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'vault/tests/helpers';
|
||||
import { render, click, find, findAll } from '@ember/test-helpers';
|
||||
import { render, click, find, findAll, triggerEvent } from '@ember/test-helpers';
|
||||
import { hbs } from 'ember-cli-htmlbars';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import sinon from 'sinon';
|
||||
import { setupMirage } from 'ember-cli-mirage/test-support';
|
||||
import { overrideResponse } from 'vault/tests/helpers/stubs';
|
||||
import { clickTrigger } from 'ember-power-select/test-support/helpers';
|
||||
|
||||
import { selectChoose } from 'ember-power-select/test-support';
|
||||
import { createSecretsEngine } from 'vault/tests/helpers/secret-engine/secret-engine-helpers';
|
||||
import { SECRET_ENGINE_SELECTORS as SES } from 'vault/tests/helpers/secret-engine/secret-engine-selectors';
|
||||
import { GENERAL } from 'vault/tests/helpers/general-selectors';
|
||||
@ -33,18 +33,19 @@ module('Integration | Component | secret-engine/list', function (hooks) {
|
||||
this.flashSuccessSpy = sinon.spy(this.flashMessages, 'success');
|
||||
this.flashDangerSpy = sinon.spy(this.flashMessages, 'danger');
|
||||
this.uid = uuidv4();
|
||||
// generate a model of cubbyhole, kv2, and nomad
|
||||
// generate a model of cubbyhole, kv, and nomad
|
||||
this.secretEngineModels = [
|
||||
createSecretsEngine(undefined, 'cubbyhole', 'cubbyhole-test'),
|
||||
createSecretsEngine(undefined, 'kv', 'kv2-test'),
|
||||
createSecretsEngine(undefined, 'kv', 'kv-test'),
|
||||
createSecretsEngine(undefined, 'aws', 'aws-1'),
|
||||
createSecretsEngine(undefined, 'aws', 'aws-2'),
|
||||
createSecretsEngine(undefined, 'nomad', 'nomad-test'),
|
||||
createSecretsEngine(undefined, 'badType', 'external-test'),
|
||||
];
|
||||
});
|
||||
|
||||
test('it allows you to disable an engine', async function (assert) {
|
||||
const enginePath = 'kv2-test';
|
||||
const enginePath = 'kv-test';
|
||||
this.server.delete(`sys/mounts/${enginePath}`, () => {
|
||||
assert.true(true, 'Request is made to delete engine');
|
||||
return overrideResponse(204);
|
||||
@ -63,6 +64,54 @@ module('Integration | Component | secret-engine/list', function (hooks) {
|
||||
);
|
||||
});
|
||||
|
||||
test('hovering over the icon of an external unrecognized engine type sets unrecognized tooltip text', async function (assert) {
|
||||
await render(hbs`<SecretEngine::List @secretEngines={{this.secretEngineModels}} />`);
|
||||
|
||||
await selectChoose(GENERAL.searchSelect.trigger('filter-by-engine-name'), 'external-test');
|
||||
await triggerEvent('.hds-tooltip-button', 'mouseenter');
|
||||
|
||||
assert
|
||||
.dom('.hds-tooltip-container')
|
||||
.hasText(
|
||||
'This plugin is not supported by the UI. Please use the CLI to manage this engine.',
|
||||
'shows tooltip text for unsupported engine'
|
||||
);
|
||||
});
|
||||
|
||||
test('hovering over the icon of an unsupported engine sets unsupported tooltip text', async function (assert) {
|
||||
await render(hbs`<SecretEngine::List @secretEngines={{this.secretEngineModels}} />`);
|
||||
|
||||
await selectChoose(GENERAL.searchSelect.trigger('filter-by-engine-type'), 'nomad');
|
||||
await triggerEvent('.hds-tooltip-button', 'mouseenter');
|
||||
|
||||
assert
|
||||
.dom('.hds-tooltip-container')
|
||||
.hasText(
|
||||
'The UI only supports configuration views for these secret engines. The CLI must be used to manage other engine resources.',
|
||||
'shows tooltip text for unsupported engine'
|
||||
);
|
||||
});
|
||||
|
||||
test('hovering over the icon of a supported engine sets engine name as tooltip', async function (assert) {
|
||||
await render(hbs`<SecretEngine::List @secretEngines={{this.secretEngineModels}} />`);
|
||||
await selectChoose(GENERAL.searchSelect.trigger('filter-by-engine-name'), 'aws-1');
|
||||
|
||||
await triggerEvent('.hds-tooltip-button', 'mouseenter');
|
||||
|
||||
assert.dom('.hds-tooltip-container').hasText('AWS', 'shows tooltip text for supported engine with name');
|
||||
});
|
||||
|
||||
test('hovering over the icon of a kv engine shows engine name and version', async function (assert) {
|
||||
await render(hbs`<SecretEngine::List @secretEngines={{this.secretEngineModels}}/>`);
|
||||
|
||||
await selectChoose(GENERAL.searchSelect.trigger('filter-by-engine-name'), `kv-test`);
|
||||
|
||||
await triggerEvent('.hds-tooltip-button', 'mouseenter');
|
||||
assert
|
||||
.dom('.hds-tooltip-container')
|
||||
.hasText('KV version 1', 'shows tooltip text for kv engine with version');
|
||||
});
|
||||
|
||||
test('it adds disabled css styling to unsupported secret engines', async function (assert) {
|
||||
await render(hbs`<SecretEngine::List @secretEngines={{this.secretEngineModels}} />`);
|
||||
assert
|
||||
|
Loading…
Reference in New Issue
Block a user