import json from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from app.core.security import decrypt_secret from app.models.router import Router, RouterCredential, CredentialMethod, RouterMethod from app.services.mikrotik.client_rest import MikroTikRESTClient from app.services.mikrotik.client_ssh import MikroTikSSHClient from app.services.mikrotik.client_api import MikroTikAPIClient async def build_client(session: AsyncSession, router_id: int): rres = await session.execute(select(Router).where(Router.id == router_id)) router = rres.scalar_one_or_none() if not router: return None cres = await session.execute(select(RouterCredential).where(RouterCredential.router_id == router_id)) creds = cres.scalars().all() # wybór: preferowana metoda albo auto: REST -> API -> SSH order = [] pref = router.preferred_method if pref == RouterMethod.REST: order = [CredentialMethod.REST] elif pref == RouterMethod.API: order = [CredentialMethod.API] elif pref == RouterMethod.SSH: order = [CredentialMethod.SSH] else: order = [CredentialMethod.REST, CredentialMethod.API, CredentialMethod.SSH] cred_by_method = {c.method: c for c in creds} for m in order: c = cred_by_method.get(m) if not c: continue secret = decrypt_secret(c.secret_encrypted) extra = {} try: extra = json.loads(c.extra_json or "{}") except Exception: extra = {} if m == CredentialMethod.REST: base_url = f"https://{router.host}:{router.port_rest}" if extra.get("scheme") in ("http", "https"): base_url = f"{extra['scheme']}://{router.host}:{router.port_rest}" return MikroTikRESTClient(base_url, c.username, secret, router.verify_ssl) if m == CredentialMethod.SSH: return MikroTikSSHClient(router.host, router.port_ssh, c.username, secret) if m == CredentialMethod.API: return MikroTikAPIClient(router.host, router.port_api, c.username, secret, use_ssl=bool(extra.get("ssl", False))) return None