Files
ZeroCentral/ping_service.py
2026-01-23 18:57:33 +01:00

103 lines
3.1 KiB
Python

import threading
import time
import subprocess
import logging
from datetime import datetime
from zerotier_client import ZeroTierClient
from config import PING_INTERVAL
logger = logging.getLogger(__name__)
class PingService:
def __init__(self):
self.zt_client = ZeroTierClient()
self.nodes_status = {}
self.running = False
self.thread = None
self.network_id = None
def set_network_id(self, network_id):
"""Imposta l'ID della rete da monitorare"""
self.network_id = network_id
def ping_node(self, ip_address):
"""Fa il ping a un nodo e ritorna True se online"""
try:
result = subprocess.run(
['ping', '-c', '1', '-W', '3', ip_address],
capture_output=True,
timeout=5
)
return result.returncode == 0
except Exception as e:
logger.error(f'Ping error for {ip_address}: {e}')
return False
def update_node_status(self):
"""Aggiorna lo stato di tutti i nodi"""
if not self.network_id:
logger.warning('Network ID not set')
return
peers = self.zt_client.get_peers(self.network_id)
current_time = datetime.now().isoformat()
for peer in peers:
peer_id = peer.get('id')
hostname = peer.get('name', 'Unknown')
config = peer.get('config', {})
# Estrai IP ZeroTier dal config
ip_addresses = config.get('ipAssignments', [])
if not ip_addresses:
continue
zt_ip = ip_addresses[0]
# Fa il ping
is_online = self.ping_node(zt_ip)
self.nodes_status[peer_id] = {
'id': peer_id,
'hostname': hostname,
'ip': zt_ip,
'online': is_online,
'status': 'online' if is_online else 'offline',
'last_check': current_time
}
logger.info(f'Updated status for {len(self.nodes_status)} nodes')
def get_nodes_status(self):
"""Ritorna lo stato di tutti i nodi"""
return list(self.nodes_status.values())
def start(self, network_id):
"""Avvia il servizio di ping in background"""
if self.running:
logger.warning('Service already running')
return
self.network_id = network_id
self.running = True
self.thread = threading.Thread(target=self._run, daemon=True)
self.thread.start()
logger.info('Ping service started')
def _run(self):
"""Loop principale del servizio"""
while self.running:
try:
self.update_node_status()
except Exception as e:
logger.error(f'Error in ping service: {e}')
time.sleep(PING_INTERVAL)
def stop(self):
"""Arresta il servizio"""
self.running = False
if self.thread:
self.thread.join(timeout=5)
logger.info('Ping service stopped')