diff --git a/ui/app/adapters/kmip/base.js b/ui/app/adapters/kmip/base.js deleted file mode 100644 index d0aadf23c4..0000000000 --- a/ui/app/adapters/kmip/base.js +++ /dev/null @@ -1,69 +0,0 @@ -/** - * Copyright IBM Corp. 2016, 2025 - * SPDX-License-Identifier: BUSL-1.1 - */ - -import ApplicationAdapter from '../application'; -import { encodePath } from 'vault/utils/path-encoding-helpers'; - -export default ApplicationAdapter.extend({ - namespace: 'v1', - pathForType(type) { - return type.replace('kmip/', ''); - }, - - _url(modelType, meta = {}, id) { - const { backend, scope, role } = meta; - const type = this.pathForType(modelType); - let base; - switch (type) { - case 'scope': - base = `${encodePath(backend)}/scope`; - break; - case 'role': - base = `${encodePath(backend)}/scope/${encodePath(scope)}/role`; - break; - case 'credential': - base = `${encodePath(backend)}/scope/${encodePath(scope)}/role/${encodePath(role)}/credential`; - break; - } - if (id && type === 'credential') { - return `/v1/${base}/lookup?serial_number=${encodePath(id)}`; - } - - if (id) { - return `/v1/${base}/${encodePath(id)}`; - } - return `/v1/${base}`; - }, - - urlForQuery(query, modelType) { - const base = this._url(modelType, query); - return base + '?list=true'; - }, - - query(store, type, query) { - return this.ajax(this.urlForQuery(query, type.modelName), 'GET').then((resp) => { - // remove pagination query items here - const { ...modelAttrs } = query; - resp._requestQuery = modelAttrs; - return resp; - }); - }, - - queryRecord(store, type, query) { - const id = query.id; - delete query.id; - return this.ajax(this._url(type.modelName, query, id), 'GET').then((resp) => { - resp.id = id; - resp = { ...resp, ...query }; - return resp; - }); - }, - buildURL(modelName, id, snapshot, requestType, query) { - if (requestType === 'createRecord') { - return this._super(...arguments); - } - return this._super(`${modelName}`, id, snapshot, requestType, query); - }, -}); diff --git a/ui/app/adapters/kmip/ca.js b/ui/app/adapters/kmip/ca.js deleted file mode 100644 index 3354fe2207..0000000000 --- a/ui/app/adapters/kmip/ca.js +++ /dev/null @@ -1,13 +0,0 @@ -/** - * Copyright IBM Corp. 2016, 2025 - * SPDX-License-Identifier: BUSL-1.1 - */ - -import BaseAdapter from './base'; - -export default BaseAdapter.extend({ - urlForFindRecord(id, modelName, snapshot) { - const name = this.pathForType(modelName); - return this.buildURL(id, name, snapshot); - }, -}); diff --git a/ui/app/adapters/kmip/config.js b/ui/app/adapters/kmip/config.js deleted file mode 100644 index a5be5e8f36..0000000000 --- a/ui/app/adapters/kmip/config.js +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Copyright IBM Corp. 2016, 2025 - * SPDX-License-Identifier: BUSL-1.1 - */ - -import BaseAdapter from './base'; - -export default BaseAdapter.extend({ - _url(id, modelName, snapshot) { - const name = this.pathForType(modelName); - // id here will be the mount path, - // modelName will be config so we want to transpose the first two call args - return this.buildURL(id, name, snapshot); - }, - urlForFindRecord() { - return this._url(...arguments); - }, - urlForCreateRecord(modelName, snapshot) { - const id = snapshot.record.mutableId; - return this._url(id, modelName, snapshot); - }, - urlForUpdateRecord() { - return this._url(...arguments); - }, - - createRecord(store, type, snapshot) { - return this._super(...arguments).then(() => { - // saving returns a 204, return object with id to please ember-data... - const id = snapshot.record.mutableId; - return { id }; - }); - }, -}); diff --git a/ui/app/adapters/kmip/credential.js b/ui/app/adapters/kmip/credential.js deleted file mode 100644 index c39947eda0..0000000000 --- a/ui/app/adapters/kmip/credential.js +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Copyright IBM Corp. 2016, 2025 - * SPDX-License-Identifier: BUSL-1.1 - */ - -import BaseAdapter from './base'; - -export default BaseAdapter.extend({ - createRecord(store, type, snapshot) { - let url = this._url(type.modelName, { - backend: snapshot.record.backend, - scope: snapshot.record.scope, - role: snapshot.record.role, - }); - url = `${url}/generate`; - return this.ajax(url, 'POST', { data: snapshot.serialize() }).then((model) => { - model.data.id = model.data.serial_number; - return model; - }); - }, - - deleteRecord(store, type, snapshot) { - let url = this._url(type.modelName, { - backend: snapshot.record.backend, - scope: snapshot.record.scope, - role: snapshot.record.role, - }); - url = `${url}/revoke`; - return this.ajax(url, 'POST', { - data: { - serial_number: snapshot.id, - }, - }); - }, -}); diff --git a/ui/app/adapters/kmip/role.js b/ui/app/adapters/kmip/role.js deleted file mode 100644 index 5ca9e3674c..0000000000 --- a/ui/app/adapters/kmip/role.js +++ /dev/null @@ -1,78 +0,0 @@ -/** - * Copyright IBM Corp. 2016, 2025 - * SPDX-License-Identifier: BUSL-1.1 - */ - -import BaseAdapter from './base'; -import { decamelize } from '@ember/string'; -import { getProperties } from '@ember/object'; -import { nonOperationFields } from 'vault/utils/model-helpers/kmip-role-fields'; - -export default BaseAdapter.extend({ - createRecord(store, type, snapshot) { - const name = snapshot.id || snapshot.record.role; - const url = this._url( - type.modelName, - { - backend: snapshot.record.backend, - scope: snapshot.record.scope, - }, - name - ); - const data = this.serialize(snapshot); - return this.ajax(url, 'POST', { data }).then(() => { - return { - id: name, - role: name, - backend: snapshot.record.backend, - scope: snapshot.record.scope, - }; - }); - }, - - deleteRecord(store, type, snapshot) { - // records must always have IDs - const name = snapshot.id; - const url = this._url( - type.modelName, - { - backend: snapshot.record.backend, - scope: snapshot.record.scope, - }, - name - ); - return this.ajax(url, 'DELETE'); - }, - - updateRecord() { - return this.createRecord(...arguments); - }, - - serialize(snapshot) { - // the endpoint here won't allow sending `operation_all` and `operation_none` at the same time or with - // other operation_ values, so we manually check for them and send an abbreviated object - const json = snapshot.serialize(); - const keys = nonOperationFields(snapshot.record.editableFields).map(decamelize); - const nonOp = getProperties(json, keys); - for (const field in nonOp) { - if (nonOp[field] == null) { - delete nonOp[field]; - } - } - if (json.operation_all) { - return { - operation_all: true, - ...nonOp, - }; - } - if (json.operation_none) { - return { - operation_none: true, - ...nonOp, - }; - } - delete json.operation_none; - delete json.operation_all; - return json; - }, -}); diff --git a/ui/app/adapters/kmip/scope.js b/ui/app/adapters/kmip/scope.js deleted file mode 100644 index 00bb3daf44..0000000000 --- a/ui/app/adapters/kmip/scope.js +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Copyright IBM Corp. 2016, 2025 - * SPDX-License-Identifier: BUSL-1.1 - */ - -import BaseAdapter from './base'; - -export default BaseAdapter.extend({ - createRecord(store, type, snapshot) { - const name = snapshot.attr('name'); - return this.ajax(this._url(type.modelName, { backend: snapshot.record.backend }, name), 'POST').then( - () => { - return { - id: name, - name, - }; - } - ); - }, - - deleteRecord(store, type, snapshot) { - let url = this._url(type.modelName, { backend: snapshot.record.backend }, snapshot.id); - url = `${url}?force=true`; - return this.ajax(url, 'DELETE'); - }, -}); diff --git a/ui/app/app.js b/ui/app/app.js index 860319d8a6..914ddfb95e 100644 --- a/ui/app/app.js +++ b/ui/app/app.js @@ -62,8 +62,6 @@ export default class App extends Application { 'namespace', 'path-help', { 'app-router': 'router' }, - 'store', - 'pagination', 'version', 'secret-mount-path', ], diff --git a/ui/app/models/kmip/ca.js b/ui/app/models/kmip/ca.js deleted file mode 100644 index 208369a661..0000000000 --- a/ui/app/models/kmip/ca.js +++ /dev/null @@ -1,13 +0,0 @@ -/** - * Copyright IBM Corp. 2016, 2025 - * SPDX-License-Identifier: BUSL-1.1 - */ - -import Model, { belongsTo, attr } from '@ember-data/model'; - -export default Model.extend({ - config: belongsTo('kmip/config', { async: false, inverse: 'ca' }), - caPem: attr('string', { - label: 'CA PEM', - }), -}); diff --git a/ui/app/models/kmip/config.js b/ui/app/models/kmip/config.js deleted file mode 100644 index f114724a75..0000000000 --- a/ui/app/models/kmip/config.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Copyright IBM Corp. 2016, 2025 - * SPDX-License-Identifier: BUSL-1.1 - */ - -import Model, { belongsTo } from '@ember-data/model'; -import { computed } from '@ember/object'; -import { combineFieldGroups } from 'vault/utils/openapi-to-attrs'; -import fieldToAttrs from 'vault/utils/field-to-attrs'; - -export default Model.extend({ - ca: belongsTo('kmip/ca', { async: false, inverse: 'config' }), - - fieldGroups: computed('newFields', function () { - let groups = [{ default: ['listenAddrs', 'connectionTimeout'] }]; - - groups = combineFieldGroups(groups, this.newFields, []); - return fieldToAttrs(this, groups); - }), -}); diff --git a/ui/app/models/kmip/credential.js b/ui/app/models/kmip/credential.js deleted file mode 100644 index a025ff116e..0000000000 --- a/ui/app/models/kmip/credential.js +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Copyright IBM Corp. 2016, 2025 - * SPDX-License-Identifier: BUSL-1.1 - */ - -import Model, { attr } from '@ember-data/model'; -import fieldToAttrs from 'vault/utils/field-to-attrs'; -import { computed } from '@ember/object'; -import apiPath from 'vault/utils/api-path'; -import lazyCapabilities from 'vault/macros/lazy-capabilities'; - -export default Model.extend({ - backend: attr({ readOnly: true }), - scope: attr({ readOnly: true }), - role: attr({ readOnly: true }), - certificate: attr('string', { readOnly: true }), - caChain: attr({ readOnly: true }), - privateKey: attr('string', { - readOnly: true, - sensitive: true, - }), - format: attr('string', { - possibleValues: ['pem', 'der', 'pem_bundle'], - defaultValue: 'pem', - label: 'Certificate format', - }), - fieldGroups: computed(function () { - const groups = [ - { - default: ['format'], - }, - ]; - - return fieldToAttrs(this, groups); - }), - deletePath: lazyCapabilities( - apiPath`${'backend'}/scope/${'scope'}/role/${'role'}/credentials/revoke`, - 'backend', - 'scope', - 'role' - ), -}); diff --git a/ui/app/models/kmip/role.js b/ui/app/models/kmip/role.js deleted file mode 100644 index 70d563e07e..0000000000 --- a/ui/app/models/kmip/role.js +++ /dev/null @@ -1,71 +0,0 @@ -/** - * Copyright IBM Corp. 2016, 2025 - * SPDX-License-Identifier: BUSL-1.1 - */ - -import Model, { attr } from '@ember-data/model'; -import apiPath from 'vault/utils/api-path'; -import lazyCapabilities from 'vault/macros/lazy-capabilities'; -import { withExpandedAttributes } from 'vault/decorators/model-expanded-attributes'; -import { - operationFields, - operationFieldsWithoutSpecial, - tlsFields, -} from 'vault/utils/model-helpers/kmip-role-fields'; -import { removeManyFromArray } from 'vault/helpers/remove-from-array'; - -@withExpandedAttributes() -export default class KmipRoleModel extends Model { - @attr({ readOnly: true }) backend; - @attr({ readOnly: true }) scope; - - get editableFields() { - return Object.keys(this.allByKey).filter((k) => !['backend', 'scope', 'role'].includes(k)); - } - - get fieldGroups() { - const tls = tlsFields(); - const groups = [{ TLS: tls }]; - // op fields are shown in OperationFieldDisplay - const opFields = operationFields(this.editableFields); - // not op fields, tls fields, or role/backend/scope - const defaultFields = this.editableFields.filter((f) => ![...opFields, ...tls].includes(f)); - if (defaultFields.length) { - groups.unshift({ default: defaultFields }); - } - return this._expandGroups(groups); - } - - get operationFormFields() { - const objects = [ - 'operationCreate', - 'operationActivate', - 'operationGet', - 'operationLocate', - 'operationRekey', - 'operationRevoke', - 'operationDestroy', - ]; - - const attributes = ['operationAddAttribute', 'operationGetAttributes']; - const server = ['operationDiscoverVersions']; - const others = removeManyFromArray(operationFieldsWithoutSpecial(this.editableFields), [ - ...objects, - ...attributes, - ...server, - ]); - const groups = [ - { 'Managed Cryptographic Objects': objects }, - { 'Object Attributes': attributes }, - { Server: server }, - ]; - if (others.length) { - groups.push({ - Other: others, - }); - } - return this._expandGroups(groups); - } - - @lazyCapabilities(apiPath`${'backend'}/scope/${'scope'}/role/${'id'}`, 'backend', 'scope', 'id') updatePath; -} diff --git a/ui/app/models/kmip/scope.js b/ui/app/models/kmip/scope.js deleted file mode 100644 index 56152d2a8f..0000000000 --- a/ui/app/models/kmip/scope.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Copyright IBM Corp. 2016, 2025 - * SPDX-License-Identifier: BUSL-1.1 - */ - -import Model, { attr } from '@ember-data/model'; -import { computed } from '@ember/object'; -import apiPath from 'vault/utils/api-path'; - -import { expandAttributeMeta } from 'vault/utils/field-to-attrs'; -import lazyCapabilities from 'vault/macros/lazy-capabilities'; - -export default Model.extend({ - name: attr('string'), - backend: attr({ readOnly: true }), - attrs: computed(function () { - return expandAttributeMeta(this, ['name']); - }), - updatePath: lazyCapabilities(apiPath`${'backend'}/scope/${'id'}`, 'backend', 'id'), -}); diff --git a/ui/app/utils/openapi-helpers.ts b/ui/app/utils/openapi-helpers.ts index b8539775c0..6b60a9bba7 100644 --- a/ui/app/utils/openapi-helpers.ts +++ b/ui/app/utils/openapi-helpers.ts @@ -208,16 +208,6 @@ export function filterPathsByItemType(pathInfo: PathInfo, itemType: string): Pat * This object maps model names to the openAPI path that hydrates the model, given the backend path. */ const OPENAPI_POWERED_MODELS = { - 'kmip/config': (backend: string) => `/v1/${backend}/config?help=1`, - 'kmip/role': (backend: string) => `/v1/${backend}/scope/example/role/example?help=1`, - 'pki/certificate/generate': (backend: string) => `/v1/${backend}/issue/example?help=1`, - 'pki/certificate/sign': (backend: string) => `/v1/${backend}/sign/example?help=1`, - 'pki/config/acme': (backend: string) => `/v1/${backend}/config/acme?help=1`, - 'pki/config/cluster': (backend: string) => `/v1/${backend}/config/cluster?help=1`, - 'pki/config/urls': (backend: string) => `/v1/${backend}/config/urls?help=1`, - 'pki/role': (backend: string) => `/v1/${backend}/roles/example?help=1`, - 'pki/sign-intermediate': (backend: string) => `/v1/${backend}/issuer/example/sign-intermediate?help=1`, - 'pki/tidy': (backend: string) => `/v1/${backend}/config/auto-tidy?help=1`, 'role-ssh': (backend: string) => `/v1/${backend}/roles/example?help=1`, }; diff --git a/ui/lib/kmip/addon/components/header-scope.js b/ui/lib/kmip/addon/components/header-scope.js deleted file mode 100644 index f270038459..0000000000 --- a/ui/lib/kmip/addon/components/header-scope.js +++ /dev/null @@ -1,12 +0,0 @@ -/** - * Copyright IBM Corp. 2016, 2025 - * SPDX-License-Identifier: BUSL-1.1 - */ - -import Component from '@ember/component'; -import { service } from '@ember/service'; - -export default Component.extend({ - tagName: '', - secretMountPath: service(), -}); diff --git a/ui/lib/kmip/addon/components/header-scope.ts b/ui/lib/kmip/addon/components/header-scope.ts new file mode 100644 index 0000000000..cd1b7a5253 --- /dev/null +++ b/ui/lib/kmip/addon/components/header-scope.ts @@ -0,0 +1,13 @@ +/** + * Copyright IBM Corp. 2016, 2025 + * SPDX-License-Identifier: BUSL-1.1 + */ + +import Component from '@glimmer/component'; +import { service } from '@ember/service'; + +import type SecretMountPath from 'vault/services/secret-mount-path'; + +export default class HeaderScopeComponent extends Component { + @service declare readonly secretMountPath: SecretMountPath; +} diff --git a/ui/lib/kmip/addon/components/kmip-breadcrumb.js b/ui/lib/kmip/addon/components/kmip-breadcrumb.js deleted file mode 100644 index cf597ded54..0000000000 --- a/ui/lib/kmip/addon/components/kmip-breadcrumb.js +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Copyright IBM Corp. 2016, 2025 - * SPDX-License-Identifier: BUSL-1.1 - */ - -import Component from '@ember/component'; -import { service } from '@ember/service'; -import { or } from '@ember/object/computed'; - -export default Component.extend({ - tagName: '', - secretMountPath: service(), - shouldShowPath: or('showPath', 'scope', 'role'), - showPath: false, - path: null, - scope: null, - role: null, -}); diff --git a/ui/lib/kmip/addon/components/kmip-breadcrumb.ts b/ui/lib/kmip/addon/components/kmip-breadcrumb.ts new file mode 100644 index 0000000000..60075f0e69 --- /dev/null +++ b/ui/lib/kmip/addon/components/kmip-breadcrumb.ts @@ -0,0 +1,25 @@ +/** + * Copyright IBM Corp. 2016, 2025 + * SPDX-License-Identifier: BUSL-1.1 + */ + +import Component from '@glimmer/component'; +import { service } from '@ember/service'; + +import type SecretMountPath from 'vault/services/secret-mount-path'; + +interface Args { + currentRoute: string; + showPath?: boolean; + scope?: string; + role?: string; +} + +export default class KmipBreadcrumbComponent extends Component { + @service declare secretMountPath: SecretMountPath; + + get shouldShowPath() { + const { showPath, scope, role } = this.args; + return showPath || scope || role; + } +} diff --git a/ui/lib/kmip/addon/components/page/credentials.hbs b/ui/lib/kmip/addon/components/page/credentials.hbs index 2fc1d07259..89d54f6a4a 100644 --- a/ui/lib/kmip/addon/components/page/credentials.hbs +++ b/ui/lib/kmip/addon/components/page/credentials.hbs @@ -81,6 +81,7 @@ @currentPage={{@credentials.meta.currentPage}} @currentPageSize={{@credentials.meta.pageSize}} @route="credentials.index" + @models={{array @scope @role}} @showSizeSelector={{false}} @totalItems={{@credentials.meta.filteredTotal}} @queryFunction={{this.paginationQueryParams}} diff --git a/ui/lib/kmip/addon/components/page/scope/roles.hbs b/ui/lib/kmip/addon/components/page/scope/roles.hbs index 093f32c893..f1a80b6253 100644 --- a/ui/lib/kmip/addon/components/page/scope/roles.hbs +++ b/ui/lib/kmip/addon/components/page/scope/roles.hbs @@ -97,6 +97,7 @@ @currentPage={{@roles.meta.currentPage}} @currentPageSize={{@roles.meta.pageSize}} @route="scope.roles" + @models={{array @scope}} @showSizeSelector={{false}} @totalItems={{@roles.meta.filteredTotal}} @queryFunction={{this.paginationQueryParams}} diff --git a/ui/lib/kmip/addon/engine.js b/ui/lib/kmip/addon/engine.js index 9eae9ec48c..c7c9e9bb40 100644 --- a/ui/lib/kmip/addon/engine.js +++ b/ui/lib/kmip/addon/engine.js @@ -22,8 +22,6 @@ export default class KmipEngine extends Engine { 'namespace', 'path-help', 'app-router', - 'store', - 'pagination', 'version', 'secret-mount-path', ], diff --git a/ui/tests/acceptance/enterprise-kmip-test.js b/ui/tests/acceptance/enterprise-kmip-test.js index 8a0637e0e8..e95cc95ed7 100644 --- a/ui/tests/acceptance/enterprise-kmip-test.js +++ b/ui/tests/acceptance/enterprise-kmip-test.js @@ -386,7 +386,6 @@ module('Acceptance | Enterprise | KMIP secrets', function (hooks) { // the kmip/role model relies on openApi so testing the form via an acceptance test module('kmip role edit form', function (hooks) { hooks.beforeEach(async function () { - this.store = this.owner.lookup('service:store'); this.scope = 'my-scope'; this.name = 'my-role'; diff --git a/ui/tests/unit/adapters/kmip/role-test.js b/ui/tests/unit/adapters/kmip/role-test.js deleted file mode 100644 index 77c0687cd8..0000000000 --- a/ui/tests/unit/adapters/kmip/role-test.js +++ /dev/null @@ -1,90 +0,0 @@ -/** - * Copyright IBM Corp. 2016, 2025 - * SPDX-License-Identifier: BUSL-1.1 - */ - -import { module, test } from 'qunit'; -import { setupTest } from 'ember-qunit'; - -module('Unit | Adapter | kmip/role', function (hooks) { - setupTest(hooks); - - // these are only some of the actual editable fields - const editableFields = ['tlsTtl', 'operationAll', 'operationNone', 'operationGet', 'operationCreate']; - const serializeTests = [ - [ - 'operation_all is the only operation item present after serialization', - { - serialize() { - return { operation_all: true, operation_get: true, operation_create: true, tls_ttl: '10s' }; - }, - record: { - editableFields, - }, - }, - { - operation_all: true, - tls_ttl: '10s', - }, - ], - [ - 'serialize does not include nonOperationFields values if they are not set', - { - serialize() { - return { operation_all: true, operation_get: true, operation_create: true }; - }, - record: { - editableFields, - }, - }, - { - operation_all: true, - }, - ], - [ - 'operation_none is the only operation item present after serialization', - { - serialize() { - return { operation_none: true, operation_get: true, operation_add_attribute: true, tls_ttl: '10s' }; - }, - record: { - editableFields, - }, - }, - { - operation_none: true, - tls_ttl: '10s', - }, - ], - [ - 'operation_all and operation_none are removed if not truthy', - { - serialize() { - return { - operation_all: false, - operation_none: false, - operation_get: true, - operation_add_attribute: true, - operation_destroy: true, - }; - }, - record: { - editableFields, - }, - }, - { - operation_get: true, - operation_add_attribute: true, - operation_destroy: true, - }, - ], - ]; - for (const testCase of serializeTests) { - const [name, snapshotStub, expected] = testCase; - test(`adapter serialize: ${name}`, function (assert) { - const adapter = this.owner.lookup('adapter:kmip/role'); - const result = adapter.serialize(snapshotStub); - assert.deepEqual(result, expected, 'output matches expected'); - }); - } -}); diff --git a/ui/tests/unit/utils/openapi-helpers-test.js b/ui/tests/unit/utils/openapi-helpers-test.js index 36d582d695..2162344fdc 100644 --- a/ui/tests/unit/utils/openapi-helpers-test.js +++ b/ui/tests/unit/utils/openapi-helpers-test.js @@ -46,7 +46,6 @@ module('Unit | Utility | OpenAPI helper utils', function (hooks) { test(`getHelpUrlForModel`, function (assert) { [ - { modelType: 'kmip/config', result: '/v1/foobar/config?help=1' }, { modelType: 'does-not-exist', result: null }, { modelType: 4, result: null }, { modelType: '', result: null },