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.

Panel de administración de hosting

Conceptos Clave

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

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:

Roles de Tenant

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:

Paquetes Ejemplo

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

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:

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:

Cuotas del Tenant

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

curl -X GET https://panel.example.com/hosting/api/rest/tenants/1/stats/ \
  -H "Authorization: Bearer $TOKEN"

Respuesta:

{
  "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:

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.