Nodea — logo

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żkaScopeOpis
GET/api/v1/hostingaccount:readLista kont hostingowych właściciela (id malejąco), paginowana.
GET/api/v1/hosting/{account}account:readSzczegóły konta: użycie dysku/transferu, SSL, lokalizacja, plan, znaczniki czasu.
GET/api/v1/hosting/{account}/emailsaccount:readLista skrzynek e-mail konta (po adresie), paginowana.
POST/api/v1/hosting/{account}/emailsaccount:writeUtworzenie skrzynki (hasło write-only). Zwraca 202.
PATCH/api/v1/hosting/{account}/emails/{email}account:writeZmiana hasła (write-only) i/lub quota skrzynki.
DELETE/api/v1/hosting/{account}/emails/{email}account:writeUsunięcie skrzynki (DA + lokalnie). Zwraca 204.
GET/api/v1/hosting/{account}/backupsaccount:readLista kopii zapasowych konta (id malejąco), paginowana.
POST/api/v1/hosting/{account}/backupsaccount:writeZlecenie nowej kopii (nazwa backup-Y-m-d-H-i). Zwraca 202.
POST/api/v1/hosting/{account}/backups/{backup}/restoreaccount:deletePrzywrócenie kopii — nadpisuje stan konta (nieodwracalne). Zwraca 202.
POST/api/v1/hosting/{account}/sslaccount:writeZlecenie wydania certyfikatu Let's Encrypt. Wymaga konta aktywnego. Zwraca 202.
DELETE/api/v1/hosting/{account}account:deleteTerminacja 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 (kod already_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.

NazwaScopeTrybOpis
hosting-listaccount:readread-onlyLista kont DirectAdmin (id malejąco); page, per_page (max 50).
hosting-getaccount:readread-onlySzczegóły konta po id. Hasło panelu DA nigdy nie jest zwracane.
hosting-emailsaccount:readread-onlyLista skrzynek konta (po adresie); account_id, page, per_page (max 50).
hosting-email-createaccount:writezapisUtworzenie skrzynki; account_id, email_local, domain, password (write-only), quota_mb. Konto musi być aktywne.
hosting-email-updateaccount:writezapisZmiana hasła (write-only) i/lub quota; account_id, email_id, password?, quota_mb?.
hosting-email-deleteaccount:writezapisUsunięcie skrzynki (DA + lokalnie); account_id, email_id. Konto musi być aktywne.
hosting-backupsaccount:readread-onlyLista kopii konta (id malejąco); account_id, page, per_page (max 50).
hosting-backup-createaccount:writezapisZlecenie kopii; account_id. Async — odpytuj hosting-backups. Konto musi być aktywne.
hosting-backup-restoreaccount:deletedestrukcyjne (confirm)Przywrócenie kopii — nadpisuje dane konta. Wymaga confirm: true; account_id, backup_id. Async.
hosting-issue-sslaccount:writezapisZlecenie certyfikatu Let's Encrypt; account_id. Async — odpytuj hosting-get. Konto musi być aktywne.
hosting-terminateaccount:deletedestrukcyjne (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 }
  }
}