65359338f8
Cutover hecho el 3-ago a las 10:50 UTC. feadulta.com y www.feadulta.com ya apuntan a 188.40.120.157, proxied. Ventana real ~3 min 10 s: dump 67 s, saneo 2 s, import 114 s, delta de uploads 6 s (0 ficheros, como estaba medido). Cuadro al digito con produccion: 43.893 posts, 1.228 usuarios, 4.416 terms, 135.959 postmeta. Los options salen 958 frente a 975 porque son transients (hay 580 y caducan solos). Con trafico real: 581 respuestas 200, 62 301, 16 302, cero 5xx y cero errores PHP en 20 minutos, 61 IPs distintas atendidas. Se anaden los cuatro scripts que faltaban, que hasta hoy solo existian como comandos sueltos del ensayo: 01-traer-dump, 02-sanear-dump, 03-importar, 04-delta-uploads y 05-mover-dns. El runbook ya los citaba por nombre. Tres cosas encontradas al ejecutar, anotadas en los propios scripts: - docker exec -i dentro de un ssh 'bash -s' <<EOF se come el resto del script, porque hereda el stdin del heredoc. Las consultas van sin -i y con </dev/null. - Smart Slider cachea el HTML del slider con URLs absolutas, una fila por idioma en wp_nextend2_section_storage con application='cache'. Al verificar el import con la constante del staging todavia puesta quedaron 5 filas apuntando a nuevo.feadulta.com. Se borran y se regeneran solas. - El cliente de MariaDB de la jaula de CDMON exige TLS y el servidor local no lo tiene: con --skip-ssl si se puede consultar la BD de produccion directamente, que es como se comprobo que no habia cambiado nada desde el dump de las 05:09. Pendiente y fuera de nuestro alcance: purgar la cache de Cloudflare (el token solo tiene permiso de DNS) y darle a Inma su contrasena nueva. Y los certificados de Let's Encrypt para www y el apex, que fallan porque el WAF de Cloudflare devuelve 403 a la validacion; no bloquea mientras la zona este en Full, pero por eso mismo no se puede subir a Full (strict) todavia. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
60 lines
2.0 KiB
Bash
Executable File
60 lines
2.0 KiB
Bash
Executable File
#!/bin/bash
|
|
#
|
|
# Paso 8 del cutover: mover el A record del apex y de www a Hetzner.
|
|
#
|
|
# Se cambia SOLO el content. proxied=true se mantiene (la web va por Cloudflare) y
|
|
# no se toca nada mas de la zona: el MX, el wildcard, los NS de cdmon y los TXT
|
|
# (SPF y brevo) se quedan igual, asi que el correo no se ve afectado.
|
|
#
|
|
# ROLLBACK: volver a poner 134.0.10.170 en estos dos mismos ids.
|
|
#
|
|
set -uo pipefail
|
|
set -a; . ~/.hermes/profiles/feadulta/.env 2>/dev/null; set +a
|
|
|
|
ZONE=5aa15f0f9cf7d45f3710177bb4a66aba
|
|
NUEVA_IP=188.40.120.157
|
|
APEX=807be63daf5a2ce9cfc710dcc1ef0a21
|
|
WWW=0ce31fc2fbf5316434ace0c944909c59
|
|
|
|
mover() {
|
|
local id=$1 name=$2
|
|
curl -s -X PATCH \
|
|
-H "Authorization: Bearer $FEA_CF_API_TOKEN" -H "Content-Type: application/json" \
|
|
"https://api.cloudflare.com/client/v4/zones/$ZONE/dns_records/$id" \
|
|
--data "{\"content\":\"$NUEVA_IP\"}" \
|
|
| python3 -c "
|
|
import sys,json
|
|
d=json.load(sys.stdin)
|
|
if d.get('success'):
|
|
r=d['result']; print(' OK %-20s -> %s proxied=%s' % (r['name'], r['content'], r['proxied']))
|
|
else:
|
|
print(' FALLO %s: %s' % ('$name', d.get('errors')))
|
|
"
|
|
}
|
|
|
|
echo "== $(date '+%F %T %Z') moviendo los A records:"
|
|
mover "$APEX" feadulta.com
|
|
mover "$WWW" www.feadulta.com
|
|
|
|
echo ""
|
|
echo "== estado en la zona tras el cambio:"
|
|
curl -s -H "Authorization: Bearer $FEA_CF_API_TOKEN" \
|
|
"https://api.cloudflare.com/client/v4/zones/$ZONE/dns_records?type=A&per_page=100" \
|
|
| python3 -c '
|
|
import sys,json
|
|
for r in json.load(sys.stdin)["result"]:
|
|
print(" %-22s %-16s proxied=%s" % (r["name"], r["content"], r["proxied"]))
|
|
'
|
|
|
|
echo ""
|
|
echo "== purgando la cache de Cloudflare:"
|
|
curl -s -X POST \
|
|
-H "Authorization: Bearer $FEA_CF_API_TOKEN" -H "Content-Type: application/json" \
|
|
"https://api.cloudflare.com/client/v4/zones/$ZONE/purge_cache" --data '{"purge_everything":true}' \
|
|
| python3 -c '
|
|
import sys,json
|
|
d=json.load(sys.stdin)
|
|
print(" purga OK" if d.get("success") else " NO se pudo purgar: %s" % d.get("errors"))
|
|
print(" (si falla es que el token solo tiene permiso de DNS: hay que purgar desde el panel)")
|
|
'
|