From 761666aade3692cf231854d5466bfcdd8dff9e92 Mon Sep 17 00:00:00 2001 From: jungwoo choi Date: Sat, 29 Aug 2026 15:34:01 +0900 Subject: [PATCH] =?UTF-8?q?feat(relay):=20agent=20describe=20=EB=A5=BC=20P?= =?UTF-8?q?odDescribeDTO=20=EC=8A=A4=ED=82=A4=EB=A7=88=EB=A1=9C=20?= =?UTF-8?q?=ED=99=95=EC=9E=A5(=EB=A1=9C=EC=BB=AC=20=EC=95=B1=20=ED=8C=8C?= =?UTF-8?q?=EB=93=9C=20=EC=83=81=EC=84=B8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 --- .yakcloud/agent.py | 52 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 8 deletions(-) diff --git a/.yakcloud/agent.py b/.yakcloud/agent.py index f3feb9c..63abc36 100644 --- a/.yakcloud/agent.py +++ b/.yakcloud/agent.py @@ -290,15 +290,51 @@ def _h_kube(action: str, params: dict) -> dict: if action == "describe": pod = params["pod"] p = json.loads(_kubectl(["get", "pod", pod, "-o", "json"]) or "{}") + meta = p.get("metadata", {}) or {} + spec = p.get("spec", {}) or {} st = p.get("status", {}) or {} - containers = [{"name": c.get("name", ""), "image": c.get("image", ""), - "ready": bool(c.get("ready")), "restarts": int(c.get("restartCount", 0)), - "state": next(iter((c.get("state", {}) or {}).keys()), "")} - for c in (st.get("containerStatuses", []) or [])] - conds = [{"type": c.get("type", ""), "status": c.get("status", "")} for c in (st.get("conditions", []) or [])] - return {"name": pod, "phase": st.get("phase", ""), "node": (p.get("spec", {}) or {}).get("nodeName", ""), - "ip": st.get("podIP", ""), "startedAt": st.get("startTime", ""), - "containers": containers, "conditions": conds} + cs = st.get("containerStatuses", []) or [] + spec_by_name = {c.get("name"): c for c in (spec.get("containers", []) or [])} + restarts = sum(int(c.get("restartCount", 0)) for c in cs) + containers = [] + for c in cs: + sc = spec_by_name.get(c.get("name"), {}) or {} + res = sc.get("resources", {}) or {} + req, lim = res.get("requests", {}) or {}, res.get("limits", {}) or {} + state = c.get("state", {}) or {} + skey = next(iter(state.keys()), "") + containers.append({ + "name": c.get("name", ""), "image": c.get("image"), "image_id": c.get("imageID"), + "ready": bool(c.get("ready")), "restarts": int(c.get("restartCount", 0)), + "state": skey, "state_detail": (state.get(skey, {}) or {}).get("reason"), + "ports": [f"{pt.get('containerPort')}/{pt.get('protocol', 'TCP')}" for pt in (sc.get("ports", []) or [])], + "cpu_request": req.get("cpu"), "mem_request": req.get("memory"), + "cpu_limit": lim.get("cpu"), "mem_limit": lim.get("memory"), + "liveness": "설정됨" if sc.get("livenessProbe") else None, + "readiness": "설정됨" if sc.get("readinessProbe") else None, + "env_from": [], "env": [], # 민감할 수 있어 생략(MVP) + "mounts": [{"path": m.get("mountPath", ""), "name": m.get("name", ""), "ro": bool(m.get("readOnly"))} + for m in (sc.get("volumeMounts", []) or [])], + }) + owner = (meta.get("ownerReferences") or [{}])[0] + return { + "summary": { + "name": meta.get("name"), "namespace": meta.get("namespace"), "node": spec.get("nodeName"), + "phase": st.get("phase"), "pod_ip": st.get("podIP"), "host_ip": st.get("hostIP"), + "qos_class": st.get("qosClass"), "service_account": spec.get("serviceAccountName"), + "priority": spec.get("priority"), + "controlled_by": f"{owner.get('kind')}/{owner.get('name')}" if owner.get("kind") else None, + "start_time": st.get("startTime"), "restarts": restarts, + }, + "labels": meta.get("labels", {}) or {}, "annotations": {}, + "containers": containers, + "conditions": [{"type": c.get("type"), "status": c.get("status"), "reason": c.get("reason"), + "last_transition": c.get("lastTransitionTime")} for c in (st.get("conditions", []) or [])], + "node_selector": spec.get("nodeSelector", {}) or {}, "tolerations": [], + "volumes": [{"name": v.get("name", ""), "type": next(iter([k for k in v.keys() if k != "name"]), "")} + for v in (spec.get("volumes", []) or [])], + "events": [], + } if action == "workloads": items = json.loads(_kubectl(["get", "deploy", "-o", "json"]) or "{}").get("items", []) wls = []