103 lines
3.1 KiB
Python
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')
|