#!/bin/bash # Author: Julien Gautier # Organization: AdAstra # Project: adastra_scripts # ################################################################################ # MongoDB Restore Utility Script (Standalone) # # This script restores MongoDB database dumps from backup files. # It provides interactive navigation through dump directories and restores # to a configured MongoDB instance. # # Usage: ./db-restore.sh # # Configuration: # Requires .env file with MongoDB connection details: # - MONGO_USERNAME # - MONGO_PASSWORD # - MONGO_HOST # - MONGO_PORT # - MONGO_DATABASE # - MONGO_AUTHSOURCE # # Example command (what the script executes): # mongorestore --uri "mongodb://user:pass@host:port/db?authSource=admin" /path/to/dumps # ################################################################################ set -e # Configuration SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" ENV_FILE="${SCRIPT_DIR}/.env" # Global variables SELECTED_DUMP_PATH="" # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' CYAN='\033[0;36m' NC='\033[0m' # Helper functions print_info() { echo -e "${BLUE}┣━${NC} ${CYAN}${1}${NC}" } print_success() { echo -e "${GREEN}✓ ${1}${NC}" } print_error() { echo -e "${RED}✗ ${1}${NC}" } print_warning() { echo -e "${YELLOW}⚠ ${1}${NC}" } print_separator() { echo -e "${BLUE}┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" } print_separator_up() { echo -e "${BLUE}┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" } print_separator_down() { echo -e "${BLUE}┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" } print_section() { echo print_separator_up print_info "$1" print_separator_down echo } check_mongorestore() { if ! command -v mongorestore &> /dev/null; then print_error "mongorestore is not installed or not in PATH" print_info "Install MongoDB Database Tools from: https://www.mongodb.com/try/download/database-tools" exit 1 fi print_success "mongorestore found: $(mongorestore --version | head -1)" } check_env_file() { if [[ ! -f "$ENV_FILE" ]]; then print_error "Configuration file not found: $ENV_FILE" print_info "Please create .env file with the following variables:" print_info " MONGO_USERNAME=" print_info " MONGO_PASSWORD=" print_info " MONGO_HOST=" print_info " MONGO_PORT=" print_info " MONGO_DATABASE=" print_info " MONGO_AUTHSOURCE=" print_info "You can copy from .env.example" exit 1 fi } load_config() { # shellcheck source=/dev/null source "$ENV_FILE" # Validate required variables if [[ -z "$MONGO_USERNAME" ]] || [[ -z "$MONGO_PASSWORD" ]] || [[ -z "$MONGO_HOST" ]] || \ [[ -z "$MONGO_PORT" ]] || [[ -z "$MONGO_DATABASE" ]] || [[ -z "$MONGO_AUTHSOURCE" ]]; then print_error "Missing required configuration variables in .env file" exit 1 fi } has_bson_files() { local dir="$1" [[ -n $(find "$dir" -maxdepth 1 -type f -name "*.bson" 2>/dev/null | head -1) ]] } has_subdirectories() { local dir="$1" [[ -n $(find "$dir" -maxdepth 1 -type d ! -name "." ! -name ".." 2>/dev/null | head -1) ]] } navigate_to_dump() { SELECTED_DUMP_PATH="" local current_path="$1" # Expand ~ in path current_path="${current_path/#\~/$HOME}" # Check if path exists if [[ ! -d "$current_path" ]]; then print_error "Path does not exist: $current_path" return 1 fi # If this directory has BSON files, we're at the right level if has_bson_files "$current_path"; then SELECTED_DUMP_PATH="$current_path" return 0 fi # If no subdirectories and no BSON files, this isn't a valid dump directory if ! has_subdirectories "$current_path"; then print_error "No BSON files found and no subdirectories in: $current_path" return 1 fi # Navigate through subdirectories while true; do print_separator_up print_info "Select Dump Directory" print_separator_down echo print_info "Current location: $current_path" echo # Get list of subdirectories local subdirs=() local count=0 # Read subdirectories into array (null-terminated, excluding . and ..) while IFS= read -r -d '' subdir; do subdirs+=("$subdir") echo " $((++count))) $(basename "$subdir")" done < <(find "$current_path" -maxdepth 1 -mindepth 1 -type d -print0 | sort -z) if [[ $count -eq 0 ]]; then print_error "No subdirectories found in: $current_path" return 1 fi echo echo -n "Enter your choice (1-$count): " read choice if [[ "$choice" =~ ^[0-9]+$ ]] && [[ $choice -ge 1 ]] && [[ $choice -le $count ]]; then current_path="${subdirs[$((choice - 1))]}" # Check if this directory has BSON files if has_bson_files "$current_path"; then SELECTED_DUMP_PATH="$current_path" return 0 fi # If no more subdirectories and no BSON files, error if ! has_subdirectories "$current_path"; then print_error "No BSON files found in: $current_path" return 1 fi # Continue loop to show next level else print_error "Invalid choice" fi done } get_backup_summary() { local dump_path="$1" local bson_count=$(find "$dump_path" -name "*.bson" -type f 2>/dev/null | wc -l) local total_size=$(du -sh "$dump_path" 2>/dev/null | cut -f1) echo "Backup files: $bson_count" echo "Total size: $total_size" } show_summary() { local dump_path="$1" print_section "Restore Summary" echo "MongoDB Connection:" echo " Host: $MONGO_HOST" echo " Port: $MONGO_PORT" echo " Username: $MONGO_USERNAME" echo " Database: $MONGO_DATABASE" echo " AuthSource: $MONGO_AUTHSOURCE" echo echo "Backup Source:" echo " Location: $dump_path" echo " $(get_backup_summary "$dump_path")" echo echo "Connection string:" echo " mongodb://:@$MONGO_HOST:$MONGO_PORT/$MONGO_DATABASE?authSource=$MONGO_AUTHSOURCE" echo } confirm_restore() { echo -n "Do you want to proceed with the restore? (yes/no): " read response [[ "$response" == "yes" ]] } perform_restore() { local dump_path="$1" print_separator_up print_info "Starting MongoDB Restore..." print_separator_down echo # Construct connection string local connection_uri="mongodb://${MONGO_USERNAME}:${MONGO_PASSWORD}@${MONGO_HOST}:${MONGO_PORT}/${MONGO_DATABASE}?authSource=${MONGO_AUTHSOURCE}" # Perform restore if mongorestore --uri "$connection_uri" "$dump_path" 2>&1; then print_success "Restore completed successfully" return 0 else print_error "Restore operation failed" return 1 fi } main() { print_separator_up print_info "MongoDB Restore Utility" print_separator_down # Initial checks check_mongorestore check_env_file load_config print_success "Configuration loaded" echo # Ask for initial dump path print_info "Enter the path to the dumps directory" echo " Example: ~/Works/dbdump/dumps" echo echo -n "Dumps path: " read dumps_path if [[ -z "$dumps_path" ]]; then print_error "Dumps path cannot be empty" return 1 fi # Navigate to the correct dump directory print_info "Navigating to backup location..." navigate_to_dump "$dumps_path" if [[ $? -ne 0 ]]; then print_error "Failed to select backup directory" return 1 fi # Show summary of what will be restored show_summary "$SELECTED_DUMP_PATH" # Ask for confirmation if ! confirm_restore; then print_info "Restore operation cancelled" return 1 fi # Perform the restore if perform_restore "$SELECTED_DUMP_PATH"; then print_success "Restore operation completed" else print_error "Restore operation failed" return 1 fi } main "$@"