======================== Gestión de Tenants ======================== NoxPanel implementa un sistema **multi-tenant** donde cada organización (empresa/cliente) opera en un espacio aislado con sus propios recursos, cuotas y usuarios. Este documento describe la gestión completa de tenants. .. image:: /_static/screenshots/09_hosting_admin.jpg :alt: Panel de administración de hosting :width: 100% :align: center | .. contents:: En esta página :local: :depth: 2 Conceptos Clave ================ .. glossary:: Tenant Organización o empresa que utiliza los servicios de hosting. Cada tenant tiene sus propios sitios, bases de datos, dominios, buzones, etc. TenantUser Relación entre un usuario Django y un tenant. Un usuario puede pertenecer a múltiples tenants con diferentes roles. HostingClient Mapeo entre un tenant/usuario y un cliente en el motor de hosting. Necesario para que las operaciones de hosting se ejecuten con los permisos correctos. HostingPackage Paquete predefinido de cuotas (S, M, XL, XXL) que se puede asignar a un tenant para configurar sus límites de forma rápida. Crear un Tenant ================ Desde Django Admin ------------------ 1. Acceder a ``/admin/`` > **Hosting > Hosting Tenants** 2. Clic en **Añadir Hosting Tenant** 3. Rellenar los campos: - **Name**: Nombre de la empresa (único) - **Slug**: Identificador URL (se auto-genera si se deja en blanco) - **Contact email**: Email de contacto principal - **Contact phone**: Teléfono (opcional) - **Package**: Paquete de hosting (opcional, aplica cuotas automáticamente) 4. Guardar Desde la API REST ----------------- .. code-block:: bash curl -X POST https://panel.example.com/hosting/api/rest/tenants/ \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "Empresa ABC", "slug": "empresa-abc", "contact_email": "admin@empresaabc.com", "contact_phone": "+34 600 123 456", "quota_sites": 10, "quota_databases": 5, "quota_domains": 5, "quota_storage_gb": 10 }' Asignar Usuarios a un Tenant =============================== Un usuario puede pertenecer a uno o varios tenants con diferentes roles: .. list-table:: Roles de Tenant :header-rows: 1 :widths: 20 80 * - Rol - Permisos * - **admin** - Gestión completa: crear/editar/eliminar todos los recursos del tenant * - **member** - Gestión operativa: crear/editar recursos, sin eliminar tenant * - **viewer** - Solo lectura: puede ver recursos pero no modificarlos Para asignar un usuario, crear un ``TenantUser`` desde el admin: 1. Ir a ``/admin/`` > **Hosting > Tenant Users** 2. Clic en **Añadir Tenant User** 3. Seleccionar el **Tenant** y el **User** 4. Elegir el **Rol** (admin, member, viewer) 5. Guardar Paquetes de Hosting ==================== Los paquetes definen cuotas predefinidas que simplifican la gestión: .. list-table:: Paquetes Ejemplo :header-rows: 1 :widths: 12 12 12 12 12 12 12 16 * - Paquete - Sitios - BBDDs - Dominios - Storage - FTP - Mailboxes - Precio/mes * - **S** - 1 - 1 - 1 - 1 GB - 1 - 2 - 4.99 EUR * - **M** - 5 - 3 - 5 - 5 GB - 3 - 5 - 9.99 EUR * - **XL** - 20 - 10 - 20 - 25 GB - 10 - 20 - 24.99 EUR * - **XXL** - 50 - 25 - 50 - 100 GB - 25 - 50 - 49.99 EUR Aplicar un paquete a un tenant ------------------------------- .. code-block:: bash curl -X POST https://panel.example.com/hosting/api/rest/packages/2/apply_to_tenant/ \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"tenant_id": 1}' Esto sobrescribe todas las cuotas del tenant con los valores del paquete. Mapeo con el Motor de Hosting ============================== Cada tenant necesita al menos un ``HostingClient`` para poder crear recursos en el servidor de hosting. El mapeo conecta: - Un **tenant** de NoxPanel con un **client_id** del motor de hosting - Un **usuario** Django con las credenciales del motor de hosting Crear mapeo desde Django Admin ------------------------------- 1. Ir a ``/admin/`` > **Hosting > Hosting Clients** 2. Clic en **Añadir Hosting Client** 3. Rellenar: - **Tenant**: El tenant al que pertenece - **User**: El usuario Django asociado - **Hosting Client ID**: ID numérico del cliente en el motor de hosting - **Hosting Username**: Nombre de usuario en el motor de hosting - **Hosting Password**: Contraseña (se almacena cifrada) 4. Guardar Sincronización -------------- Para sincronizar los recursos de un tenant desde el motor de hosting: .. code-block:: bash curl -X POST https://panel.example.com/hosting/api/rest/tenants/1/sync/ \ -H "Authorization: Bearer $TOKEN" Esto importa sitios, bases de datos, dominios, etc. desde el motor de hosting a la base de datos local de NoxPanel. Cuotas y Límites ================= Cada tenant tiene cuotas individuales que limitan la cantidad de recursos: .. list-table:: Cuotas del Tenant :header-rows: 1 :widths: 35 15 50 * - Cuota - Default - Descripción * - ``quota_sites`` - 10 - Número máximo de sitios web * - ``quota_databases`` - 5 - Número máximo de bases de datos * - ``quota_domains`` - 5 - Número máximo de dominios * - ``quota_storage_gb`` - 10 - Almacenamiento máximo en GB * - ``quota_ftp_users`` - 5 - Número máximo de cuentas FTP * - ``quota_mailboxes`` - 10 - Número máximo de buzones de email * - ``quota_mail_aliases`` - 20 - Número máximo de alias de email * - ``quota_shell_users`` - 1 - Número máximo de usuarios shell/SSH Cuando un usuario intenta crear un recurso que excede la cuota, la API devuelve un error ``400 Bad Request`` con un mensaje descriptivo. Ver estadísticas de uso ------------------------ .. code-block:: bash curl -X GET https://panel.example.com/hosting/api/rest/tenants/1/stats/ \ -H "Authorization: Bearer $TOKEN" **Respuesta:** .. code-block:: json { "sites_count": 3, "databases_count": 2, "domains_count": 3, "storage_usage_gb": 0, "quota_sites": 10, "quota_databases": 5, "quota_domains": 5, "quota_storage_gb": 10 } Aislamiento de Datos ====================== El middleware ``TenantIsolationMiddleware`` garantiza que: 1. Cada petición se ejecuta en el contexto del tenant activo del usuario 2. Las queries de base de datos se filtran automáticamente por tenant 3. Un usuario no puede acceder a recursos de otros tenants 4. Los superusuarios pueden ver todos los tenants El aislamiento es configurable mediante la variable de entorno: .. code-block:: text TENANT_ISOLATION_STRICT=True Cuando está habilitado (por defecto), se aplican validaciones adicionales en cada operación para verificar la pertenencia al tenant. Eliminar un Tenant =================== La eliminación de un tenant es un **soft delete**: se marca como inactivo pero no se borran los datos. Solo los superusuarios pueden realizar esta acción. Al eliminar un tenant: 1. Se desactiva el tenant (``is_active=False``) 2. Se elimina el cliente del motor de hosting asociado (si existe) 3. Los recursos del tenant quedan inaccesibles pero preservados .. warning:: La eliminación del cliente en el motor de hosting es irreversible. Los sitios web, bases de datos y buzones en el servidor de hosting se eliminarán.