"""Manager Gen6 — 플랫폼 관리: 멀티클러스터·GitOps·배포맵·서비스카탈로그""" import uuid from datetime import datetime from typing import Any, Dict, List, Optional from fastapi import APIRouter, HTTPException, Query from pydantic import BaseModel router = APIRouter(prefix="/api/platform-mgmt", tags=["Platform Management"]) _clusters: Dict[str, Dict] = {} _gitops: Dict[str, Dict] = {} _service_map: Dict[str, Dict] = {} class ClusterCreate(BaseModel): name: str; type: str = "kubernetes" # kubernetes|docker-swarm|bare-metal endpoint: str; region: str = "kr-1"; tags: List[str] = [] class GitOpsCreate(BaseModel): name: str; repo_url: str; branch: str = "main" target_cluster: str; auto_sync: bool = True class ServiceMapEntry(BaseModel): service: str; version: str; cluster: str replicas: int = 1; expose: bool = True # ── 멀티 클러스터 ───────────────────────────────────────────────────────── @router.post("/clusters") async def register_cluster(cluster: ClusterCreate): cid = f"CLU-{uuid.uuid4().hex[:8].upper()}" _clusters[cid] = {**cluster.model_dump(), "id": cid, "status": "connected", "node_count": 3, "registered_at": datetime.utcnow().isoformat()} return _clusters[cid] @router.get("/clusters") async def list_clusters(): clusters = list(_clusters.values()) or [ {"id": "CLU-PROD01", "name": "production", "type": "kubernetes", "node_count": 5, "status": "healthy"}, {"id": "CLU-DEV01", "name": "development", "type": "kubernetes", "node_count": 2, "status": "healthy"}, ] return {"clusters": clusters, "total": len(clusters)} @router.get("/clusters/{cid}/nodes") async def cluster_nodes(cid: str): return {"cluster_id": cid, "nodes": [ {"name": "node-01", "status": "ready", "cpu_usage": 42.1, "mem_usage": 67.8, "pods": 12}, {"name": "node-02", "status": "ready", "cpu_usage": 38.4, "mem_usage": 55.2, "pods": 9}, {"name": "node-03", "status": "ready", "cpu_usage": 51.0, "mem_usage": 71.3, "pods": 14}, ]} @router.get("/clusters/{cid}/workloads") async def cluster_workloads(cid: str): return {"cluster_id": cid, "workloads": [ {"name": "guardia-itsm", "namespace": "default", "replicas": "2/2", "status": "running"}, {"name": "guardia-manager", "namespace": "default", "replicas": "1/1", "status": "running"}, {"name": "postgres", "namespace": "data", "replicas": "1/1", "status": "running"}, ]} # ── GitOps ──────────────────────────────────────────────────────────────── @router.post("/gitops") async def create_gitops(gitops: GitOpsCreate): gid = f"GIT-{uuid.uuid4().hex[:8].upper()}" _gitops[gid] = {**gitops.model_dump(), "id": gid, "status": "synced", "last_sync": datetime.utcnow().isoformat(), "drift": False} return _gitops[gid] @router.get("/gitops") async def list_gitops(): items = list(_gitops.values()) or [ {"id": "GIT-001", "name": "guardia-itsm-deploy", "branch": "main", "status": "synced", "drift": False}, ] return {"gitops": items, "total": len(items)} @router.post("/gitops/{gid}/sync") async def sync_gitops(gid: str): g = _gitops.get(gid) if not g: raise HTTPException(404) g["last_sync"] = datetime.utcnow().isoformat(); g["drift"] = False return {"synced": True, **g} @router.get("/gitops/{gid}/diff") async def gitops_diff(gid: str): return {"gitops_id": gid, "diff": [ {"resource": "Deployment/guardia-itsm", "type": "modified", "fields": ["image.tag"]}, ], "drift_detected": False} # ── 서비스 맵 (배포 위상도) ──────────────────────────────────────────────── @router.post("/service-map") async def register_service(entry: ServiceMapEntry): eid = f"SVC-{uuid.uuid4().hex[:8].upper()}" _service_map[eid] = {**entry.model_dump(), "id": eid, "health": "healthy", "registered_at": datetime.utcnow().isoformat()} return _service_map[eid] @router.get("/service-map") async def get_service_map(): svcs = list(_service_map.values()) or [ {"service": "guardia-itsm", "cluster": "production", "version": "2.1.0", "health": "healthy"}, {"service": "guardia-manager", "cluster": "production", "version": "1.5.0", "health": "healthy"}, {"service": "guardia-messenger", "cluster": "N/A", "version": "1.0.0", "health": "healthy"}, ] return {"services": svcs, "edges": [ {"from": "guardia-manager", "to": "guardia-itsm", "type": "api"}, ]} # ── 배포 파이프라인 관제 ──────────────────────────────────────────────────── @router.get("/pipelines") async def list_pipelines(): return {"pipelines": [ {"id": "PIPE-001", "name": "guardia-itsm-ci", "status": "success", "last_run": datetime.utcnow().isoformat(), "duration_sec": 124}, {"id": "PIPE-002", "name": "guardia-manager-ci", "status": "success", "last_run": datetime.utcnow().isoformat(), "duration_sec": 87}, ]} @router.post("/pipelines/{pid}/trigger") async def trigger_pipeline(pid: str, branch: str = "main"): return {"pipeline_id": pid, "branch": branch, "triggered": True, "run_id": str(uuid.uuid4()), "ts": datetime.utcnow().isoformat()} @router.get("/health") async def health(): return {"status": "ok", "clusters": len(_clusters), "gitops": len(_gitops)}