"""GUARDiA P3 배포 완료 검증""" import paramiko, sys, time sys.stdout.reconfigure(encoding='utf-8', errors='replace') c = paramiko.SSHClient(); c.set_missing_host_key_policy(paramiko.AutoAddPolicy()) c.connect('101.79.17.164', username='root', password='1q2w3e!Q', timeout=15) sftp = c.open_sftp() verify = """ import urllib.request, json, asyncio, sys sys.path.insert(0, '/opt/guardia/app') # 1. API 전체 엔드포인트 수 + P3 확인 d = json.loads(urllib.request.urlopen("http://localhost:9001/openapi.json", timeout=10).read()) paths = sorted(d["paths"].keys()) all_kw = { "P1": ["/api/rag","/api/jira","/api/kpi","/api/portal","/api/bi/","/api/workflow"], "P2": ["/api/k8s","/api/sso","/api/predict","/api/slack","/api/brand"], "P3": ["/api/multimodal","/api/learn","/api/insights","/api/container-alerts", "/api/ncloud","/api/billing","/api/servicenow","/api/erp", "/api/kakao","/api/auto-report","/api/benchmark","/api/cohort"], } print(f"=== API 엔드포인트 ===") print(f"전체: {len(paths)}개") for phase, kws in all_kw.items(): matched = [p for p in paths if any(k in p for k in kws)] print(f"{phase}: {len(matched)}개") # 2. DB 테이블 확인 from database import engine from sqlalchemy import text P3_TABLES = [ 'tb_learning_run','tb_container_alert_rule','tb_container_alert_log', 'tb_ncloud_config','tb_subscription','tb_invoice', 'tb_servicenow_config','tb_servicenow_mapping','tb_erp_config', 'tb_kakao_config','tb_kakao_notify_log','tb_report_record', 'tb_report_schedule','tb_benchmark_contrib', ] async def check_tables(): print("\\n=== DB 테이블 (P3) ===") async with engine.connect() as conn: for t in P3_TABLES: try: await conn.execute(text(f"SELECT COUNT(*) FROM {t}")) print(f" ✅ {t}") except Exception as e: print(f" ❌ {t}: {str(e)[:50]}") asyncio.run(check_tables()) # 3. 서비스 상태 import subprocess result = subprocess.run(['systemctl','is-active','guardia'], capture_output=True, text=True) print(f"\\n=== 서비스 상태 ===") print(f"guardia: {result.stdout.strip()}") # 4. 라우터 파일 존재 확인 import os P3_ROUTERS = [ 'multimodal','learning_loop','ai_insights','container_alerts','ncloud', 'billing','servicenow','erp_connector','kakao_notify', 'auto_report','benchmark','cohort_analysis', ] print("\\n=== 라우터 파일 ===") for r in P3_ROUTERS: path = f'/opt/guardia/app/routers/{r}.py' status = '✅' if os.path.exists(path) else '❌ 없음' print(f" {status} {r}.py") print("\\n=== 검증 완료 ===") """ with sftp.open('/tmp/verify_p3_final.py', 'w') as f: f.write(verify) def run(label, cmd, timeout=20): _, o, _ = c.exec_command(cmd, timeout=timeout) print(f'\n[{label}]\n' + o.read().decode('utf-8','replace').strip()[:800]) run('P3 배포 검증', 'cd /opt/guardia/app && /opt/guardia/venv/bin/python3 /tmp/verify_p3_final.py 2>&1; rm /tmp/verify_p3_final.py') sftp.close(); c.close()