Feldtest auf zwei echten Proxmox-VE-9.2-Hosts (#018): Installation, Timer, Zwischenspeicher und Nachsenden laufen wie vorgesehen. `pvesubscription get` kennt kein JSON, ohne Subscription fehlen fast alle Felder, `pveversion` enthaelt den Kernel doppelt - alles im Agent beruecksichtigt. Dabei zeigte sich: in Proxmox hat jeder Knoten eine eigene Subscription. Der Agent meldet darum die Cluster-Mitglieder aus `pvecm nodes`, und eine elfte Warnregel meldet Knoten, von denen sich kein Agent meldet (#022). Ausserdem behoben: die Bilder des Handbuchs zeigten allesamt die Anmeldeseite, weil Firefox eine selbst erzeugte Cookie-Datei stillschweigend verwirft. Das Skript nutzt jetzt einen lokalen Vermittler und bricht ab, wenn alle Aufnahmen gleich gross sind. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -144,6 +144,29 @@ productname: Proxmox "VE" \\ Subscription mit Tab`,
|
||||
});
|
||||
});
|
||||
|
||||
it("meldet die Cluster-Mitglieder", () => {
|
||||
befehlErsetzen("pvesubscription", PVE_SUBSCRIPTION);
|
||||
befehlErsetzen(
|
||||
"pvecm",
|
||||
`Membership information
|
||||
----------------------
|
||||
Nodeid Votes Name
|
||||
1 1 hv-rz5-pve-01 (local)
|
||||
2 1 hv-rz5-pve-02
|
||||
3 1 hv-rz5-pve-03`,
|
||||
);
|
||||
|
||||
const report = reportErzeugen() as { host: { clusterMitglieder: string[] } };
|
||||
expect(report.host.clusterMitglieder).toEqual(["hv-rz5-pve-01", "hv-rz5-pve-02", "hv-rz5-pve-03"]);
|
||||
});
|
||||
|
||||
it("meldet eine leere Liste, wenn der Host in keinem Cluster ist", () => {
|
||||
befehlErsetzen("pvesubscription", PVE_SUBSCRIPTION);
|
||||
|
||||
const report = reportErzeugen() as { host: { clusterMitglieder: string[] } };
|
||||
expect(report.host.clusterMitglieder).toEqual([]);
|
||||
});
|
||||
|
||||
it("gibt die Version aus", () => {
|
||||
const ausgabe = execFileSync("bash", [AGENT, "--version"], { encoding: "utf8" }).trim();
|
||||
expect(ausgabe).toBe("0.2.0");
|
||||
|
||||
@@ -30,7 +30,7 @@ describe.runIf(datenbankVerfuegbar)("Abgleich der Warnungen", () => {
|
||||
|
||||
it("legt die Standard-Einstellungen für alle Regeln an", async () => {
|
||||
const einstellungen = await testPrisma.warnregelEinstellung.findMany();
|
||||
expect(einstellungen).toHaveLength(10);
|
||||
expect(einstellungen).toHaveLength(11);
|
||||
const ablauf = einstellungen.find((e) => e.regel === "subscription-laeuft-ab");
|
||||
expect(ablauf?.schwellwerte).toEqual({ tage: [30, 14, 7] });
|
||||
});
|
||||
|
||||
@@ -18,6 +18,8 @@ function host(überschreibungen: Partial<HostDaten> = {}): HostDaten {
|
||||
return {
|
||||
id: "h1",
|
||||
hostname: "pve-01",
|
||||
clusterName: null,
|
||||
clusterMitglieder: [],
|
||||
kundeId: "k1",
|
||||
kundeName: "Brandl Elektrotechnik GmbH",
|
||||
subKey: "pve1c-aaaa",
|
||||
@@ -70,9 +72,9 @@ function ausRegel(k: RegelKontext, name: string) {
|
||||
}
|
||||
|
||||
describe("Warnregeln", () => {
|
||||
it("prüft alle zehn Regeln, wenn nichts abgeschaltet ist", () => {
|
||||
expect(REGELN).toHaveLength(10);
|
||||
expect(new Set(REGELN.map((r) => r.name)).size).toBe(10);
|
||||
it("prüft alle elf Regeln, wenn nichts abgeschaltet ist", () => {
|
||||
expect(REGELN).toHaveLength(11);
|
||||
expect(new Set(REGELN.map((r) => r.name)).size).toBe(11);
|
||||
});
|
||||
|
||||
describe("Subscription läuft ab", () => {
|
||||
@@ -297,6 +299,63 @@ describe("Warnregeln", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("Cluster-Knoten ohne Agent", () => {
|
||||
it("meldet einen Knoten, der im Cluster steht, sich aber nicht meldet", () => {
|
||||
const k = kontext({
|
||||
hosts: [
|
||||
host({
|
||||
id: "h1",
|
||||
hostname: "pve-node-01",
|
||||
clusterName: "rz5",
|
||||
clusterMitglieder: ["pve-node-01", "pve-node-02", "pve-node-03"],
|
||||
}),
|
||||
host({ id: "h2", hostname: "pve-node-02", clusterName: "rz5", clusterMitglieder: [] }),
|
||||
],
|
||||
});
|
||||
|
||||
const kandidaten = ausRegel(k, "cluster-knoten-ohne-agent");
|
||||
expect(kandidaten).toHaveLength(1);
|
||||
expect(kandidaten[0].beschreibung).toContain("pve-node-03");
|
||||
expect(kandidaten[0].fingerprint).toBe("cluster-knoten-ohne-agent:rz5:pve-node-03");
|
||||
});
|
||||
|
||||
it("meldet nichts, wenn alle Knoten melden", () => {
|
||||
const mitglieder = ["pve-node-01", "pve-node-02"];
|
||||
const k = kontext({
|
||||
hosts: [
|
||||
host({ id: "h1", hostname: "pve-node-01", clusterName: "rz5", clusterMitglieder: mitglieder }),
|
||||
host({ id: "h2", hostname: "pve-node-02", clusterName: "rz5", clusterMitglieder: mitglieder }),
|
||||
],
|
||||
});
|
||||
expect(ausRegel(k, "cluster-knoten-ohne-agent")).toHaveLength(0);
|
||||
});
|
||||
|
||||
it("beachtet Groß- und Kleinschreibung nicht", () => {
|
||||
const k = kontext({
|
||||
hosts: [
|
||||
host({ id: "h1", hostname: "PVE-Node-01", clusterName: "rz5", clusterMitglieder: ["pve-node-01"] }),
|
||||
],
|
||||
});
|
||||
expect(ausRegel(k, "cluster-knoten-ohne-agent")).toHaveLength(0);
|
||||
});
|
||||
|
||||
it("meldet nichts für Hosts ohne Cluster", () => {
|
||||
const k = kontext({ hosts: [host({ clusterName: null, clusterMitglieder: [] })] });
|
||||
expect(ausRegel(k, "cluster-knoten-ohne-agent")).toHaveLength(0);
|
||||
});
|
||||
|
||||
it("meldet jeden fehlenden Knoten nur einmal, auch wenn mehrere ihn melden", () => {
|
||||
const mitglieder = ["pve-node-01", "pve-node-02", "pve-node-03"];
|
||||
const k = kontext({
|
||||
hosts: [
|
||||
host({ id: "h1", hostname: "pve-node-01", clusterName: "rz5", clusterMitglieder: mitglieder }),
|
||||
host({ id: "h2", hostname: "pve-node-02", clusterName: "rz5", clusterMitglieder: mitglieder }),
|
||||
],
|
||||
});
|
||||
expect(ausRegel(k, "cluster-knoten-ohne-agent")).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
|
||||
it("überspringt abgeschaltete Regeln", () => {
|
||||
const k = kontext({
|
||||
hosts: [host({ kundeId: null, kundeName: null })],
|
||||
|
||||
Reference in New Issue
Block a user