cli: 'yakcloud datasource ls'(=source ls) — 클러스터 이용가능 소스 목록(이름·타입·내부/외부·상태·플랜)

This commit is contained in:
2026-08-27 18:46:40 +09:00
parent d19242029f
commit eb58df76d2
3 changed files with 33 additions and 2 deletions

View File

@ -5,7 +5,7 @@
scale/set/env/domain 은 이미 배포돼 있으면 재빌드 없이 라이브 반영(PATCH)한다.
env: YAKCLOUD_URL, YAKCLOUD_TOKEN(배포토큰 yakd_…), (선택) YAKCLOUD_CLUSTER
서브커맨드: info · domain · scale · set · env · source · bind · unbind
서브커맨드: info · domain · scale · set · env · source(ls/add/rm) · bind · unbind
"""
from __future__ import annotations
@ -240,6 +240,33 @@ def cmd_source(a) -> None:
print(" ✓ requires 에서 제거: %s (관련 binds 정리). 'yakcloud deploy' 로 반영" % a.name)
def cmd_source_ls(a) -> None:
"""클러스터에서 이용 가능한 데이터 소스 목록 — 이름·타입·내부/외부·상태·플랜."""
need_api()
m = (yaml.safe_load(open(MANIFEST)) if os.path.exists(MANIFEST) else {}) or {}
c = resolve_cluster(cluster_ref(m))
svcs = unwrap(api("GET", "/clusters/%s/services" % c["id"])) or []
if not svcs:
print("클러스터 '%s' — 데이터 소스 없음. 콘솔 '데이터 소스' 또는 'yakcloud source add' 로 추가."
% (c.get("name") or c["id"]))
return
used = {r.get("name") for r in (m.get("requires", []) or [])}
rows = []
for s in sorted(svcs, key=lambda x: (x.get("type", ""), x.get("name", ""))):
mode = s.get("mode")
loc = "내부" if mode == "LOCAL" else "외부" if mode == "REMOTE" else (mode or "?")
mark = "" if s.get("name") in used else " "
rows.append((mark, s.get("name", "?"), s.get("type", "?"), loc,
s.get("status", "?"), s.get("size") or s.get("plan") or "-"))
wn = max([len(r[1]) for r in rows] + [4])
wt = max([len(r[2]) for r in rows] + [4])
print("클러스터 '%s' 데이터 소스 (%d)" % (c.get("name") or c["id"], len(rows)))
print(" %-*s %-*s %-4s %-8s 플랜" % (wn, "이름", wt, "타입", "위치", "상태"))
for mark, name, typ, loc, st, plan in rows:
print(" %s %-*s %-*s %-4s %-8s %s" % (mark, wn, name, wt, typ, loc, st, plan))
print("\n ✓=매니페스트 requires 에 이미 있음 · 바인딩: yakcloud bind <workload> <이름> <alias>")
def cmd_bind(a) -> None:
m = load_manifest(); w = find_workload(m, a.workload)
if not any(r.get("name") == a.source for r in (m.get("requires", []) or [])):
@ -326,8 +353,9 @@ def build_parser() -> argparse.ArgumentParser:
e.add_argument("--unset", action="append", help="이 KEY 제거")
e.set_defaults(fn=cmd_env)
so = sub.add_parser("source", help="데이터 소스(requires) 추가/삭제")
so = sub.add_parser("source", help="데이터 소스: ls(클러스터 목록) · add · rm")
sosub = so.add_subparsers(dest="action", required=True)
sol = sosub.add_parser("ls", help="클러스터에서 이용 가능한 소스 목록"); sol.set_defaults(fn=cmd_source_ls)
soa = sosub.add_parser("add"); soa.add_argument("name"); soa.add_argument("type")
soa.add_argument("plan", nargs="?", default="small"); soa.set_defaults(fn=cmd_source)
sor = sosub.add_parser("rm"); sor.add_argument("name"); sor.set_defaults(fn=cmd_source)