feat(schluessel): Zuweisen und Ausrollen auf der Schluesselseite (#017)

Auf der Seite eines Schluessels: Public Key einem Host oder einer
Gruppe zuweisen, Private Key (nur Admin) auf einen Quell-Host legen -
mit ~/.ssh/config-Eintrag und dem Host-Key des Ziels in known_hosts -,
Dry-Run fuer alle Ziele, anwenden und die Verbindung von A nach B
testen. Der Kern-Anwendungsfall laeuft damit im Browser durch (E2E).

Der Dry-Run nimmt Private-Key-Ziele nur fuer Admins auf: sonst koennte
ein Operator einen vorbereiteten Private Key ausrollen lassen. Die
Vorschau zeigt je Datei die Aktion; der Inhalt eines Private Keys
erreicht den Browser nie.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-12 11:05:03 +02:00
co-authored by Claude Opus 5.5
parent 68136e8f07
commit 12603eb145
15 changed files with 660 additions and 39 deletions
@@ -1,10 +1,35 @@
"use client";
/**
* Platzhalter fuer „+ Ausrollen“ in der Karte „Private Key ausgerollt auf“ (#012).
* Inhalt folgt mit #017 (Private Key auf einen Host legen); bis dahin bewusst leer.
*/
export function PrivateAusrollenAktion(props: { schluesselId: string; darf: boolean }): null {
void props;
return null;
import { AusrollDialog } from "@/components/ausrollen/AusrollDialog";
import { PrivateZuweisenFormular } from "@/components/ausrollen/PrivateZuweisenFormular";
import type { ZielAuswahl } from "@/server/queries/ziele";
/** „+ Ausrollen“ in der Karte „Private Key ausgerollt auf“ (#017) – nur Admins. */
export function PrivateAusrollenAktion({
schluesselId,
darf,
auswahl,
slug,
passphraseGeschuetzt = false,
}: {
schluesselId: string;
darf: boolean;
auswahl?: ZielAuswahl;
slug?: string;
passphraseGeschuetzt?: boolean;
}) {
if (!darf || !auswahl || !slug) return null;
return (
<AusrollDialog titel="Private Key ausrollen">
{(schliessen) => (
<PrivateZuweisenFormular
schluesselId={schluesselId}
slug={slug}
auswahl={auswahl}
passphraseGeschuetzt={passphraseGeschuetzt}
beiErfolg={schliessen}
/>
)}
</AusrollDialog>
);
}