guardia-itsm/main.py
2026-06-02 18:48:18 +09:00

474 lines
22 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from contextlib import asynccontextmanager
from fastapi import FastAPI
from fastapi.responses import FileResponse
from fastapi.staticfiles import StaticFiles
from database import init_db
from fastapi.middleware.cors import CORSMiddleware
from routers import (
approvals, assign, audit, auth, cmdb, dashboard, kb, nlcmd, rating, tasks, work,
institutions, shell_scripts, timetable, attachments, notifications,
messenger, ssh, projects, vibe,
ssl_manager, pm, incidents, oncall, batch,
si_projects, si_wbs, si_requirements, si_issues,
si_risks, si_milestones, si_change_requests, si_tests,
agents,
analytics,
ws as ws_router,
timeline,
code_review,
anomaly,
chatbot,
kb_agent,
orchestrator,
predictive,
change,
problem,
capacity,
catalog,
ldap,
pam,
vuln_scan,
report,
metrics,
finops,
tenant_mgmt,
gateway,
license as license_router,
learning,
push as push_router,
scouter as scouter_router,
deliverables,
si_report,
compliance,
jmeter,
public_checklist,
customer_portal,
onboarding,
groupware,
siem,
topology,
portfolio,
infra_ext,
admin as admin_router,
external_api,
export_import,
dr,
network_devices,
autonomous,
rpa,
scraping,
)
@asynccontextmanager
async def lifespan(app: FastAPI):
# 디렉토리 생성
from pathlib import Path
(Path(__file__).parent / "uploads" / "sr_files").mkdir(parents=True, exist_ok=True)
(Path(__file__).parent / "uploads" / "workspaces").mkdir(parents=True, exist_ok=True)
await init_db()
from database import SessionLocal
from core.seed import seed_all
async with SessionLocal() as db:
await seed_all(db)
# 라이선스 상태 확인 (시작 시) — TRIAL 키는 GUARDIA_LICENSE_KEY 없이도 동작
from routers.license import get_license_status
async with SessionLocal() as db:
lic_status = await get_license_status(db)
if lic_status.get("valid"):
edition = lic_status["edition"]
days = lic_status["days_remaining"]
cust = lic_status["customer"]
if lic_status.get("is_trial"):
print(f"[LICENSE] TRIAL 체험판 활성 (D-{days}) - {cust}")
else:
print(f"[LICENSE] {edition} 라이선스 활성 ({days}일 남음) - {cust}")
if lic_status.get("expiry_warning"):
print(f"[LICENSE] 만료 {days}일 남음 - 갱신을 준비하세요.")
elif lic_status.get("expired"):
print("[LICENSE] 라이선스가 만료되었습니다. 갱신이 필요합니다.")
else:
print("[LICENSE] 라이선스 미등록 - /license 에서 무료 체험을 시작하거나 키를 등록하세요.")
# A-1: WebSocket ↔ SSE 통합 패치
from routers.ws import _integrate_with_sse_bus
_integrate_with_sse_bus()
# 백그라운드 스케줄러 시작
from core.scheduler import start_scheduler, init_batch_jobs_from_db
start_scheduler()
await init_batch_jobs_from_db() # DB에서 활성 배치 잡 자동 등록
yield
# 스케줄러 종료
from core.scheduler import stop_scheduler
stop_scheduler()
# F-2: Redis 연결 종료
try:
from core.cache import close_redis
await close_redis()
except Exception:
pass
app = FastAPI(title="GUARDiA ITSM", version="2.0.0", lifespan=lifespan)
@app.middleware("http")
async def add_copyright_header(request, call_next):
response = await call_next(request)
response.headers["X-Powered-By"] = "GUARDiA ITSM 2.0"
response.headers["X-Copyright"] = "Copyright 2026 GUARDiA All Rights Reserved"
return response
# ── F-2: Redis 캐시 종료 훅 ──────────────────────────────────────────────────
# (lifespan의 yield 이후에 실행 — close_redis는 shutdown시 호출)
# ── F-3: Rate Limiting 미들웨어 등록 ─────────────────────────────────────────
from core.ratelimit import setup_rate_limiting
setup_rate_limiting(app)
# ── CORS: 개방망/폐쇄망 자동 전환 ───────────────────────────────────────────
import os as _os
_NETWORK_MODE = _os.environ.get("GUARDIA_NETWORK_MODE", "closed") # closed | open
_ALLOWED_ORIGINS_ENV = _os.environ.get("GUARDIA_ALLOWED_ORIGINS", "")
if _NETWORK_MODE == "open":
# 개방망: 환경변수로 지정된 출처 + 기본 로컬 허용
_extra = [o.strip() for o in _ALLOWED_ORIGINS_ENV.split(",") if o.strip()]
_cors_origins = ["http://localhost:8001", "http://127.0.0.1:8001"] + _extra
_cors_allow_credentials = True
else:
# 폐쇄망 기본값 (localhost only)
_cors_origins = ["http://localhost:8001", "http://127.0.0.1:8001"]
_cors_allow_credentials = False
app.add_middleware(
CORSMiddleware,
allow_origins=_cors_origins,
allow_origin_regex=r"https?://.*" if _NETWORK_MODE == "open" else None,
allow_methods=["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"],
allow_headers=["*"],
allow_credentials=_cors_allow_credentials,
expose_headers=["X-Request-ID", "X-Powered-By"],
max_age=600,
)
app.include_router(auth.router)
app.include_router(dashboard.router)
app.include_router(assign.router)
app.include_router(kb.router)
app.include_router(nlcmd.router)
app.include_router(tasks.router)
app.include_router(approvals.router)
app.include_router(cmdb.router)
app.include_router(audit.router)
app.include_router(work.router)
app.include_router(rating.router)
app.include_router(institutions.router)
app.include_router(shell_scripts.router)
app.include_router(timetable.router)
app.include_router(attachments.router)
app.include_router(notifications.router)
app.include_router(messenger.router)
app.include_router(ssh.router)
app.include_router(projects.router)
app.include_router(vibe.router)
app.include_router(ssl_manager.router)
app.include_router(pm.router)
app.include_router(incidents.router)
app.include_router(oncall.router)
app.include_router(batch.router)
# ── SI 프로젝트 관리 (분석→설계→구현→인도) ─────────────────────────────────
app.include_router(si_projects.router)
app.include_router(si_wbs.router)
app.include_router(si_requirements.router)
app.include_router(si_issues.router)
app.include_router(si_risks.router)
app.include_router(si_milestones.router)
app.include_router(si_change_requests.router)
app.include_router(si_tests.router)
# ── AI 에이전트 (Paperclip × GUARDiA, Ollama 로컬 LLM) ──────────────────────
app.include_router(agents.router)
# ── Analytics (E-2 배포 성공률 트렌드, E-3 엔지니어 워크로드) ─────────────────
app.include_router(analytics.router)
# ── A-1: WebSocket 실시간 대시보드 ───────────────────────────────────────────
app.include_router(ws_router.router)
# ── A-4: 운영 이벤트 타임라인 ────────────────────────────────────────────────
app.include_router(timeline.router)
# ── B-3: 코드 리뷰 에이전트 ──────────────────────────────────────────────────
app.include_router(code_review.router)
# ── B-1: AI 이상 탐지 ────────────────────────────────────────────────────────
app.include_router(anomaly.router)
# ── B-2: 자연어 SR 접수 챗봇 ─────────────────────────────────────────────────
app.include_router(chatbot.router)
# ── B-4: KB 자동 업데이트 에이전트 ───────────────────────────────────────────
app.include_router(kb_agent.router)
# ── B-5: 멀티 에이전트 협업 오케스트레이션 ────────────────────────────────────
app.include_router(orchestrator.router)
# ── B-6: 예측 유지보수 ────────────────────────────────────────────────────────
app.include_router(predictive.router)
# ── C-2: 변경 관리 CAB ───────────────────────────────────────────────────────
app.include_router(change.router)
# ── C-3: Problem Management ─────────────────────────────────────────────────
app.include_router(problem.router)
# ── C-4: 용량 관리 대시보드 ──────────────────────────────────────────────────
app.include_router(capacity.router)
# ── C-5: 서비스 카탈로그 ──────────────────────────────────────────────────────
app.include_router(catalog.router)
# ── D-1: LDAP/AD 연동 ────────────────────────────────────────────────────────
app.include_router(ldap.router)
# ── D-3: 특권 접근 관리 (PAM) ─────────────────────────────────────────────────
app.include_router(pam.router)
# ── D-4: 보안 취약점 자동 스캔 ───────────────────────────────────────────────
app.include_router(vuln_scan.router)
# ── E-1: 월별 리포트 자동 생성 ───────────────────────────────────────────────
app.include_router(report.router)
# ── E-4: Grafana 연동 (Prometheus 메트릭) ─────────────────────────────────
app.include_router(metrics.router)
# ── E-5: FinOps 비용 분석 ────────────────────────────────────────────────
app.include_router(finops.router)
# ── F-1: 멀티테넌트 데이터 격리 ──────────────────────────────────────────
from middleware.tenant import TenantMiddleware
app.add_middleware(TenantMiddleware)
app.include_router(tenant_mgmt.router)
# ── F-5: OpenAPI 외부 연동 게이트웨이 ────────────────────────────────────
app.include_router(gateway.router)
# ── Self-Improving Learning Loop ──────────────────────────────────────────
app.include_router(learning.router)
# ── 라이선스 관리 ──────────────────────────────────────────────────────────
app.include_router(license_router.router)
# ── G-10: PWA Push 알림 ──────────────────────────────────────────────────
app.include_router(push_router.router)
# Scouter APM
app.include_router(scouter_router.router)
# PMS — 산출물 + 보고서
app.include_router(deliverables.router)
app.include_router(si_report.router)
# 준수성 점검 (시큐어코딩/웹접근성/개인정보보호)
app.include_router(compliance.router)
# 성능 테스트 (JMeter JTL 분석 + 내장 부하 테스트)
app.include_router(jmeter.router)
# 공공기관 필수 기능 체크리스트
app.include_router(public_checklist.router)
# 추가 기능
app.include_router(customer_portal.router) # 고객 셀프서비스 포털
app.include_router(onboarding.router) # 온보딩 가이드 챗봇
app.include_router(groupware.router) # 그룹웨어 전자결재 연동
app.include_router(siem.router) # SIEM 보안 이벤트 연동
app.include_router(topology.router) # 네트워크 토폴로지 시각화
app.include_router(portfolio.router) # 포트폴리오 + 리소스 관리
app.include_router(infra_ext.router) # Zero Trust + K8s + ERP
app.include_router(admin_router.router) # GS인증: About + 백업/복구 + 에러코드
app.include_router(external_api.router) # 개방망 외부 API (API Key 인증)
app.include_router(export_import.router) # 폐쇄망 ↔ 개방망 Export/Import
app.include_router(dr.router) # DR 자동화 (Failover/RTO-RPO/백업검증)
app.include_router(network_devices.router) # 네트워크 장비 관리 (스위치/라우터/방화벽)
app.include_router(autonomous.router) # 자율 운영 (자동처리/승인 게이트)
app.include_router(rpa.router) # RPA 봇 (Validation 학습 + 자동화 실행)
app.include_router(scraping.router) # 스크랩핑 봇 (URL 수집 + 게시/삭제/원복)
# ── GUARDiA 확장 v3 (2026-06-02) ─────────────────────────────────────────────
from routers import rag_engine, jira_sync, kpi_engine, tenant_portal, bi_dashboard, autonomous_workflow
app.include_router(rag_engine.router) # RAG 하이브리드 검색 + Ollama 답변
app.include_router(jira_sync.router) # Jira 양방향 SR 동기화
app.include_router(kpi_engine.router) # KPI 정의·계산·신호등
app.include_router(tenant_portal.router) # 테넌트 셀프서비스 포털
app.include_router(bi_dashboard.router) # BI 대시보드 (트렌드·히트맵·퍼널)
app.include_router(autonomous_workflow.router) # 자율 워크플로우 엔진
# ── GUARDiA 확장 v3 P2 (2026-06-02) ──────────────────────────────────────────
from routers import kubernetes, sso_provider, predictive_ops, slack_connector, white_label
app.include_router(kubernetes.router) # K8s 클러스터 에이전트리스 관리
app.include_router(sso_provider.router) # SSO 통합 인증 (SAML/OIDC)
app.include_router(predictive_ops.router) # 예측 운영 분석 (SLA/SR급증/서버장애)
app.include_router(slack_connector.router) # Slack 연동 (알림/명령어)
app.include_router(white_label.router) # 화이트라벨 브랜딩
# ── GUARDiA 확장 v3 P3 (2026-06-02) ──────────────────────────────────────────
from routers import (
multimodal, learning_loop, ai_insights, container_alerts, ncloud,
billing, servicenow, erp_connector, kakao_notify,
auto_report, benchmark, cohort_analysis,
)
app.include_router(multimodal.router) # 멀티모달 AI (이미지/로그 분석)
app.include_router(learning_loop.router) # Self-Improving Learning Loop
app.include_router(ai_insights.router) # AI 운영 인사이트 + 주간 리포트
app.include_router(container_alerts.router) # 컨테이너 이상 감지 → SR 자동 생성
app.include_router(ncloud.router) # NCloud 서버/LB/스토리지 관리
app.include_router(billing.router) # 구독·과금·청구서
app.include_router(servicenow.router) # ServiceNow CMDB/Incident 연동
app.include_router(erp_connector.router) # ERP/그룹웨어 연동
app.include_router(kakao_notify.router) # 카카오 알림톡
app.include_router(auto_report.router) # 자동 보고서 생성·다운로드
app.include_router(benchmark.router) # 기관 간 익명 벤치마킹
app.include_router(cohort_analysis.router) # 코호트 분석
# ── GUARDiA 고급 확장 (2026-06-02) — 20개 신규 라우터 ─────────────────────────
from routers import (
# CMDB 자동 발견
autodiscovery, snmp_discovery, dependency_map, config_inventory,
# NL 쿼리
nlquery, op_assistant, query_history,
# 구성 드리프트
drift_detection, golden_config, auto_remediation,
# 멀티클라우드
multicloud, aws_connector, cost_optimizer, cloud_migration,
# 공공기관 특화
narasajang, public_api_hub, isp_support, network_zone, k_cloud, e_procurement,
)
app.include_router(autodiscovery.router) # CMDB SSH 자동 발견
app.include_router(snmp_discovery.router) # SNMP 네트워크 장비 발견
app.include_router(dependency_map.router) # 서비스 의존성 자동 매핑
app.include_router(config_inventory.router) # 서버 구성 인벤토리 자동 수집
app.include_router(nlquery.router) # Text-to-SQL 자연어 쿼리
app.include_router(op_assistant.router) # 대화형 운영 어시스턴트
app.include_router(query_history.router) # 쿼리 이력·즐겨찾기·공유
app.include_router(drift_detection.router) # 구성 드리프트 감지
app.include_router(golden_config.router) # 골든 구성 정의·버전 관리
app.include_router(auto_remediation.router) # 승인 기반 자동 교정
app.include_router(multicloud.router) # 멀티클라우드 통합 관제
app.include_router(aws_connector.router) # AWS EC2/RDS 연동
app.include_router(cost_optimizer.router) # 클라우드 비용 최적화 AI
app.include_router(cloud_migration.router) # On-prem → K-Cloud 전환
app.include_router(narasajang.router) # 나라장터 조달 연동
app.include_router(public_api_hub.router) # 공공 API 허브 (data.go.kr)
app.include_router(isp_support.router) # ISP 수립 지원
app.include_router(network_zone.router) # 행정망/인터넷망 분리 관리
app.include_router(k_cloud.router) # K-Cloud 공공 클라우드 전환
app.include_router(e_procurement.router) # 전자조달 계약·검수·납품
# ── Upstage OCR 연동 (2026-06-02) ────────────────────────────────────────────
from routers import upstage_ocr, doc_workflow, doc_template
app.include_router(upstage_ocr.router) # Upstage Document AI OCR 엔진
app.include_router(doc_workflow.router) # 문서 워크플로우 (계약서/납품서/청구서 등)
app.include_router(doc_template.router) # 문서 추출 템플릿 관리
# ── 개방망 보안 헤더 미들웨어 ────────────────────────────────────────────────
@app.middleware("http")
async def add_security_headers(request, call_next):
response = await call_next(request)
response.headers["X-Content-Type-Options"] = "nosniff"
response.headers["X-Frame-Options"] = "DENY"
response.headers["X-XSS-Protection"] = "1; mode=block"
response.headers["Referrer-Policy"] = "strict-origin-when-cross-origin"
if _os.environ.get("GUARDIA_NETWORK_MODE") == "open":
response.headers["Strict-Transport-Security"] = "max-age=31536000; includeSubDomains"
response.headers["Content-Security-Policy"] = (
"default-src 'self'; script-src 'self' 'unsafe-inline'; "
"style-src 'self' 'unsafe-inline'; img-src 'self' data:;"
)
return response
@app.get("/topology")
async def topology_page():
return FileResponse("static/index.html")
app.mount("/static", StaticFiles(directory="static"), name="static")
@app.get("/")
async def index():
return FileResponse("static/index.html")
@app.get("/customer")
async def customer():
return FileResponse("static/customer.html")
@app.get("/login")
async def login_page():
return FileResponse("static/login.html")
@app.get("/change-password")
async def change_password_page():
return FileResponse("static/change-password.html")
@app.get("/agents")
async def agents_page():
return FileResponse("static/agents.html")
@app.get("/incidents")
async def incidents_page():
return FileResponse("static/incidents.html")
@app.get("/ssl")
async def ssl_page():
return FileResponse("static/ssl.html")
@app.get("/pm")
async def pm_page():
return FileResponse("static/pm.html")
@app.get("/oncall")
async def oncall_page():
return FileResponse("static/oncall.html")
@app.get("/batch")
async def batch_page():
return FileResponse("static/batch.html")
@app.get("/vibe")
async def vibe_page():
return FileResponse("static/vibe.html")
@app.get("/si")
async def si_page():
return FileResponse("static/si.html")
@app.get("/license")
async def license_page():
return FileResponse("static/license.html")