import { beforeEach, describe, expect, it } from "vitest"; import { POST as ausrollenPost } from "@/app/api/v1/auftraege/route"; import { verschluesseln } from "@/lib/geheimnisse"; import { cliBefehl, AusrollAnfrage } from "@/lib/schemas/ausrollen"; import { katalogSynchronisieren } from "@/server/services/katalog"; import { datenbankLeeren, datenbankVerfuegbar, testPrisma } from "./helpers/db"; import { angemeldet, anfrage } from "./helpers/anfragen"; const SCHLUESSEL = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEFTdkCuqQ6mF7I8QzmkNaQpKj7S/I2+yuxWeYasJjLd florian@test"; const gueltig = { typ: "vm", server: "rz1", distribution: "debian-13", name: "web01", storage: "local-zfs", netz: { bridge: "vmbr0" }, zugang: { benutzer: "florian", sshSchluessel: [SCHLUESSEL] }, profile: ["docker"], }; describe("CLI-Befehl aus der Anfrage", () => { it("nennt nur Abweichungen vom Standard und entspricht der Vorgabe", () => { const a = AusrollAnfrage.parse({ ...gueltig, profile: ["base", "docker"], netz: { bridge: "vmbr0", vlan: 20, modus: "statisch", ip: "10.0.20.15/24", gateway: "10.0.20.1" }, cores: 2, speicherMb: 4096, diskGb: 40, }); expect(cliBefehl(a)).toBe( "proxdeploy vm web01 --server rz1 --distro debian-13 --profile base,docker --ip 10.0.20.15/24 --gw 10.0.20.1 --vlan 20 --memory 4096 --disk 40G --storage local-zfs --user florian", ); }); it("quotet Variablenwerte mit Leerzeichen", () => { const a = AusrollAnfrage.parse({ ...gueltig, variablen: { "zabbix-agent": { server: "a b" } } }); expect(cliBefehl(a)).toContain("--var zabbix-agent.server='a b'"); }); }); describe.runIf(datenbankVerfuegbar)("POST /api/v1/auftraege", () => { let cookie: string; beforeEach(async () => { await datenbankLeeren(); await katalogSynchronisieren(); cookie = (await angemeldet("OPERATOR")).cookie; await testPrisma.server.create({ data: { name: "rz1", titel: "RZ 1", url: "https://127.0.0.1:8006", tokenId: "a@pve!b", tokenGeheimnis: verschluesseln("x"), fingerabdruck: "AA", }, }); }); const senden = async (rumpf: unknown) => { const antwort = await ausrollenPost(anfrage("POST", "/api/v1/auftraege", cookie, rumpf)); return { status: antwort.status, inhalt: await antwort.json() }; }; it("meldet Feldfehler einzeln: Name, Schlüssel, root", async () => { const { status, inhalt } = await senden({ ...gueltig, name: "Web_01", zugang: { benutzer: "root", sshSchluessel: ["kein schlüssel"] }, }); expect(status).toBe(400); expect(Object.keys(inhalt.fehler.felder)).toEqual( expect.arrayContaining(["name", "zugang.benutzer", "zugang.sshSchluessel.0"]), ); }); it("fehlende Profil-Variable landet am richtigen Feld", async () => { const { status, inhalt } = await senden({ ...gueltig, profile: ["zabbix-agent"] }); expect(status).toBe(400); expect(inhalt.fehler.felder).toEqual({ "variablen.zabbix-agent.server": "Zabbix-Server fehlt." }); }); it("deaktivierte Distribution und unbekannter Server werden abgewiesen", async () => { await testPrisma.distribution.update({ where: { id: "debian-13" }, data: { aktiv: false } }); expect((await senden(gueltig)).status).toBe(400); expect((await senden({ ...gueltig, server: "gibtsnicht" })).status).toBe(404); }); });