added multi node functionality
This commit is contained in:
78
app/services/pls.py
Normal file
78
app/services/pls.py
Normal file
@@ -0,0 +1,78 @@
|
||||
"""PLS API client for cluster and per-node discovery."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from urllib.parse import urlsplit, urlunsplit
|
||||
|
||||
import httpx
|
||||
|
||||
from app.config import PLS_AUTH_BACKEND, PLS_BASE_URL, PLS_PASSWORD, PLS_USERNAME, PLS_VERIFY_TLS
|
||||
|
||||
_token: str | None = None
|
||||
|
||||
|
||||
def _base_url_for_host(host: str | None = None) -> str:
|
||||
if not host:
|
||||
return PLS_BASE_URL.rstrip("/")
|
||||
parts = urlsplit(PLS_BASE_URL)
|
||||
return urlunsplit((parts.scheme, host, parts.path.rstrip("/"), "", ""))
|
||||
|
||||
|
||||
async def _login() -> str | None:
|
||||
global _token
|
||||
if _token:
|
||||
return _token
|
||||
if not PLS_USERNAME or not PLS_PASSWORD:
|
||||
return None
|
||||
|
||||
try:
|
||||
async with httpx.AsyncClient(timeout=5, verify=PLS_VERIFY_TLS) as client:
|
||||
response = await client.post(
|
||||
f"{_base_url_for_host()}/auth/login",
|
||||
json={
|
||||
"username": PLS_USERNAME,
|
||||
"password": PLS_PASSWORD,
|
||||
"backend": PLS_AUTH_BACKEND,
|
||||
},
|
||||
)
|
||||
response.raise_for_status()
|
||||
data = response.json()
|
||||
_token = data.get("access_token")
|
||||
return _token
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
|
||||
async def _get(path: str, host: str | None = None) -> dict | list | None:
|
||||
token = await _login()
|
||||
if not token:
|
||||
return None
|
||||
|
||||
headers = {"Authorization": f"Bearer {token}"}
|
||||
url = f"{_base_url_for_host(host)}/{path.lstrip('/')}"
|
||||
try:
|
||||
async with httpx.AsyncClient(timeout=5, verify=PLS_VERIFY_TLS) as client:
|
||||
response = await client.get(url, headers=headers)
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
|
||||
def node_host(node_name: str) -> str:
|
||||
return node_name.split("@", 1)[1] if "@" in node_name else node_name
|
||||
|
||||
|
||||
async def get_cluster_status() -> dict | None:
|
||||
data = await _get("data_layer/cluster/status")
|
||||
return data if isinstance(data, dict) else None
|
||||
|
||||
|
||||
async def get_system_info(host: str | None = None) -> dict | None:
|
||||
data = await _get("system/info", host=host)
|
||||
return data if isinstance(data, dict) else None
|
||||
|
||||
|
||||
async def get_services(host: str | None = None) -> list[dict]:
|
||||
data = await _get("services", host=host)
|
||||
return data if isinstance(data, list) else []
|
||||
Reference in New Issue
Block a user