Hosting (DirectAdmin) — API v1 i MCP | Dokumentacja Nodea
Moduł Hosting obejmuje konta hostingowe DirectAdmin użytkownika: listowanie i szczegóły konta, zarządzanie skrzynkami e-mail, kopie zapasowe wraz z przywracaniem, wydanie certyfikatu Let's Encrypt oraz terminację konta. Dokument opisuje warstwę REST API v1 (/api/v1) oraz narzędzia MCP z tego modułu.
Uwierzytelnianie i zakresy (scopes)
API v1 uwierzytelnia się osobistym tokenem Passport przez nagłówek Authorization: Bearer <token>. Trasy tego modułu są chronione zakresem konta odpowiadającym poziomowi operacji:
account:read— listowanie i podgląd (konto, skrzynki, kopie).account:write— tworzenie/edycja/usuwanie skrzynek, tworzenie kopii, wydanie SSL.account:delete— przywracanie kopii (nadpisuje stan) oraz terminacja konta.
Cały moduł jest dodatkowo bramkowany flagą Pennant features:hosting-suite — wyłączenie ukrywa go w web UI i w API. Limit zapytań: throttle:api-v1 = 240/min na użytkownika tokenu. W MCP każde narzędzie wymaga dodatkowo zakresu transportowego mcp:use oraz flagi hosting-suite.
Własność i widoczność (ownership)
Konta DirectAdmin nie mają klasy polityki i nie są współdzielone — każdy dostęp jest twardo ograniczony do właściciela przez user_id. Skrzynki i kopie są sprawdzane dwukrotnie: konto musi należeć do właściciela tokenu, a skrzynka/kopia musi należeć do tego konta. Każde niedopasowanie zwraca 404 (a nie 403), więc API nie potwierdza istnienia cudzego zasobu. W MCP odpowiada temu jeden komunikat „nie znaleziono lub brak dostępu”.
Bezpieczeństwo danych wrażliwych
Hasła skrzynek e-mail są wyłącznie do zapisu (write-only): przyjmowane w payloadzie tworzenia/edycji, przekazywane wprost do API DirectAdmin, nigdy nieprzechowywane lokalnie i nigdy niezwracane w żadnej odpowiedzi. Hasło panelu DA (encrypted_password), klucze logowania SSO oraz hostname/IP/port i poświadczenia API serwera DA są celowo nigdy nieserializowane — konto ujawnia jedynie lokalizację. Kolumny wewnętrzne kopii (local_path, restore_log) także nie są eksponowane.
Efekty uboczne — asynchroniczne i stan konta
Efekty po stronie DirectAdmin (tworzenie/przywracanie kopii, wydanie SSL, terminacja) działają out-of-band przez zadania kolejki, jak w web — akcje zwracają 202 Accepted. Tworzenie/usuwanie/edycja skrzynek woła API DA synchronicznie, a lokalny mirror odświeża SyncEmailAccountsJob. Każda operacja sięgająca backendu DA wymaga aktywnego konta: konto pending jeszcze się provisionuje, a terminated nie przyjmie już akcji — w obu przypadkach API zwraca 409 Conflict.
API v1 — endpointy
| Metoda | Ścieżka | Scope | Opis |
|---|---|---|---|
| GET | /api/v1/hosting | account:read | Lista kont hostingowych właściciela (id malejąco), paginowana. |
| GET | /api/v1/hosting/{account} | account:read | Szczegóły konta: użycie dysku/transferu, SSL, lokalizacja, plan, znaczniki czasu. |
| GET | /api/v1/hosting/{account}/emails | account:read | Lista skrzynek e-mail konta (po adresie), paginowana. |
| POST | /api/v1/hosting/{account}/emails | account:write | Utworzenie skrzynki (hasło write-only). Zwraca 202. |
| PATCH | /api/v1/hosting/{account}/emails/{email} | account:write | Zmiana hasła (write-only) i/lub quota skrzynki. |
| DELETE | /api/v1/hosting/{account}/emails/{email} | account:write | Usunięcie skrzynki (DA + lokalnie). Zwraca 204. |
| GET | /api/v1/hosting/{account}/backups | account:read | Lista kopii zapasowych konta (id malejąco), paginowana. |
| POST | /api/v1/hosting/{account}/backups | account:write | Zlecenie nowej kopii (nazwa backup-Y-m-d-H-i). Zwraca 202. |
| POST | /api/v1/hosting/{account}/backups/{backup}/restore | account:delete | Przywrócenie kopii — nadpisuje stan konta (nieodwracalne). Zwraca 202. |
| POST | /api/v1/hosting/{account}/ssl | account:write | Zlecenie wydania certyfikatu Let's Encrypt. Wymaga konta aktywnego. Zwraca 202. |
| DELETE | /api/v1/hosting/{account} | account:delete | Terminacja konta (destrukcyjna, async). Zwraca 202; konto już terminated → 422. |
Wyłącznie web (poza API i MCP): logowanie SSO do panelu DirectAdmin (mint klucza logowania) oraz reset hasła konta — to interaktywne przekazania do przeglądarki, nie operacje headless.
Skrzynki e-mail — parametry ciała
email_local(string, wymagany przy tworzeniu, 1–64 znaki, charset[a-zA-Z0-9._-]) — część lokalna adresu.domain(string, wymagany przy tworzeniu, 4–253, kształt FQDN).password(string, 10–128 znaków; wymagany przy tworzeniu, opcjonalny przy edycji) — write-only.quota_mb(int 50–10000; wymagany przy tworzeniu, opcjonalny przy edycji).
Skrzynka (HostingEmailResource): id, email, domain, quota_mb, used_mb, is_forwarder, forward_to, is_active, last_synced_at — nigdy nie zawiera pola hasła. Kopia (HostingBackupResource): id, backup_name, size_mb, status, is_remote, created_at, expires_at, restore_url (link do akcji restore).
Kody błędów
401— brak/niepoprawny token.403— brak wymaganego scope.404— nieznane/cudze konto, skrzynka lub kopia.409— konto nie jest aktywne (pending/terminated) dla akcji sięgającej backendu DA.422— walidacja lub próba terminacji już zterminowanego konta (kodalready_terminated).
Przykłady — API
Lista kont hostingowych
curl -s "https://app.nodea.io/api/v1/hosting?per_page=20" \
-H "Authorization: Bearer $NODEA_TOKEN" \
-H "Accept: application/json"
Utworzenie skrzynki e-mail (hasło write-only)
curl -s -X POST https://app.nodea.io/api/v1/hosting/{account}/emails \
-H "Authorization: Bearer $NODEA_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"email_local": "biuro",
"domain": "example.com",
"password": "TajneHaslo123!",
"quota_mb": 2000
}'
Zlecenie kopii zapasowej
curl -s -X POST https://app.nodea.io/api/v1/hosting/{account}/backups \
-H "Authorization: Bearer $NODEA_TOKEN" \
-H "Accept: application/json"
Przywrócenie kopii (nieodwracalne)
curl -s -X POST https://app.nodea.io/api/v1/hosting/{account}/backups/{backup}/restore \
-H "Authorization: Bearer $NODEA_TOKEN" \
-H "Accept: application/json"
MCP — narzędzia
Narzędzia MCP dzielą model uwierzytelniania i zakresów z API v1 (Bearer + scope w ensureScope) oraz flagę hosting-suite (narzędzie na nieaktywnej fladze znika z tools/list). Identyfikatory to liczby całkowite. Brakujący i cudzy identyfikator zwracają ten sam błąd. Akcje sięgające DirectAdmin są asynchroniczne (zwracają potwierdzenie zlecenia). Narzędzia niszczące — hosting-backup-restore i hosting-terminate — są oznaczone jako destructive i wymagają jawnego confirm: true. Hasła skrzynek pozostają write-only.
| Nazwa | Scope | Tryb | Opis |
|---|---|---|---|
| hosting-list | account:read | read-only | Lista kont DirectAdmin (id malejąco); page, per_page (max 50). |
| hosting-get | account:read | read-only | Szczegóły konta po id. Hasło panelu DA nigdy nie jest zwracane. |
| hosting-emails | account:read | read-only | Lista skrzynek konta (po adresie); account_id, page, per_page (max 50). |
| hosting-email-create | account:write | zapis | Utworzenie skrzynki; account_id, email_local, domain, password (write-only), quota_mb. Konto musi być aktywne. |
| hosting-email-update | account:write | zapis | Zmiana hasła (write-only) i/lub quota; account_id, email_id, password?, quota_mb?. |
| hosting-email-delete | account:write | zapis | Usunięcie skrzynki (DA + lokalnie); account_id, email_id. Konto musi być aktywne. |
| hosting-backups | account:read | read-only | Lista kopii konta (id malejąco); account_id, page, per_page (max 50). |
| hosting-backup-create | account:write | zapis | Zlecenie kopii; account_id. Async — odpytuj hosting-backups. Konto musi być aktywne. |
| hosting-backup-restore | account:delete | destrukcyjne (confirm) | Przywrócenie kopii — nadpisuje dane konta. Wymaga confirm: true; account_id, backup_id. Async. |
| hosting-issue-ssl | account:write | zapis | Zlecenie certyfikatu Let's Encrypt; account_id. Async — odpytuj hosting-get. Konto musi być aktywne. |
| hosting-terminate | account:delete | destrukcyjne (confirm) | Terminacja konta — nieodwracalne. Wymaga confirm: true; account_id. Async. |
Przykłady — MCP (JSON-RPC)
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "hosting-email-create",
"arguments": {
"account_id": 7,
"email_local": "biuro",
"domain": "example.com",
"password": "TajneHaslo123!",
"quota_mb": 2000
}
}
}
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "hosting-backup-restore",
"arguments": { "account_id": 7, "backup_id": 128, "confirm": true }
}
}