core: Inventar/Placement, Konfig-Validierung, CLI, HTTP-API, LiteLLM-Konfiguration, Beispiel-Skills
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
"""Kommandozeile: serve, validate, inventory, placement, registry export."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import yaml
|
||||
|
||||
|
||||
def main(argv: list[str] | None = None) -> int:
|
||||
parser = argparse.ArgumentParser(prog="knaster")
|
||||
sub = parser.add_subparsers(dest="cmd", required=True)
|
||||
|
||||
p_serve = sub.add_parser("serve", help="Router-Service starten")
|
||||
p_serve.add_argument("--host", default="0.0.0.0")
|
||||
p_serve.add_argument("--port", type=int, default=8080)
|
||||
|
||||
p_val = sub.add_parser("validate", help="Konfiguration prüfen")
|
||||
p_val.add_argument("--root", default=".")
|
||||
p_val.add_argument("--site", default="knaster")
|
||||
|
||||
p_inv = sub.add_parser("inventory", help="Inventar")
|
||||
inv_sub = p_inv.add_subparsers(dest="inv_cmd", required=True)
|
||||
p_col = inv_sub.add_parser("collect", help="lokales System auslesen")
|
||||
p_col.add_argument("--name")
|
||||
|
||||
p_plan = sub.add_parser("placement", help="Placement-Plan")
|
||||
p_plan.add_argument("--inventory", required=True)
|
||||
p_plan.add_argument("--catalog", default="catalog")
|
||||
|
||||
p_reg = sub.add_parser("registry", help="Registry")
|
||||
reg_sub = p_reg.add_subparsers(dest="reg_cmd", required=True)
|
||||
reg_sub.add_parser("export", help="effektiven Stand (inkl. Laufzeitzustand) als YAML ausgeben")
|
||||
|
||||
args = parser.parse_args(argv)
|
||||
|
||||
if args.cmd == "serve":
|
||||
import uvicorn
|
||||
|
||||
uvicorn.run("knaster.api:create_app", factory=True, host=args.host, port=args.port)
|
||||
return 0
|
||||
|
||||
if args.cmd == "validate":
|
||||
from .validate import validate_repo
|
||||
|
||||
issues = validate_repo(Path(args.root), args.site)
|
||||
for level, msg in issues:
|
||||
print(f"{level.upper():8} {msg}")
|
||||
errors = [i for i in issues if i[0] == "error"]
|
||||
print(f"{len(errors)} Fehler, {len(issues) - len(errors)} Warnungen")
|
||||
return 1 if errors else 0
|
||||
|
||||
if args.cmd == "inventory":
|
||||
from .inventory.profile import collect
|
||||
|
||||
print(yaml.safe_dump({"nodes": [collect(args.name).model_dump()]}, sort_keys=False, allow_unicode=True))
|
||||
return 0
|
||||
|
||||
if args.cmd == "placement":
|
||||
from .inventory.placement import load_catalog, load_nodes, plan
|
||||
|
||||
roles, models = load_catalog(args.catalog)
|
||||
result = plan(load_nodes(args.inventory), roles, models)
|
||||
print(yaml.safe_dump(result.model_dump(), sort_keys=False, allow_unicode=True))
|
||||
return 1 if any(not u.optional for u in result.unplaced) else 0
|
||||
|
||||
if args.cmd == "registry":
|
||||
from .registry import Registry
|
||||
from .settings import Settings
|
||||
from .store import Store
|
||||
|
||||
settings = Settings.from_env()
|
||||
registry = Registry.from_file(settings.site_dir / "registry.yaml", Store(settings.db_url))
|
||||
print(yaml.safe_dump(registry.export(), sort_keys=False, allow_unicode=True))
|
||||
return 0
|
||||
return 2
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user