feat(260923-dhh): Proxmox-Modul Aufgabe 5 - Einstellungsseite (anlegen, bearbeiten, loeschen, testen)
- proxmox.service.ts: updateServer (Muster LdapConfigService.updateConfig - nicht gesendet laesst unveraendert, leer loescht, gefuellt verschluesselt neu; PMG+Token auch beim Bearbeiten abgelehnt, geprueft gegen den EFFEKTIVEN Stand nach Zusammenfuehren), deleteServer - proxmox.controller.ts: PUT/DELETE servers/:id, beide zusaetzlich mit scheduler.refreshTenant() nach dem Schreiben - Frontend: proxmox-api.ts (updateServer/deleteServer/testServer), settings/page.tsx (Rollenpruefung nur Anzeige, Serverliste, Loeschen mit Rueckfrage), ServerForm.tsx (PMG bietet Token gar nicht an, Geheimnisfelder nie vorbefuellt, Zertifikatspruefung-Schalter Standard "pruefen", Verbindungstest mit Klartext-Fehlertext) - umlaut-dictionary.ts: zwei neue, bereits korrekte Woerter (bewusst/gemessene) auf die Positivliste des Regressions-Waechters Tore: api 1311/1311 (>=1240), web 701/701 (>=693), type-check 4/4, lint 5/5, Biome apps/web 53 Warnungen (unveraendert). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -68,6 +68,26 @@ export interface CreateProxmoxServerPayload {
|
||||
|
||||
export type UpdateProxmoxServerPayload = Partial<CreateProxmoxServerPayload>;
|
||||
|
||||
export interface ProxmoxTestResult {
|
||||
reachable: boolean;
|
||||
errorKind: ProxmoxErrorKind | null;
|
||||
errorDetail: string | null;
|
||||
metrics: unknown;
|
||||
rawSample: unknown;
|
||||
}
|
||||
|
||||
/** Liest die NestJS-Fehlermeldung aus dem Antwortkoerper, faellt sonst auf einen Standardtext zurueck. */
|
||||
async function readErrorMessage(res: Response, fallback: string): Promise<string> {
|
||||
try {
|
||||
const body = await res.json();
|
||||
if (typeof body?.message === 'string') return body.message;
|
||||
if (Array.isArray(body?.message) && body.message.length > 0) return String(body.message[0]);
|
||||
} catch {
|
||||
/* Antwort war kein JSON — Standardtext bleibt */
|
||||
}
|
||||
return fallback;
|
||||
}
|
||||
|
||||
/** GET /modules/proxmox/servers — Serverliste samt Zwischenlager. */
|
||||
export async function listServers(): Promise<ProxmoxServer[]> {
|
||||
const res = await fetch(`${API_URL}/modules/proxmox/servers`, {
|
||||
@@ -87,16 +107,50 @@ export async function createServer(
|
||||
credentials: 'include',
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
if (!res.ok) throw new Error('Failed to create proxmox server');
|
||||
if (!res.ok) throw new Error(await readErrorMessage(res, 'Failed to create proxmox server'));
|
||||
return res.json();
|
||||
}
|
||||
|
||||
/** PUT /modules/proxmox/servers/:id — Server bearbeiten (ADMIN/SUPER_ADMIN). */
|
||||
export async function updateServer(
|
||||
id: string,
|
||||
payload: UpdateProxmoxServerPayload,
|
||||
): Promise<ProxmoxServer> {
|
||||
const res = await fetch(`${API_URL}/modules/proxmox/servers/${id}`, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
credentials: 'include',
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
if (!res.ok) throw new Error(await readErrorMessage(res, 'Failed to update proxmox server'));
|
||||
return res.json();
|
||||
}
|
||||
|
||||
/** DELETE /modules/proxmox/servers/:id — Server samt Zwischenlagerzeile loeschen (ADMIN/SUPER_ADMIN). */
|
||||
export async function deleteServer(id: string): Promise<void> {
|
||||
const res = await fetch(`${API_URL}/modules/proxmox/servers/${id}`, {
|
||||
method: 'DELETE',
|
||||
credentials: 'include',
|
||||
});
|
||||
if (!res.ok) throw new Error(await readErrorMessage(res, 'Failed to delete proxmox server'));
|
||||
}
|
||||
|
||||
/** POST /modules/proxmox/servers/:id/poll — sofortige Abfrage (ADMIN/SUPER_ADMIN). */
|
||||
export async function pollServer(id: string): Promise<unknown> {
|
||||
export async function pollServer(id: string): Promise<ProxmoxTestResult> {
|
||||
const res = await fetch(`${API_URL}/modules/proxmox/servers/${id}/poll`, {
|
||||
method: 'POST',
|
||||
credentials: 'include',
|
||||
});
|
||||
if (!res.ok) throw new Error('Failed to poll proxmox server');
|
||||
if (!res.ok) throw new Error(await readErrorMessage(res, 'Failed to poll proxmox server'));
|
||||
return res.json();
|
||||
}
|
||||
|
||||
/** POST /modules/proxmox/servers/:id/test — Verbindungstest, schreibt NICHT ins Zwischenlager. */
|
||||
export async function testServer(id: string): Promise<ProxmoxTestResult> {
|
||||
const res = await fetch(`${API_URL}/modules/proxmox/servers/${id}/test`, {
|
||||
method: 'POST',
|
||||
credentials: 'include',
|
||||
});
|
||||
if (!res.ok) throw new Error(await readErrorMessage(res, 'Failed to test proxmox server'));
|
||||
return res.json();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user