fix: diagnostics tab — run ping/traceroute in cell-wireguard, fix wrong method call
The connectivity endpoint was calling routing_manager.test_connectivity() (no args, internal health check) instead of test_routing_connectivity(target_ip). Also ping/traceroute aren't installed in the API container; run them via docker exec cell-wireguard instead. Updated test_api_endpoints to mock test_routing_connectivity and cover the new DELETE /firewall/<id> and GET /live-iptables endpoints. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+4
-2
@@ -1638,8 +1638,10 @@ def get_live_iptables():
|
|||||||
def test_routing_connectivity():
|
def test_routing_connectivity():
|
||||||
"""Test routing connectivity."""
|
"""Test routing connectivity."""
|
||||||
try:
|
try:
|
||||||
data = request.get_json(silent=True)
|
data = request.get_json(silent=True) or {}
|
||||||
result = routing_manager.test_connectivity(data)
|
target_ip = data.get('target_ip', '8.8.8.8')
|
||||||
|
via_peer = data.get('via_peer')
|
||||||
|
result = routing_manager.test_routing_connectivity(target_ip, via_peer)
|
||||||
return jsonify(result)
|
return jsonify(result)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error testing routing connectivity: {e}")
|
logger.error(f"Error testing routing connectivity: {e}")
|
||||||
|
|||||||
+29
-58
@@ -388,68 +388,39 @@ class RoutingManager(BaseServiceManager):
|
|||||||
}
|
}
|
||||||
|
|
||||||
def test_routing_connectivity(self, target_ip: str, via_peer: str = None) -> Dict:
|
def test_routing_connectivity(self, target_ip: str, via_peer: str = None) -> Dict:
|
||||||
"""Test routing connectivity"""
|
"""Test routing connectivity by running ping/traceroute in cell-wireguard."""
|
||||||
try:
|
WG = 'cell-wireguard'
|
||||||
results = {}
|
|
||||||
|
|
||||||
# Test basic connectivity
|
def _exec(cmd):
|
||||||
try:
|
result = subprocess.run(
|
||||||
result = subprocess.run(['ping', '-c', '3', '-W', '5', target_ip],
|
['docker', 'exec', WG] + cmd,
|
||||||
capture_output=True, text=True, timeout=30)
|
capture_output=True, text=True, timeout=35
|
||||||
results['ping'] = {
|
)
|
||||||
'success': result.returncode == 0,
|
|
||||||
'output': result.stdout,
|
|
||||||
'error': result.stderr
|
|
||||||
}
|
|
||||||
except Exception as e:
|
|
||||||
results['ping'] = {
|
|
||||||
'success': False,
|
|
||||||
'output': '',
|
|
||||||
'error': str(e)
|
|
||||||
}
|
|
||||||
|
|
||||||
# Test traceroute
|
|
||||||
try:
|
|
||||||
result = subprocess.run(['traceroute', '-m', '10', target_ip],
|
|
||||||
capture_output=True, text=True, timeout=30)
|
|
||||||
results['traceroute'] = {
|
|
||||||
'success': result.returncode == 0,
|
|
||||||
'output': result.stdout,
|
|
||||||
'error': result.stderr
|
|
||||||
}
|
|
||||||
except Exception as e:
|
|
||||||
results['traceroute'] = {
|
|
||||||
'success': False,
|
|
||||||
'output': '',
|
|
||||||
'error': str(e)
|
|
||||||
}
|
|
||||||
|
|
||||||
# Test specific route if via_peer is specified
|
|
||||||
if via_peer:
|
|
||||||
try:
|
|
||||||
# Test route through specific peer
|
|
||||||
result = subprocess.run(['ping', '-c', '3', '-W', '5', '-I', via_peer, target_ip],
|
|
||||||
capture_output=True, text=True, timeout=30)
|
|
||||||
results['peer_route'] = {
|
|
||||||
'success': result.returncode == 0,
|
|
||||||
'output': result.stdout,
|
|
||||||
'error': result.stderr
|
|
||||||
}
|
|
||||||
except Exception as e:
|
|
||||||
results['peer_route'] = {
|
|
||||||
'success': False,
|
|
||||||
'output': '',
|
|
||||||
'error': str(e)
|
|
||||||
}
|
|
||||||
|
|
||||||
return results
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
return {
|
return {
|
||||||
'ping': {'success': False, 'output': '', 'error': str(e)},
|
'success': result.returncode == 0,
|
||||||
'traceroute': {'success': False, 'output': '', 'error': str(e)}
|
'output': result.stdout,
|
||||||
|
'error': result.stderr,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
results = {}
|
||||||
|
try:
|
||||||
|
results['ping'] = _exec(['ping', '-c', '4', '-W', '3', target_ip])
|
||||||
|
except Exception as e:
|
||||||
|
results['ping'] = {'success': False, 'output': '', 'error': str(e)}
|
||||||
|
|
||||||
|
try:
|
||||||
|
results['traceroute'] = _exec(['traceroute', '-m', '10', '-w', '2', target_ip])
|
||||||
|
except Exception as e:
|
||||||
|
results['traceroute'] = {'success': False, 'output': '', 'error': str(e)}
|
||||||
|
|
||||||
|
if via_peer:
|
||||||
|
try:
|
||||||
|
results['peer_route'] = _exec(['ping', '-c', '3', '-W', '3', '-I', via_peer, target_ip])
|
||||||
|
except Exception as e:
|
||||||
|
results['peer_route'] = {'success': False, 'output': '', 'error': str(e)}
|
||||||
|
|
||||||
|
return results
|
||||||
|
|
||||||
def get_routing_logs(self, lines: int = 50) -> Dict:
|
def get_routing_logs(self, lines: int = 50) -> Dict:
|
||||||
"""Get routing and firewall logs"""
|
"""Get routing and firewall logs"""
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -531,7 +531,9 @@ class TestAPIEndpoints(unittest.TestCase):
|
|||||||
mock_routing.add_exit_node.return_value = {'result': 'ok'}
|
mock_routing.add_exit_node.return_value = {'result': 'ok'}
|
||||||
mock_routing.add_bridge_route.return_value = {'result': 'ok'}
|
mock_routing.add_bridge_route.return_value = {'result': 'ok'}
|
||||||
mock_routing.add_split_route.return_value = {'result': 'ok'}
|
mock_routing.add_split_route.return_value = {'result': 'ok'}
|
||||||
mock_routing.test_connectivity.return_value = {'success': True}
|
mock_routing.test_routing_connectivity.return_value = {'ping': {'success': True, 'output': '', 'error': ''}}
|
||||||
|
mock_routing.remove_firewall_rule.return_value = True
|
||||||
|
mock_routing.get_live_iptables.return_value = {'filter': '', 'nat': ''}
|
||||||
mock_routing.get_routing_logs.return_value = {'logs': 'logdata'}
|
mock_routing.get_routing_logs.return_value = {'logs': 'logdata'}
|
||||||
# /api/routing/status (GET)
|
# /api/routing/status (GET)
|
||||||
response = self.client.get('/api/routing/status')
|
response = self.client.get('/api/routing/status')
|
||||||
@@ -618,12 +620,26 @@ class TestAPIEndpoints(unittest.TestCase):
|
|||||||
self.assertEqual(response.status_code, 500)
|
self.assertEqual(response.status_code, 500)
|
||||||
mock_routing.add_split_route.side_effect = None
|
mock_routing.add_split_route.side_effect = None
|
||||||
# /api/routing/connectivity (POST)
|
# /api/routing/connectivity (POST)
|
||||||
response = self.client.post('/api/routing/connectivity', data=json.dumps({'target': '10.0.0.2'}), content_type='application/json')
|
response = self.client.post('/api/routing/connectivity', data=json.dumps({'target_ip': '8.8.8.8'}), content_type='application/json')
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
mock_routing.test_connectivity.side_effect = Exception('fail')
|
mock_routing.test_routing_connectivity.side_effect = Exception('fail')
|
||||||
response = self.client.post('/api/routing/connectivity', data=json.dumps({'target': '10.0.0.2'}), content_type='application/json')
|
response = self.client.post('/api/routing/connectivity', data=json.dumps({'target_ip': '8.8.8.8'}), content_type='application/json')
|
||||||
self.assertEqual(response.status_code, 500)
|
self.assertEqual(response.status_code, 500)
|
||||||
mock_routing.test_connectivity.side_effect = None
|
mock_routing.test_routing_connectivity.side_effect = None
|
||||||
|
# /api/routing/firewall/<id> (DELETE)
|
||||||
|
response = self.client.delete('/api/routing/firewall/fw_1')
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
mock_routing.remove_firewall_rule.return_value = False
|
||||||
|
response = self.client.delete('/api/routing/firewall/fw_999')
|
||||||
|
self.assertEqual(response.status_code, 404)
|
||||||
|
mock_routing.remove_firewall_rule.return_value = True
|
||||||
|
# /api/routing/live-iptables (GET)
|
||||||
|
response = self.client.get('/api/routing/live-iptables')
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
mock_routing.get_live_iptables.side_effect = Exception('fail')
|
||||||
|
response = self.client.get('/api/routing/live-iptables')
|
||||||
|
self.assertEqual(response.status_code, 500)
|
||||||
|
mock_routing.get_live_iptables.side_effect = None
|
||||||
# /api/routing/logs (GET)
|
# /api/routing/logs (GET)
|
||||||
mock_routing.get_logs.return_value = {
|
mock_routing.get_logs.return_value = {
|
||||||
'iptables': 'iptables log data',
|
'iptables': 'iptables log data',
|
||||||
|
|||||||
Reference in New Issue
Block a user