upskill-event-manager/wordpress-dev/bin/fix-db-connection.sh

459 lines
No EOL
16 KiB
Bash
Executable file

#!/bin/bash
# =========================================================================
# fix-db-connection.sh
# =========================================================================
# Description: This script checks and fixes database connection issues on the
# staging server that are causing E2E test failures. It specifically addresses
# the "Access denied for user 'root'@'localhost'" error by verifying and
# correcting database configuration settings in local scripts and configurations.
#
# Usage: ./bin/fix-db-connection.sh [--verbose] [--dry-run]
#
# Options:
# --verbose Show detailed output during execution
# --dry-run Show what would be done without making changes
#
# Author: Roo Code
# Date: April 24, 2025
# =========================================================================
# Get absolute path to this script's directory
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Load environment variables
ENV_FILE="$SCRIPT_DIR/../.env"
if [ ! -f "$ENV_FILE" ]; then
echo "Error: .env file not found at: $ENV_FILE"
exit 1
fi
source "$ENV_FILE"
# Colors for output
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# Default options
VERBOSE=false
DRY_RUN=false
# Parse command line arguments
for arg in "$@"; do
case $arg in
--verbose)
VERBOSE=true
shift
;;
--dry-run)
DRY_RUN=true
shift
;;
--help)
echo "Usage: $0 [--verbose] [--dry-run]"
echo ""
echo "Options:"
echo " --verbose Show detailed output during execution"
echo " --dry-run Show what would be done without making changes"
echo " --help Show this help message"
exit 0
;;
esac
done
# Function to check if a command was successful
check_status() {
if [ $? -eq 0 ]; then
echo -e "${GREEN}$1${NC}"
return 0
else
echo -e "${RED}$1${NC}"
return 1
fi
}
# Function to log verbose output
log_verbose() {
if [ "$VERBOSE" = true ]; then
echo -e "${BLUE}[INFO] $1${NC}"
fi
}
# Function to log error messages
log_error() {
echo -e "${RED}[ERROR] $1${NC}"
}
# Function to log warning messages
log_warning() {
echo -e "${YELLOW}[WARNING] $1${NC}"
}
# Function to log success messages
log_success() {
echo -e "${GREEN}[SUCCESS] $1${NC}"
}
# Function to check SSH connection
check_ssh_connection() {
log_verbose "Testing SSH connection to staging server..."
if ! sshpass -p "$UPSKILL_STAGING_PASS" ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 "$UPSKILL_STAGING_SSH_USER@$UPSKILL_STAGING_IP" "echo 'SSH connection successful'" > /dev/null 2>&1; then
log_error "Cannot connect to staging server. Please check your SSH credentials and network connection."
exit 1
fi
log_verbose "SSH connection successful."
}
# Function to check database connection from staging server
check_remote_db_connection() {
log_verbose "Testing database connection from staging server..."
# Construct the MySQL command to run on the staging server
local mysql_cmd="mysql -h localhost -u $UPSKILL_STAGING_DB_USER -p'$UPSKILL_STAGING_DB_PASSWORD' $UPSKILL_STAGING_DB_NAME -e 'SELECT 1;' 2>&1"
# Execute the command on the staging server
local result
result=$(sshpass -p "$UPSKILL_STAGING_PASS" ssh -o StrictHostKeyChecking=no "$UPSKILL_STAGING_SSH_USER@$UPSKILL_STAGING_IP" "$mysql_cmd")
# Check if the command was successful
if [[ $result == *"1"* ]]; then
log_success "Database connection from staging server successful."
return 0
else
log_error "Database connection from staging server failed: $result"
return 1
fi
}
# Function to check database connection from local machine
check_local_db_connection() {
log_verbose "Testing database connection from local machine..."
# Construct the MySQL command to run locally
local mysql_cmd="mysql -h $UPSKILL_STAGING_IP -u $UPSKILL_STAGING_DB_USER -p'$UPSKILL_STAGING_DB_PASSWORD' $UPSKILL_STAGING_DB_NAME -e 'SELECT 1;' 2>&1"
# Execute the command locally
local result
result=$(eval "$mysql_cmd")
# Check if the command was successful
if [[ $result == *"1"* ]]; then
log_success "Database connection from local machine successful."
return 0
else
log_warning "Database connection from local machine failed: $result"
log_verbose "This is expected if the database is not accessible from outside the server."
return 1
fi
}
# Function to check WordPress database configuration
check_wp_config() {
log_verbose "Checking WordPress database configuration on staging server..."
# Get the database configuration from wp-config.php
local wp_config_cmd="cd $UPSKILL_STAGING_PATH && grep -E \"^define\\('DB_[A-Z]+', '.*'\\);\" wp-config.php"
local wp_config
wp_config=$(sshpass -p "$UPSKILL_STAGING_PASS" ssh -o StrictHostKeyChecking=no "$UPSKILL_STAGING_SSH_USER@$UPSKILL_STAGING_IP" "$wp_config_cmd")
# Extract database settings
local db_name=$(echo "$wp_config" | grep "DB_NAME" | sed -E "s/define\('DB_NAME', '(.*)'\);/\1/")
local db_user=$(echo "$wp_config" | grep "DB_USER" | sed -E "s/define\('DB_USER', '(.*)'\);/\1/")
local db_password=$(echo "$wp_config" | grep "DB_PASSWORD" | sed -E "s/define\('DB_PASSWORD', '(.*)'\);/\1/")
local db_host=$(echo "$wp_config" | grep "DB_HOST" | sed -E "s/define\('DB_HOST', '(.*)'\);/\1/")
echo "Current WordPress database configuration on staging server:"
echo " DB_NAME: $db_name"
echo " DB_USER: $db_user"
echo " DB_HOST: $db_host"
echo " DB_PASSWORD: [HIDDEN]"
# Check if the configuration matches the environment variables
if [ "$db_name" != "$UPSKILL_STAGING_DB_NAME" ]; then
log_warning "DB_NAME in wp-config.php ($db_name) does not match .env file ($UPSKILL_STAGING_DB_NAME)"
fi
if [ "$db_user" != "$UPSKILL_STAGING_DB_USER" ]; then
log_warning "DB_USER in wp-config.php ($db_user) does not match .env file ($UPSKILL_STAGING_DB_USER)"
fi
if [ "$db_password" != "$UPSKILL_STAGING_DB_PASSWORD" ]; then
log_warning "DB_PASSWORD in wp-config.php does not match .env file"
fi
# Return the extracted values
echo "$db_name|$db_user|$db_password|$db_host"
}
# Function to check for hardcoded database credentials in test files
check_test_files() {
log_verbose "Checking for hardcoded database credentials in test files..."
# Search for 'root' user in test files
local search_cmd="find $SCRIPT_DIR/.. -type f -name \"*.php\" -o -name \"*.js\" -o -name \"*.ts\" | xargs grep -l \"'root'\\|\\\"root\\\"\" 2>/dev/null || true"
local files
files=$(eval "$search_cmd")
if [ -n "$files" ]; then
echo "Found files with potential hardcoded 'root' database user:"
echo "$files"
return 0
else
log_verbose "No files with hardcoded 'root' database user found."
return 1
fi
}
# Function to check Playwright configuration
check_playwright_config() {
log_verbose "Checking Playwright configuration..."
local config_file="$SCRIPT_DIR/../playwright.config.ts"
if [ ! -f "$config_file" ]; then
log_warning "Playwright configuration file not found: $config_file"
return 1
fi
# Check for database configuration in Playwright config
local db_config
db_config=$(grep -A 10 "database\|DB_" "$config_file" 2>/dev/null || true)
if [ -n "$db_config" ]; then
echo "Found database configuration in Playwright config:"
echo "$db_config"
return 0
else
log_verbose "No database configuration found in Playwright config."
return 1
fi
}
# Function to check E2E test files for database connection issues
check_e2e_tests() {
log_verbose "Checking E2E test files for database connection issues..."
local tests_dir="$SCRIPT_DIR/../tests"
if [ ! -d "$tests_dir" ]; then
log_warning "Tests directory not found: $tests_dir"
return 1
fi
# Search for database connection code in E2E test files
local search_cmd="find $tests_dir -type f -name \"*.spec.ts\" -o -name \"*.spec.js\" | xargs grep -l \"mysql\\|database\\|connection\\|root\" 2>/dev/null || true"
local files
files=$(eval "$search_cmd")
if [ -n "$files" ]; then
echo "Found E2E test files with potential database connection code:"
echo "$files"
return 0
else
log_verbose "No E2E test files with database connection code found."
return 1
fi
}
# Function to fix database connection in a file
fix_file() {
local file="$1"
local backup_file="${file}.bak.$(date +%Y%m%d%H%M%S)"
log_verbose "Fixing database connection in file: $file"
# Create a backup of the file
if [ "$DRY_RUN" = true ]; then
log_verbose "Would create backup of $file to $backup_file"
else
cp "$file" "$backup_file"
check_status "Created backup of $file"
fi
# Replace 'root' with the correct database user
if [ "$DRY_RUN" = true ]; then
log_verbose "Would replace 'root' with '$UPSKILL_STAGING_DB_USER' in $file"
else
sed -i.tmp "s/'root'/'$UPSKILL_STAGING_DB_USER'/g" "$file"
sed -i.tmp "s/\"root\"/\"$UPSKILL_STAGING_DB_USER\"/g" "$file"
rm -f "${file}.tmp"
check_status "Replaced 'root' with '$UPSKILL_STAGING_DB_USER' in $file"
fi
# Replace hardcoded password if found
if [ "$DRY_RUN" = true ]; then
log_verbose "Would replace hardcoded password with '$UPSKILL_STAGING_DB_PASSWORD' in $file"
else
# This is a simplified approach; in a real scenario, you'd need a more sophisticated pattern matching
sed -i.tmp "s/'password'/'$UPSKILL_STAGING_DB_PASSWORD'/g" "$file"
sed -i.tmp "s/\"password\"/\"$UPSKILL_STAGING_DB_PASSWORD\"/g" "$file"
rm -f "${file}.tmp"
check_status "Replaced hardcoded password in $file"
fi
}
# Function to check and fix wp-tests-config.php
check_wp_tests_config() {
log_verbose "Checking wp-tests-config.php..."
local config_file="$SCRIPT_DIR/../wp-tests-config.php"
if [ ! -f "$config_file" ]; then
log_warning "wp-tests-config.php not found: $config_file"
return 1
fi
# Check for 'root' user in wp-tests-config.php
local root_user
root_user=$(grep -E "define\\( *'DB_USER', *'root' *\\)" "$config_file" 2>/dev/null || true)
if [ -n "$root_user" ]; then
echo "Found 'root' user in wp-tests-config.php:"
echo "$root_user"
# Fix wp-tests-config.php
if [ "$DRY_RUN" = true ]; then
log_verbose "Would update wp-tests-config.php to use '$UPSKILL_STAGING_DB_USER' instead of 'root'"
else
local backup_file="${config_file}.bak.$(date +%Y%m%d%H%M%S)"
cp "$config_file" "$backup_file"
sed -i.tmp "s/define( *'DB_USER', *'root' *)/define( 'DB_USER', '$UPSKILL_STAGING_DB_USER' )/g" "$config_file"
sed -i.tmp "s/define( *'DB_PASSWORD', *'[^']*' *)/define( 'DB_PASSWORD', '$UPSKILL_STAGING_DB_PASSWORD' )/g" "$config_file"
rm -f "${config_file}.tmp"
check_status "Updated wp-tests-config.php to use correct database credentials"
fi
return 0
else
log_verbose "No 'root' user found in wp-tests-config.php."
return 1
fi
}
# Function to check and fix wp-tests-config-staging.php
check_wp_tests_config_staging() {
log_verbose "Checking wp-tests-config-staging.php..."
local config_file="$SCRIPT_DIR/wp-tests-config-staging.php"
if [ ! -f "$config_file" ]; then
log_warning "wp-tests-config-staging.php not found: $config_file"
return 1
fi
# Check for 'root' user in wp-tests-config-staging.php
local root_user
root_user=$(grep -E "define\\( *'DB_USER', *'root' *\\)" "$config_file" 2>/dev/null || true)
if [ -n "$root_user" ]; then
echo "Found 'root' user in wp-tests-config-staging.php:"
echo "$root_user"
# Fix wp-tests-config-staging.php
if [ "$DRY_RUN" = true ]; then
log_verbose "Would update wp-tests-config-staging.php to use '$UPSKILL_STAGING_DB_USER' instead of 'root'"
else
local backup_file="${config_file}.bak.$(date +%Y%m%d%H%M%S)"
cp "$config_file" "$backup_file"
sed -i.tmp "s/define( *'DB_USER', *'root' *)/define( 'DB_USER', '$UPSKILL_STAGING_DB_USER' )/g" "$config_file"
sed -i.tmp "s/define( *'DB_PASSWORD', *'[^']*' *)/define( 'DB_PASSWORD', '$UPSKILL_STAGING_DB_PASSWORD' )/g" "$config_file"
rm -f "${config_file}.tmp"
check_status "Updated wp-tests-config-staging.php to use correct database credentials"
fi
return 0
else
log_verbose "No 'root' user found in wp-tests-config-staging.php."
return 1
fi
}
# Main function
main() {
echo "=== Database Connection Fix Script ==="
echo "Staging Server: $UPSKILL_STAGING_IP"
echo "Database: $UPSKILL_STAGING_DB_NAME"
echo "User: $UPSKILL_STAGING_DB_USER"
echo "==============================="
if [ "$DRY_RUN" = true ]; then
echo -e "${YELLOW}Running in dry-run mode. No changes will be made.${NC}"
fi
# Step 1: Check SSH connection
echo -e "\n${YELLOW}Step 1: Checking SSH connection...${NC}"
check_ssh_connection
check_status "SSH connection check"
# Step 2: Check remote database connection
echo -e "\n${YELLOW}Step 2: Checking database connection from staging server...${NC}"
check_remote_db_connection
check_status "Remote database connection check"
# Step 3: Check WordPress configuration
echo -e "\n${YELLOW}Step 3: Checking WordPress configuration...${NC}"
check_wp_config
check_status "WordPress configuration check"
# Step 4: Check test files for hardcoded credentials
echo -e "\n${YELLOW}Step 4: Checking test files for hardcoded credentials...${NC}"
if check_test_files; then
echo "Found files with potential hardcoded credentials. Fixing..."
# Fix each file
for file in $(find $SCRIPT_DIR/.. -type f -name "*.php" -o -name "*.js" -o -name "*.ts" | xargs grep -l "'root'\\|\"root\"" 2>/dev/null || true); do
fix_file "$file"
done
else
echo "No files with hardcoded 'root' credentials found."
fi
# Step 5: Check and fix wp-tests-config.php
echo -e "\n${YELLOW}Step 5: Checking and fixing wp-tests-config.php...${NC}"
check_wp_tests_config
# Step 6: Check and fix wp-tests-config-staging.php
echo -e "\n${YELLOW}Step 6: Checking and fixing wp-tests-config-staging.php...${NC}"
check_wp_tests_config_staging
# Step 7: Check Playwright configuration
echo -e "\n${YELLOW}Step 7: Checking Playwright configuration...${NC}"
check_playwright_config
# Step 8: Check E2E test files
echo -e "\n${YELLOW}Step 8: Checking E2E test files...${NC}"
check_e2e_tests
# Step 9: Verify fixes
echo -e "\n${YELLOW}Step 9: Verifying fixes...${NC}"
if [ "$DRY_RUN" = false ]; then
# Check remote database connection again
check_remote_db_connection
check_status "Remote database connection verification"
# Run a simple E2E test if available
if [ -f "$SCRIPT_DIR/../node_modules/.bin/playwright" ]; then
echo "Running a simple Playwright test to verify database connection..."
cd "$SCRIPT_DIR/.." && npx playwright test -g "database connection" --headed
check_status "Playwright test"
else
log_warning "Playwright not found. Skipping E2E test verification."
fi
else
echo -e "${YELLOW}Skipping verification in dry-run mode.${NC}"
fi
# Summary
echo -e "\n${YELLOW}Summary:${NC}"
if [ "$DRY_RUN" = true ]; then
echo "Dry run completed. No changes were made."
echo "Run the script without --dry-run to apply the fixes."
else
echo "Database connection fix script completed."
echo "If you encounter any issues, you can restore the backup files created during the fix process."
fi
}
# Run the main function
main