debian 开发,modiqi 修复 cf_load_profile 缺失问题。 9 个命令:cf-api/cf-zone/cf-dns/cf-cache/cf-ssl/cf-fw/cf-pagerule/cf-analytics/cf-hostname 支持多账号、域名自动解析 zone_id。 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
98 lines
2.6 KiB
Bash
Executable file
98 lines
2.6 KiB
Bash
Executable file
#!/usr/bin/env bash
|
||
# cf-lib.sh — Cloudflare CLI 工具共享库
|
||
# 被所有 cf-* 工具 source,不直接执行
|
||
|
||
CF_CONFIG_DIR="${CF_CONFIG_DIR:-$HOME/.config/cloudflare}"
|
||
CF_PROFILE="${CF_PROFILE:-default}"
|
||
CF_API_BASE="https://api.cloudflare.com/client/v4"
|
||
|
||
# 加载 profile 配置
|
||
cf_load_profile() {
|
||
local conf="$CF_CONFIG_DIR/${CF_PROFILE}.conf"
|
||
if [[ ! -f "$conf" ]]; then
|
||
echo "错误: 找不到配置 $conf" >&2
|
||
echo "提示: 复制 config.example 为 ${CF_PROFILE}.conf 并填入凭证" >&2
|
||
return 1
|
||
fi
|
||
source "$conf"
|
||
|
||
# 验证凭证
|
||
if [[ -n "${CF_API_TOKEN:-}" ]]; then
|
||
CF_AUTH_HEADER="Authorization: Bearer $CF_API_TOKEN"
|
||
elif [[ -n "${CF_EMAIL:-}" && -n "${CF_API_KEY:-}" ]]; then
|
||
CF_AUTH_HEADER="X-Auth-Key: $CF_API_KEY"
|
||
CF_AUTH_EMAIL="X-Auth-Email: $CF_EMAIL"
|
||
else
|
||
echo "错误: 配置文件缺少 CF_API_TOKEN 或 CF_EMAIL+CF_API_KEY" >&2
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
# 底层 API 调用
|
||
cf_call() {
|
||
local method="$1" endpoint="$2"
|
||
shift 2
|
||
local url="${CF_API_BASE}${endpoint}"
|
||
local -a headers=(-H "Content-Type: application/json" -H "$CF_AUTH_HEADER")
|
||
[[ -n "${CF_AUTH_EMAIL:-}" ]] && headers+=(-H "$CF_AUTH_EMAIL")
|
||
|
||
curl -sf --max-time 30 -X "$method" "${headers[@]}" "$@" "$url"
|
||
}
|
||
|
||
# 解析 zone: 域名 -> zone_id
|
||
cf_resolve_zone() {
|
||
local input="$1"
|
||
# 如果已经是 32 位 hex,直接返回
|
||
if [[ "$input" =~ ^[0-9a-f]{32}$ ]]; then
|
||
echo "$input"
|
||
return
|
||
fi
|
||
# 查找配置中的别名
|
||
local alias_key="CF_ZONE_${input//[.-]/_}"
|
||
if [[ -n "${!alias_key:-}" ]]; then
|
||
echo "${!alias_key}"
|
||
return
|
||
fi
|
||
# 调 API 查询
|
||
local resp
|
||
resp=$(cf_call GET "/zones?name=$input&status=active" 2>/dev/null)
|
||
local zone_id
|
||
zone_id=$(echo "$resp" | jq -r '.result[0].id // empty')
|
||
if [[ -z "$zone_id" ]]; then
|
||
echo "错误: 找不到域名 $input 对应的 zone" >&2
|
||
return 1
|
||
fi
|
||
echo "$zone_id"
|
||
}
|
||
|
||
# 通用 -p profile 参数解析
|
||
cf_parse_profile() {
|
||
while [[ $# -gt 0 ]]; do
|
||
case "$1" in
|
||
-p|--profile) CF_PROFILE="$2"; shift 2 ;;
|
||
*) break ;;
|
||
esac
|
||
done
|
||
CF_REMAINING_ARGS=("$@")
|
||
}
|
||
|
||
# 格式化输出
|
||
cf_pretty() {
|
||
if command -v jq &>/dev/null; then
|
||
jq "${1:-.}"
|
||
else
|
||
cat
|
||
fi
|
||
}
|
||
|
||
# 错误检查
|
||
cf_check_error() {
|
||
local resp="$1"
|
||
local success
|
||
success=$(echo "$resp" | jq -r '.success // true')
|
||
if [[ "$success" == "false" ]]; then
|
||
echo "API 错误:" >&2
|
||
echo "$resp" | jq -r '.errors[]? | " [\(.code)] \(.message)"' >&2
|
||
return 1
|
||
fi
|
||
}
|