#!/bin/bash # Скрипт восстановления NetBox из бэкапа set -e # Останавливаемся при любой ошибке BACKUP_DIR="/opt/netbox/backups" YADISK_MOUNT="/opt/netbox/yadisk" RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color # Функция для вывода цветных сообщений print_error() { echo -e "${RED}❌ $1${NC}"; } print_success() { echo -e "${GREEN}✅ $1${NC}"; } print_warning() { echo -e "${YELLOW}⚠️ $1${NC}"; } print_info() { echo -e "ℹ️ $1"; } # Показать доступные бэкапы show_backups() { echo "" echo "📁 Доступные бэкапы:" echo "====================" # Локальные бэкапы if [ -d "$BACKUP_DIR" ] && [ -n "$(ls -A $BACKUP_DIR 2>/dev/null)" ]; then echo -e "\n${GREEN}Локальные бэкапы:${NC}" ls -lh $BACKUP_DIR/netbox_db_*.sql.gz 2>/dev/null | awk '{print " " $9 " (" $5 ")"}' fi # Бэкапы на Яндекс.Диске if mountpoint -q ${YADISK_MOUNT} && [ -d "$YADISK_MOUNT/netbox-backups" ]; then echo -e "\n${GREEN}Бэкапы на Яндекс.Диске:${NC}" ls -lh $YADISK_MOUNT/netbox-backups/netbox_db_*.sql.gz 2>/dev/null | awk '{print " " $9 " (" $5 ")"}' fi echo "" } # Выбор бэкапа select_backup() { local backup_files=() # Собираем все доступные бэкапы if [ -d "$BACKUP_DIR" ]; then for f in $BACKUP_DIR/netbox_db_*.sql.gz; do [ -f "$f" ] && backup_files+=("$f") done fi if mountpoint -q ${YADISK_MOUNT} && [ -d "$YADISK_MOUNT/netbox-backups" ]; then for f in $YADISK_MOUNT/netbox-backups/netbox_db_*.sql.gz; do [ -f "$f" ] && backup_files+=("$f") done fi if [ ${#backup_files[@]} -eq 0 ]; then print_error "Нет доступных бэкапов!" exit 1 fi echo "Выберите бэкап для восстановления:" for i in "${!backup_files[@]}"; do local size=$(du -h "${backup_files[$i]}" | cut -f1) local date=$(basename "${backup_files[$i]}" | sed 's/netbox_db_\(.*\)\.sql.gz/\1/') echo " $((i+1)). $date (${size}) - $(basename $(dirname ${backup_files[$i]}))" done echo " 0. Отмена" echo "" read -p "Введите номер [1-${#backup_files[@]}]: " choice if [ "$choice" == "0" ]; then echo "Восстановление отменено." exit 0 fi if [ "$choice" -ge 1 ] && [ "$choice" -le ${#backup_files[@]} ]; then SELECTED_BACKUP="${backup_files[$((choice-1))]}" BACKUP_DATE=$(basename "$SELECTED_BACKUP" | sed 's/netbox_db_\(.*\)\.sql.gz/\1/') BACKUP_SOURCE=$(basename $(dirname "$SELECTED_BACKUP")) print_success "Выбран бэкап от $BACKUP_DATE (источник: $BACKUP_SOURCE)" else print_error "Неверный выбор!" exit 1 fi } # Проверка, что NetBox не запущен check_netbox_stopped() { if docker compose ps | grep -q "Up"; then print_warning "NetBox контейнеры запущены!" read -p "Остановить их перед восстановлением? [y/N]: " stop_containers if [[ $stop_containers =~ ^[Yy]$ ]]; then print_info "Останавливаем контейнеры..." docker compose down else print_error "Пожалуйста, остановите контейнеры вручную: docker compose down" exit 1 fi fi } # Основной процесс восстановления restore_backup() { echo "" print_info "Начинаем восстановление из бэкапа $BACKUP_DATE" echo "==========================================" # 1. Распаковка и восстановление базы данных echo "" print_info "1. Восстановление базы данных PostgreSQL..." # Запускаем только PostgreSQL docker compose up -d postgres redis redis-cache sleep 5 # Проверяем, что PostgreSQL готов until docker compose exec -T postgres pg_isready -U netbox; do echo " Ожидаем запуска PostgreSQL..." sleep 2 done # Восстанавливаем базу данных echo " Восстанавливаем базу данных из $SELECTED_BACKUP..." gunzip -c "$SELECTED_BACKUP" | docker compose exec -T postgres psql -U netbox -d netbox if [ $? -eq 0 ]; then print_success "База данных восстановлена" else print_error "Ошибка восстановления базы данных" exit 1 fi # 2. Восстановление медиа-файлов MEDIA_BACKUP="${BACKUP_DIR}/netbox_media_${BACKUP_DATE}.tar.gz" if [ ! -f "$MEDIA_BACKUP" ] && mountpoint -q ${YADISK_MOUNT}; then MEDIA_BACKUP="${YADISK_MOUNT}/netbox-backups/netbox_media_${BACKUP_DATE}.tar.gz" fi if [ -f "$MEDIA_BACKUP" ]; then echo "" print_info "2. Восстановление медиа-файлов..." docker compose exec -T netbox rm -rf /opt/netbox/netbox/media/* 2>/dev/null docker compose exec -T netbox tar xzf - -C /opt/netbox/netbox/media < "$MEDIA_BACKUP" print_success "Медиа-файлы восстановлены" else print_warning "Медиа-бэкап не найден: netbox_media_${BACKUP_DATE}.tar.gz" fi # 3. Восстановление .env файлов ENV_BACKUP="${BACKUP_DIR}/netbox_env_${BACKUP_DATE}.tar.gz" if [ ! -f "$ENV_BACKUP" ] && mountpoint -q ${YADISK_MOUNT}; then ENV_BACKUP="${YADISK_MOUNT}/netbox-backups/netbox_env_${BACKUP_DATE}.tar.gz" fi if [ -f "$ENV_BACKUP" ]; then echo "" print_info "3. Восстановление .env файлов..." tar xzf "$ENV_BACKUP" -C /opt/netbox print_success ".env файлы восстановлены" else print_warning ".env бэкап не найден: netbox_env_${BACKUP_DATE}.tar.gz" fi # 4. Запуск миграций и сбор статики echo "" print_info "4. Запуск миграций и сбор статики..." docker compose up -d netbox sleep 10 docker compose exec netbox python /opt/netbox/netbox/manage.py migrate docker compose exec netbox python /opt/netbox/netbox/manage.py collectstatic --no-input # 5. Запуск всех контейнеров echo "" print_info "5. Запуск всех сервисов..." docker compose up -d echo "" print_success "Восстановление завершено!" echo "" print_info "Проверьте логи: docker compose logs netbox --tail 50" print_info "Веб-интерфейс: http://localhost:8080" } # Функция для быстрого восстановления последнего бэкапа quick_restore() { local latest_backup=$(ls -t $BACKUP_DIR/netbox_db_*.sql.gz 2>/dev/null | head -1) if [ -z "$latest_backup" ] && mountpoint -q ${YADISK_MOUNT}; then latest_backup=$(ls -t $YADISK_MOUNT/netbox-backups/netbox_db_*.sql.gz 2>/dev/null | head -1) fi if [ -z "$latest_backup" ]; then print_error "Нет доступных бэкапов!" exit 1 fi SELECTED_BACKUP="$latest_backup" BACKUP_DATE=$(basename "$SELECTED_BACKUP" | sed 's/netbox_db_\(.*\)\.sql.gz/\1/') BACKUP_SOURCE=$(basename $(dirname "$SELECTED_BACKUP")) print_info "Восстанавливаем последний бэкап: $BACKUP_DATE (источник: $BACKUP_SOURCE)" restore_backup } # Основное меню main() { cd /opt/netbox echo "🔄 NetBox Recovery Script" echo "========================" echo "" echo "1. Показать доступные бэкапы" echo "2. Восстановить из выбранного бэкапа" echo "3. Быстрое восстановление (последний бэкап)" echo "0. Выход" echo "" read -p "Выберите действие [0-3]: " action case $action in 1) show_backups ;; 2) show_backups select_backup check_netbox_stopped restore_backup ;; 3) quick_restore ;; 0) echo "Выход." exit 0 ;; *) print_error "Неверный выбор!" exit 1 ;; esac } # Запуск main "$@"