[UI] Ember Data Migration - Form Type Updates (#31011)

* updates type handling for forms

* fixes validation in aws and ssh config forms

* fixes issue with missing sync destination name
This commit is contained in:
Jordan Reimer 2025-06-19 10:03:09 -06:00 committed by GitHub
parent 43c3aa37b9
commit a6ab9bed1d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 110 additions and 88 deletions

View File

@ -56,7 +56,6 @@ export default class ConfigureWif extends Component<Args> {
@service declare readonly version: VersionService; @service declare readonly version: VersionService;
@service declare readonly flashMessages: FlashMessageService; @service declare readonly flashMessages: FlashMessageService;
@tracked accessType = 'account'; // for community users they will not be able to change this. for enterprise users, they will have the option to select "wif".
@tracked errorMessage = ''; @tracked errorMessage = '';
@tracked invalidFormAlert = ''; @tracked invalidFormAlert = '';
@tracked saveIssuerWarning = ''; @tracked saveIssuerWarning = '';
@ -68,7 +67,7 @@ export default class ConfigureWif extends Component<Args> {
constructor(owner: Owner, args: Args) { constructor(owner: Owner, args: Args) {
super(owner, args); super(owner, args);
// the following checks are only relevant to existing enterprise configurations // the following checks are only relevant to existing enterprise configurations
const { isNew, isWifPluginConfigured, isAccountPluginConfigured } = this.args.configForm; const { isNew, data, isWifPluginConfigured, isAccountPluginConfigured } = this.args.configForm;
if (this.version.isEnterprise && !isNew) { if (this.version.isEnterprise && !isNew) {
assert( assert(
@ -83,7 +82,7 @@ export default class ConfigureWif extends Component<Args> {
} }
// cache the issuer to check if it has been changed later // cache the issuer to check if it has been changed later
this.originalIssuer = this.args.configForm.data['issuer'] as string | undefined; this.originalIssuer = data.issuer;
} }
@action continueSubmitForm() { @action continueSubmitForm() {
@ -105,7 +104,7 @@ export default class ConfigureWif extends Component<Args> {
return; return;
} }
if (this.originalIssuer !== data['issuer']) { if (this.originalIssuer !== data.issuer) {
// if the issuer has changed show modal with warning that the config will change // if the issuer has changed show modal with warning that the config will change
// if the modal is shown, the user has to click confirm to continue saving // if the modal is shown, the user has to click confirm to continue saving
this.saveIssuerWarning = `You are updating the global issuer config. This will overwrite Vault's current issuer ${ this.saveIssuerWarning = `You are updating the global issuer config. This will overwrite Vault's current issuer ${
@ -178,19 +177,19 @@ export default class ConfigureWif extends Component<Args> {
@action @action
onChangeAccessType(accessType: 'account' | 'wif') { onChangeAccessType(accessType: 'account' | 'wif') {
const { configForm, type } = this.args; const { configForm, type } = this.args;
configForm['accessType'] = accessType; configForm.accessType = accessType;
if (accessType === 'account') { if (accessType === 'account') {
// reset all "wif" attributes that are mutually exclusive with "account" attributes // reset all "wif" attributes that are mutually exclusive with "account" attributes
// these attributes are the same for each engine // these attributes are the same for each engine
configForm['identityTokenAudience'] = configForm['identityTokenTtl'] = undefined; configForm.data.identityTokenAudience = configForm.data.identityTokenTtl = undefined;
} else if (accessType === 'wif') { } else if (accessType === 'wif') {
// reset all "account" attributes that are mutually exclusive with "wif" attributes // reset all "account" attributes that are mutually exclusive with "wif" attributes
// these attributes are different for each engine // these attributes are different for each engine
if (type === 'azure') { if (type === 'azure') {
configForm['clientSecret'] = undefined; (configForm as AzureConfigForm).data.clientSecret = undefined;
} else if (type === 'aws') { } else if (type === 'aws') {
configForm['accessKey'] = undefined; (configForm as AwsConfigForm).data.accessKey = undefined;
} }
} }
} }

View File

@ -12,9 +12,7 @@ import { Validations } from 'vault/vault/app-types';
type CustomMessageFormData = Partial<CreateCustomMessageRequest>; type CustomMessageFormData = Partial<CreateCustomMessageRequest>;
export default class CustomMessageForm extends Form { export default class CustomMessageForm extends Form<CustomMessageFormData> {
declare data: CustomMessageFormData;
formFields = [ formFields = [
new FormField('authenticated', undefined, { new FormField('authenticated', undefined, {
label: 'Where should we display this message?', label: 'Where should we display this message?',

View File

@ -13,14 +13,13 @@ export type FormOptions = {
isNew?: boolean; isNew?: boolean;
}; };
export default class Form { export default class Form<T extends object> {
[key: string]: unknown; // Add an index signature to allow dynamic property assignment for set shim declare data: T;
declare data: Record<string, unknown>;
declare validations: Validations; declare validations: Validations;
declare isNew: boolean; declare isNew: boolean;
constructor(data = {}, options: FormOptions = {}, validations?: Validations) { constructor(data: Partial<T> = {}, options: FormOptions = {}, validations?: Validations) {
this.data = { ...data }; this.data = { ...data } as T;
this.isNew = options.isNew || false; this.isNew = options.isNew || false;
// typically this would be defined on the subclass // typically this would be defined on the subclass
// if validations are conditional, it may be preferable to define them during instantiation // if validations are conditional, it may be preferable to define them during instantiation
@ -31,16 +30,20 @@ export default class Form {
// this allows for form field properties to be accessed directly on the class rather than form.data.someField // this allows for form field properties to be accessed directly on the class rather than form.data.someField
const proxyTarget = (target: this, prop: string) => { const proxyTarget = (target: this, prop: string) => {
// check if the property that is being accessed is a form field // check if the property that is being accessed is a form field
const formFields = Array.isArray(target['formFields']) ? target['formFields'] : []; const { formFields, formFieldGroups } = target as {
formFields?: FormField[];
formFieldGroups?: FormFieldGroup[];
};
const fields = Array.isArray(formFields) ? formFields : [];
// in the case of formFieldGroups we need extract the fields out into a flat array // in the case of formFieldGroups we need extract the fields out into a flat array
const formGroupFields = Array.isArray(target['formFieldGroups']) const groupFields = Array.isArray(formFieldGroups)
? target['formFieldGroups'].reduce((arr: FormField[], group: FormFieldGroup) => { ? formFieldGroups.reduce((arr: FormField[], group) => {
const values = Object.values(group)[0] || []; const values = Object.values(group)[0] || [];
return [...arr, ...values]; return [...arr, ...values];
}, []) }, [])
: []; : [];
// combine the formFields and formGroupFields into a single array // combine the formFields and formGroupFields into a single array
const allFields = [...formFields, ...formGroupFields]; const allFields = [...fields, ...groupFields];
const formDataKeys = allFields.map((field) => field.name) || []; const formDataKeys = allFields.map((field) => field.name) || [];
// if the property is a form field return the data object as the target, otherwise return the original target (this) // if the property is a form field return the data object as the target, otherwise return the original target (this)
// account for nested form data properties like 'config.maxLeaseTtl' when accessing the object like this.config // account for nested form data properties like 'config.maxLeaseTtl' when accessing the object like this.config

View File

@ -9,13 +9,14 @@ import FormFieldGroup from 'vault/utils/forms/field-group';
import { regions } from 'vault/helpers/aws-regions'; import { regions } from 'vault/helpers/aws-regions';
import type { Validations } from 'vault/app-types'; import type { Validations } from 'vault/app-types';
import type { AwsConfigFormData } from 'vault/secrets/engine';
export default class AwsConfigForm extends WifConfigForm { export default class AwsConfigForm extends WifConfigForm<AwsConfigFormData> {
validations: Validations = { validations: Validations = {
lease: [ lease: [
{ {
validator(form: AwsConfigForm) { validator(data: AwsConfigForm['data']) {
const { lease, leaseMax } = form; const { lease, leaseMax } = data;
return (lease && leaseMax) || (!lease && !leaseMax) ? true : false; return (lease && leaseMax) || (!lease && !leaseMax) ? true : false;
}, },
message: 'Lease TTL and Max Lease TTL are both required if one of them is set.', message: 'Lease TTL and Max Lease TTL are both required if one of them is set.',
@ -24,7 +25,7 @@ export default class AwsConfigForm extends WifConfigForm {
}; };
get isAccountPluginConfigured() { get isAccountPluginConfigured() {
return !!this.data['accessKey']; return !!this.data.accessKey;
} }
get isWifPluginConfigured() { get isWifPluginConfigured() {

View File

@ -7,7 +7,9 @@ import WifConfigForm from './wif-config';
import FormField from 'vault/utils/forms/field'; import FormField from 'vault/utils/forms/field';
import FormFieldGroup from 'vault/utils/forms/field-group'; import FormFieldGroup from 'vault/utils/forms/field-group';
export default class AzureConfigForm extends WifConfigForm { import type { AzureConfigFormData } from 'vault/vault/secrets/engine';
export default class AzureConfigForm extends WifConfigForm<AzureConfigFormData> {
// the "clientSecret" param is not checked because it's never returned by the API. // the "clientSecret" param is not checked because it's never returned by the API.
// thus we can never say for sure if the account accessType has been configured so we always return false // thus we can never say for sure if the account accessType has been configured so we always return false
isAccountPluginConfigured = false; isAccountPluginConfigured = false;

View File

@ -13,8 +13,7 @@ import { tracked } from '@glimmer/tracking';
import type { SecretsEngineFormData } from 'vault/secrets/engine'; import type { SecretsEngineFormData } from 'vault/secrets/engine';
import type { Validations } from 'vault/app-types'; import type { Validations } from 'vault/app-types';
export default class SecretsEngineForm extends Form { export default class SecretsEngineForm extends Form<SecretsEngineFormData> {
declare data: Partial<SecretsEngineFormData>;
@tracked declare type: string; @tracked declare type: string;
validations: Validations = { validations: Validations = {
@ -179,6 +178,7 @@ export default class SecretsEngineForm extends Form {
...this.data, ...this.data,
config: { config: {
...(config || {}), ...(config || {}),
forceNoCache: config?.forceNoCache ?? false,
listingVisibility: config?.listingVisibility ? 'unauth' : 'hidden', listingVisibility: config?.listingVisibility ? 'unauth' : 'hidden',
}, },
}; };

View File

@ -7,7 +7,9 @@ import WifConfigForm from './wif-config';
import FormField from 'vault/utils/forms/field'; import FormField from 'vault/utils/forms/field';
import FormFieldGroup from 'vault/utils/forms/field-group'; import FormFieldGroup from 'vault/utils/forms/field-group';
export default class AzureConfigForm extends WifConfigForm { import type { GcpConfigFormData } from 'vault/secrets/engine';
export default class AzureConfigForm extends WifConfigForm<GcpConfigFormData> {
// the "credentials" param is not checked for "isAccountPluginConfigured" because it's never return by the API // the "credentials" param is not checked for "isAccountPluginConfigured" because it's never return by the API
// additionally credentials can be set via GOOGLE_APPLICATION_CREDENTIALS env var so we cannot call it a required field in the ui. // additionally credentials can be set via GOOGLE_APPLICATION_CREDENTIALS env var so we cannot call it a required field in the ui.
// thus we can never say for sure if the account accessType has been configured so we always return false // thus we can never say for sure if the account accessType has been configured so we always return false

View File

@ -9,14 +9,12 @@ import FormField from 'vault/utils/forms/field';
import type { Validations } from 'vault/app-types'; import type { Validations } from 'vault/app-types';
import type { SshConfigureCaRequest } from '@hashicorp/vault-client-typescript'; import type { SshConfigureCaRequest } from '@hashicorp/vault-client-typescript';
export default class SshConfigForm extends Form { export default class SshConfigForm extends Form<SshConfigureCaRequest> {
declare data: Partial<SshConfigureCaRequest>;
validations: Validations = { validations: Validations = {
generateSigningKey: [ generateSigningKey: [
{ {
validator(form: SshConfigForm) { validator(data: SshConfigForm['data']) {
const { publicKey, privateKey, generateSigningKey } = form; const { publicKey, privateKey, generateSigningKey } = data;
// if generateSigningKey is false, both public and private keys are required // if generateSigningKey is false, both public and private keys are required
if (!generateSigningKey && (!publicKey || !privateKey)) { if (!generateSigningKey && (!publicKey || !privateKey)) {
return false; return false;
@ -28,8 +26,8 @@ export default class SshConfigForm extends Form {
], ],
publicKey: [ publicKey: [
{ {
validator(form: SshConfigForm) { validator(data: SshConfigForm['data']) {
const { publicKey, privateKey } = form; const { publicKey, privateKey } = data;
// regardless of generateSigningKey, if one key is set they both need to be set. // regardless of generateSigningKey, if one key is set they both need to be set.
return publicKey || privateKey ? !!(publicKey && privateKey) : true; return publicKey || privateKey ? !!(publicKey && privateKey) : true;
}, },

View File

@ -7,7 +7,7 @@ import Form from 'vault/forms/form';
import FormField from 'vault/utils/forms/field'; import FormField from 'vault/utils/forms/field';
import { tracked } from '@glimmer/tracking'; import { tracked } from '@glimmer/tracking';
export default class WifConfigForm extends Form { export default class WifConfigForm<T extends object> extends Form<T> {
// for community users they will not be able to change this. for enterprise users, they will have the option to select "wif". // for community users they will not be able to change this. for enterprise users, they will have the option to select "wif".
@tracked accessType: 'account' | 'wif' = 'account'; @tracked accessType: 'account' | 'wif' = 'account';

View File

@ -10,11 +10,11 @@ import { commonFields, getPayload } from './shared';
import type { SystemWriteSyncDestinationsAwsSmNameRequest } from '@hashicorp/vault-client-typescript'; import type { SystemWriteSyncDestinationsAwsSmNameRequest } from '@hashicorp/vault-client-typescript';
type AwsSmFormData = Partial<SystemWriteSyncDestinationsAwsSmNameRequest>; type AwsSmFormData = SystemWriteSyncDestinationsAwsSmNameRequest & {
name: string;
export default class AwsSmForm extends Form { };
declare data: AwsSmFormData;
export default class AwsSmForm extends Form<AwsSmFormData> {
formFieldGroups = [ formFieldGroups = [
new FormFieldGroup('default', [ new FormFieldGroup('default', [
commonFields.name, commonFields.name,
@ -59,6 +59,7 @@ export default class AwsSmForm extends Form {
toJSON() { toJSON() {
const formState = super.toJSON(); const formState = super.toJSON();
return { ...formState, data: getPayload('aws-sm', this.data, this.isNew) }; const data = getPayload<AwsSmFormData>('aws-sm', this.data, this.isNew);
return { ...formState, data };
} }
} }

View File

@ -10,11 +10,11 @@ import { commonFields, getPayload } from './shared';
import type { SystemWriteSyncDestinationsAzureKvNameRequest } from '@hashicorp/vault-client-typescript'; import type { SystemWriteSyncDestinationsAzureKvNameRequest } from '@hashicorp/vault-client-typescript';
type AzureKvFormData = Partial<SystemWriteSyncDestinationsAzureKvNameRequest>; type AzureKvFormData = SystemWriteSyncDestinationsAzureKvNameRequest & {
name: string;
export default class AzureKvForm extends Form { };
declare data: AzureKvFormData;
export default class AzureKvForm extends Form<AzureKvFormData> {
formFieldGroups = [ formFieldGroups = [
new FormFieldGroup('default', [ new FormFieldGroup('default', [
commonFields.name, commonFields.name,
@ -57,6 +57,7 @@ export default class AzureKvForm extends Form {
toJSON() { toJSON() {
const formState = super.toJSON(); const formState = super.toJSON();
return { ...formState, data: getPayload('azure-kv', this.data, this.isNew) }; const data = getPayload<AzureKvFormData>('azure-kv', this.data, this.isNew);
return { ...formState, data };
} }
} }

View File

@ -10,11 +10,11 @@ import { commonFields, getPayload } from './shared';
import type { SystemWriteSyncDestinationsGcpSmNameRequest } from '@hashicorp/vault-client-typescript'; import type { SystemWriteSyncDestinationsGcpSmNameRequest } from '@hashicorp/vault-client-typescript';
type GcpSmFormData = Partial<SystemWriteSyncDestinationsGcpSmNameRequest>; type GcpSmFormData = SystemWriteSyncDestinationsGcpSmNameRequest & {
name: string;
export default class GcpSmForm extends Form { };
declare data: GcpSmFormData;
export default class GcpSmForm extends Form<GcpSmFormData> {
formFieldGroups = [ formFieldGroups = [
new FormFieldGroup('default', [ new FormFieldGroup('default', [
commonFields.name, commonFields.name,
@ -42,6 +42,7 @@ export default class GcpSmForm extends Form {
toJSON() { toJSON() {
const formState = super.toJSON(); const formState = super.toJSON();
return { ...formState, data: getPayload('gcp-sm', this.data, this.isNew) }; const data = getPayload<GcpSmFormData>('gcp-sm', this.data, this.isNew);
return { ...formState, data };
} }
} }

View File

@ -10,11 +10,11 @@ import { commonFields, getPayload } from './shared';
import type { SystemWriteSyncDestinationsGhNameRequest } from '@hashicorp/vault-client-typescript'; import type { SystemWriteSyncDestinationsGhNameRequest } from '@hashicorp/vault-client-typescript';
type GhFormData = Partial<SystemWriteSyncDestinationsGhNameRequest>; type GhFormData = SystemWriteSyncDestinationsGhNameRequest & {
name: string;
export default class GcpSmForm extends Form { };
declare data: GhFormData;
export default class GcpSmForm extends Form<GhFormData> {
formFieldGroups = [ formFieldGroups = [
new FormFieldGroup('default', [ new FormFieldGroup('default', [
commonFields.name, commonFields.name,
@ -42,6 +42,7 @@ export default class GcpSmForm extends Form {
toJSON() { toJSON() {
const formState = super.toJSON(); const formState = super.toJSON();
return { ...formState, data: getPayload('gh', this.data, this.isNew) }; const data = getPayload<GhFormData>('gh', this.data, this.isNew);
return { ...formState, data };
} }
} }

View File

@ -45,26 +45,27 @@ export const commonFields = {
}), }),
}; };
export function getPayload(type: DestinationType, data: Record<string, unknown>, isNew: boolean) { export function getPayload<T>(type: DestinationType, data: T, isNew: boolean) {
const { maskedParams, readonlyParams } = findDestination(type); const { maskedParams, readonlyParams } = findDestination(type);
const payload = { ...data }; const payload: T = { ...data };
// the server returns ****** for sensitive fields // the server returns ****** for sensitive fields
// these are represented as maskedParams in the sync-destinations helper // these are represented as maskedParams in the sync-destinations helper
// when editing, remove these fields from the payload if they haven't been changed // when editing, remove these fields from the payload if they haven't been changed
if (!isNew) { if (!isNew) {
maskedParams.forEach((maskedParam) => { maskedParams.forEach((maskedParam) => {
const value = (payload[maskedParam] as string) || ''; const key = maskedParam as keyof T;
const value = (payload[key] as string) || '';
// if the value is asterisks, remove it from the payload // if the value is asterisks, remove it from the payload
if (value.match(/^\*+$/)) { if (value.match(/^\*+$/)) {
delete payload[maskedParam]; delete payload[key];
} }
}); });
// to preserve the original Ember Data payload structure, remove fields that are not editable // to preserve the original Ember Data payload structure, remove fields that are not editable
// since editing is disabled in the form the value will not change so this is mostly to satisfy existing test conditions // since editing is disabled in the form the value will not change so this is mostly to satisfy existing test conditions
readonlyParams.forEach((readonlyParam) => { readonlyParams.forEach((readonlyParam) => {
delete payload[readonlyParam]; delete payload[readonlyParam as keyof T];
}); });
} }

View File

@ -10,11 +10,11 @@ import { commonFields, getPayload } from './shared';
import type { SystemWriteSyncDestinationsVercelProjectNameRequest } from '@hashicorp/vault-client-typescript'; import type { SystemWriteSyncDestinationsVercelProjectNameRequest } from '@hashicorp/vault-client-typescript';
type VercelProjectFormData = Partial<SystemWriteSyncDestinationsVercelProjectNameRequest>; type VercelProjectFormData = SystemWriteSyncDestinationsVercelProjectNameRequest & {
name: string;
export default class GcpSmForm extends Form { };
declare data: VercelProjectFormData;
export default class VercelProjectForm extends Form<VercelProjectFormData> {
formFieldGroups = [ formFieldGroups = [
new FormFieldGroup('default', [ new FormFieldGroup('default', [
commonFields.name, commonFields.name,
@ -45,6 +45,7 @@ export default class GcpSmForm extends Form {
toJSON() { toJSON() {
const formState = super.toJSON(); const formState = super.toJSON();
return { ...formState, data: getPayload('vercel-project', this.data, this.isNew) }; const data = getPayload<VercelProjectFormData>('vercel-project', this.data, this.isNew);
return { ...formState, data };
} }
} }

View File

@ -21,7 +21,7 @@ export default class VaultClusterSettingsMountSecretBackendRoute extends Route {
kvConfig: { kvConfig: {
maxVersions: 0, maxVersions: 0,
casRequired: false, casRequired: false,
deleteVersionAfter: 0, deleteVersionAfter: undefined,
}, },
options: { version: 2 }, options: { version: 2 },
}; };

View File

@ -39,15 +39,17 @@ export default class DestinationsCreateForm extends Component<Args> {
super(owner, args); super(owner, args);
// cache initial custom tags value to compare against updates // cache initial custom tags value to compare against updates
// tags that are removed when editing need to be added to the payload // tags that are removed when editing need to be added to the payload
if (args.form['customTags']) { // cast type here since not all types have customTags
this.initialCustomTags = { ...args.form['customTags'] }; const { customTags } = args.form.data as unknown as Record<string, unknown>;
if (customTags) {
this.initialCustomTags = { ...customTags };
} }
} }
get header() { get header() {
const { type, form } = this.args; const { type, form } = this.args;
const { name: typeDisplayName } = findDestination(type); const { name: typeDisplayName } = findDestination(type);
const { name } = form; const { name } = form.data;
return form.isNew return form.isNew
? { ? {
@ -87,18 +89,18 @@ export default class DestinationsCreateForm extends Component<Args> {
} }
} }
diffCustomTags(customTags?: Record<string, string>) { diffCustomTags(payload: Record<string, unknown>) {
// if tags were removed we need to add them to the payload // if tags were removed we need to add them to the payload
const { form } = this.args; const { isNew } = this.args.form;
if (!form.isNew && customTags && this.initialCustomTags) { const { customTags } = payload;
if (!isNew && customTags && this.initialCustomTags) {
// compare the new and old keys of customTags object to determine which need to be removed // compare the new and old keys of customTags object to determine which need to be removed
const oldKeys = Object.keys(this.initialCustomTags).filter((k) => !Object.keys(customTags).includes(k)); const oldKeys = Object.keys(this.initialCustomTags).filter((k) => !Object.keys(customTags).includes(k));
// add tagsToRemove to the payload if there is a diff // add tagsToRemove to the payload if there is a diff
if (oldKeys.length > 0) { if (oldKeys.length > 0) {
return { tagsToRemove: oldKeys }; payload['tagsToRemove'] = oldKeys;
} }
} }
return {};
} }
save = task( save = task(
@ -109,21 +111,18 @@ export default class DestinationsCreateForm extends Component<Args> {
this.modelValidations = null; this.modelValidations = null;
const { form, type } = this.args; const { form, type } = this.args;
const { name } = form.data;
const { isValid, state, invalidFormMessage, data } = form.toJSON(); const { isValid, state, invalidFormMessage, data } = form.toJSON();
const name = form['name'] as string;
this.modelValidations = isValid ? null : state; this.modelValidations = isValid ? null : state;
this.invalidFormMessage = isValid ? '' : invalidFormMessage; this.invalidFormMessage = isValid ? '' : invalidFormMessage;
if (isValid) { if (isValid) {
try { try {
const { tagsToRemove } = this.diffCustomTags(data['customTags'] as Record<string, string>); const payload = data as unknown as Record<string, unknown>;
if (tagsToRemove) { this.diffCustomTags(payload);
data['tagsToRemove'] = tagsToRemove; const method = apiMethodResolver(form.isNew ? 'write' : 'patch', type);
} await this.api.sys[method](name, payload);
const method = apiMethodResolver(form.isNew ? 'write' : 'patch', this.args.type);
await this.api.sys[method](name, data);
this.router.transitionTo('vault.cluster.sync.secrets.destinations.destination.details', type, name); this.router.transitionTo('vault.cluster.sync.secrets.destinations.destination.details', type, name);
} catch (error) { } catch (error) {

View File

@ -3,13 +3,19 @@
* SPDX-License-Identifier: BUSL-1.1 * SPDX-License-Identifier: BUSL-1.1
*/ */
import type { MountsEnableSecretsEngineRequest } from '@hashicorp/vault-client-typescript'; import type {
MountsEnableSecretsEngineRequest,
AwsConfigureRootIamCredentialsRequest,
AwsConfigureLeaseRequest,
AzureConfigureRequest,
GoogleCloudConfigureRequest,
} from '@hashicorp/vault-client-typescript';
export type EngineConfig = { export type EngineConfig = {
forceNoCache: boolean; forceNoCache?: boolean;
listingVisibility: string; listingVisibility?: string | boolean;
defaultLeaseTtl: number; defaultLeaseTtl?: number;
maxLeaseTtl: number; maxLeaseTtl?: number;
allowedManagedKeys?: string[]; allowedManagedKeys?: string[];
auditNonHmacRequestKeys?: string[]; auditNonHmacRequestKeys?: string[];
auditNonHmacResponseKeys?: string[]; auditNonHmacResponseKeys?: string[];
@ -91,3 +97,11 @@ export type SecretsEngineFormData = MountsEnableSecretsEngineRequest & {
deleteVersionAfter?: string; deleteVersionAfter?: string;
}; };
}; };
type Issuer = {
issuer?: string;
};
export type AwsConfigFormData = AwsConfigureRootIamCredentialsRequest & AwsConfigureLeaseRequest & Issuer;
export type AzureConfigFormData = AzureConfigureRequest & Issuer;
export type GcpConfigFormData = GoogleCloudConfigureRequest & Issuer;