Tareas Celery ============== NoxPanel usa Celery 5.3+ con Redis como broker y ``DatabaseScheduler`` de ``django-celery-beat`` para programar tareas periódicas. Las tareas se definen en ficheros ``tasks.py`` de cada módulo. Configuración -------------- .. code-block:: python # proxmoxpanel/settings.py CELERY_BROKER_URL = os.environ.get('CELERY_BROKER_URL', 'redis://redis:6379/0') CELERY_BEAT_SCHEDULER = 'django_celery_beat.schedulers:DatabaseScheduler' Servicios Docker: - **celery_worker**: Ejecuta las tareas (``concurrency=4``) - **celery_beat**: Programa y despacha tareas periódicas Tareas por Módulo ------------------ Billing ~~~~~~~~ **Ubicación**: ``billing/tasks.py`` .. list-table:: :header-rows: 1 :widths: 30 45 25 * - Tarea - Descripción - Frecuencia * - ``billing.track_vm_usage_hourly`` - Registra uso horario para suscripciones VM activas con facturación por hora - Cada hora * - ``billing.track_hosting_usage_daily`` - Registra uso diario para suscripciones de hosting - Cada 24h * - ``billing.generate_monthly_invoices`` - Genera facturas mensuales para todos los tenants con suscripciones activas. Ejecuta verificación diaria, genera factura del mes anterior - Cada 24h * - ``billing.check_overdue_invoices`` - Marca facturas pendientes como vencidas y envía emails de recordatorio (dunning). También envía notificaciones Telegram - Cada hora * - ``billing.renew_expiring_subscriptions`` - Renueva suscripciones cuyo periodo ha finalizado. Avanza fechas al siguiente periodo y genera facturas de renovación. Excluye suscripciones Stripe/PayPal (gestionadas via webhooks) - Cada hora Hosting ~~~~~~~~ **Ubicación**: ``hosting/tasks.py`` .. list-table:: :header-rows: 1 :widths: 30 45 25 * - Tarea - Descripción - Frecuencia * - ``hosting.sync_hosting_quotas`` - Sincroniza el uso real de cuotas por tenant: sitios, bases de datos, dominios, FTP, buzones, alias y shell users. Alerta cuando se superan cuotas - Cada hora * - ``hosting.verify_dns_records`` - Verifica registros DNS críticos (A root, MX, SPF) para todas las zonas activas. Registra warnings para DNS mal configurado - Cada hora * - ``hosting.check_ssl_expiry`` - Verifica fechas de expiración de certificados SSL. Alerta si expiran en <30 días. Intenta renovación automática para Let's Encrypt - Cada 24h * - ``hosting.sync_mail_cert`` - Registra estado de despliegue de certificados SNI para mail. El sync real lo ejecuta ``sync_sni_certs.sh`` via cron del host - Cada 6h * - ``hosting.sync_ssl_certificates`` - Sincroniza certificados SSL desde ``acme.json`` de Traefik a la base de datos Django (modelo ``HostingSSLCertificate``) - Cada 6h * - ``hosting.auto_backup_sites`` - Backup nocturno automatizado de todos los sitios activos. Genera tarballs con archivos + dumps de BD - Cada 24h (nocturno) * - ``hosting.cleanup_old_backups`` - Elimina backups automáticos con más de 30 días. Preserva backups manuales y limpia registros de backups fallidos - Cada 24h * - ``hosting.cleanup_orphan_records`` - Detecta registros huérfanos (existen en DB pero no en hosting engine) y los marca como inactivos - Solo manual Ticketing ~~~~~~~~~~ **Ubicación**: ``ticketing/tasks.py`` .. list-table:: :header-rows: 1 :widths: 30 45 25 * - Tarea - Descripción - Frecuencia * - ``ticketing.fetch_emails`` - Recupera emails de todas las cuentas de correo activas y los convierte en tickets. Soporta IMAP y OAuth2 (Microsoft/Google) - Cada 5 min * - ``ticketing.check_sla_breaches`` - Detecta y escala tickets con violaciones SLA. Incumplimiento de primera respuesta: asigna al manager del departamento. Incumplimiento de resolución: escala prioridad a 'urgente' y notifica admins - Cada 15 min * - ``ticketing.send_ticket_notification`` - Envía emails de notificación para eventos: new_ticket, new_reply, status_changed, sla_breach. Enruta a destinatarios apropiados - Bajo demanda (``.delay()``) * - ``ticketing.auto_close_resolved`` - Cierra automáticamente tickets resueltos hace >7 días. Actualiza estado a 'closed' y registra timestamp - Cada 24h Notifications ~~~~~~~~~~~~~~ **Ubicación**: ``notifications/tasks.py`` .. list-table:: :header-rows: 1 :widths: 30 45 25 * - Tarea - Descripción - Frecuencia * - ``notifications.send_notification_email`` - Envía email para una notificación específica. Compone asunto + cuerpo con título, mensaje y URL. Marca como ``email_sent`` - Bajo demanda * - ``notifications.cleanup_old_notifications`` - Elimina notificaciones leídas con más de 90 días. Las no leídas se preservan independientemente de la antigüedad - Solo manual VMs (Threading, no Celery) ~~~~~~~~~~~~~~~~~~~~~~~~~~~ **Ubicación**: ``vms/tasks.py`` .. note:: Las tareas de VMs usan threading (no Celery ``@shared_task``) para comunicación en tiempo real via WebSocket durante la creación/eliminación de VMs. - ``create_vm_async()`` — Creación de VM con progreso via WebSocket - ``delete_vm_async()`` — Eliminación de VM con progreso - ``clone_vm_async()`` — Clonación de VM - ``migrate_vm_async()`` — Migración de VM entre nodos Resumen de Programación ------------------------ .. list-table:: :header-rows: 1 :widths: 40 20 20 20 * - Tarea - Frecuencia - Módulo - Criticidad * - ``ticketing.fetch_emails`` - 5 min - Ticketing - Alta * - ``ticketing.check_sla_breaches`` - 15 min - Ticketing - Alta * - ``billing.track_vm_usage_hourly`` - 1 hora - Billing - Alta * - ``billing.check_overdue_invoices`` - 1 hora - Billing - Alta * - ``billing.renew_expiring_subscriptions`` - 1 hora - Billing - Alta * - ``hosting.sync_hosting_quotas`` - 1 hora - Hosting - Media * - ``hosting.verify_dns_records`` - 1 hora - Hosting - Media * - ``hosting.sync_mail_cert`` - 6 horas - Hosting - Media * - ``hosting.sync_ssl_certificates`` - 6 horas - Hosting - Baja * - ``billing.track_hosting_usage_daily`` - 24 horas - Billing - Alta * - ``billing.generate_monthly_invoices`` - 24 horas - Billing - Alta * - ``hosting.check_ssl_expiry`` - 24 horas - Hosting - Media * - ``hosting.auto_backup_sites`` - 24 horas - Hosting - Alta * - ``hosting.cleanup_old_backups`` - 24 horas - Hosting - Baja * - ``ticketing.auto_close_resolved`` - 24 horas - Ticketing - Baja Comandos Útiles ---------------- .. code-block:: bash # Ver logs del worker docker logs noxpanel-celery_worker-1 --tail 100 # Ver logs del beat (scheduler) docker logs noxpanel-celery_beat-1 --tail 100 # Ejecutar tarea manualmente docker exec noxpanel-web-1 python manage.py shell -c \ "from billing.tasks import check_overdue_invoices; \ check_overdue_invoices.delay()" # Ver tareas programadas (via Django admin) # /admin/django_celery_beat/periodictask/ # Reiniciar worker y beat docker restart noxpanel-celery_worker-1 noxpanel-celery_beat-1 Troubleshooting ---------------- **Las tareas no se ejecutan:** 1. Verificar que Redis está corriendo: ``docker logs noxpanel-redis-1`` 2. Verificar que el worker está sano: ``docker ps | grep celery`` 3. Verificar conexión del worker: ``docker logs noxpanel-celery_worker-1 | head -20`` **Las tareas periódicas no se disparan:** 1. Verificar que celery_beat está corriendo y sano 2. Verificar que ``DatabaseScheduler`` se configuró correctamente 3. Comprobar las tareas en Django admin: ``/admin/django_celery_beat/periodictask/`` **Error de importación en tarea:** Las tareas se registran con nombres explícitos (``name='module.task_name'``). Si cambia el nombre del módulo, actualizar el ``CELERY_BEAT_SCHEDULE`` y los registros en ``django_celery_beat``.