mirror of
https://github.com/eduardogsilva/routerfleet.git
synced 2025-06-23 10:18:33 +02:00
fetch and store router information
This commit is contained in:
parent
130bb25dca
commit
e40eb2fdca
10 changed files with 325 additions and 3 deletions
161
routerlib/router_functions.py
Normal file
161
routerlib/router_functions.py
Normal file
|
@ -0,0 +1,161 @@
|
|||
import json
|
||||
import datetime
|
||||
from django.utils import timezone
|
||||
from router_manager.models import RouterInformation, Router
|
||||
from routerlib.functions import connect_to_ssh
|
||||
|
||||
|
||||
def _parse_routeros_key_value_output(output: str) -> dict:
|
||||
"""
|
||||
Parse lines like "key: value" into a dict.
|
||||
Skip blank lines or lines starting with '[' (the prompt).
|
||||
"""
|
||||
data = {}
|
||||
# Normalize and split
|
||||
for raw_line in output.replace('\r', '').splitlines():
|
||||
line = raw_line.strip()
|
||||
# skip empty or prompt lines
|
||||
if not line or line.startswith('['):
|
||||
continue
|
||||
if ':' not in line:
|
||||
continue
|
||||
key, val = line.split(':', 1)
|
||||
data[key.strip()] = val.strip()
|
||||
return data
|
||||
|
||||
|
||||
def get_router_information(router_information: RouterInformation):
|
||||
"""
|
||||
Connect to the router, retrieve info, and store it in RouterInformation.
|
||||
"""
|
||||
router = router_information.router
|
||||
field_max_length = 100
|
||||
success = False
|
||||
error_message = ''
|
||||
|
||||
try:
|
||||
ssh = connect_to_ssh(router.address, router.port, router.username, router.password, router.ssh_key)
|
||||
json_data = {}
|
||||
|
||||
if router.router_type in ('routeros', 'routeros-branded'):
|
||||
for cmd in ['/system resource print', '/system routerboard print']:
|
||||
stdin, stdout, stderr = ssh.exec_command(cmd)
|
||||
raw = stdout.read().decode('utf-8', errors='ignore')
|
||||
parsed = _parse_routeros_key_value_output(raw)
|
||||
json_data[cmd] = parsed
|
||||
|
||||
rb = json_data['/system routerboard print']
|
||||
sr = json_data['/system resource print']
|
||||
|
||||
if sr:
|
||||
router_information.model_name = sr.get('board-name', '')[:field_max_length]
|
||||
router_information.os_version = sr.get('version', '')[:field_max_length]
|
||||
router_information.architecture = sr.get('architecture-name', '')[:field_max_length]
|
||||
router_information.cpu = sr.get('cpu', '')[:field_max_length]
|
||||
success = True
|
||||
if rb:
|
||||
router_information.model_version = rb.get('model', '')[:field_max_length]
|
||||
router_information.serial_number = rb.get('serial-number', '')[:field_max_length]
|
||||
router_information.firmware_version = rb.get('current-firmware', '')[:field_max_length]
|
||||
success = True
|
||||
if not success:
|
||||
return False, 'Failed to retrieve router information'
|
||||
|
||||
elif router.router_type == 'openwrt':
|
||||
stdin, stdout, stderr = ssh.exec_command('cat /etc/os-release')
|
||||
osrel = {}
|
||||
for line in stdout.read().decode('utf-8').splitlines():
|
||||
if '=' in line:
|
||||
k, v = line.split('=', 1)
|
||||
osrel[k] = v.strip().strip('"')
|
||||
json_data['cat /etc/os-release'] = osrel
|
||||
|
||||
# hostname
|
||||
stdin, stdout, stderr = ssh.exec_command('uci get system.@system[0].hostname')
|
||||
hostname = stdout.read().decode('utf-8').strip()
|
||||
json_data['uci get system.@system[0].hostname'] = hostname
|
||||
|
||||
# architecture
|
||||
stdin, stdout, stderr = ssh.exec_command('uname -m')
|
||||
arch = stdout.read().decode('utf-8').strip()
|
||||
json_data['uname -m'] = arch
|
||||
|
||||
# fallback serial (MAC of eth0)
|
||||
stdin, stdout, stderr = ssh.exec_command('cat /sys/class/net/eth0/address')
|
||||
mac = stdout.read().decode('utf-8').strip()
|
||||
json_data['cat /sys/class/net/eth0/address'] = mac
|
||||
|
||||
if osrel:
|
||||
router_information.model_name = osrel.get('OPENWRT_DEVICE_MODEL', '')[:field_max_length]
|
||||
router_information.model_version = osrel.get('VERSION_ID', '')[:field_max_length]
|
||||
router_information.serial_number = mac[:field_max_length]
|
||||
router_information.os_version = osrel.get('VERSION', '')[:field_max_length]
|
||||
router_information.firmware_version = osrel.get('OPENWRT_RELEASE', '')[:field_max_length]
|
||||
router_information.architecture = arch[:field_max_length]
|
||||
success = True
|
||||
if not success:
|
||||
return False, 'Failed to retrieve router information'
|
||||
else:
|
||||
return False, f"Router type not supported: {router.get_router_type_display()}"
|
||||
|
||||
if success:
|
||||
router_information.success = True
|
||||
router_information.error = False
|
||||
router_information.retry_count = 0
|
||||
router_information.next_retry = None
|
||||
router_information.error_message = ''
|
||||
router_information.last_retrieval = timezone.now()
|
||||
router_information.json_data = json.dumps(json_data)
|
||||
router_information.save()
|
||||
|
||||
except Exception as e:
|
||||
success = False
|
||||
error_message = str(e)
|
||||
|
||||
finally:
|
||||
try:
|
||||
ssh.close()
|
||||
except:
|
||||
pass
|
||||
|
||||
return success, error_message
|
||||
|
||||
|
||||
def update_router_information(router_information: RouterInformation):
|
||||
max_retry = 3
|
||||
retry_minutes = 5
|
||||
|
||||
success = False
|
||||
error_message = ''
|
||||
|
||||
if router_information.retry_count > max_retry:
|
||||
router_information.error = True
|
||||
router_information.success = False
|
||||
router_information.next_retry = None
|
||||
router_information.retry_count = 0
|
||||
router_information.last_retrieval = timezone.now()
|
||||
if router_information.error_message:
|
||||
router_information.error_message += f"\nMax retries reached for {router_information.router.name}"
|
||||
else:
|
||||
router_information.error_message = f"Max retries reached for {router_information.router.name}"
|
||||
router_information.save()
|
||||
return False, router_information.error_message
|
||||
try:
|
||||
success, error_message = get_router_information(router_information)
|
||||
except Exception as e:
|
||||
success = False
|
||||
error_message = f"Failed to update router information for {router_information.router.name}. Exception: {e}"
|
||||
|
||||
if not success:
|
||||
router_information.error = True
|
||||
router_information.success = False
|
||||
router_information.next_retry = timezone.now() + datetime.timedelta(minutes=retry_minutes)
|
||||
router_information.retry_count += 1
|
||||
router_information.last_retrieval = timezone.now()
|
||||
if error_message:
|
||||
router_information.error_message = error_message
|
||||
else:
|
||||
router_information.error_message = f"Failed to update router information for {router_information.router.name}"
|
||||
router_information.save()
|
||||
|
||||
return success, error_message
|
Loading…
Add table
Add a link
Reference in a new issue