fix(cdn): resolve a pull zone when the API answers with a bare array
The zone lookup used `.Items // .` to accept both response shapes. It accepts neither: indexing an array with a string is an error in jq, not a null, so `//` never substitutes and the whole expression aborts with "Cannot index array with string". The listing endpoint answers with a bare array for this account, so every purge of cran.allianceswisspass.devxy.io has been failing. Reindex pipelines reported failure at the purge step while the reindex itself had succeeded, and that zone kept serving objects the rebuild replaced. Also surfaced by the same failure: - The listing response was used without checking the HTTP status, so an auth or rate-limit error was reported as a missing hostname. - A hostname matching several zones silently purged only the first. Verified against stubbed array-shaped and object-shaped responses; the previous script fails the array case.
This commit is contained in:
parent
aba2063ea0
commit
6b5d7d16c5
1 changed files with 29 additions and 4 deletions
|
|
@ -47,12 +47,31 @@ resolve_zone_id() {
|
||||||
fi
|
fi
|
||||||
|
|
||||||
response_file=$(mktemp)
|
response_file=$(mktemp)
|
||||||
curl -sS -o "${response_file}" \
|
local status
|
||||||
-H "AccessKey: ${api_key}" \
|
status=$(
|
||||||
"https://api.bunny.net/pullzone"
|
curl -sS -o "${response_file}" -w '%{http_code}' \
|
||||||
|
-H "AccessKey: ${api_key}" \
|
||||||
|
"https://api.bunny.net/pullzone?perPage=1000"
|
||||||
|
)
|
||||||
|
|
||||||
|
if [[ "${status}" != "200" ]]; then
|
||||||
|
echo "Listing BunnyCDN pull zones failed with HTTP ${status}:" >&2
|
||||||
|
head -c 500 "${response_file}" >&2
|
||||||
|
echo >&2
|
||||||
|
rm -f "${response_file}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# The endpoint answers with a bare array on some accounts and a paginated
|
||||||
|
# object on others. `.Items // .` looks like it covers both but does not:
|
||||||
|
# indexing an array with a string is an *error*, and `//` only substitutes
|
||||||
|
# for null, so the array case aborted with
|
||||||
|
# "Cannot index array with string" and the zone was never purged.
|
||||||
zone_id=$(
|
zone_id=$(
|
||||||
jq -r --arg hostname "${zone}" \
|
jq -r --arg hostname "${zone}" \
|
||||||
'(.Items // .)[] | select(any(.Hostnames[]?; .Value == $hostname)) | .Id' \
|
'(if type == "object" then (.Items // []) else . end)[]
|
||||||
|
| select(any(.Hostnames[]?; .Value == $hostname))
|
||||||
|
| .Id' \
|
||||||
"${response_file}"
|
"${response_file}"
|
||||||
)
|
)
|
||||||
rm -f "${response_file}"
|
rm -f "${response_file}"
|
||||||
|
|
@ -62,6 +81,12 @@ resolve_zone_id() {
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Two zones sharing a hostname would purge only whichever jq emitted first.
|
||||||
|
if [[ $(wc -l <<<"${zone_id}") -gt 1 ]]; then
|
||||||
|
echo "Hostname ${zone} matched multiple pull zones: ${zone_id//$'\n'/ }" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
echo "${zone_id}"
|
echo "${zone_id}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue