72 lines
8.5 KiB
Markdown
72 lines
8.5 KiB
Markdown
|
|
# KeyHelp-Connector: API-Fähigkeiten und Abbildung
|
|||
|
|
|
|||
|
|
## Umsetzungsstand (27.09.2026)
|
|||
|
|
Paket `packages/connector-keyhelp`, getestet gegen einen nach der Definition nachgebauten Server (`test/fake.ts`), **nicht gegen eine echte Instanz**. Zugang: KeyHelp-Adresse + API-Schlüssel (IP-beschränkt); die Version wird über `GET /server` erkannt.
|
|||
|
|
- **Lesen/Abgleich**: Kunden mit Nutzung und Limits (Statistik je Kunde), Tarife, Health mit Version. Der Abgleich arbeitet rein lesend.
|
|||
|
|
- **Kunden übernehmen** (Kunden → Aus Verbindung übernehmen): Kontaktdaten → Kunde und Rechnungsanschrift, Inhaber als „eingeladen“ **ohne E-Mail-Versand** (Einladung später gezielt), Konto wird zugeordnet, optional **Bestandsvertrag** zum passenden Produkt (Beginn wählbar, Laufzeit wird in die Zukunft fortgeschrieben, keine Rechnung). Doppelte Übernahme ist ausgeschlossen (`organizations.legacy_ref`); Verknüpfung mit vorhandenem Kunden möglich.
|
|||
|
|
- **Tarife/Produkte**: vorhandene Tarife über „Produkte → Aus Verbindung übernehmen“; **neue Tarife** über „Neuen Hosting-Tarif anlegen“ (legt den Tarif in KeyHelp an und das Produkt im Kundencenter). Name muss frei sein, „unbegrenzt“ nur, wenn die Instanz es bereits kennt.
|
|||
|
|
- **Bereitstellung** (Bestellung): Konto anlegen, Benutzername `kc` + Ziffern der Vertragsnummer (stabil, bei Wiederholung wird das eigene Konto übernommen), Vermerk „Kundencenter K-… V-…“, Zugangsdaten gehen per KeyHelp an die Kunden-E-Mail (Passwort wird nie gelesen/gespeichert).
|
|||
|
|
- **Aktionen**: Sperren/Entsperren, Tarifwechsel (Connector; UI folgt mit Upgrade/Downgrade), Löschen nur manuell und nie automatisch wiederholt.
|
|||
|
|
- **Kundenpanel-Login** (SSO, 60 Min., nicht gespeichert, im Audit).
|
|||
|
|
- **Hosting-Ressourcen** je Konto: Domains, E-Mail, Datenbanken, FTP lesen und ändern (als Auftrag, Passwörter nur verschlüsselt bis zur Ausführung), SSL-Zertifikate nur lesen. Freigabe pro Produkt/Ressource (`domain.manage`, `email.manage`, `database.manage`, `ftp.manage`, `panel.login`) plus Rolle Inhaber/Admin.
|
|||
|
|
- **Mandantentrennung**: Der API-Schlüssel ist ein Administratorzugang, deshalb prüft der Connector vor jeder Änderung, dass das Objekt dem Konto gehört; neue Objekte bekommen immer die Kunden-ID; Namenskonflikte mit fremden Objekten werden abgelehnt (getestet).
|
|||
|
|
|
|||
|
|
### Annahmen, die an der echten Instanz zu prüfen sind
|
|||
|
|
1. Speicher/Traffic in **Byte** (Definition gibt keine Einheit an; Anzeige und Tarif-Anlage gehen davon aus).
|
|||
|
|
2. **Zeitstempel ohne Zeitzone** werden als UTC gelesen.
|
|||
|
|
3. Negative Limits = **unbegrenzt** (nur beim Anlegen genutzt, wenn die Instanz es schon kennt).
|
|||
|
|
4. Pflichtfelder von `POST /clients` (E-Mail, Benutzername; Passwort wird vom Panel erzeugt) und Benutzernamensregeln (`kc` + Ziffern).
|
|||
|
|
5. FTP-Anlage setzt ein vollständig eingerichtetes System-Konto voraus (Panel meldet sonst 400).
|
|||
|
|
6. Verhalten bei Tarifwechsel, wenn neue Limits unterschritten werden.
|
|||
|
|
7. Listen liefern alles (kein Paging): bei sehr vielen Kunden dauert der Abgleich (Statistik je Kunde, 4 parallel).
|
|||
|
|
|
|||
|
|
### Noch nicht umgesetzt
|
|||
|
|
DNS-Editor, Cronjobs, Verzeichnisschutz, PHP-Einstellungen je Kunde, Zertifikate hochladen, Fail2Ban-Entsperren, Backup-Liste anzeigen; Hauptdomain bei der Bestellung erfragen; Kündigung mit `delete_on` statt Sperre; Tarifwechsel in der Oberfläche.
|
|||
|
|
|
|||
|
|
# (Auswertung der API-Definition)
|
|||
|
|
|
|||
|
|
Quelle: offizielle OpenAPI-Definition **KeyHelp RESTful API 2.15** (geändert 25.09.2026), Kopie: `docs/api-specs/keyhelp-api-2.15.openapi.json`. Stand: nur die Definition gelesen, **nicht** gegen eine echte KeyHelp-Instanz geprüft (kein Testzugang, Version der Instanz unbekannt).
|
|||
|
|
|
|||
|
|
## Grundregeln der API
|
|||
|
|
- URL `https://<host>/api/v2/<Endpunkt>`, Anmeldung per Header `X-API-Key`. Formate: JSON (Standard), XML, YAML.
|
|||
|
|
- **API ist standardmäßig aus.** Schlüssel legt man in KeyHelp an (Admin-Bereich → Konfiguration → API) und **soll auf IP/IP-Bereich beschränkt** werden. Es gibt keine Rechte-Stufen pro Schlüssel: Ein Schlüssel ist praktisch ein Administratorzugang → höchste Vertraulichkeit (verschlüsselt speichern, nur Superadmin).
|
|||
|
|
- Objekte sind per numerischer ID **oder Name** ansprechbar (`/clients/{id}` und `/clients/name/{name}`).
|
|||
|
|
- Listen liefern **alles auf einmal** (nur `sort`/`order`, kein Paging). Bei sehr vielen Kunden Antwortzeit beachten.
|
|||
|
|
- Fehlerformat `{code, message}`, Statuscodes 200/201/202/204/400/401/404.
|
|||
|
|
- Beim Neuladen des Webservers antwortet KeyHelp kurz mit **500/503** → Aufrufer muss nach einigen Sekunden erneut versuchen.
|
|||
|
|
- Objekte haben ein Feld `status`: 0 unbekannt, 1 ok, 2 Fehler, 3 Konfiguration neu, 4 Konfiguration wird aktualisiert (→ Zustand „in Bearbeitung“).
|
|||
|
|
- Keine Webhooks, keine Paginierung, keine Rechnungs-/Ticket-Funktionen.
|
|||
|
|
|
|||
|
|
## Abbildung auf den Connector-Vertrag
|
|||
|
|
| Fähigkeit | KeyHelp | Bemerkung |
|
|||
|
|
|---|---|---|
|
|||
|
|
| Health / Version | `GET /ping`, `GET /server` | Server-Info mit Komponenten (Apache, PHP, MariaDB, Postfix …), Auslastung, Ports |
|
|||
|
|
| Ressourcen lesen | `GET /clients`, `/clients/{id}`, `/clients/{id}/resources` | Kunde = Hosting-Konto; Ressourcen-Liste enthält die Unterobjekte |
|
|||
|
|
| Nutzung | `GET /clients/{id}/stats`, `/traffic` | Speicher und Traffic (`value`/`max`), Anzahl Domains, Postfächer, DBs, FTP, Cronjobs; Traffic je Protokoll (HTTP, FTP, POP3, IMAP, SMTP) |
|
|||
|
|
| Limits/Tarif | `client.resource_limits` (nur lesend), `GET /hosting-plans` | **Limits nur über den Tarif** änderbar, keine Einzelabweichung pro Kunde per API (dafür eigenen Tarif anlegen) |
|
|||
|
|
| `lifecycle.create` | `POST /clients` → 201 `{id}` | Pflicht/Optionen: Benutzername, E-Mail, Passwort oder generiert, `id_hosting_plan` (sonst Standardtarif), Kontaktdaten, `create_system_domain`, `send_login_credentials`. Natürliche Idempotenz über den eindeutigen Benutzernamen (vorher `GET /clients/name/{name}`) |
|
|||
|
|
| `lifecycle.suspend/unsuspend` | `PUT /clients/{id}` `{is_suspended}` | Zielzustand → idempotent. Zusätzlich **geplant**: `suspend_on` und `delete_on` (Datum oder „+30 days“) → passt zu Kündigung, Kulanz- und Sperrregeln |
|
|||
|
|
| `lifecycle.terminate` | `DELETE /clients/{id}` | **Löscht Konto und ALLE Ressourcen** (destruktiv): nie automatisch wiederholen, immer manuelle Bestätigung; besser `delete_on` mit Kulanzfrist |
|
|||
|
|
| `plan.change` | `PUT /clients/{id}` `{id_hosting_plan}` | Up-/Downgrade über Tarifwechsel (Verhalten bei Überschreitung der neuen Limits an der Instanz prüfen) |
|
|||
|
|
| Passwort/Zugang | `PUT /clients/{id}` `{password}` | Optional Zugangsdaten per E-Mail (`send_login_credentials`) |
|
|||
|
|
| `sso.login` | `GET /login/{id}` bzw. `/login/name/{name}` | **Offiziell unterstützt**: URL 60 Minuten gültig, mit Brute-Force-Schutz. Passt zu „sicherer Panel-Login“ |
|
|||
|
|
| Domains | `/domains` (CRUD), `php_version`, `is_disabled`, `delete_on`, `security` (Let’s Encrypt, HTTPS erzwingen, HSTS), `is_email_domain` | Haupt- und Subdomains, System-Domains filterbar |
|
|||
|
|
| DNS | `/dns/{id}` lesen/ersetzen/zurücksetzen | Datensätze, DKIM |
|
|||
|
|
| SSL | `/certificates` (CRUD) | `valid_till`, `issuer`, `secured_domains` → **Ablaufdaten** verfügbar |
|
|||
|
|
| E-Mail | `/emails` (CRUD) | Postfachgröße/-limit, Aliase, Weiterleitungen, Catch-all, Passwort |
|
|||
|
|
| Datenbanken | `/databases` (CRUD) | Name, Benutzer, Passwort, Größe, Remote-Hosts |
|
|||
|
|
| FTP | `/ftp-users` (CRUD) | Benutzer, Heimverzeichnis |
|
|||
|
|
| Weiteres | `/scheduled-tasks` (Cronjobs), `/directory-protections`, `/backups/operations` (nur Liste), `/fail2ban/banned-ips` (Liste, Entsperren) | Backup-Wiederherstellung ist nicht per API möglich |
|
|||
|
|
| Nicht vorhanden | Webhooks, Paging, Limits pro Kunde, Rechnungen/Tickets | Abgleich daher per Polling (Sync-Job) |
|
|||
|
|
| Nie freigeben | `/admins/*`, `POST /server/reboot` | Administratorkonten und Server-Neustart gehören nicht in das Kundencenter |
|
|||
|
|
|
|||
|
|
## Vorschlag für den Umfang
|
|||
|
|
1. **Lesend zuerst:** Health, Kunden mit Nutzung/Limits/Status, Domains, SSL-Ablauf, Übernahme der **Hosting-Tarife als Produktvorlagen** (wie beim Lizenzsystem: Limits aus `hosting-plans`).
|
|||
|
|
2. **Lebenszyklus:** anlegen, sperren/entsperren, Tarifwechsel, geplantes Löschen (`delete_on`) statt sofortigem `DELETE`.
|
|||
|
|
3. **Panel-Login (SSO)** und Unterobjekte (E-Mail, Datenbanken, FTP) für Kunden gemäß Produktregeln.
|
|||
|
|
|
|||
|
|
## Benötigt für die Umsetzung
|
|||
|
|
- KeyHelp-URL und **Version** (Definition kennt 2.1–2.15; Abweichungen kapselt der Connector).
|
|||
|
|
- Ein **Test-API-Schlüssel**, auf die IP des Kundencenter-Servers beschränkt (idealerweise gegen eine Testinstanz; sonst Schlüssel mit Bedacht, da er Administratorrechte hat).
|
|||
|
|
- Entscheidung, welche Tarife als Produkte angeboten werden und ob Kunden Unterobjekte selbst verwalten dürfen.
|