hy-app-monitor/testbox/scripts/import-nacos-configs.py

109 lines
3.3 KiB
Python
Executable File

#!/usr/bin/env python3
from __future__ import annotations
import os
from pathlib import Path
import sys
import time
import urllib.parse
import urllib.request
ROOT = Path(__file__).resolve().parents[1]
ENV_PATH = ROOT / ".env"
def load_env(path: Path) -> dict[str, str]:
values: dict[str, str] = {}
if not path.exists():
return values
for raw in path.read_text(encoding="utf-8").splitlines():
line = raw.strip()
if not line or line.startswith("#") or "=" not in line:
continue
key, value = line.split("=", 1)
values[key.strip()] = value.strip().strip('"').strip("'")
return values
ENV = {**load_env(ENV_PATH), **os.environ}
NACOS_BASE_URL = ENV.get("NACOS_BASE_URL", "http://127.0.0.1:8848").rstrip("/")
NAMESPACE_ID = ENV.get("NACOS_NAMESPACE_ID", "RedCircleServiceTest")
NAMESPACE_NAME = ENV.get("NACOS_NAMESPACE_NAME", NAMESPACE_ID)
JAVA_SOURCE_DIR = Path(ENV.get("JAVA_SOURCE_DIR", str(ROOT / "sources" / "chatapp3-java")))
def request(method: str, path: str, data: dict[str, str] | None = None) -> str:
url = f"{NACOS_BASE_URL}{path}"
body = None
headers = {"User-Agent": "chatapp-testbox/1.0"}
if data is not None:
body = urllib.parse.urlencode(data).encode("utf-8")
headers["Content-Type"] = "application/x-www-form-urlencoded; charset=utf-8"
req = urllib.request.Request(url, data=body, headers=headers, method=method)
with urllib.request.urlopen(req, timeout=15) as resp:
return resp.read().decode("utf-8", errors="replace")
def wait_nacos() -> None:
for _ in range(90):
try:
text = request("GET", "/nacos/v1/console/health/readiness")
if "UP" in text or "OK" in text:
return
except Exception:
pass
time.sleep(2)
raise RuntimeError("nacos readiness timeout")
def ensure_namespace() -> None:
data = {
"customNamespaceId": NAMESPACE_ID,
"namespaceName": NAMESPACE_NAME,
"namespaceDesc": "single-node chatapp testbox",
}
try:
request("POST", "/nacos/v1/console/namespaces", data)
except Exception as exc:
print(f"warn: namespace create skipped: {exc}", file=sys.stderr)
def publish_config(group: str, data_id: str, content: str) -> None:
payload = {
"tenant": NAMESPACE_ID,
"group": group,
"dataId": data_id,
"type": "yaml" if data_id.endswith((".yml", ".yaml")) else "text",
"content": content,
}
result = request("POST", "/nacos/v1/cs/configs", payload).strip()
if result.lower() == "false":
raise RuntimeError(f"nacos rejected config {group}/{data_id}")
def main() -> int:
config_root = JAVA_SOURCE_DIR / "nacos_config"
if not config_root.is_dir():
raise RuntimeError(f"missing nacos_config: {config_root}")
wait_nacos()
ensure_namespace()
count = 0
for path in sorted(config_root.glob("*/*")):
if not path.is_file():
continue
group = path.parent.name
data_id = path.name
publish_config(group, data_id, path.read_text(encoding="utf-8"))
count += 1
print(f"published {group}/{data_id}")
print(f"nacos import ok: namespace={NAMESPACE_ID} configs={count}")
return 0
if __name__ == "__main__":
raise SystemExit(main())