vault/ui/tests/unit/models/secret-engine-external-plugins-test.js
Vault Automation 91025c9ce7
[VAULT-33083] UI: support builtin plugins as external plugins (#11244) (#11489)
* [VAULT-33083] UI: support builtin plugins as external plugins

* address copilot review comments

* add changelog

* remove unused id property

* address some nits & add test coverage

* should use utils instead of mixins

* update comments

* move/consolidate logic for 'transform' engine type into ENGINE_TYPE_TO_MODEL_TYPE_MAP, added/updated test coverage

* cleanup: extract transform engine model type logic into helper functions

* address pr comment

* separation of concerns - move relevant vars/fns from all engines metadata to external plugin helpers & secret engine model helpers files

* add TODO; remove unnecessary exports

* rename secret-engine-model-helpers to secret-engine-helpers

* update unknown engine metadata from var to fn to handle a methodType param

* remove unnecessary test

* update changelog; return methodType for unknown engine metadata, simplify code for readability

* add optional chaining for fail-safe

* address kvv1 edge case - on exit configuration, kvv1 should redirect to list-root while kvv2 should redirect to the engineRoute defined in all-engines-metadata

* add ibm header

* fix test failure after updating unknown engine type

Co-authored-by: Shannon Roberts (Beagin) <beagins@users.noreply.github.com>
2025-12-18 18:29:20 +00:00

153 lines
5.1 KiB
JavaScript

/**
* Copyright IBM Corp. 2016, 2025
* SPDX-License-Identifier: BUSL-1.1
*/
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
/**
* Test the secret-engine model to ensure external plugin mapping
* works correctly for key getters that affect routing and UI behavior.
*/
module('Unit | Model | secret-engine external plugin support', function (hooks) {
setupTest(hooks);
module('isV2KV getter', function () {
test('returns true for external KV v2 plugins', function (assert) {
const store = this.owner.lookup('service:store');
const externalKvV2 = store.createRecord('secret-engine', {
type: 'vault-plugin-secrets-kv',
version: 2,
});
assert.true(externalKvV2.isV2KV, 'External KV v2 plugin is recognized as V2 KV');
});
test('returns false for external KV v1 plugins', function (assert) {
const store = this.owner.lookup('service:store');
const externalKvV1 = store.createRecord('secret-engine', {
type: 'vault-plugin-secrets-kv',
version: 1,
});
assert.false(externalKvV1.isV2KV, 'External KV v1 plugin is not V2 KV');
});
test('returns true for builtin KV v2 engines', function (assert) {
const store = this.owner.lookup('service:store');
const builtinKvV2 = store.createRecord('secret-engine', {
type: 'kv',
version: 2,
});
assert.true(builtinKvV2.isV2KV, 'Builtin KV v2 engine is recognized as V2 KV');
});
test('returns true for generic v2 engines', function (assert) {
const store = this.owner.lookup('service:store');
const genericV2 = store.createRecord('secret-engine', {
type: 'generic',
version: 2,
});
assert.true(genericV2.isV2KV, 'Generic v2 engine is recognized as V2 KV');
});
test('returns false for non-KV external plugins', function (assert) {
const store = this.owner.lookup('service:store');
const externalKeymgmt = store.createRecord('secret-engine', {
type: 'vault-plugin-secrets-keymgmt',
version: 1,
});
assert.false(externalKeymgmt.isV2KV, 'External keymgmt plugin is not V2 KV');
});
});
module('backendLink getter', function () {
test('returns KV engine route for external KV v2 plugins', function (assert) {
const store = this.owner.lookup('service:store');
const externalKvV2 = store.createRecord('secret-engine', {
type: 'vault-plugin-secrets-kv',
version: 2,
});
const backendLink = externalKvV2.backendLink;
assert.true(backendLink.includes('kv.list'), `External KV v2 uses KV engine route: ${backendLink}`);
});
test('returns correct route for external database plugins', function (assert) {
const store = this.owner.lookup('service:store');
// Mock external database plugin (though not in our current mapping)
const externalDb = store.createRecord('secret-engine', {
type: 'vault-plugin-database-postgresql',
});
const backendLink = externalDb.backendLink;
// Should fall back to list-root for unmapped plugins
assert.strictEqual(
backendLink,
'vault.cluster.secrets.backend.list-root',
'Unmapped external plugin uses generic route'
);
});
test('handles external keymgmt plugins correctly', function (assert) {
const store = this.owner.lookup('service:store');
const externalKeymgmt = store.createRecord('secret-engine', {
type: 'vault-plugin-secrets-keymgmt',
});
const backendLink = externalKeymgmt.backendLink;
// External keymgmt should route to generic since keymgmt doesn't have engineRoute
assert.strictEqual(
backendLink,
'vault.cluster.secrets.backend.list-root',
'External keymgmt uses list-root route'
);
});
});
module('backendConfigurationLink getter', function () {
test('returns effective type configuration route for external plugins', function (assert) {
const store = this.owner.lookup('service:store');
const externalAzure = store.createRecord('secret-engine', {
type: 'vault-plugin-secrets-azure',
});
const configLink = externalAzure.backendConfigurationLink;
// Note: The old secret-engine model uses isAddonEngine logic, so Azure (not an addon)
// falls back to general-settings rather than plugin-settings
assert.strictEqual(
configLink,
'vault.cluster.secrets.backend.configuration.general-settings',
`External Azure uses general settings route in old model: ${configLink}`
);
});
test('fallback to generic configuration for unmapped plugins', function (assert) {
const store = this.owner.lookup('service:store');
const unknownExternal = store.createRecord('secret-engine', {
type: 'vault-plugin-secrets-unknown',
});
const configLink = unknownExternal.backendConfigurationLink;
assert.strictEqual(
configLink,
'vault.cluster.secrets.backend.configuration.general-settings',
'Unknown external plugin uses generic configuration route'
);
});
});
});