switchos support

This commit is contained in:
Mateusz Gruszczyński
2026-04-13 11:59:17 +02:00
parent 5163704b59
commit 4d2356f60b
28 changed files with 1142 additions and 330 deletions

View File

@@ -6,6 +6,7 @@ import paramiko
from sqlalchemy.orm import Session
from app.models.router import Router
from app.services.swos_beta_service import swos_beta_service
class RouterService:
@@ -47,18 +48,25 @@ class RouterService:
return client
def export(self, router: Router, global_ssh_key: str | None = None) -> str:
if router.device_type != 'routeros':
raise ValueError('Export tekstowy jest dostępny tylko dla RouterOS.')
client = self._connect(router, global_ssh_key)
_, stdout, _ = client.exec_command("/export")
output = stdout.read().decode("utf-8", errors="ignore")
_, stdout, _ = client.exec_command('/export')
output = stdout.read().decode('utf-8', errors='ignore')
client.close()
return output
def binary_backup(self, router: Router, backup_name: str, local_path: str, global_ssh_key: str | None = None) -> str:
def binary_backup(self, router: Router, backup_name: str, local_path: str, global_ssh_key: str | None = None, global_settings=None) -> str:
if router.device_type == 'switchos':
downloaded = swos_beta_service.download_backup_for_router(router, global_settings)
Path(local_path).write_bytes(downloaded.content)
return local_path
client = self._connect(router, global_ssh_key)
_, stdout, _ = client.exec_command(f"/system backup save name={backup_name}")
_, stdout, _ = client.exec_command(f'/system backup save name={backup_name}')
stdout.channel.recv_exit_status()
sftp = client.open_sftp()
remote_file = f"{backup_name}.backup"
remote_file = f'{backup_name}.backup'
sftp.get(remote_file, local_path)
try:
sftp.remove(remote_file)
@@ -69,6 +77,8 @@ class RouterService:
return local_path
def upload_backup(self, router: Router, local_backup_path: str, global_ssh_key: str | None = None):
if router.device_type != 'routeros':
raise ValueError('Przywracanie plików jest dostępne tylko dla RouterOS.')
client = self._connect(router, global_ssh_key)
sftp = client.open_sftp()
target_name = Path(local_backup_path).name
@@ -76,64 +86,84 @@ class RouterService:
sftp.close()
client.close()
def probe_connection(self, router: Router, global_ssh_key: str | None = None):
def _probe_routeros_connection(self, router: Router, global_ssh_key: str | None = None):
tested_at = datetime.utcnow()
try:
client = self._connect(router, global_ssh_key)
_, stdout, _ = client.exec_command("/system resource print without-paging")
resource_output = stdout.read().decode("utf-8", errors="ignore")
_, stdout, _ = client.exec_command("/system identity print")
identity_output = stdout.read().decode("utf-8", errors="ignore")
_, stdout, _ = client.exec_command('/system resource print without-paging')
resource_output = stdout.read().decode('utf-8', errors='ignore')
_, stdout, _ = client.exec_command('/system identity print')
identity_output = stdout.read().decode('utf-8', errors='ignore')
client.close()
model = "Unknown"
uptime = "Unknown"
hostname = "Unknown"
version = "Unknown"
model = 'Unknown'
uptime = 'Unknown'
hostname = 'Unknown'
version = 'Unknown'
for line in resource_output.splitlines():
if "board-name" in line:
model = line.split(":", 1)[1].strip()
if "uptime" in line:
uptime = line.split(":", 1)[1].strip()
if "version" in line:
version = line.split(":", 1)[1].strip()
if 'board-name' in line:
model = line.split(':', 1)[1].strip()
if 'uptime' in line:
uptime = line.split(':', 1)[1].strip()
if 'version' in line:
version = line.split(':', 1)[1].strip()
for line in identity_output.splitlines():
if "name" in line:
hostname = line.split(":", 1)[1].strip()
if 'name' in line:
hostname = line.split(':', 1)[1].strip()
return {
"success": True,
"tested_at": tested_at,
"model": model,
"uptime": uptime,
"hostname": hostname,
"version": version,
"error": None,
'success': True,
'tested_at': tested_at,
'model': model,
'uptime': uptime,
'hostname': hostname,
'version': version,
'error': None,
'transport': 'ssh',
'server': None,
'auth_mode': 'ssh',
'http_status': None,
'backup_available': None,
}
except Exception as exc:
return {
"success": False,
"tested_at": tested_at,
"model": "Unknown",
"uptime": "Unknown",
"hostname": router.name,
"version": None,
"error": str(exc),
'success': False,
'tested_at': tested_at,
'model': 'Unknown',
'uptime': 'Unknown',
'hostname': router.name,
'version': None,
'error': str(exc),
'transport': 'ssh',
'server': None,
'auth_mode': 'ssh',
'http_status': None,
'backup_available': None,
}
def probe_connection(self, router: Router, global_ssh_key: str | None = None, global_settings=None):
if router.device_type == 'switchos':
return swos_beta_service.probe_router(router, global_settings)
return self._probe_routeros_connection(router, global_ssh_key)
def _store_connection_result(self, db: Session, router: Router, result: dict):
router.last_connection_status = result["success"]
router.last_connection_tested_at = result["tested_at"]
router.last_connection_error = result.get("error")
router.last_connection_hostname = result.get("hostname")
router.last_connection_model = result.get("model")
router.last_connection_version = result.get("version")
router.last_connection_uptime = result.get("uptime")
router.last_connection_status = result['success']
router.last_connection_tested_at = result['tested_at']
router.last_connection_error = result.get('error')
router.last_connection_hostname = result.get('hostname')
router.last_connection_model = result.get('model')
router.last_connection_version = result.get('version')
router.last_connection_uptime = result.get('uptime')
router.last_connection_transport = result.get('transport')
router.last_connection_server = result.get('server')
router.last_connection_auth_mode = result.get('auth_mode')
router.last_connection_http_status = result.get('http_status')
router.last_connection_backup_available = result.get('backup_available')
db.add(router)
db.commit()
db.refresh(router)
return result
def test_connection(self, db: Session, router: Router, global_ssh_key: str | None = None):
result = self.probe_connection(router, global_ssh_key)
def test_connection(self, db: Session, router: Router, global_settings):
result = self.probe_connection(router, global_settings.global_ssh_key, global_settings)
return self._store_connection_result(db, router, result)