fix(cdn): resolve a pull zone when the API answers with a bare array (#178)
## Motivation
Every reindex reports `failure` at the purge step:
```
Purging BunnyCDN pull zone 3857050
Purged pull zone 3857050 (HTTP 204)
jq: error (at /tmp/tmp.eFPFmO:0): Cannot index array with string "Items"
Could not find BunnyCDN pull zone for hostname cran.allianceswisspass.devxy.io
```
`cran.rpkgs.com` purges fine. The Alliance zone never has, so it is still serving objects that rebuilds replaced, behind a ~370-day `cache_expiration_time`.
## The defect
```sh
jq -r '(.Items // .)[] | ...'
```
This was meant to accept both response shapes. It accepts neither: indexing an array with a string is an **error** in jq, not a null, so `//` never gets the chance to substitute and the whole expression aborts. The listing endpoint answers with a bare array for this account, so the lookup has always failed.
## Change
- Select the array explicitly by type instead of relying on `//` to absorb an error.
- Check the HTTP status of the listing call. It was previously used unconditionally, so an auth or rate-limit failure surfaced as "could not find hostname" — pointing at the wrong thing entirely.
- Fail when a hostname matches multiple zones rather than silently purging whichever jq emitted first.
- Request `perPage=1000`, so a paginated response cannot silently truncate the zone list.
## Verification
Ran the current `main` script and the fixed one against a stubbed `curl` returning an array-shaped listing:
```
=== BEFORE (main) ===
Purged pull zone 3857050 (HTTP 204)
jq: error (at ...): Cannot index array with string ("Items")
Could not find BunnyCDN pull zone for hostname cran.allianceswisspass.devxy.io
=== AFTER ===
Purged pull zone 3857050 (HTTP 204)
Purging BunnyCDN pull zone 222
Purged pull zone 222 (HTTP 204)
```
The jq expression was also checked against both an array-shaped and an object-shaped (`.Items`) response; the old one fails the array case, the new one handles both. `shellcheck` clean.
Reviewed-on: #178
This commit is contained in:
parent
f3077677d7
commit
85295a9495
1 changed files with 29 additions and 4 deletions
|
|
@ -47,12 +47,31 @@ resolve_zone_id() {
|
|||
fi
|
||||
|
||||
response_file=$(mktemp)
|
||||
curl -sS -o "${response_file}" \
|
||||
-H "AccessKey: ${api_key}" \
|
||||
"https://api.bunny.net/pullzone"
|
||||
local status
|
||||
status=$(
|
||||
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=$(
|
||||
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}"
|
||||
)
|
||||
rm -f "${response_file}"
|
||||
|
|
@ -62,6 +81,12 @@ resolve_zone_id() {
|
|||
exit 1
|
||||
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}"
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue