from flask import Blueprint, current_app, render_template, request, make_response, jsonify from api.http_client import HttpClient from operations.get_instances import get_organization, get_instances from operations.get_services import get_services, get_service_detail from runner import load_config bp = Blueprint("main", __name__) def _mask(s): if not s or len(s) < 8: return "" return s[:4] + "*" * (len(s) - 8) + s[-4:] def _client_id(token): import base64, json try: parts = token.split(".") if len(parts) >= 2: payload = base64.urlsafe_b64decode(parts[1] + "==") return json.loads(payload).get("ClientID", "") except Exception: pass return "" def _token_info(token): import base64, json try: parts = token.split(".") if len(parts) >= 2: payload = base64.urlsafe_b64decode(parts[1] + "==") d = json.loads(payload) return { "email": d.get("email", ""), "company": d.get("company_name", ""), "client_id": d.get("ClientID", ""), } except Exception: pass return {} @bp.route("/", methods=["GET", "POST"]) def index(): env_token = current_app.config["NUBES_API_TOKEN"] user_token = request.cookies.get("token") or request.form.get("token") or "" active_token = user_token or env_token org = None error = None action = request.form.get("action", "") if action == "clear": resp = make_response(render_template("index.html", organization=None, error=None, env_token_masked=_mask(env_token), has_user_token=False)) resp.delete_cookie("token") return resp if action == "save": user_token = request.form.get("token", "") active_token = user_token or env_token resp = make_response() resp.set_cookie("token", user_token, max_age=60*60*24*365) # redirect to GET resp.headers["Location"] = "/" resp.status_code = 302 return resp services = [] instances = [] config = {} if active_token: try: client = HttpClient( current_app.config["NUBES_API_ENDPOINT"], active_token, ) org = get_organization(client) raw_svc = get_services(client) services = sorted(raw_svc, key=lambda s: (s.get("svcId", 0), s.get("svc", ""))) # инфраструктурные сервисы (платформа/среда) infra_ids = {2, 12, 21, 22, 25, 26, 29, 110, 150} raw_inst = get_instances(client) instances = [i for i in raw_inst if i.get("explainedStatus") not in ("deleted", "not created") and i.get("serviceId") in infra_ids] instances.sort(key=lambda i: (0 if i.get("serviceId") == 19 else 1, i.get("displayName", ""))) # group by service type instance_groups = {} for i in instances: svc_name = i.get("svc", "Прочее") instance_groups.setdefault(svc_name, []).append(i) config = load_config() except Exception as e: error = str(e) return render_template("index.html", organization=org, error=error, env_token_masked=_mask(env_token), has_user_token=bool(user_token), client_id=_client_id(active_token), token_info=_token_info(active_token), instance_groups=instance_groups) @bp.route("/api/operations/") def api_operations(svc_id): env_token = current_app.config["NUBES_API_TOKEN"] user_token = request.cookies.get("token") or "" active_token = user_token or env_token try: client = HttpClient(current_app.config["NUBES_API_ENDPOINT"], active_token) detail = get_service_detail(client, svc_id) ops = detail.get("operations", []) return jsonify({"svc": detail.get("svc", ""), "operations": ops}) except Exception as e: return jsonify({"error": str(e)}), 500