import { benoetigteRechte, versionLesen } from "@/engine/proxmox/faehigkeiten"; import type { ProxmoxMock } from "./mock"; /** * Typische Proxmox-Zustände für Tests. Die Antworten folgen dem Format der echten API * (geprüft gegen das API-Schema von PVE 9.2). */ export type Szenario = { version: string; cluster?: { name: string; nodes: Array<{ name: string; ip: string; online?: boolean }> }; /** Storage `local` mit Inhaltstyp import? (ab 8.4 nötig für Template-Bau per API) */ importStorage?: boolean; /** Rechte, die dem Token fehlen sollen. */ ohneRechte?: string[]; /** Ohne Sys.Audit auf / antwortet /cluster/status mit 403. */ ohneClusterStatus?: boolean; }; export function szenarioEinrichten(mock: ProxmoxMock, szenario: Szenario): void { const version = versionLesen(szenario.version)!; const nodes = szenario.cluster?.nodes ?? [{ name: "pve01", ip: "127.0.0.1", online: true }]; const ohne = new Set(szenario.ohneRechte ?? []); const alle = benoetigteRechte(version).map((r) => r.recht); const rechte = Object.fromEntries(alle.filter((r) => !ohne.has(r)).map((r) => [r, 1])); mock.route("GET", "/version", () => ({ data: { version: szenario.version, release: `${version.major}.${version.minor}`, repoid: "abcdef" }, })); mock.route("GET", "/cluster/status", () => szenario.ohneClusterStatus ? { status: 403, statusText: "Permission check failed (/, Sys.Audit)" } : { data: [ ...(szenario.cluster ? [ { type: "cluster", name: szenario.cluster.name, quorate: 1, nodes: nodes.length, version: 3, }, ] : []), ...nodes.map((n, i) => ({ type: "node", name: n.name, online: n.online === false ? 0 : 1, ip: n.ip, local: i === 0 ? 1 : 0, nodeid: i + 1, })), ], }, ); mock.route("GET", "/nodes", () => ({ data: nodes.map((n) => ({ node: n.name, status: n.online === false ? "offline" : "online", cpu: 0.05, maxcpu: 16, mem: 8 * 1024 ** 3, maxmem: 64 * 1024 ** 3, uptime: 3600, })), })); mock.route("GET", /^\/nodes\/([^/]+)\/version$/, () => ({ data: { version: szenario.version, release: `${version.major}.${version.minor}`, repoid: "abcdef" }, })); mock.route("GET", /^\/nodes\/([^/]+)\/storage$/, () => ({ data: [ { storage: "local", type: "dir", content: ["iso", "vztmpl", "backup", "snippets", ...(szenario.importStorage ? ["import"] : [])].join( ",", ), active: 1, enabled: 1, shared: 0, avail: 80 * 1024 ** 3, total: 100 * 1024 ** 3, }, { storage: "local-zfs", type: "zfspool", content: "images,rootdir", active: 1, enabled: 1, shared: 0, avail: 800 * 1024 ** 3, total: 1000 * 1024 ** 3, }, ], })); mock.route("GET", /^\/nodes\/([^/]+)\/network$/, () => ({ data: [ { iface: "eno1", type: "eth", active: 1 }, { iface: "vmbr0", type: "bridge", active: 1, bridge_vlan_aware: 1, cidr: "10.0.10.2/24", comments: "LAN\n", }, { iface: "vmbr1", type: "bridge", active: 1 }, ], })); mock.route("GET", "/cluster/sdn/vnets", () => ohne.has("SDN.Audit") ? { status: 403, statusText: "Permission check failed (/sdn, SDN.Audit)" } : { data: [{ vnet: "dmz", zone: "zone1", tag: 30, alias: "DMZ" }] }, ); mock.route("GET", "/access/permissions", (anfrage) => { const p = anfrage.abfrage.get("path") ?? "/"; return { data: { [p]: rechte } }; }); }