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

@ -32,6 +32,7 @@ YakCloud 콘솔 API로 **데이터소스 리컨실 + 워크로드 배포 + 바
- `yakcloud scale <wl> <n>` replicas - `yakcloud scale <wl> <n>` replicas
- `yakcloud set <wl> --image/--port/--health/--cpu/--mem/--path/--rewrite` - `yakcloud set <wl> --image/--port/--health/--cpu/--mem/--path/--rewrite`
- `yakcloud env <wl> KEY=VAL … [--secret KEY] [--unset KEY]` - `yakcloud env <wl> KEY=VAL … [--secret KEY] [--unset KEY]`
- `yakcloud datasource ls` (=`source ls`) 클러스터에서 이용 가능한 소스 목록(이름·타입·내부/외부·상태·플랜)
- `yakcloud source add <name> <type> [plan]` · `yakcloud source rm <name>` - `yakcloud source add <name> <type> [plan]` · `yakcloud source rm <name>`
- `yakcloud bind <wl> <source> <alias>` · `yakcloud unbind <wl> <alias>` - `yakcloud bind <wl> <source> <alias>` · `yakcloud unbind <wl> <alias>`

View File

@ -332,6 +332,7 @@ yakcloud $VERSION — YakCloud 프로젝트 CLI
scale <wl> <n> replicas 변경 scale <wl> <n> replicas 변경
set <wl> --image/--port/--health/--cpu/--mem/--path/--rewrite set <wl> --image/--port/--health/--cpu/--mem/--path/--rewrite
env <wl> KEY=VAL … [--secret KEY] [--unset KEY] env <wl> KEY=VAL … [--secret KEY] [--unset KEY]
datasource ls 클러스터에서 이용 가능한 소스 목록(이름·타입·내부/외부·상태)
source add <name> <type> [plan] | source rm <name> source add <name> <type> [plan] | source rm <name>
bind <wl> <source> <alias> | unbind <wl> <alias> bind <wl> <source> <alias> | unbind <wl> <alias>
env: YAKCLOUD_URL, YAKCLOUD_TOKEN(배포토큰 yakd_…), (선택) YAKCLOUD_CLUSTER env: YAKCLOUD_URL, YAKCLOUD_TOKEN(배포토큰 yakd_…), (선택) YAKCLOUD_CLUSTER
@ -354,6 +355,7 @@ case "${1:-help}" in
login) cmd_login ;; login) cmd_login ;;
config) cmd_config ;; config) cmd_config ;;
logout) cmd_logout ;; logout) cmd_logout ;;
datasource|ds) shift; ctl source "$@" ;;
domain|scale|set|env|source|bind|unbind) ctl "$@" ;; domain|scale|set|env|source|bind|unbind) ctl "$@" ;;
upgrade|self-update) cmd_upgrade ;; upgrade|self-update) cmd_upgrade ;;
version|-v|--version) echo "yakcloud $VERSION" ;; version|-v|--version) echo "yakcloud $VERSION" ;;

View File

@ -5,7 +5,7 @@
scale/set/env/domain 은 이미 배포돼 있으면 재빌드 없이 라이브 반영(PATCH)한다. scale/set/env/domain 은 이미 배포돼 있으면 재빌드 없이 라이브 반영(PATCH)한다.
env: YAKCLOUD_URL, YAKCLOUD_TOKEN(배포토큰 yakd_…), (선택) YAKCLOUD_CLUSTER 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 from __future__ import annotations
@ -240,6 +240,33 @@ def cmd_source(a) -> None:
print(" ✓ requires 에서 제거: %s (관련 binds 정리). 'yakcloud deploy' 로 반영" % a.name) 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: def cmd_bind(a) -> None:
m = load_manifest(); w = find_workload(m, a.workload) m = load_manifest(); w = find_workload(m, a.workload)
if not any(r.get("name") == a.source for r in (m.get("requires", []) or [])): 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.add_argument("--unset", action="append", help="이 KEY 제거")
e.set_defaults(fn=cmd_env) 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) 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 = 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) 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) sor = sosub.add_parser("rm"); sor.add_argument("name"); sor.set_defaults(fn=cmd_source)