diff --git a/ui/app/adapters/secret-engine.js b/ui/app/adapters/secret-engine.js
index f8230f7e6532..c19b68b3fb17 100644
--- a/ui/app/adapters/secret-engine.js
+++ b/ui/app/adapters/secret-engine.js
@@ -117,14 +117,12 @@ export default ApplicationAdapter.extend({
}
},
- // ARG Todo moving to own adapter/model/serializer
saveAWSRoot(store, type, snapshot) {
const { data } = snapshot.adapterOptions;
const path = encodePath(snapshot.id);
return this.ajax(`/v1/${path}/config/root`, 'POST', { data });
},
- // ARG Todo moving to own adapter/model/serializer
saveAWSLease(store, type, snapshot) {
const { data } = snapshot.adapterOptions;
const path = encodePath(snapshot.id);
diff --git a/ui/app/components/secret-engine/configurable-secret-engine-details.js b/ui/app/components/secret-engine/configurable-secret-engine-details.js
deleted file mode 100644
index 81b7bf2ed43b..000000000000
--- a/ui/app/components/secret-engine/configurable-secret-engine-details.js
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- * Copyright (c) HashiCorp, Inc.
- * SPDX-License-Identifier: BUSL-1.1
- */
-
-import { service } from '@ember/service';
-import Component from '@glimmer/component';
-import errorMessage from 'vault/utils/error-message';
-import { tracked } from '@glimmer/tracking';
-// ARG TODO add documentation
-export default class ConfigurableSecretEngineDetails extends Component {
- @service store;
- @tracked configModel = null;
- @tracked configError = null;
-
- constructor() {
- super(...arguments);
- const { model } = this.args;
- // Currently two secret engines that return configuration data and that can be configured by the user on the ui: aws, and ssh.
- if (model.type === 'aws') {
- this.fetchAwsRootConfig(model.id);
- }
- if (model.type === 'ssh') {
- this.fetchSshCaConfig(model.id);
- }
- }
-
- async fetchAwsRootConfig(backend) {
- try {
- this.configModel = await this.store.queryRecord('aws/root-config', { backend });
- } catch (e) {
- this.configError = errorMessage(e);
- }
- }
-
- async fetchSshCaConfig(backend) {
- try {
- this.configModel = await this.store.queryRecord('ssh/ca-config', { backend });
- } catch (e) {
- this.configError = errorMessage(e);
- }
- }
-
- get typeDisplay() {
- // TODO will eventually handle GCP and Azure.
- // Did not use capitalize helper because some are all caps and some only title case.
- const { type } = this.args.model;
- switch (type) {
- case 'aws':
- return 'AWS';
- case 'ssh':
- return 'SSH';
- default:
- return type;
- }
- }
-}
diff --git a/ui/app/components/secret-engine/configurable-secret-engine-details.ts b/ui/app/components/secret-engine/configurable-secret-engine-details.ts
new file mode 100644
index 000000000000..c990ae763f5b
--- /dev/null
+++ b/ui/app/components/secret-engine/configurable-secret-engine-details.ts
@@ -0,0 +1,89 @@
+/**
+ * Copyright (c) HashiCorp, Inc.
+ * SPDX-License-Identifier: BUSL-1.1
+ */
+
+import { service } from '@ember/service';
+import Component from '@glimmer/component';
+import errorMessage from 'vault/utils/error-message';
+import { tracked } from '@glimmer/tracking';
+
+import type Store from '@ember-data/store';
+import type SecretEngineModel from 'vault/models/secret-engine';
+import type AdapterError from 'ember-data/adapter'; // eslint-disable-line ember/use-ember-data-rfc-395-imports
+
+/**
+ * @module ConfigurableSecretEngineDetails
+ * The `ConfigurableSecretEngineDetails` is used by configurable secret engines to show either a prompt, error
+ * or configuration details depending on the response from the engines specific config endpoint (ex: aws -> aws/root-config vs ssh: ssh/ca-config).
+ *
+ * @example ```js
+ * ```
+ *
+ * @param {object} model - The secret-engine model to be configured.
+ *
+ */
+
+interface Args {
+ model: SecretEngineModel;
+}
+
+export default class ConfigurableSecretEngineDetails extends Component {
+ @service declare readonly store: Store;
+ @tracked configModel = null;
+ @tracked configError: string | null = null;
+
+ constructor(owner: unknown, args: Args) {
+ super(owner, args);
+ const { model } = this.args;
+ // Currently two secret engines that return configuration data and that can be configured by the user on the ui: aws, and ssh.
+ if (model.type === 'aws') {
+ this.fetchAwsRootConfig(model.id);
+ }
+ if (model.type === 'ssh') {
+ this.fetchSshCaConfig(model.id);
+ }
+ }
+
+ async fetchAwsRootConfig(backend: string) {
+ try {
+ this.configModel = await this.store.queryRecord('aws/root-config', { backend });
+ } catch (e: AdapterError) {
+ // if it's a 404 then the user has not configured the backend yet and we want to show the prompt instead
+ if (e.httpStatus !== 404) {
+ this.configError = errorMessage(e);
+ }
+ return;
+ }
+ }
+
+ async fetchSshCaConfig(backend: string) {
+ try {
+ this.configModel = await this.store.queryRecord('ssh/ca-config', { backend });
+ } catch (e: AdapterError) {
+ // Unfortunately, SSH Api will return a 400 Bad request when GET /v1/ssh/ca-config is called.
+ // Unlike the AWS Api, the SSH Api does not return a 404 not found but always an error.
+ // Thus to show a prompt instead of an error when first configuring the backend, we need to catch the error,
+ // and transform it into a semi-prompt. This way, in case there is a true error we show it, but we also don't immediately show an error after mounting the engine.
+ if (e.httpStatus !== 404) {
+ // if it's a 404 then the user has not configured the backend yet and we want to show the prompt instead
+ this.configError = `${backend} has not been configured yet. Please configure it to use this feature. ${e.message}`;
+ }
+ return;
+ }
+ }
+
+ get typeDisplay() {
+ // Will eventually handle GCP and Azure.
+ // Did not use capitalize helper because some are all caps and some only title case.
+ const { type } = this.args.model;
+ switch (type) {
+ case 'aws':
+ return 'AWS';
+ case 'ssh':
+ return 'SSH';
+ default:
+ return type;
+ }
+ }
+}
diff --git a/ui/app/templates/vault/cluster/secrets/backend/configuration.hbs b/ui/app/templates/vault/cluster/secrets/backend/configuration.hbs
index 33bf815f3284..24522608108d 100644
--- a/ui/app/templates/vault/cluster/secrets/backend/configuration.hbs
+++ b/ui/app/templates/vault/cluster/secrets/backend/configuration.hbs
@@ -15,7 +15,7 @@
/>
{{#if this.isConfigurable}}
- {{! only relevant to SSH and AWS, eventually Azure and GCP }}
+ {{! only configurable secret engines are SSH and AWS. Eventually we will add Azure and GCP }}
-
+
diff --git a/ui/types/vault/models/secret-engine.d.ts b/ui/types/vault/models/secret-engine.d.ts
index cce4d0d6be95..635542df2f4d 100644
--- a/ui/types/vault/models/secret-engine.d.ts
+++ b/ui/types/vault/models/secret-engine.d.ts
@@ -9,6 +9,7 @@ import type { ModelValidations, FormField, FormFieldGroups } from 'vault/app-typ
import type MountConfigModel from 'vault/models/mount-config';
export default class SecretEngineModel extends Model {
+ id: string;
path: string;
type: string;
description: string;