55 lines
2.1 KiB
Python
55 lines
2.1 KiB
Python
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
|