From a4f7fa750a940dd07c99ed3ca18efa290de45374 Mon Sep 17 00:00:00 2001 From: xiaolipro <2357729423@qq.com> Date: Tue, 8 Sep 2026 14:38:28 +0800 Subject: [PATCH] =?UTF-8?q?feat=EF=BC=9A=E6=94=AF=E6=8C=81jsonc?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/sync-to-consul.sh | 104 ++++++++++++++++++++++++++++++++------ 1 file changed, 88 insertions(+), 16 deletions(-) diff --git a/scripts/sync-to-consul.sh b/scripts/sync-to-consul.sh index c21d129..bed8387 100644 --- a/scripts/sync-to-consul.sh +++ b/scripts/sync-to-consul.sh @@ -22,18 +22,90 @@ IDWMS_DIR="${ROOT}/idwms" need() { command -v "$1" >/dev/null || { echo "FAIL: 需要 $1"; exit 1; }; } need kubectl need curl +need python3 command -v envsubst >/dev/null || { echo "FAIL: 需要 envsubst(apt install gettext-base)"; exit 1; } -# JSON 校验:优先 python3(runner 主机通常有),其次 jq -json_ok() { - local f="$1" - if command -v python3 >/dev/null; then - python3 -c 'import json,sys; json.load(open(sys.argv[1],encoding="utf-8"))' "$f" - elif command -v jq >/dev/null; then - jq empty "$f" - else - echo "FAIL: 需要 python3 或 jq 校验 JSON"; return 1 - fi +# 按 JSONC 校验(允许 //、/* */、尾逗号);通过后原样写入 Consul,不剥离注释 +jsonc_check() { + python3 - "$1" <<'PY' +import json, sys + +def strip_jsonc(text: str) -> str: + out = [] + i, n = 0, len(text) + in_str = escape = False + while i < n: + c = text[i] + if in_str: + out.append(c) + if escape: + escape = False + elif c == "\\": + escape = True + elif c == '"': + in_str = False + i += 1 + continue + if c == '"': + in_str = True + out.append(c) + i += 1 + continue + if c == "/" and i + 1 < n: + nxt = text[i + 1] + if nxt == "/": + i += 2 + while i < n and text[i] not in "\r\n": + i += 1 + continue + if nxt == "*": + i += 2 + while i + 1 < n and not (text[i] == "*" and text[i + 1] == "/"): + i += 1 + i = min(i + 2, n) + continue + out.append(c) + i += 1 + cleaned = [] + s = "".join(out) + i, n = 0, len(s) + in_str = escape = False + while i < n: + c = s[i] + if in_str: + cleaned.append(c) + if escape: + escape = False + elif c == "\\": + escape = True + elif c == '"': + in_str = False + i += 1 + continue + if c == '"': + in_str = True + cleaned.append(c) + i += 1 + continue + if c == ",": + j = i + 1 + while j < n and s[j] in " \t\r\n": + j += 1 + if j < n and s[j] in "]}": + i += 1 + continue + cleaned.append(c) + i += 1 + return "".join(cleaned) + +path = sys.argv[1] +raw = open(path, encoding="utf-8").read() +try: + json.loads(strip_jsonc(raw)) +except json.JSONDecodeError as e: + print(f"FAIL: {path} 不是合法 JSONC: {e}", file=sys.stderr) + sys.exit(1) +PY } secret_b64() { @@ -127,18 +199,18 @@ for name in "${TARGETS[@]}"; do envsubst '${MYSQL_ROOT_PASSWORD} ${REDIS_PASSWORD} ${RABBITMQ_DEFAULT_PASS} ${ELASTIC_PASSWORD} ${JWT_SECRET_KEY}' \ <"$src" >"${TMP}/${name}.json" - if ! json_ok "${TMP}/${name}.json" 2>/dev/null; then - echo "FAIL: ${name}.json 渲染后不是合法 JSON" - exit 1 - fi - - # 禁止未替换的占位符漏网 + # 禁止未替换的占位符漏网(注释里的 ${...} 也会拦) if grep -qE '\$\{[A-Z0-9_]+\}' "${TMP}/${name}.json"; then echo "FAIL: ${name}.json 仍有未替换占位符:" grep -E '\$\{[A-Z0-9_]+\}' "${TMP}/${name}.json" || true exit 1 fi + # JSONC 校验通过后,原样 PUT(保留注释,便于和 git 对照排查) + if ! jsonc_check "${TMP}/${name}.json"; then + exit 1 + fi + put_kv "idwms/${name}" "${TMP}/${name}.json" case "$name" in