fix: LLDP input validation, mgmt_ip early validation, poll timer cleanup, monitor backoff
Lint / Python (flake8) (push) Failing after 41s
Lint / JS (eslint) (push) Successful in 8s
Security / Python Security (bandit) (push) Successful in 42s
Test / Python Tests (pytest) (push) Failing after 1m35s
Lint / Notify on failure (push) Successful in 5s
Lint / Deploy (push) Has been skipped
Lint / Python (flake8) (push) Failing after 41s
Lint / JS (eslint) (push) Successful in 8s
Security / Python Security (bandit) (push) Successful in 42s
Test / Python Tests (pytest) (push) Failing after 1m35s
Lint / Notify on failure (push) Successful in 5s
Lint / Deploy (push) Has been skipped
- app.py: validate server_name from LLDP with fullmatch before use in logs/lookups (prevents log injection) - app.py: validate each mgmt_ip candidate before assigning host_ip (avoids assigning non-IP string that then fails later check) - app.py: log actual exception in link_stats JSON parse error - inspector.html: clear _diagPollTimer in closePanel() so timer doesn't orphan when panel is closed mid-poll - monitor.py: sleep 30s after a monitor loop exception before resuming normal poll interval Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -371,8 +371,8 @@ def api_diagnose_start():
|
||||
return jsonify({'error': 'No link_stats data available'}), 503
|
||||
try:
|
||||
link_data = json.loads(raw)
|
||||
except Exception:
|
||||
logger.error('Failed to parse link_stats JSON in /api/diagnose')
|
||||
except Exception as e:
|
||||
logger.error(f'Failed to parse link_stats JSON in /api/diagnose: {e}')
|
||||
return jsonify({'error': 'Internal data error'}), 500
|
||||
|
||||
switches = link_data.get('unifi_switches', {})
|
||||
@@ -396,6 +396,9 @@ def api_diagnose_start():
|
||||
return jsonify({'error': 'No LLDP neighbor data for this port'}), 400
|
||||
|
||||
server_name = lldp['system_name']
|
||||
if not re.fullmatch(r'[a-zA-Z0-9._-]+', server_name):
|
||||
logger.error(f'Refusing diagnostic: invalid server_name from LLDP: {server_name!r}')
|
||||
return jsonify({'error': 'LLDP neighbor name contains invalid characters'}), 400
|
||||
lldp_port_id = lldp.get('port_id', '')
|
||||
|
||||
# Find matching host + interface in link_stats hosts
|
||||
@@ -421,9 +424,14 @@ def api_diagnose_start():
|
||||
# Resolve host IP from link_stats host data
|
||||
host_ip = (server_ifaces.get(matched_iface) or {}).get('host_ip')
|
||||
if not host_ip:
|
||||
# Fallback: use LLDP mgmt IPs
|
||||
mgmt_ips = lldp.get('mgmt_ips') or []
|
||||
host_ip = mgmt_ips[0] if mgmt_ips else None
|
||||
# Fallback: use first valid IP from LLDP mgmt IPs
|
||||
for candidate in (lldp.get('mgmt_ips') or []):
|
||||
try:
|
||||
ipaddress.ip_address(candidate)
|
||||
host_ip = candidate
|
||||
break
|
||||
except ValueError:
|
||||
continue
|
||||
if not host_ip:
|
||||
return jsonify({'error': 'Cannot determine host IP for SSH'}), 400
|
||||
|
||||
|
||||
@@ -966,6 +966,7 @@ class NetworkMonitor:
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f'Monitor loop error: {e}', exc_info=True)
|
||||
time.sleep(30)
|
||||
|
||||
time.sleep(self.poll_interval)
|
||||
|
||||
|
||||
@@ -231,6 +231,7 @@ function selectPort(el) {
|
||||
}
|
||||
|
||||
function closePanel() {
|
||||
if (_diagPollTimer) { clearInterval(_diagPollTimer); _diagPollTimer = null; }
|
||||
document.getElementById('inspector-panel').classList.remove('open');
|
||||
document.querySelectorAll('.switch-port-block.selected')
|
||||
.forEach(el => el.classList.remove('selected'));
|
||||
|
||||
Reference in New Issue
Block a user