diff --git a/ui/app/components/configure-aws-secret.hbs b/ui/app/components/configure-aws-secret.hbs index 0bd38b378e..af1652cf05 100644 --- a/ui/app/components/configure-aws-secret.hbs +++ b/ui/app/components/configure-aws-secret.hbs @@ -61,7 +61,7 @@ - + {{#if this.showOptions}}
@@ -74,7 +74,7 @@ name="region" id="region" onchange={{action (mut @region) value="target.value"}} - data-test-input="region" + data-test-select="region" > {{#each (aws-regions) as |val|}} @@ -104,7 +104,7 @@ {{/if}}
- +
@@ -134,7 +134,7 @@ @onChange={{fn this.handleTtlChange "leaseMax"}} />
- +
diff --git a/ui/app/controllers/vault/cluster/secrets/backend/configuration.js b/ui/app/controllers/vault/cluster/secrets/backend/configuration.js index 771a72f004..1c0c65754b 100644 --- a/ui/app/controllers/vault/cluster/secrets/backend/configuration.js +++ b/ui/app/controllers/vault/cluster/secrets/backend/configuration.js @@ -5,10 +5,10 @@ import { computed } from '@ember/object'; import Controller from '@ember/controller'; +import { CONFIGURABLE_SECRET_ENGINES } from 'vault/helpers/mountable-secret-engines'; export default Controller.extend({ isConfigurable: computed('model.type', function () { - const configurableEngines = ['aws', 'ssh']; - return configurableEngines.includes(this.model.type); + return CONFIGURABLE_SECRET_ENGINES.includes(this.model.type); }), }); diff --git a/ui/app/helpers/mountable-secret-engines.js b/ui/app/helpers/mountable-secret-engines.js index 398ed5e367..979cc908c5 100644 --- a/ui/app/helpers/mountable-secret-engines.js +++ b/ui/app/helpers/mountable-secret-engines.js @@ -134,6 +134,15 @@ const MOUNTABLE_SECRET_ENGINES = [ }, ]; +// Secret Engines that have their own configuration page and actions +// These engines do not exist in their own Ember engine. +// Ex: AWS vs. LDAP which is configurable but is handled inside the routing of its own Ember engine. +export const CONFIGURABLE_SECRET_ENGINES = ['aws', 'ssh']; + +export function configurableSecretEngines() { + return MOUNTABLE_SECRET_ENGINES.slice(); +} + export function mountableEngines() { return MOUNTABLE_SECRET_ENGINES.slice(); } diff --git a/ui/app/routes/vault/cluster/secrets/backend/configuration.js b/ui/app/routes/vault/cluster/secrets/backend/configuration.js index faaf3e71e6..816fadf58e 100644 --- a/ui/app/routes/vault/cluster/secrets/backend/configuration.js +++ b/ui/app/routes/vault/cluster/secrets/backend/configuration.js @@ -6,8 +6,9 @@ import { service } from '@ember/service'; import Route from '@ember/routing/route'; -export default Route.extend({ - store: service(), +export default class SecretsBackendConfigurationRoute extends Route { + @service store; + async model() { const backend = this.modelFor('vault.cluster.secrets.backend'); if (backend.isV2KV) { @@ -17,11 +18,8 @@ export default Route.extend({ // only set these config params if they can read the config endpoint. if (canRead) { // design wants specific default to show that can't be set in the model - backend.set('casRequired', backend.casRequired ? backend.casRequired : 'False'); - backend.set( - 'deleteVersionAfter', - backend.deleteVersionAfter !== '0s' ? backend.deleteVersionAfter : 'Never delete' - ); + backend.casRequired = backend.casRequired ? backend.casRequired : 'False'; + backend.deleteVersionAfter = backend.deleteVersionAfter ? backend.deleteVersionAfter : 'Never delete'; } else { // remove the default values from the model if they don't have read access otherwise it will display the defaults even if they've been set (because they error on returning config data) backend.set('casRequired', null); @@ -30,5 +28,5 @@ export default Route.extend({ } } return backend; - }, -}); + } +} diff --git a/ui/app/routes/vault/cluster/settings/configure-secret-backend.js b/ui/app/routes/vault/cluster/settings/configure-secret-backend.js index 10117b6c37..e3a711bc71 100644 --- a/ui/app/routes/vault/cluster/settings/configure-secret-backend.js +++ b/ui/app/routes/vault/cluster/settings/configure-secret-backend.js @@ -7,7 +7,7 @@ import AdapterError from '@ember-data/adapter/error'; import { set } from '@ember/object'; import Route from '@ember/routing/route'; import { service } from '@ember/service'; -const CONFIGURABLE_BACKEND_TYPES = ['aws', 'ssh']; +import { CONFIGURABLE_SECRET_ENGINES } from 'vault/helpers/mountable-secret-engines'; export default Route.extend({ store: service(), @@ -16,7 +16,7 @@ export default Route.extend({ const { backend } = this.paramsFor(this.routeName); return this.store.query('secret-engine', { path: backend }).then((modelList) => { const model = modelList && modelList[0]; - if (!model || !CONFIGURABLE_BACKEND_TYPES.includes(model.type)) { + if (!model || !CONFIGURABLE_SECRET_ENGINES.includes(model.type)) { const error = new AdapterError(); set(error, 'httpStatus', 404); throw error; diff --git a/ui/app/templates/vault/cluster/settings/configure-secret-backend.hbs b/ui/app/templates/vault/cluster/settings/configure-secret-backend.hbs index ce6bb40264..61ccf0e1b5 100644 --- a/ui/app/templates/vault/cluster/settings/configure-secret-backend.hbs +++ b/ui/app/templates/vault/cluster/settings/configure-secret-backend.hbs @@ -13,7 +13,7 @@ /> -

+

Configure {{get (options-for-backend this.model.type) "displayName"}}

diff --git a/ui/lib/core/addon/components/secrets-engine-mount-config.ts b/ui/lib/core/addon/components/secrets-engine-mount-config.ts index e1db2bdd18..30a46eee2a 100644 --- a/ui/lib/core/addon/components/secrets-engine-mount-config.ts +++ b/ui/lib/core/addon/components/secrets-engine-mount-config.ts @@ -5,9 +5,20 @@ import Component from '@glimmer/component'; import { tracked } from '@glimmer/tracking'; +import { duration } from 'core/helpers/format-duration'; import type SecretEngineModel from 'vault/models/secret-engine'; +/** + * @module SecretsEngineMountConfig + * SecretsEngineMountConfig component is used to display a "Show mount configuration" toggle section. It is generally used alongside the fetch-secret-engine-config decorator which displays the engine configuration above this component. Mount configuration is always available for display but is hidden by default behind a toggle. + * + * @example + * + * + * @param {Model} model- The secret engines model, generated via the secret-engine model and a belongsTo relationship connecting to the mount-config model. + */ + interface Args { model: SecretEngineModel; } @@ -16,7 +27,7 @@ interface Field { value: string | boolean; } -export default class SecretsEngineMountConfigComponent extends Component { +export default class SecretsEngineMountConfig extends Component { @tracked showConfig = false; get fields(): Array { @@ -27,8 +38,8 @@ export default class SecretsEngineMountConfigComponent extends Component { { label: 'Accessor', value: model.accessor }, { label: 'Local', value: model.local }, { label: 'Seal Wrap', value: model.sealWrap }, - { label: 'Default Lease TTL', value: model.config.defaultLeaseTtl }, - { label: 'Max Lease TTL', value: model.config.maxLeaseTtl }, + { label: 'Default Lease TTL', value: duration([model.config.defaultLeaseTtl]) }, + { label: 'Max Lease TTL', value: duration([model.config.maxLeaseTtl]) }, ]; } } diff --git a/ui/lib/core/addon/decorators/fetch-secrets-engine-config.ts b/ui/lib/core/addon/decorators/fetch-secrets-engine-config.ts index c01a0df7eb..bb071782d6 100644 --- a/ui/lib/core/addon/decorators/fetch-secrets-engine-config.ts +++ b/ui/lib/core/addon/decorators/fetch-secrets-engine-config.ts @@ -27,7 +27,7 @@ export function withConfig(modelName: string) { return function BaseRoute>(SuperClass: RouteClass) { if (!Object.prototype.isPrototypeOf.call(Route, SuperClass)) { // eslint-disable-next-line - console.error( + console.debug( 'withConfig decorator must be used on an instance of Ember Route class. Decorator not applied to returned class' ); return SuperClass; @@ -40,7 +40,10 @@ export function withConfig(modelName: string) { async beforeModel(transition: Transition) { super.beforeModel(transition); - + if (!this.secretMountPath) { + // eslint-disable-next-line + console.debug('secretMountPath service is required for withConfig decorator. Add it to the route'); + } const backend = this.secretMountPath.currentPath; // check the store for record first this.configModel = this.store.peekRecord(modelName, backend); diff --git a/ui/lib/core/addon/templates/components/select.hbs b/ui/lib/core/addon/templates/components/select.hbs index a58604095f..5405fb0aef 100644 --- a/ui/lib/core/addon/templates/components/select.hbs +++ b/ui/lib/core/addon/templates/components/select.hbs @@ -12,6 +12,7 @@