fix(scripts/ops): #3140 ADDENDUM — PRUNE_ZONE_DOMAIN covers staging.moleculesai.app #3148

Merged
devops-engineer merged 1 commits from feat/prune-cf-e2e-dns into main 2026-06-22 04:15:25 +00:00
2 changed files with 39 additions and 15 deletions
+18 -7
View File
@@ -1,7 +1,8 @@
#!/usr/bin/env bash
# prune_cf_e2e_dns.sh — targeted, fail-closed cleanup of disposable E2E DNS
# records that accumulate under the moleculesai.app zone and exhaust the
# Cloudflare DNS record quota (code 81045).
# records that accumulate under the moleculesai.app zone (typically the
# staging.moleculesai.app subdomain) and exhaust the Cloudflare DNS record
# quota (code 81045).
#
# Why this exists: staging E2E harnesses create DNS records for slugs like
# e2e-smoke-<date>-<run>-<uuid> and e2e-tmpl-<rand> (see
@@ -16,6 +17,8 @@
# - Records whose full name matches
# e2e-smoke-*.<zone-domain>
# e2e-tmpl-*.<zone-domain>
# - Multiple zone domains may be supplied as a comma-separated list
# (e.g. "moleculesai.app,staging.moleculesai.app").
# - Records older than --min-age-hours / PRUNE_MIN_AGE_HOURS (default 24)
# so in-flight runs are not touched.
# - Anything else is kept untouched.
@@ -33,7 +36,8 @@
# PRUNE_MIN_AGE_HOURS=<int> — default minimum age in hours (default: 24).
# MAX_DELETE_PCT=<int> — refuse to delete more than this percentage of
# matched ephemeral records (default: 50).
# PRUNE_ZONE_DOMAIN=<domain> — zone domain to anchor matches (default: moleculesai.app).
# PRUNE_ZONE_DOMAIN=<domain> — comma-separated zone domain(s) to anchor
# matches (default: staging.moleculesai.app).
#
# Exit codes:
# 0 — dry-run completed or prune executed successfully
@@ -45,7 +49,10 @@ set -euo pipefail
DRY_RUN=1
MIN_AGE_HOURS="${PRUNE_MIN_AGE_HOURS:-24}"
MAX_DELETE_PCT="${MAX_DELETE_PCT:-50}"
ZONE_DOMAIN="${PRUNE_ZONE_DOMAIN:-moleculesai.app}"
ZONE_DOMAIN="${PRUNE_ZONE_DOMAIN:-}"
if [ -z "$ZONE_DOMAIN" ]; then
ZONE_DOMAIN="staging.moleculesai.app"
fi
while [ $# -gt 0 ]; do
case "$1" in
@@ -246,15 +253,19 @@ from datetime import datetime, timezone, timedelta
min_age = timedelta(hours=int(os.environ["MIN_AGE_HOURS"]))
zone_domain = os.environ["ZONE_DOMAIN"]
zone_domains = [d.strip() for d in zone_domain.split(",") if d.strip()]
now = datetime.now(timezone.utc)
# Conservative: only the two known disposable E2E prefixes, anchored to the
# configured zone domain so similarly-named records in other zones never match.
# Conservative: only the two known disposable E2E prefixes, anchored to one
# of the configured zone domains so similarly-named records in other zones
# never match. Multiple zone domains may be supplied as a comma-separated
# list (e.g. "moleculesai.app,staging.moleculesai.app").
# The prefix MUST be followed immediately by a hyphen and then at least one
# suffix character, so names like e2e-smokeprod, e2e-smoketest-keep, or
# prod-e2e-smoke-x are NEVER matched.
zone_part = r"(?:" + r"|".join(re.escape(d) for d in zone_domains) + r")"
EPHEMERAL_RE = re.compile(
r"^(e2e-smoke-[a-zA-Z0-9_-]+|e2e-tmpl-[a-zA-Z0-9_-]+)\." + re.escape(zone_domain) + r"$"
r"^(e2e-smoke-[a-zA-Z0-9_-]+|e2e-tmpl-[a-zA-Z0-9_-]+)\." + zone_part + r"$"
)
def parse_iso(s):
+21 -8
View File
@@ -17,7 +17,7 @@ PASS=0
FAIL=0
run_case() {
local name="$1" list_exit="$2" list_body="$3" expect_delete_sentinel="$4" zone_domain="${5:-moleculesai.app}"
local name="$1" list_exit="$2" list_body="$3" expect_delete_sentinel="$4" zone_domain="${5:-}"
local tmp
tmp=$(mktemp -d -t cf-e2e-prune-fail-closed-XXXXXX)
local delete_sentinel="$tmp/delete_reached"
@@ -129,9 +129,10 @@ run_case "CF DNS list returns malformed JSON" 0 'this is not json'
run_case "CF DNS list returns non-array result" 0 '{"success":true,"result":{"id":"rec1"}}' false-abort
# Helper to build a DNS list result with one record, given created_on ISO string
# and optional zone domain (default: moleculesai.app).
# and optional zone domain (default: staging.moleculesai.app, the observed
# domain for leaked e2e-smoke/e2e-tmpl records).
make_list() {
local created_on="$1" zone_domain="${2:-moleculesai.app}"
local created_on="$1" zone_domain="${2:-staging.moleculesai.app}"
cat <<JSON
{"success":true,"result":[{"id":"rec1","name":"e2e-smoke-20260622-1234-abcdef12.${zone_domain}","type":"A","created_on":"$created_on"}],"result_info":{"page":1,"total_pages":1,"per_page":100,"count":1}}
JSON
@@ -154,12 +155,24 @@ run_case "e2e-tmplate-keep (extra chars before hyphen) kept" 0 "$(make_list "$ol
run_case "e2e-smoke (no hyphen suffix) kept" 0 "$(make_list "$old_ts" | sed 's/e2e-smoke-20260622-1234-abcdef12/e2e-smoke/')" false-keep
run_case "prod-e2e-smoke-x (does not start with prefix) kept" 0 "$(make_list "$old_ts" | sed 's/e2e-smoke-20260622-1234-abcdef12/prod-e2e-smoke-x/')" false-keep
# Staging subdomain must match when PRUNE_ZONE_DOMAIN is set.
run_case "old e2e-smoke staging subdomain deleted" 0 "$(make_list "$old_ts" staging.moleculesai.app)" true staging.moleculesai.app
# Zone-domain coverage (Researcher RC 13130 correctness blocker).
# Default PRUNE_ZONE_DOMAIN is staging.moleculesai.app, matching observed leaks.
run_case "old e2e-smoke staging subdomain deleted (default)" 0 "$(make_list "$old_ts")" true
# Old e2e-smoke record must be deleted (happy path, apex domain).
run_case "old e2e-smoke record deleted" 0 "$(make_list "$old_ts")" true
# Apex domain is NOT matched when PRUNE_ZONE_DOMAIN is staging only.
run_case "apex e2e-smoke kept when staging-only" 0 "$(make_list "$old_ts" moleculesai.app)" false-keep staging.moleculesai.app
echo
# A record under a different subdomain is NOT matched.
run_case "dev-subdomain e2e-smoke kept" 0 "$(make_list "$old_ts" dev.moleculesai.app)" false-keep staging.moleculesai.app
# Explicit apex zone domain still works when requested.
run_case "old e2e-smoke apex domain deleted" 0 "$(make_list "$old_ts" moleculesai.app)" true moleculesai.app
# Comma-separated zone domains match both apex and staging.
run_case "multi-zone matches staging record" 0 "$(make_list "$old_ts")" true "moleculesai.app,staging.moleculesai.app"
run_case "multi-zone matches apex record" 0 "$(make_list "$old_ts" moleculesai.app)" true "moleculesai.app,staging.moleculesai.app"
# Near-miss under the staging zone is still kept (safety guard).
run_case "e2e-smoketest-keep under staging kept" 0 "$(make_list "$old_ts" | sed 's/e2e-smoke-20260622-1234-abcdef12/e2e-smoketest-keep/')" false-keep
echo "passed=$PASS failed=$FAIL"
[ "$FAIL" -eq 0 ]