c2ebc8daa0
- Proxmox-Schreibwege und Handelsware-Einstellungen auf @ModuleManage umgestellt - DKV-Fleet: ganze Klasse Verwalten-Stufe, Benutzen allein bleibt ohne Zugriff - Metadaten-Test belegt umgestellte und bewusst Administratoren vorbehaltene Handler - Webseiten (Proxmox, Handelsware, Widget) folgen canManage, DKV-Zugriffsseite erklärt die Stufe Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
124 lines
4.3 KiB
TypeScript
124 lines
4.3 KiB
TypeScript
import {
|
|
Body,
|
|
Controller,
|
|
Delete,
|
|
ForbiddenException,
|
|
Get,
|
|
Param,
|
|
Post,
|
|
Put,
|
|
Req,
|
|
} from '@nestjs/common';
|
|
import type { AuthenticatedRequest } from '../auth/types/auth-user';
|
|
import { ModuleManage, UseModule } from '../module-registry/module.guard';
|
|
import {
|
|
CreateProxmoxServerDto,
|
|
TestProxmoxServerDto,
|
|
UpdateProxmoxServerDto,
|
|
} from './dto/proxmox-server.dto';
|
|
import { ProxmoxSchedulerService } from './proxmox-scheduler.service';
|
|
import { ProxmoxService } from './proxmox.service';
|
|
|
|
/**
|
|
* `@UseModule('proxmox')` auf Klassenebene (D-09, Vorbild
|
|
* `domaincheck.controller.ts`) — Aktivierung UND Freigabe. `tenantId` kommt
|
|
* ausschliesslich aus `req.tenantId` (gesetzt vom `TenantGuard`), nie aus
|
|
* Body oder Query. Lesen (`GET servers`) steht jedem Benutzer mit
|
|
* Modulzugriff offen; Schreiben (`POST servers`, `PUT`/`DELETE servers/:id`,
|
|
* `POST servers/test`, `POST servers/:id/poll`, `POST servers/:id/test`)
|
|
* zusaetzlich `@ModuleManage('proxmox')` — Administratoren und Benutzer mit
|
|
* der Freigabestufe Verwalten (261002-icv, vorher `@Roles(ADMIN,
|
|
* SUPER_ADMIN)`; T-DHH-05). `servers/test` (statisch, zwei
|
|
* Segmente) und `servers/:id/test` (drei Segmente) ueberschneiden sich
|
|
* nicht — beide POST, aber unterschiedliche Segmentzahl, deshalb keine
|
|
* Reihenfolge-Abhaengigkeit (anders als `GET :id` vs. statische Routen).
|
|
*/
|
|
@Controller('modules/proxmox')
|
|
@UseModule('proxmox')
|
|
export class ProxmoxController {
|
|
constructor(
|
|
private readonly proxmoxService: ProxmoxService,
|
|
private readonly scheduler: ProxmoxSchedulerService,
|
|
) {}
|
|
|
|
private requireTenantId(req: AuthenticatedRequest): string {
|
|
const tenantId = req.tenantId;
|
|
if (!tenantId) {
|
|
throw new ForbiddenException('Kein Mandantenkontext');
|
|
}
|
|
return tenantId;
|
|
}
|
|
|
|
@Get('servers')
|
|
async list(@Req() req: AuthenticatedRequest) {
|
|
return this.proxmoxService.listWithStatus(this.requireTenantId(req));
|
|
}
|
|
|
|
@Post('servers')
|
|
@ModuleManage('proxmox')
|
|
async create(@Req() req: AuthenticatedRequest, @Body() dto: CreateProxmoxServerDto) {
|
|
const tenantId = this.requireTenantId(req);
|
|
const created = await this.proxmoxService.createServer(tenantId, dto);
|
|
// Planer sofort nachziehen — ohne Neustart (Aufgabe 4, Vorbild DkvController).
|
|
await this.scheduler.refreshTenant(tenantId);
|
|
return created;
|
|
}
|
|
|
|
@Put('servers/:id')
|
|
@ModuleManage('proxmox')
|
|
async update(
|
|
@Req() req: AuthenticatedRequest,
|
|
@Param('id') id: string,
|
|
@Body() dto: UpdateProxmoxServerDto,
|
|
) {
|
|
const tenantId = this.requireTenantId(req);
|
|
const updated = await this.proxmoxService.updateServer(tenantId, id, dto);
|
|
await this.scheduler.refreshTenant(tenantId);
|
|
return updated;
|
|
}
|
|
|
|
@Delete('servers/:id')
|
|
@ModuleManage('proxmox')
|
|
async remove(@Req() req: AuthenticatedRequest, @Param('id') id: string) {
|
|
const tenantId = this.requireTenantId(req);
|
|
const deleted = await this.proxmoxService.deleteServer(tenantId, id);
|
|
await this.scheduler.refreshTenant(tenantId);
|
|
return { deleted };
|
|
}
|
|
|
|
@Post('servers/:id/poll')
|
|
@ModuleManage('proxmox')
|
|
async poll(@Req() req: AuthenticatedRequest, @Param('id') id: string) {
|
|
return this.proxmoxService.pollServer(this.requireTenantId(req), id);
|
|
}
|
|
|
|
/**
|
|
* Verbindungstest fuer einen gespeicherten Server (Aufgabe 4, `<behavior>`;
|
|
* Nachbesserung Befund 1: `dto` traegt den aktuellen Formularstand,
|
|
* `ProxmoxService.testConnection` prueft diesen statt blind des
|
|
* gespeicherten Stands). Liefert bei Erfolg eine Erfolgsmeldung und bei
|
|
* Misserfolg einen der sieben Fehlerschluessel samt kurzer Ergaenzung,
|
|
* OHNE den Zwischenlagerstand zu ueberschreiben.
|
|
*/
|
|
@Post('servers/:id/test')
|
|
@ModuleManage('proxmox')
|
|
async test(
|
|
@Req() req: AuthenticatedRequest,
|
|
@Param('id') id: string,
|
|
@Body() dto: TestProxmoxServerDto,
|
|
) {
|
|
return this.proxmoxService.testConnection(this.requireTenantId(req), id, dto);
|
|
}
|
|
|
|
/**
|
|
* Verbindungstest waehrend der Neuanlage (Nachbesserung Befund 1): es gibt
|
|
* noch keinen gespeicherten Server, `dto` ist deshalb die einzige Quelle.
|
|
*/
|
|
@Post('servers/test')
|
|
@ModuleManage('proxmox')
|
|
async testDraft(@Req() req: AuthenticatedRequest, @Body() dto: TestProxmoxServerDto) {
|
|
this.requireTenantId(req);
|
|
return this.proxmoxService.testDraftConnection(dto);
|
|
}
|
|
}
|