vault/ui/app/components/secret-engine/configure-ssh.ts
Jordan Reimer 2417aa9aad
[UI] Ember Data Migration - Secrets Engine (#30829)
* [UI] Ember Data Migration - Secrets Engine Resource (#30791)

* adds base factory for resources and secrets engine resource

* updates dashboard and secret-engine list route to fetch mounts from api service

* updates secret backends routes to use api service

* updates secrets engine config routes to use api service

* updates secrets backend route to use internal mounts endpoint and fixes error handling

* updates property casing in config details card component

* fixes dashboard tests

* fixes issues with engine configuration

* updates api service to only set token header if value is defined in auth service

* fixes more tests

* Update ui/app/routes/vault/cluster/secrets/backend/configuration/index.js

Co-authored-by: Angel Garbarino <Monkeychip@users.noreply.github.com>

* removes alwaysRender from publicKey field in secret engine configuration details component

* removes unused hideToggle arg from secret engine mount config template

* updates kv config route to load secret-engine model

* fixes kv config route

---------

Co-authored-by: Angel Garbarino <Monkeychip@users.noreply.github.com>

* [UI] Ember Data Migration - Secrets Engine Forms (#30951)

* adds secrets engine form class

* updates mount-secret-backend route and form component to use secrets engine form class and api service

* updates to form class proxy for nested form data properties

* adds form classes for configurable secrets engines

* updates secrets engine config edit route and components to use form classes and api service

* adds missing copyright header

* fixes tests

* fixes type error

* updates configure-ssh component to use form class and api service

* updates configure-ssh tests

* updates configuration-wif component tests

* fixes mount secret backend and form tests

* adds method to normalize request key casing to api service

* addresses pr review feedback

* removes unused secrets engine config models, adapters and serializers (#30980)

* fixes azure config tests

* fixes more ent tests

---------

Co-authored-by: Angel Garbarino <Monkeychip@users.noreply.github.com>
2025-06-16 14:29:17 -06:00

107 lines
3.1 KiB
TypeScript

/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
import Component from '@glimmer/component';
import { action } from '@ember/object';
import { task } from 'ember-concurrency';
import { waitFor } from '@ember/test-waiters';
import { service } from '@ember/service';
import { tracked } from '@glimmer/tracking';
import { ValidationMap } from 'vault/vault/app-types';
import type SshConfigForm from 'vault/forms/secrets/ssh-config';
import type Router from '@ember/routing/router';
import type FlashMessageService from 'vault/services/flash-messages';
import type ApiService from 'vault/services/api';
/**
* @module ConfigureSshComponent is used to configure the SSH secret engine.
*
* @example
* ```js
* <SecretEngine::ConfigureSsh
* @configForm={{this.model.configForm}}
* @id={{this.model.id}}
* />
* ```
*
* @param {string} configForm - SSH ca-config form
* @param {string} id - name of the SSH secret engine, ex: 'ssh-123'
*/
interface Args {
configForm: SshConfigForm;
id: string;
}
export default class ConfigureSshComponent extends Component<Args> {
@service declare readonly router: Router;
@service declare readonly api: ApiService;
@service declare readonly flashMessages: FlashMessageService;
@tracked errorMessage: string | null = null;
@tracked invalidFormAlert: string | null = null;
@tracked modelValidations: ValidationMap | null = null;
save = task(
waitFor(async (event: Event) => {
event.preventDefault();
this.resetErrors();
const { id, configForm } = this.args;
const { isValid, state, invalidFormMessage, data } = configForm.toJSON();
this.modelValidations = isValid ? null : state;
this.invalidFormAlert = isValid ? '' : invalidFormMessage;
if (isValid) {
try {
await this.api.secrets.sshConfigureCa(id, data);
this.flashMessages.success(`Successfully saved ${id}'s root configuration.`);
this.transition();
} catch (error) {
const { message } = await this.api.parseError(error);
this.errorMessage = message;
this.invalidFormAlert = 'There was an error submitting this form.';
}
}
})
);
resetErrors() {
this.flashMessages.clearMessages();
this.errorMessage = null;
this.invalidFormAlert = null;
}
transition(isDelete = false) {
// deleting a key is the only case in which we want to stay on the create/edit page.
const { id } = this.args;
if (isDelete) {
this.router.transitionTo('vault.cluster.secrets.backend.configuration.edit', id);
} else {
this.router.transitionTo('vault.cluster.secrets.backend.configuration', id);
}
}
@action
onCancel() {
// clear errors because they're canceling out of the workflow.
this.resetErrors();
this.transition();
}
@action
async deleteCaConfig() {
try {
await this.api.secrets.sshDeleteCaConfiguration(this.args.id);
this.flashMessages.success('CA information deleted successfully.');
this.transition(true);
} catch (error) {
const { message } = await this.api.parseError(error);
this.flashMessages.danger(message);
}
}
}