initial commit. phase 1 complete

This commit is contained in:
2026-05-05 20:45:19 +02:00
parent d9c68313a0
commit 89e058ffac
20631 changed files with 3224610 additions and 43 deletions
View File
+27
View File
@@ -0,0 +1,27 @@
"""
Discovery task stubs — Phase 1 scaffolding.
Phase 2 implementations will:
scan_all_networks — iterate Network queryset, run nmap per CIDR, upsert Nodes
poll_proxmox — call Proxmox API, upsert VM/container Nodes via PROXMOX_URL/TOKEN env vars
"""
import logging
from config.celery import app
logger = logging.getLogger(__name__)
@app.task(name="tasks.discovery.scan_all_networks", bind=True, max_retries=3)
def scan_all_networks(self) -> dict: # type: ignore[type-arg]
"""Stub: scan all configured Network CIDRs for live hosts."""
logger.info("discovery.scan_all_networks: stub — Phase 2 not yet implemented")
return {"status": "stub", "message": "Phase 2 not yet implemented"}
@app.task(name="tasks.discovery.poll_proxmox", bind=True, max_retries=3)
def poll_proxmox(self) -> dict: # type: ignore[type-arg]
"""Stub: poll Proxmox API for VMs and containers."""
logger.info("discovery.poll_proxmox: stub — Phase 2 not yet implemented")
return {"status": "stub", "message": "Phase 2 not yet implemented"}
+29
View File
@@ -0,0 +1,29 @@
"""
Heartbeat task stubs — Phase 1 scaffolding.
Phase 2 implementations will:
check_all_nodes — query Node.objects.filter(ip_address__isnull=False),
dispatch check_single_node subtasks via Celery group()
check_single_node — icmplib.ping() for ICMP, socket.connect_ex() for TCP,
httpx.get() for HTTP; write HeartbeatLog record
"""
import logging
from config.celery import app
logger = logging.getLogger(__name__)
@app.task(name="tasks.heartbeat.check_all_nodes", bind=True)
def check_all_nodes(self) -> dict: # type: ignore[type-arg]
"""Stub: ICMP/TCP liveness check for all nodes that have an IP address."""
logger.debug("heartbeat.check_all_nodes: stub — Phase 2 not yet implemented")
return {"status": "stub", "checked": 0}
@app.task(name="tasks.heartbeat.check_single_node", bind=True, max_retries=2)
def check_single_node(self, node_id: str, check_type: str = "icmp") -> dict: # type: ignore[type-arg]
"""Stub: check a single node and write a HeartbeatLog record."""
logger.debug("heartbeat.check_single_node: stub for node_id=%s", node_id)
return {"status": "stub", "node_id": node_id, "check_type": check_type}
+35
View File
@@ -0,0 +1,35 @@
"""
Maintenance tasks — cleanup and housekeeping.
Scheduled via Celery Beat to run daily at 03:00 UTC.
"""
import logging
from datetime import timedelta
from django.utils import timezone
from config.celery import app
logger = logging.getLogger(__name__)
@app.task(name="tasks.maintenance.prune_old_heartbeat_logs", bind=True)
def prune_old_heartbeat_logs(self, days: int = 30) -> dict: # type: ignore[type-arg]
"""
Delete HeartbeatLog records older than `days` days.
Returns the count of deleted rows for monitoring/alerting.
Runs as a single bulk DELETE to avoid row-by-row overhead.
"""
from apps.core.models import HeartbeatLog
cutoff = timezone.now() - timedelta(days=days)
deleted_count, _ = HeartbeatLog.objects.filter(timestamp__lt=cutoff).delete()
logger.info(
"maintenance.prune_old_heartbeat_logs: deleted %d records older than %d days",
deleted_count,
days,
)
return {"status": "ok", "deleted": deleted_count, "cutoff_days": days}