163 lines
5.6 KiB
Bash
163 lines
5.6 KiB
Bash
#!/bin/bash
|
|
set -Eeuo pipefail
|
|
|
|
# Configuration
|
|
TARGET_ENV="${1:-stsharedservices-dev}"
|
|
DBNAME="${2:-geco}"
|
|
POD_NAME="${3:-stpgclusterdev-1}"
|
|
CONTAINER_NAME="${4:-postgres}"
|
|
BACKUP_FILE="${5:-.}"
|
|
DROP_IF_EXISTS="${6:-true}"
|
|
DB_USER="${7:-${PGUSER:-postgres}}"
|
|
DB_PASSWORD="${8:-${PGPASSWORD:-}}"
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m'
|
|
|
|
# Logging functions
|
|
log() {
|
|
echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')]${NC} $*"
|
|
}
|
|
|
|
error() {
|
|
echo -e "${RED}[$(date '+%Y-%m-%d %H:%M:%S')] ERROR:${NC} $*" >&2
|
|
exit 1
|
|
}
|
|
|
|
warn() {
|
|
echo -e "${YELLOW}[$(date '+%Y-%m-%d %H:%M:%S')] WARN:${NC} $*"
|
|
}
|
|
|
|
info() {
|
|
echo -e "${BLUE}[$(date '+%Y-%m-%d %H:%M:%S')] INFO:${NC} $*"
|
|
}
|
|
|
|
log "Inizio restore database PostgreSQL"
|
|
log "Namespace target: ${TARGET_ENV}"
|
|
log "Pod target: ${POD_NAME}"
|
|
log "Database: ${DBNAME}"
|
|
log "DB user: ${DB_USER}"
|
|
log "File backup: ${BACKUP_FILE}"
|
|
|
|
# Validate backup file exists
|
|
if [ ! -f "${BACKUP_FILE}" ]; then
|
|
error "File di backup non trovato: ${BACKUP_FILE}"
|
|
fi
|
|
|
|
FILE_SIZE=$(du -h "${BACKUP_FILE}" | cut -f1)
|
|
log "Dimensione file backup: ${FILE_SIZE}"
|
|
|
|
# Determine if backup is compressed
|
|
if [[ "${BACKUP_FILE}" == *.gz ]]; then
|
|
IS_COMPRESSED=true
|
|
info "Backup compresso (gzip) rilevato"
|
|
else
|
|
IS_COMPRESSED=false
|
|
info "Backup non compresso rilevato"
|
|
fi
|
|
|
|
# Check if namespace exists
|
|
if ! kubectl get namespace "${TARGET_ENV}" &>/dev/null; then
|
|
error "Namespace '${TARGET_ENV}' non trovato"
|
|
fi
|
|
|
|
# Check if pod exists
|
|
if ! kubectl get pod "${POD_NAME}" -n "${TARGET_ENV}" &>/dev/null; then
|
|
error "Pod '${POD_NAME}' non trovato nel namespace '${TARGET_ENV}'"
|
|
fi
|
|
|
|
# Check if pod is running
|
|
POD_STATUS=$(kubectl get pod "${POD_NAME}" -n "${TARGET_ENV}" -o jsonpath='{.status.phase}')
|
|
if [ "${POD_STATUS}" != "Running" ]; then
|
|
error "Pod '${POD_NAME}' non è in stato Running (stato attuale: ${POD_STATUS})"
|
|
fi
|
|
|
|
# Check database connectivity
|
|
info "Verifica connessione al database..."
|
|
if ! kubectl exec -i "${POD_NAME}" \
|
|
-c "${CONTAINER_NAME}" \
|
|
-n "${TARGET_ENV}" \
|
|
-- env "PGPASSWORD=${DB_PASSWORD}" pg_isready -U "${DB_USER}" -d "${DBNAME}" &>/dev/null; then
|
|
error "Impossibile connettersi a PostgreSQL nel pod '${POD_NAME}'"
|
|
fi
|
|
|
|
log "Connessione al database verificata"
|
|
|
|
# Drop database if requested
|
|
if [ "${DROP_IF_EXISTS}" = "true" ]; then
|
|
warn "Elimino il database '${DBNAME}' se esiste..."
|
|
kubectl exec -i "${POD_NAME}" \
|
|
-c "${CONTAINER_NAME}" \
|
|
-n "${TARGET_ENV}" \
|
|
-- env "PGPASSWORD=${DB_PASSWORD}" psql -U "${DB_USER}" -c "DROP DATABASE IF EXISTS \"${DBNAME}\" WITH (FORCE);" 2>/dev/null || warn "Database non esiste o elimina non è riuscita"
|
|
|
|
info "Creo nuovo database '${DBNAME}'..."
|
|
kubectl exec -i "${POD_NAME}" \
|
|
-c "${CONTAINER_NAME}" \
|
|
-n "${TARGET_ENV}" \
|
|
-- env "PGPASSWORD=${DB_PASSWORD}" psql -U "${DB_USER}" -c "CREATE DATABASE \"${DBNAME}\";" || error "Impossibile creare il database '${DBNAME}'"
|
|
fi
|
|
|
|
log "Inizio restore del database..."
|
|
|
|
# Execute restore
|
|
if [ "${IS_COMPRESSED}" = "true" ]; then
|
|
info "Decompressione e restore in corso..."
|
|
gunzip -c "${BACKUP_FILE}" | kubectl exec -i "${POD_NAME}" \
|
|
-c "${CONTAINER_NAME}" \
|
|
-n "${TARGET_ENV}" \
|
|
-- env "PGPASSWORD=${DB_PASSWORD}" pg_restore -U "${DB_USER}" -d "${DBNAME}" --no-owner -v 2>&1 | grep -E "(NOTICE|ERROR|completed)" || true
|
|
else
|
|
info "Restore da file plain SQL in corso..."
|
|
cat "${BACKUP_FILE}" | kubectl exec -i "${POD_NAME}" \
|
|
-c "${CONTAINER_NAME}" \
|
|
-n "${TARGET_ENV}" \
|
|
-- env "PGPASSWORD=${DB_PASSWORD}" psql -U "${DB_USER}" -d "${DBNAME}" -v ON_ERROR_STOP=1 2>&1 | grep -E "(NOTICE|ERROR|INSERT|CREATE)" | tail -20 || true
|
|
fi
|
|
|
|
log "Restore completato"
|
|
|
|
info "Allineo owner delle tabelle al proprietario del database target..."
|
|
TARGET_DB_OWNER=$(kubectl exec -i "${POD_NAME}" \
|
|
-c "${CONTAINER_NAME}" \
|
|
-n "${TARGET_ENV}" \
|
|
-- env "PGPASSWORD=${DB_PASSWORD}" psql -U "${DB_USER}" -d postgres -t -A -c "SELECT pg_get_userbyid(datdba) FROM pg_database WHERE datname='${DBNAME}';")
|
|
|
|
if [ -z "${TARGET_DB_OWNER}" ]; then
|
|
error "Impossibile determinare l'owner del database '${DBNAME}'"
|
|
fi
|
|
|
|
kubectl exec -i "${POD_NAME}" \
|
|
-c "${CONTAINER_NAME}" \
|
|
-n "${TARGET_ENV}" \
|
|
-- env "PGPASSWORD=${DB_PASSWORD}" psql -U "${DB_USER}" -d "${DBNAME}" -v ON_ERROR_STOP=1 -c "DO \$\$ DECLARE r RECORD; BEGIN FOR r IN SELECT n.nspname, c.relname FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind IN ('r', 'p') AND n.nspname NOT IN ('pg_catalog', 'information_schema') AND n.nspname NOT LIKE 'pg_toast%' LOOP EXECUTE format('ALTER TABLE %I.%I OWNER TO %I', r.nspname, r.relname, '${TARGET_DB_OWNER}'); END LOOP; END \$\$;" >/dev/null
|
|
|
|
log "Owner tabelle allineato a '${TARGET_DB_OWNER}'"
|
|
|
|
# Verify restore success
|
|
info "Verifica integrità database..."
|
|
TABLE_COUNT=$(kubectl exec -i "${POD_NAME}" \
|
|
-c "${CONTAINER_NAME}" \
|
|
-n "${TARGET_ENV}" \
|
|
-- env "PGPASSWORD=${DB_PASSWORD}" psql -U "${DB_USER}" -d "${DBNAME}" -t -c "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='public';" 2>/dev/null || echo "0")
|
|
|
|
if [ "${TABLE_COUNT}" -gt 0 ]; then
|
|
log "✅ Restore completato con successo"
|
|
log "Database '${DBNAME}' contiene ${TABLE_COUNT} tabelle"
|
|
else
|
|
warn "⚠️ Database '${DBNAME}' non contiene tabelle pubbliche (potrebbe essere empty)"
|
|
fi
|
|
|
|
# Get database size
|
|
DB_SIZE=$(kubectl exec -i "${POD_NAME}" \
|
|
-c "${CONTAINER_NAME}" \
|
|
-n "${TARGET_ENV}" \
|
|
-- env "PGPASSWORD=${DB_PASSWORD}" psql -U "${DB_USER}" -t -c "SELECT pg_size_pretty(pg_database_size('${DBNAME}'));" 2>/dev/null || echo "N/A")
|
|
|
|
log "Dimensione database: ${DB_SIZE}"
|
|
log "✅ Restore completato con successo"
|