diff --git a/backup-system/configmaps.yaml b/backup-system/configmaps.yaml new file mode 100644 index 0000000..6b968da --- /dev/null +++ b/backup-system/configmaps.yaml @@ -0,0 +1,198 @@ +apiVersion: v1 +data: + backup.sh: "#!/bin/sh\nset -e\n\nBACKUP_DIR=\"/backups\"\nDATE=$(date +%Y-%m-%d_%H-%M-%S)\n\ + RETENTION_DAYS=7\n\necho \"==========================================\"\necho\ + \ \"Backup iniciado: $DATE\"\necho \"==========================================\"\ + \n\nbackup_dir() {\n NAME=$1\n SRC=$2\n\n if [ ! -d \"$SRC\" ]; then\n echo\ + \ \"[WARN] $NAME: directorio $SRC no encontrado, omitiendo.\"\n return\n fi\n\ + \n DEST=\"$BACKUP_DIR/${NAME}_${DATE}.tar.gz\"\n echo \"[INFO] Comprimiendo\ + \ $NAME ($SRC) \u2192 $DEST\"\n tar -czf \"$DEST\" -C \"$(dirname $SRC)\" \"\ + $(basename $SRC)\"\n SIZE=$(du -sh \"$DEST\" | cut -f1)\n echo \"[OK] $NAME\ + \ backup completado. Tamano: $SIZE\"\n}\n\nbackup_dir \"n8n\" \"/src/n8n\"\ + \nbackup_dir \"openclaw\" \"/src/openclaw\"\nbackup_dir \"agent-ia\" \"\ + /src/agent-ia\"\nbackup_dir \"agente-data\" \"/src/agente-data\"\nbackup_dir\ + \ \"authentik-pg\" \"/src/authentik-pg\"\nbackup_dir \"homarr\" \"/src/homarr\"\ + \nbackup_dir \"grafana\" \"/src/grafana\"\n\necho \"\"\necho \"--- Limpiando\ + \ backups con mas de $RETENTION_DAYS dias ---\"\nfind \"$BACKUP_DIR\" -name \"\ + *.tar.gz\" -mtime +${RETENTION_DAYS} -print -delete\necho \"\"\n\necho \"--- Backups\ + \ actuales en $BACKUP_DIR ---\"\nls -lh \"$BACKUP_DIR\"/*.tar.gz 2>/dev/null ||\ + \ echo \"(ninguno aun)\"\n\necho \"\"\necho \"Backup finalizado: $(date +%Y-%m-%d_%H-%M-%S)\"\ + \n" +kind: ConfigMap +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: "{\"apiVersion\":\"v1\",\"data\"\ + :{\"backup.sh\":\"#!/bin/sh\\nset -e\\n\\nBACKUP_DIR=\\\"/backups\\\"\\nDATE=$(date\ + \ +%Y-%m-%d_%H-%M-%S)\\nRETENTION_DAYS=7\\n\\necho \\\"==========================================\\\ + \"\\necho \\\"Backup iniciado: $DATE\\\"\\necho \\\"==========================================\\\ + \"\\n\\nbackup_dir() {\\n NAME=$1\\n SRC=$2\\n\\n if [ ! -d \\\"$SRC\\\"\ + \ ]; then\\n echo \\\"[WARN] $NAME: directorio $SRC no encontrado, omitiendo.\\\ + \"\\n return\\n fi\\n\\n DEST=\\\"$BACKUP_DIR/${NAME}_${DATE}.tar.gz\\\"\ + \\n echo \\\"[INFO] Comprimiendo $NAME ($SRC) \u2192 $DEST\\\"\\n tar -czf\ + \ \\\"$DEST\\\" -C \\\"$(dirname $SRC)\\\" \\\"$(basename $SRC)\\\"\\n SIZE=$(du\ + \ -sh \\\"$DEST\\\" | cut -f1)\\n echo \\\"[OK] $NAME backup completado.\ + \ Tama\xF1o: $SIZE\\\"\\n}\\n\\nbackup_dir \\\"n8n\\\" \\\"/src/n8n\\\ + \"\\nbackup_dir \\\"openclaw\\\" \\\"/src/openclaw\\\"\\nbackup_dir \\\"\ + agent-ia\\\" \\\"/src/agent-ia\\\"\\nbackup_dir \\\"agente-data\\\" \\\"\ + /src/agente-data\\\"\\n\\necho \\\"\\\"\\necho \\\"--- Limpiando backups con\ + \ m\xE1s de $RETENTION_DAYS d\xEDas ---\\\"\\nfind \\\"$BACKUP_DIR\\\" -name\ + \ \\\"*.tar.gz\\\" -mtime +${RETENTION_DAYS} -print -delete\\necho \\\"\\\"\\\ + n\\necho \\\"--- Backups actuales en $BACKUP_DIR ---\\\"\\nls -lh \\\"$BACKUP_DIR\\\ + \"/*.tar.gz 2\\u003e/dev/null || echo \\\"(ninguno a\xFAn)\\\"\\n\\necho \\\"\ + \\\"\\necho \\\"Backup finalizado: $(date +%Y-%m-%d_%H-%M-%S)\\\"\\n\"},\"kind\"\ + :\"ConfigMap\",\"metadata\":{\"annotations\":{},\"name\":\"backup-scripts\"\ + ,\"namespace\":\"backup-system\"}}\n" + name: backup-scripts + namespace: backup-system +--- +apiVersion: v1 +data: + verify.sh: "#!/bin/sh\nset -e\n\nBOT_TOKEN=\"8611913802:AAFlrFtc0vYISOliO_W8B4c-W1ue0hG9Fio\"\ + \nCHAT_ID=\"5138407666\"\nBACKUP_DIR=\"/backups\"\nERRORS=\"\"\nREPORT=\"\"\n\n\ + send_telegram() {\n MSG=\"$1\"\n wget -qO- \"https://api.telegram.org/bot${BOT_TOKEN}/sendMessage\"\ + \ \\\n --post-data=\"chat_id=${CHAT_ID}&text=${MSG}&parse_mode=Markdown\" >\ + \ /dev/null 2>&1 || true\n}\n\n# \u2500\u2500 1. Verificar backups locales \u2500\ + \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\ + \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\ + \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\ + \u2500\nREPORT=\"${REPORT}*Verificaci\xF3n Backups \u2014 $(date +%Y-%m-%d)*\\\ + n\\n\"\nREPORT=\"${REPORT}\U0001F4C2 *Backups locales:*\\n\"\n\nfor SERVICE in\ + \ n8n openclaw agent-ia agente-data authentik-pg homarr grafana; do\n LATEST=$(ls\ + \ -t \"${BACKUP_DIR}/${SERVICE}_\"*.tar.gz 2>/dev/null | head -1)\n if [ -z \"\ + $LATEST\" ]; then\n REPORT=\"${REPORT}\u274C ${SERVICE}: no encontrado\\n\"\ + \n ERRORS=\"${ERRORS}${SERVICE}:missing \"\n continue\n fi\n AGE_DAYS=$((\ + \ ( $(date +%s) - $(date -r \"$LATEST\" +%s) ) / 86400 ))\n if [ \"$AGE_DAYS\"\ + \ -gt 2 ]; then\n REPORT=\"${REPORT}\u26A0\uFE0F ${SERVICE}: antiguo (${AGE_DAYS}d)\\\ + n\"\n ERRORS=\"${ERRORS}${SERVICE}:old \"\n continue\n fi\n # Verificar\ + \ integridad\n if tar -tzf \"$LATEST\" > /dev/null 2>&1; then\n SIZE=$(du\ + \ -sh \"$LATEST\" | cut -f1)\n REPORT=\"${REPORT}\u2705 ${SERVICE}: OK (${SIZE},\ + \ ${AGE_DAYS}d)\\n\"\n else\n REPORT=\"${REPORT}\u274C ${SERVICE}: CORRUPTO\\\ + n\"\n ERRORS=\"${ERRORS}${SERVICE}:corrupt \"\n fi\ndone\n\n# \u2500\u2500\ + \ 2. Verificar backup en Mega \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\ + \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\ + \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\ + \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nREPORT=\"${REPORT}\\n\u2601\uFE0F\ + \ *Backup Mega:*\\n\"\n\n# Configurar rclone con credenciales del secret (montadas\ + \ como env)\nMEGA_PASS_OBF=$(rclone obscure \"$MEGA_PASSWORD\")\nmkdir -p /root/.config/rclone\n\ + cat > /root/.config/rclone/rclone.conf << RCLEOF\n[mega]\ntype = mega\nuser =\ + \ ${MEGA_USER}\npass = ${MEGA_PASS_OBF}\nRCLEOF\n\nMEGA_FILES=$(rclone lsf mega:k3s-backups/\ + \ 2>/dev/null | grep \"backup-k3s-\" | sort | tail -3)\nif [ -z \"$MEGA_FILES\"\ + \ ]; then\n REPORT=\"${REPORT}\u274C Sin backups en Mega\\n\"\n ERRORS=\"${ERRORS}mega:missing\ + \ \"\nelse\n LATEST_MEGA=$(echo \"$MEGA_FILES\" | tail -1)\n MEGA_DATE=$(echo\ + \ \"$LATEST_MEGA\" | grep -oE '[0-9]{4}-[0-9]{2}-[0-9]{2}' | head -1)\n REPORT=\"\ + ${REPORT}\u2705 \xDAltimo: ${LATEST_MEGA}\\n\"\nfi\n\n# \u2500\u2500 3. Enviar\ + \ resumen \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\ + \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\ + \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\ + \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\ + \u2500\nif [ -n \"$ERRORS\" ]; then\n HEADER=\"\u274C *BACKUP ALERT \u2014 Problemas\ + \ detectados*\\n\"\nelse\n HEADER=\"\u2705 *Backups OK*\\n\"\nfi\n\nFULL_MSG=\"\ + ${HEADER}${REPORT}\"\nsend_telegram \"$FULL_MSG\"\n\necho \"Verificaci\xF3n completada.\ + \ Errores: ${ERRORS:-ninguno}\"\n[ -z \"$ERRORS\" ] || exit 1\n" +kind: ConfigMap +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: "{\"apiVersion\":\"v1\",\"data\"\ + :{\"verify.sh\":\"#!/bin/sh\\nset -e\\n\\nBOT_TOKEN=\\\"8611913802:AAFlrFtc0vYISOliO_W8B4c-W1ue0hG9Fio\\\ + \"\\nCHAT_ID=\\\"5138407666\\\"\\nBACKUP_DIR=\\\"/backups\\\"\\nERRORS=\\\"\\\ + \"\\nREPORT=\\\"\\\"\\n\\nsend_telegram() {\\n MSG=\\\"$1\\\"\\n wget -qO-\ + \ \\\"https://api.telegram.org/bot${BOT_TOKEN}/sendMessage\\\" \\\\\\n --post-data=\\\ + \"chat_id=${CHAT_ID}\\u0026text=${MSG}\\u0026parse_mode=Markdown\\\" \\u003e\ + \ /dev/null 2\\u003e\\u00261 || true\\n}\\n\\n# \u2500\u2500 1. Verificar backups\ + \ locales \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\ + \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\ + \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\ + \u2500\u2500\u2500\u2500\\nREPORT=\\\"${REPORT}*Verificaci\xF3n Backups \u2014\ + \ $(date +%Y-%m-%d)*\\\\n\\\\n\\\"\\nREPORT=\\\"${REPORT}\U0001F4C2 *Backups\ + \ locales:*\\\\n\\\"\\n\\nfor SERVICE in n8n openclaw agent-ia agente-data authentik-pg\ + \ homarr grafana; do\\n LATEST=$(ls -t \\\"${BACKUP_DIR}/${SERVICE}_\\\"*.tar.gz\ + \ 2\\u003e/dev/null | head -1)\\n if [ -z \\\"$LATEST\\\" ]; then\\n REPORT=\\\ + \"${REPORT}\u274C ${SERVICE}: no encontrado\\\\n\\\"\\n ERRORS=\\\"${ERRORS}${SERVICE}:missing\ + \ \\\"\\n continue\\n fi\\n AGE_DAYS=$(( ( $(date +%s) - $(date -r \\\"\ + $LATEST\\\" +%s) ) / 86400 ))\\n if [ \\\"$AGE_DAYS\\\" -gt 2 ]; then\\n \ + \ REPORT=\\\"${REPORT}\u26A0\uFE0F ${SERVICE}: antiguo (${AGE_DAYS}d)\\\\n\\\ + \"\\n ERRORS=\\\"${ERRORS}${SERVICE}:old \\\"\\n continue\\n fi\\n #\ + \ Verificar integridad\\n if tar -tzf \\\"$LATEST\\\" \\u003e /dev/null 2\\\ + u003e\\u00261; then\\n SIZE=$(du -sh \\\"$LATEST\\\" | cut -f1)\\n REPORT=\\\ + \"${REPORT}\u2705 ${SERVICE}: OK (${SIZE}, ${AGE_DAYS}d)\\\\n\\\"\\n else\\\ + n REPORT=\\\"${REPORT}\u274C ${SERVICE}: CORRUPTO\\\\n\\\"\\n ERRORS=\\\ + \"${ERRORS}${SERVICE}:corrupt \\\"\\n fi\\ndone\\n\\n# \u2500\u2500 2. Verificar\ + \ backup en Mega \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\ + \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\ + \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\ + \u2500\u2500\u2500\u2500\u2500\u2500\\nREPORT=\\\"${REPORT}\\\\n\u2601\uFE0F\ + \ *Backup Mega:*\\\\n\\\"\\n\\n# Configurar rclone con credenciales del secret\ + \ (montadas como env)\\nMEGA_PASS_OBF=$(rclone obscure \\\"$MEGA_PASSWORD\\\"\ + )\\nmkdir -p /root/.config/rclone\\ncat \\u003e /root/.config/rclone/rclone.conf\ + \ \\u003c\\u003c RCLEOF\\n[mega]\\ntype = mega\\nuser = ${MEGA_USER}\\npass\ + \ = ${MEGA_PASS_OBF}\\nRCLEOF\\n\\nMEGA_FILES=$(rclone lsf mega:k3s-backups/\ + \ 2\\u003e/dev/null | grep \\\"backup-k3s-\\\" | sort | tail -3)\\nif [ -z \\\ + \"$MEGA_FILES\\\" ]; then\\n REPORT=\\\"${REPORT}\u274C Sin backups en Mega\\\ + \\n\\\"\\n ERRORS=\\\"${ERRORS}mega:missing \\\"\\nelse\\n LATEST_MEGA=$(echo\ + \ \\\"$MEGA_FILES\\\" | tail -1)\\n MEGA_DATE=$(echo \\\"$LATEST_MEGA\\\" |\ + \ grep -oE '[0-9]{4}-[0-9]{2}-[0-9]{2}' | head -1)\\n REPORT=\\\"${REPORT}\u2705\ + \ \xDAltimo: ${LATEST_MEGA}\\\\n\\\"\\nfi\\n\\n# \u2500\u2500 3. Enviar resumen\ + \ \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\ + \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\ + \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\ + \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\ + \\nif [ -n \\\"$ERRORS\\\" ]; then\\n HEADER=\\\"\u274C *BACKUP ALERT \u2014\ + \ Problemas detectados*\\\\n\\\"\\nelse\\n HEADER=\\\"\u2705 *Backups OK*\\\ + \\n\\\"\\nfi\\n\\nFULL_MSG=\\\"${HEADER}${REPORT}\\\"\\nsend_telegram \\\"$FULL_MSG\\\ + \"\\n\\necho \\\"Verificaci\xF3n completada. Errores: ${ERRORS:-ninguno}\\\"\ + \\n[ -z \\\"$ERRORS\\\" ] || exit 1\\n\"},\"kind\":\"ConfigMap\",\"metadata\"\ + :{\"annotations\":{},\"name\":\"backup-verify-script\",\"namespace\":\"backup-system\"\ + }}\n" + name: backup-verify-script + namespace: backup-system +--- +apiVersion: v1 +data: + backup-mega.sh: "#!/bin/sh\nset -e\n\nDATE=$(date +%Y-%m-%d)\nBACKUP_FILE=\"/tmp/backup-k3s-${DATE}.tar.gz\"\ + \n\necho \"=== Rclone Mega Backup - ${DATE} ===\"\n\n# Generar rclone config con\ + \ password ofuscado\nMEGA_PASS_OBF=$(rclone obscure \"$MEGA_PASSWORD\")\nmkdir\ + \ -p /root/.config/rclone\ncat > /root/.config/rclone/rclone.conf << EOF\n[mega]\n\ + type = mega\nuser = ${MEGA_USER}\npass = ${MEGA_PASS_OBF}\nEOF\n\n# Comprimir\ + \ /data/backups\necho \"Comprimiendo /data/backups...\"\ntar -czf \"$BACKUP_FILE\"\ + \ -C /data backups/\nSIZE=$(du -sh \"$BACKUP_FILE\" | cut -f1)\necho \"Archivo\ + \ generado: $BACKUP_FILE ($SIZE)\"\n\n# Crear carpeta destino en Mega si no existe\n\ + rclone mkdir mega:k3s-backups/ 2>/dev/null || true\n\n# Subir a Mega\necho \"\ + Subiendo a Mega...\"\nrclone copy \"$BACKUP_FILE\" mega:k3s-backups/ --progress\n\ + echo \"Upload completado.\"\n\n# Limpiar archivo temporal\nrm -f \"$BACKUP_FILE\"\ + \n\n# Retenci\xF3n: mantener solo las \xFAltimas 4 semanas\necho \"Aplicando retenci\xF3\ + n (m\xE1ximo 4 backups)...\"\nFILES=$(rclone lsf mega:k3s-backups/ | sort)\nCOUNT=$(echo\ + \ \"$FILES\" | grep -c . || true)\necho \"Backups en Mega: $COUNT\"\n\nif [ \"\ + $COUNT\" -gt 4 ]; then\n TO_DELETE=$((COUNT - 4))\n echo \"Eliminando $TO_DELETE\ + \ backup(s) antiguo(s)...\"\n echo \"$FILES\" | head -n \"$TO_DELETE\" | while\ + \ IFS= read -r f; do\n echo \" Borrando: $f\"\n rclone deletefile \"mega:k3s-backups/$f\"\ + \n done\nfi\n\necho \"=== Backup a Mega finalizado - $(date) ===\"\n" +kind: ConfigMap +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: "{\"apiVersion\":\"v1\",\"data\"\ + :{\"backup-mega.sh\":\"#!/bin/sh\\nset -e\\n\\nDATE=$(date +%Y-%m-%d)\\nBACKUP_FILE=\\\ + \"/tmp/backup-k3s-${DATE}.tar.gz\\\"\\n\\necho \\\"=== Rclone Mega Backup -\ + \ ${DATE} ===\\\"\\n\\n# Generar rclone config con password ofuscado\\nMEGA_PASS_OBF=$(rclone\ + \ obscure \\\"$MEGA_PASSWORD\\\")\\nmkdir -p /root/.config/rclone\\ncat \\u003e\ + \ /root/.config/rclone/rclone.conf \\u003c\\u003c EOF\\n[mega]\\ntype = mega\\\ + nuser = ${MEGA_USER}\\npass = ${MEGA_PASS_OBF}\\nEOF\\n\\n# Comprimir /data/backups\\\ + necho \\\"Comprimiendo /data/backups...\\\"\\ntar -czf \\\"$BACKUP_FILE\\\"\ + \ -C /data backups/\\nSIZE=$(du -sh \\\"$BACKUP_FILE\\\" | cut -f1)\\necho \\\ + \"Archivo generado: $BACKUP_FILE ($SIZE)\\\"\\n\\n# Crear carpeta destino en\ + \ Mega si no existe\\nrclone mkdir mega:k3s-backups/ 2\\u003e/dev/null || true\\\ + n\\n# Subir a Mega\\necho \\\"Subiendo a Mega...\\\"\\nrclone copy \\\"$BACKUP_FILE\\\ + \" mega:k3s-backups/ --progress\\necho \\\"Upload completado.\\\"\\n\\n# Limpiar\ + \ archivo temporal\\nrm -f \\\"$BACKUP_FILE\\\"\\n\\n# Retenci\xF3n: mantener\ + \ solo las \xFAltimas 4 semanas\\necho \\\"Aplicando retenci\xF3n (m\xE1ximo\ + \ 4 backups)...\\\"\\nFILES=$(rclone lsf mega:k3s-backups/ | sort)\\nCOUNT=$(echo\ + \ \\\"$FILES\\\" | grep -c . || true)\\necho \\\"Backups en Mega: $COUNT\\\"\ + \\n\\nif [ \\\"$COUNT\\\" -gt 4 ]; then\\n TO_DELETE=$((COUNT - 4))\\n echo\ + \ \\\"Eliminando $TO_DELETE backup(s) antiguo(s)...\\\"\\n echo \\\"$FILES\\\ + \" | head -n \\\"$TO_DELETE\\\" | while IFS= read -r f; do\\n echo \\\" \ + \ Borrando: $f\\\"\\n rclone deletefile \\\"mega:k3s-backups/$f\\\"\\n done\\\ + nfi\\n\\necho \\\"=== Backup a Mega finalizado - $(date) ===\\\"\\n\"},\"kind\"\ + :\"ConfigMap\",\"metadata\":{\"annotations\":{},\"name\":\"rclone-mega-script\"\ + ,\"namespace\":\"backup-system\"}}\n" + name: rclone-mega-script + namespace: backup-system +