diff --git a/site/api/auth.py b/site/api/auth.py index 6f06712..2bb4bb7 100644 --- a/site/api/auth.py +++ b/site/api/auth.py @@ -32,27 +32,48 @@ def get_token(): return request.cookies.get("token") or current_app.config["NUBES_API_TOKEN"] -def get_client(): - """HttpClient с автоопределением стенда. +def _make_client(*, use_polygon): + """Фабрика HttpClient — ЕДИНСТВЕННОЕ место где выбирается endpoint. - Если POLYGON_ENDPOINT задан → направить ВСЕ запросы в polygon. - Реальный NUBES_API_TOKEN остаётся нетронутым — polygon его не проверяет. + Args: + use_polygon: если True и POLYGON_ENDPOINT задан → polygon. + Если False → всегда реальный API (для чтения сервисов/инстансов). - Иначе: - - Если NUBES_API_ENDPOINT — известный стенд (STANDS) → detect_endpoint() - - Если кастомный URL → использовать напрямую + Returns: + HttpClient с правильным endpoint и токеном. """ - polygon = current_app.config.get("POLYGON_ENDPOINT", "") - if polygon: - return HttpClient(polygon, get_token()) - token = get_token() + + # Режим полигона — только если разрешено и переменная задана + if use_polygon: + polygon = current_app.config.get("POLYGON_ENDPOINT", "") + if polygon: + return HttpClient(polygon, token) + + # Реальный API: автоопределение или NUBES_API_ENDPOINT endpoint = current_app.config["NUBES_API_ENDPOINT"] if endpoint in STANDS: endpoint = detect_endpoint(token) or endpoint return HttpClient(endpoint, token) +def get_client(): + """HttpClient для ОПЕРАЦИЙ (create/modify/delete/run/poll). + + Если POLYGON_ENDPOINT задан → polygon. + Иначе → автоопределение реального стенда. + """ + return _make_client(use_polygon=True) + + +def get_real_client(): + """HttpClient для ЧТЕНИЯ (сервисы, список инстансов). + + ВСЕГДА реальный API, даже при POLYGON_ENDPOINT. + """ + return _make_client(use_polygon=False) + + def get_client_id(): """Извлечь ClientID из payload JWT-токена (base64url, без проверки подписи). diff --git a/site/app.py b/site/app.py index 6e07c06..c0571ad 100644 --- a/site/app.py +++ b/site/app.py @@ -32,7 +32,7 @@ from routes.api_scenario_defs import bp_defs as api_scenario_defs_bp # Версия — показывается в топбаре UI. Меняется при КАЖДОМ изменении кода. # Нужна для фильтрации истории (пользователь видит только записи своей версии). -VERSION = "1.2.27" +VERSION = "1.2.28" # Flask-приложение с Jinja2-шаблонами из папки templates/ app = Flask(__name__, template_folder="templates", static_folder="static") diff --git a/site/routes/api_test.py b/site/routes/api_test.py index 4847f3b..2f0fcb8 100644 --- a/site/routes/api_test.py +++ b/site/routes/api_test.py @@ -31,7 +31,7 @@ import json import fcntl from api.http_client import HttpClient, detect_endpoint, stand_name -from api.auth import get_token, get_client, get_client_id, get_stand, get_token_info +from api.auth import get_token, get_client, get_real_client, get_client_id, get_stand, get_token_info from api.utils import find_uid, uid_from_location from operations.get_services import get_services, get_service_detail from operations.get_instances import get_instances @@ -103,7 +103,7 @@ def _unique_display_name(client, requested_name): @bp.route("/api/services") def api_services(): try: - raw = get_services(get_client()) + raw = get_services(get_real_client()) svc_list = [{"svcId": s["svcId"], "svc": s["svc"], "svcExtendedName": s.get("svcExtendedName", "")} for s in raw] svc_list.sort(key=lambda s: s["svcId"]) return jsonify(svc_list) diff --git a/site/routes/main.py b/site/routes/main.py index 3f44f31..df9e81a 100644 --- a/site/routes/main.py +++ b/site/routes/main.py @@ -11,7 +11,7 @@ GET /api/operations/ — операции и autotest-инста from flask import Blueprint, current_app, render_template, request, make_response, jsonify, redirect from api.http_client import HttpClient, detect_endpoint, create_client, stand_name -from api.auth import get_token, get_client_id, get_token_info, get_token_masked, get_client, get_stand +from api.auth import get_token, get_client_id, get_token_info, get_token_masked, get_client, get_real_client, get_stand from operations.get_instances import get_organization, get_instances from operations.get_services import get_services, get_service_detail from operations.service_list import load_service_ids @@ -105,24 +105,26 @@ def index(): config["service_ids"] = [] stand = "?" if active_token: - # get_client — учитывает POLYGON_ENDPOINT - client = get_client() + # Сервисы — ВСЕГДА из реального API (метаданные) + real_client = get_real_client() + # Инстансы — из polygon если POLYGON_ENDPOINT задан + inst_client = get_client() endpoint = current_app.config["NUBES_API_ENDPOINT"] stand = get_stand() - if client: + if real_client: try: - # Организация — инстанс с serviceId=19 - org = get_organization(client) + # Организация — инстанс с serviceId=19 (из реального API) + org = get_organization(real_client) - # Все сервисы — сортировка по svcId - raw_svc = get_services(client) + # Все сервисы — из реального API + raw_svc = get_services(real_client) services = sorted(raw_svc, key=lambda s: (s.get("svcId", 0), s.get("svc", ""))) - # Инфраструктурные инстансы — только определённые serviceId + # Инфраструктурные инстансы — из polygon или реального API # 19=Org, 21=vDC, 22=NSX-T, 25=External IP, 26=vApp, 29=vDC Group # 2=Template, 12=S3, 110=?, 150=K8s infra_ids = {2, 12, 21, 22, 25, 26, 29, 110, 150} - raw_inst = get_instances(client) + raw_inst = get_instances(inst_client) instances = [i for i in raw_inst if i.get("explainedStatus") not in ("deleted", "not created") and i.get("serviceId") in infra_ids] @@ -168,20 +170,22 @@ def api_operations(svc_id): active_token = user_token or env_token try: - # get_client — учитывает POLYGON_ENDPOINT - client = get_client() + # Сервисы — ВСЕГДА из реального API (метаданные) + real_client = get_real_client() + # Инстансы — из polygon если POLYGON_ENDPOINT задан + inst_client = get_client() endpoint = current_app.config["NUBES_API_ENDPOINT"] # Детали сервиса: список операций (modify, delete, suspend, ...) - detail = get_service_detail(client, svc_id) + detail = get_service_detail(real_client, svc_id) ops = detail.get("operations", []) # Трекер: наши autotest-инстансы (изолирован по пользователю и стенду) tracked = tracker_list(get_client_id(), stand_name(endpoint)) tracked_by_uid = {t["instanceUid"]: t for t in tracked if t["svcId"] == svc_id} - # Все инстансы из облака - instances = get_instances(client) + # Все инстансы — из polygon или реального API + instances = get_instances(inst_client) nubes_uids = {i["instanceUid"] for i in instances} svc_instances = []