Rustelo/scripts/setup/setup-config.sh

486 lines
15 KiB
Bash
Raw Normal View History

2025-07-07 23:53:50 +01:00
#!/bin/bash
# Configuration Setup Script
# This script helps initialize the configuration system for your Rust application
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Function to print colored output
print_status() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
print_header() {
echo -e "${BLUE}$1${NC}"
}
# Function to check if a command exists
command_exists() {
command -v "$1" >/dev/null 2>&1
}
# Function to prompt for user input
prompt_user() {
local prompt="$1"
local default="$2"
local result
if [ -n "$default" ]; then
echo -n "$prompt [$default]: "
else
echo -n "$prompt: "
fi
read -r result
if [ -z "$result" ] && [ -n "$default" ]; then
result="$default"
fi
echo "$result"
}
# Function to generate a random secret
generate_secret() {
openssl rand -base64 32 2>/dev/null || echo "change-this-to-a-secure-random-string-$(date +%s)"
}
# Main setup function
setup_config() {
print_header "=== Rust Application Configuration Setup ==="
echo
# Check dependencies
print_status "Checking dependencies..."
if ! command_exists "cargo"; then
print_error "Cargo is required but not installed. Please install Rust first."
exit 1
fi
# Determine environment
print_status "Configuring environment..."
ENVIRONMENT=$(prompt_user "Enter environment (dev/prod)" "dev")
case "$ENVIRONMENT" in
"dev"|"development")
ENVIRONMENT="dev"
CONFIG_FILE="config.dev.toml"
;;
"prod"|"production")
ENVIRONMENT="prod"
CONFIG_FILE="config.prod.toml"
;;
*)
print_warning "Unknown environment '$ENVIRONMENT', using 'dev'"
ENVIRONMENT="dev"
CONFIG_FILE="config.dev.toml"
;;
esac
print_status "Environment: $ENVIRONMENT"
print_status "Config file: $CONFIG_FILE"
# Check if config file already exists
if [ -f "$CONFIG_FILE" ]; then
print_warning "Configuration file $CONFIG_FILE already exists."
OVERWRITE=$(prompt_user "Overwrite existing file? (y/N)" "n")
if [[ ! "$OVERWRITE" =~ ^[Yy]$ ]]; then
print_status "Keeping existing configuration file."
CONFIG_EXISTS=true
else
CONFIG_EXISTS=false
fi
else
CONFIG_EXISTS=false
fi
# Create configuration file if it doesn't exist or should be overwritten
if [ "$CONFIG_EXISTS" != true ]; then
print_status "Creating configuration file..."
# Get configuration values from user
APP_NAME=$(prompt_user "Application name" "My Rust App")
APP_VERSION=$(prompt_user "Application version" "0.1.0")
if [ "$ENVIRONMENT" = "dev" ]; then
SERVER_HOST=$(prompt_user "Server host" "127.0.0.1")
SERVER_PORT=$(prompt_user "Server port" "3030")
SERVER_PROTOCOL=$(prompt_user "Server protocol (http/https)" "http")
LOG_LEVEL=$(prompt_user "Log level (debug/info/warn/error)" "debug")
DATABASE_URL=$(prompt_user "Database URL" "postgresql://dev:dev@localhost:5432/${APP_NAME,,}_dev")
else
SERVER_HOST=$(prompt_user "Server host" "0.0.0.0")
SERVER_PORT=$(prompt_user "Server port" "443")
SERVER_PROTOCOL=$(prompt_user "Server protocol (http/https)" "https")
LOG_LEVEL=$(prompt_user "Log level (debug/info/warn/error)" "info")
DATABASE_URL=$(prompt_user "Database URL" "postgresql://prod:\${DATABASE_PASSWORD}@db.example.com:5432/${APP_NAME,,}_prod")
fi
# Create the configuration file
cat > "$CONFIG_FILE" << EOF
# ${APP_NAME} Configuration - ${ENVIRONMENT^} Environment
[server]
protocol = "${SERVER_PROTOCOL}"
host = "${SERVER_HOST}"
port = ${SERVER_PORT}
environment = "${ENVIRONMENT}"
log_level = "${LOG_LEVEL}"
EOF
# Add TLS configuration if HTTPS
if [ "$SERVER_PROTOCOL" = "https" ]; then
if [ "$ENVIRONMENT" = "dev" ]; then
TLS_CERT_PATH=$(prompt_user "TLS certificate path" "certs/server.crt")
TLS_KEY_PATH=$(prompt_user "TLS private key path" "certs/server.key")
else
TLS_CERT_PATH=$(prompt_user "TLS certificate path" "/etc/ssl/certs/server.crt")
TLS_KEY_PATH=$(prompt_user "TLS private key path" "/etc/ssl/private/server.key")
fi
cat >> "$CONFIG_FILE" << EOF
# TLS Configuration
[server.tls]
cert_path = "${TLS_CERT_PATH}"
key_path = "${TLS_KEY_PATH}"
EOF
fi
# Add database configuration
cat >> "$CONFIG_FILE" << EOF
# Database Configuration
[database]
url = "${DATABASE_URL}"
max_connections = $([ "$ENVIRONMENT" = "dev" ] && echo "5" || echo "20")
min_connections = 1
connect_timeout = 30
idle_timeout = 600
max_lifetime = 1800
EOF
# Add session configuration
cat >> "$CONFIG_FILE" << EOF
# Session Configuration
[session]
secret = $([ "$ENVIRONMENT" = "dev" ] && echo "\"dev-secret-not-for-production\"" || echo "\"\${SESSION_SECRET}\"")
cookie_name = "session_id"
cookie_secure = $([ "$SERVER_PROTOCOL" = "https" ] && echo "true" || echo "false")
cookie_http_only = true
cookie_same_site = $([ "$ENVIRONMENT" = "dev" ] && echo "\"lax\"" || echo "\"strict\"")
max_age = $([ "$ENVIRONMENT" = "dev" ] && echo "7200" || echo "3600")
EOF
# Add remaining configuration sections
cat >> "$CONFIG_FILE" << EOF
# CORS Configuration
[cors]
allowed_origins = [$([ "$ENVIRONMENT" = "dev" ] && echo "\"http://localhost:3030\", \"http://127.0.0.1:3030\"" || echo "\"https://yourdomain.com\"")]
allowed_methods = ["GET", "POST", "PUT", "DELETE", "OPTIONS"]
allowed_headers = ["Content-Type", "Authorization", "X-Requested-With"]
allow_credentials = true
max_age = 3600
# Static Files Configuration
[static]
assets_dir = "public"
site_root = "target/site"
site_pkg_dir = "pkg"
# Server Directories Configuration
[server_dirs]
public_dir = $([ "$ENVIRONMENT" = "dev" ] && echo "\"public\"" || echo "\"/var/www/public\"")
uploads_dir = $([ "$ENVIRONMENT" = "dev" ] && echo "\"uploads\"" || echo "\"/var/www/uploads\"")
logs_dir = $([ "$ENVIRONMENT" = "dev" ] && echo "\"logs\"" || echo "\"/var/log/app\"")
temp_dir = $([ "$ENVIRONMENT" = "dev" ] && echo "\"tmp\"" || echo "\"/tmp/app\"")
cache_dir = $([ "$ENVIRONMENT" = "dev" ] && echo "\"cache\"" || echo "\"/var/cache/app\"")
config_dir = $([ "$ENVIRONMENT" = "dev" ] && echo "\"config\"" || echo "\"/etc/app\"")
data_dir = $([ "$ENVIRONMENT" = "dev" ] && echo "\"data\"" || echo "\"/var/lib/app\"")
backup_dir = $([ "$ENVIRONMENT" = "dev" ] && echo "\"backups\"" || echo "\"/var/backups/app\"")
# Security Configuration
[security]
enable_csrf = $([ "$ENVIRONMENT" = "dev" ] && echo "false" || echo "true")
csrf_token_name = "csrf_token"
rate_limit_requests = $([ "$ENVIRONMENT" = "dev" ] && echo "1000" || echo "50")
rate_limit_window = 60
bcrypt_cost = $([ "$ENVIRONMENT" = "dev" ] && echo "4" || echo "12")
# OAuth Configuration
[oauth]
enabled = false
[oauth.google]
client_id = "\${GOOGLE_CLIENT_ID}"
client_secret = "\${GOOGLE_CLIENT_SECRET}"
redirect_uri = "${SERVER_PROTOCOL}://${SERVER_HOST}:${SERVER_PORT}/auth/google/callback"
[oauth.github]
client_id = "\${GITHUB_CLIENT_ID}"
client_secret = "\${GITHUB_CLIENT_SECRET}"
redirect_uri = "${SERVER_PROTOCOL}://${SERVER_HOST}:${SERVER_PORT}/auth/github/callback"
# Email Configuration
[email]
enabled = false
smtp_host = "smtp.gmail.com"
smtp_port = 587
smtp_username = "\${SMTP_USERNAME}"
smtp_password = "\${SMTP_PASSWORD}"
from_email = "noreply@example.com"
from_name = "${APP_NAME}"
# Redis Configuration
[redis]
enabled = false
url = "redis://localhost:6379"
pool_size = 10
connection_timeout = 5
command_timeout = 5
# Application Settings
[app]
name = "${APP_NAME}"
version = "${APP_VERSION}"
debug = $([ "$ENVIRONMENT" = "dev" ] && echo "true" || echo "false")
enable_metrics = $([ "$ENVIRONMENT" = "dev" ] && echo "true" || echo "true")
enable_health_check = true
enable_compression = $([ "$ENVIRONMENT" = "dev" ] && echo "false" || echo "true")
max_request_size = $([ "$ENVIRONMENT" = "dev" ] && echo "52428800" || echo "5242880")
# Logging Configuration
[logging]
format = $([ "$ENVIRONMENT" = "dev" ] && echo "\"text\"" || echo "\"json\"")
level = "${LOG_LEVEL}"
file_path = "logs/app.log"
max_file_size = 10485760
max_files = 5
enable_console = true
enable_file = $([ "$ENVIRONMENT" = "dev" ] && echo "true" || echo "true")
# Content Management
[content]
enabled = false
content_dir = "content"
cache_enabled = $([ "$ENVIRONMENT" = "dev" ] && echo "false" || echo "true")
cache_ttl = 3600
max_file_size = 5242880
# Feature Flags
[features]
auth = true
tls = $([ "$SERVER_PROTOCOL" = "https" ] && echo "true" || echo "false")
content_db = true
two_factor_auth = false
EOF
print_status "Configuration file created: $CONFIG_FILE"
fi
# Create .env file
ENV_FILE=".env"
if [ "$ENVIRONMENT" = "dev" ]; then
ENV_FILE=".env.development"
elif [ "$ENVIRONMENT" = "prod" ]; then
ENV_FILE=".env.production"
fi
if [ -f "$ENV_FILE" ]; then
print_warning "Environment file $ENV_FILE already exists."
OVERWRITE_ENV=$(prompt_user "Overwrite existing environment file? (y/N)" "n")
if [[ ! "$OVERWRITE_ENV" =~ ^[Yy]$ ]]; then
print_status "Keeping existing environment file."
ENV_EXISTS=true
else
ENV_EXISTS=false
fi
else
ENV_EXISTS=false
fi
if [ "$ENV_EXISTS" != true ]; then
print_status "Creating environment file..."
cat > "$ENV_FILE" << EOF
# Environment Configuration for ${ENVIRONMENT^}
ENVIRONMENT=${ENVIRONMENT}
# Database Configuration
EOF
if [ "$ENVIRONMENT" = "dev" ]; then
cat >> "$ENV_FILE" << EOF
DATABASE_URL=postgresql://dev:dev@localhost:5432/myapp_dev
# Session Configuration
SESSION_SECRET=dev-secret-not-for-production
EOF
else
cat >> "$ENV_FILE" << EOF
DATABASE_PASSWORD=your-production-database-password
# Session Configuration
SESSION_SECRET=$(generate_secret)
EOF
fi
cat >> "$ENV_FILE" << EOF
# OAuth Configuration (optional)
# GOOGLE_CLIENT_ID=your-google-client-id
# GOOGLE_CLIENT_SECRET=your-google-client-secret
# GITHUB_CLIENT_ID=your-github-client-id
# GITHUB_CLIENT_SECRET=your-github-client-secret
# Email Configuration (optional)
# SMTP_USERNAME=your-smtp-username
# SMTP_PASSWORD=your-smtp-password
# Server Overrides (optional)
# SERVER_HOST=0.0.0.0
# SERVER_PORT=8080
# LOG_LEVEL=debug
EOF
print_status "Environment file created: $ENV_FILE"
fi
# Create directories
print_status "Creating directories..."
# Create basic directories
mkdir -p logs
mkdir -p content/public
# Create server directories based on environment
if [ "$ENVIRONMENT" = "dev" ]; then
mkdir -p public uploads tmp cache config data backups
print_status "Created development directories: public, uploads, logs, tmp, cache, config, data, backups"
else
print_status "Production directories should be created by system administrator with proper permissions"
print_warning "Required directories: /var/www/public, /var/www/uploads, /var/log/app, /tmp/app, /var/cache/app, /etc/app, /var/lib/app, /var/backups/app"
fi
if [ "$SERVER_PROTOCOL" = "https" ]; then
mkdir -p certs
print_warning "HTTPS is enabled. You'll need to provide TLS certificates in the certs/ directory."
fi
# Create a default config.toml symlink if it doesn't exist
if [ ! -f "config.toml" ]; then
ln -sf "$CONFIG_FILE" config.toml
print_status "Created config.toml symlink to $CONFIG_FILE"
fi
# Validate configuration
print_status "Validating configuration..."
if command_exists "cargo"; then
if cargo run --bin config_tool -- validate 2>/dev/null; then
print_status "Configuration validation passed!"
else
print_warning "Configuration validation failed. Please check your settings."
fi
else
print_warning "Could not validate configuration (cargo not found)."
fi
# Display next steps
print_header "=== Setup Complete ==="
echo
print_status "Configuration has been set up successfully!"
echo
print_status "Next steps:"
echo "1. Review and customize your configuration file: $CONFIG_FILE"
echo "2. Set up your environment variables: $ENV_FILE"
echo "3. If using HTTPS, place your TLS certificates in the certs/ directory"
echo "4. Set up your database and update the connection string"
echo "5. Configure OAuth providers if needed"
echo "6. Run 'cargo run --bin config_tool -- show' to view your configuration"
echo "7. Start your application with 'cargo run'"
echo
if [ "$ENVIRONMENT" = "prod" ]; then
print_warning "Production environment detected!"
echo "- Make sure to set secure values for SESSION_SECRET and DATABASE_PASSWORD"
echo "- Review all security settings in your configuration"
echo "- Use proper secrets management in production"
echo "- Enable HTTPS with valid TLS certificates"
fi
print_status "For more information, see CONFIG_README.md"
}
# Function to show usage
show_usage() {
echo "Usage: $0 [OPTIONS]"
echo
echo "Options:"
echo " -h, --help Show this help message"
echo " -e, --env ENV Set environment (dev/prod)"
echo " -f, --force Overwrite existing files without prompting"
echo
echo "Examples:"
echo " $0 # Interactive setup"
echo " $0 -e dev # Setup for development"
echo " $0 -e prod # Setup for production"
echo " $0 -f # Force overwrite existing files"
}
# Parse command line arguments
FORCE=false
ENV_ARG=""
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help)
show_usage
exit 0
;;
-e|--env)
ENV_ARG="$2"
shift 2
;;
-f|--force)
FORCE=true
shift
;;
*)
print_error "Unknown option: $1"
show_usage
exit 1
;;
esac
done
# Set environment if provided
if [ -n "$ENV_ARG" ]; then
ENVIRONMENT="$ENV_ARG"
fi
# Set force mode
if [ "$FORCE" = true ]; then
export FORCE_OVERWRITE=true
fi
# Run setup
setup_config