ohs to nginx – c

#!/bin/bash

# OHS to Nginx Configuration Converter
# Converts Oracle HTTP Server configuration files to Nginx format
# Author: Configuration Converter Script
# Version: 1.0

set -euo pipefail

# Configuration
OHS_CONFIG_DIR="${1:-./ohs_config}"
OUTPUT_FILE="${2:-nginx.conf}"
TEMP_DIR="/tmp/ohs_nginx_convert_$$"

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# Logging functions
log_info() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

log_warn() {
    echo -e "${YELLOW}[WARN]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

log_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

# Cleanup function
cleanup() {
    if [[ -d "$TEMP_DIR" ]]; then
        rm -rf "$TEMP_DIR"
    fi
}

trap cleanup EXIT

# Initialize
init() {
    log_info "Starting OHS to Nginx conversion..."
    
    if [[ ! -d "$OHS_CONFIG_DIR" ]]; then
        log_error "OHS config directory '$OHS_CONFIG_DIR' not found!"
        echo "Usage: $0 [ohs_config_directory] [output_file]"
        exit 1
    fi
    
    mkdir -p "$TEMP_DIR"
    
    # Initialize output file
    cat > "$OUTPUT_FILE" << 'EOF'
# Nginx configuration converted from Oracle HTTP Server
# Generated automatically - review before use

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

events {
    worker_connections 1024;
    use epoll;
    multi_accept on;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    
    # Logging format
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                   '$status $body_bytes_sent "$http_referer" '
                   '"$http_user_agent" "$http_x_forwarded_for"';
    
    access_log /var/log/nginx/access.log main;
    
    # Basic settings
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    server_tokens off;
    
    # Gzip compression
    gzip on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml;

EOF
}

# Extract server instances from config files
find_instances() {
    local instances=()
    
    # Look for instance-specific files
    for file in "$OHS_CONFIG_DIR"/*; do
        if [[ -f "$file" ]]; then
            filename=$(basename "$file")
            # Extract instance name from files like OHS1_ssl.conf, OHS2_httpd.conf, etc.
            if [[ "$filename" =~ ^([A-Z0-9]+)_.*\.conf$ ]]; then
                instance="${BASH_REMATCH[1]}"
                if [[ ! " ${instances[*]} " =~ " ${instance} " ]]; then
                    instances+=("$instance")
                fi
            # Also check for non-prefixed files (default instance)
            elif [[ "$filename" =~ ^(httpd|ssl|mod_wl_ohs)\.conf$ ]]; then
                if [[ ! " ${instances[*]} " =~ " DEFAULT " ]]; then
                    instances+=("DEFAULT")
                fi
            fi
        fi
    done
    
    echo "${instances[@]}"
}

# Parse Apache/OHS Listen directives
parse_listen_directives() {
    local config_file="$1"
    local temp_file="$TEMP_DIR/listen_$(basename "$config_file")"
    
    if [[ ! -f "$config_file" ]]; then
        return
    fi
    
    grep -i "^[[:space:]]*Listen" "$config_file" 2>/dev/null | while read -r line; do
        # Remove comments
        line=$(echo "$line" | sed 's/#.*//')
        
        if [[ "$line" =~ Listen[[:space:]]+([0-9.]*:?[0-9]+)([[:space:]]+ssl)? ]]; then
            listen_addr="${BASH_REMATCH[1]}"
            ssl_flag="${BASH_REMATCH[2]}"
            
            # Convert to nginx format
            if [[ -n "$ssl_flag" ]]; then
                echo "    listen $listen_addr ssl http2;" >> "$temp_file"
            else
                echo "    listen $listen_addr;" >> "$temp_file"
            fi
        fi
    done
}

# Parse VirtualHost directives
parse_virtual_hosts() {
    local config_file="$1"
    local instance="$2"
    local temp_file="$TEMP_DIR/vhosts_${instance}_$(basename "$config_file")"
    local in_vhost=false
    local vhost_addr=""
    local server_name=""
    local document_root=""
    local ssl_cert=""
    local ssl_key=""
    local locations=""
    
    if [[ ! -f "$config_file" ]]; then
        return
    fi
    
    while IFS= read -r line; do
        # Remove leading/trailing whitespace and comments
        line=$(echo "$line" | sed 's/^[[:space:]]*//' | sed 's/#.*//')
        
        if [[ "$line" =~ ^\<VirtualHost[[:space:]]+([^>]+)\> ]]; then
            in_vhost=true
            vhost_addr="${BASH_REMATCH[1]}"
            # Reset variables for new vhost
            server_name=""
            document_root=""
            ssl_cert=""
            ssl_key=""
            locations=""
            
        elif [[ "$line" =~ ^\</VirtualHost\> ]] && [[ "$in_vhost" == true ]]; then
            # Generate nginx server block
            {
                echo ""
                echo "    # Virtual Host from $instance"
                echo "    server {"
                
                # Listen directive
                if [[ "$vhost_addr" =~ ([0-9.]*):([0-9]+) ]]; then
                    ip="${BASH_REMATCH[1]}"
                    port="${BASH_REMATCH[2]}"
                    if [[ "$port" == "443" ]] || [[ -n "$ssl_cert" ]]; then
                        echo "        listen ${ip:+$ip:}$port ssl http2;"
                    else
                        echo "        listen ${ip:+$ip:}$port;"
                    fi
                else
                    echo "        listen $vhost_addr;"
                fi
                
                # Server name
                if [[ -n "$server_name" ]]; then
                    echo "        server_name $server_name;"
                fi
                
                # SSL certificates
                if [[ -n "$ssl_cert" ]]; then
                    echo "        ssl_certificate $ssl_cert;"
                fi
                if [[ -n "$ssl_key" ]]; then
                    echo "        ssl_certificate_key $ssl_key;"
                fi
                
                # Document root
                if [[ -n "$document_root" ]]; then
                    echo "        root $document_root;"
                    echo "        index index.html index.htm index.php;"
                fi
                
                # Default location if document root exists
                if [[ -n "$document_root" ]]; then
                    echo ""
                    echo "        location / {"
                    echo "            try_files \$uri \$uri/ =404;"
                    echo "        }"
                fi
                
                # Additional locations
                if [[ -n "$locations" ]]; then
                    echo "$locations"
                fi
                
                echo "    }"
            } >> "$temp_file"
            
            in_vhost=false
            
        elif [[ "$in_vhost" == true ]]; then
            # Parse directives within VirtualHost
            if [[ "$line" =~ ^ServerName[[:space:]]+(.+) ]]; then
                server_name="${BASH_REMATCH[1]}"
            elif [[ "$line" =~ ^ServerAlias[[:space:]]+(.+) ]]; then
                server_name="$server_name ${BASH_REMATCH[1]}"
            elif [[ "$line" =~ ^DocumentRoot[[:space:]]+(.+) ]]; then
                document_root="${BASH_REMATCH[1]}"
                # Remove quotes if present
                document_root="${document_root//\"/}"
            elif [[ "$line" =~ ^SSLCertificateFile[[:space:]]+(.+) ]]; then
                ssl_cert="${BASH_REMATCH[1]}"
            elif [[ "$line" =~ ^SSLCertificateKeyFile[[:space:]]+(.+) ]]; then
                ssl_key="${BASH_REMATCH[1]}"
            fi
        fi
    done < "$config_file"
}

# Parse mod_weblogic (mod_wl_ohs) configuration
parse_weblogic_config() {
    local config_file="$1"
    local instance="$2"
    local temp_file="$TEMP_DIR/weblogic_${instance}_$(basename "$config_file")"
    
    if [[ ! -f "$config_file" ]]; then
        return
    fi
    
    # Look for WebLogicHost, WebLogicPort, and Location directives
    while IFS= read -r line; do
        line=$(echo "$line" | sed 's/^[[:space:]]*//' | sed 's/#.*//')
        
        if [[ "$line" =~ ^\<Location[[:space:]]+(.+)\> ]]; then
            location_path="${BASH_REMATCH[1]}"
            echo "" >> "$temp_file"
            echo "        # WebLogic location block" >> "$temp_file"
            echo "        location $location_path {" >> "$temp_file"
            
            # Read until </Location>
            while IFS= read -r wl_line; do
                wl_line=$(echo "$wl_line" | sed 's/^[[:space:]]*//' | sed 's/#.*//')
                
                if [[ "$wl_line" =~ ^\</Location\> ]]; then
                    break
                elif [[ "$wl_line" =~ ^WebLogicHost[[:space:]]+(.+) ]]; then
                    wl_host="${BASH_REMATCH[1]}"
                elif [[ "$wl_line" =~ ^WebLogicPort[[:space:]]+([0-9]+) ]]; then
                    wl_port="${BASH_REMATCH[1]}"
                elif [[ "$wl_line" =~ ^SetHandler[[:space:]]+weblogic-handler ]]; then
                    # Generate upstream and proxy_pass
                    if [[ -n "${wl_host:-}" && -n "${wl_port:-}" ]]; then
                        echo "            proxy_pass http://$wl_host:$wl_port;" >> "$temp_file"
                        echo "            proxy_set_header Host \$host;" >> "$temp_file"
                        echo "            proxy_set_header X-Real-IP \$remote_addr;" >> "$temp_file"
                        echo "            proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;" >> "$temp_file"
                        echo "            proxy_set_header X-Forwarded-Proto \$scheme;" >> "$temp_file"
                    fi
                fi
            done
            
            echo "        }" >> "$temp_file"
            # Reset variables
            wl_host=""
            wl_port=""
        fi
    done < "$config_file"
}

# Process a single instance
process_instance() {
    local instance="$1"
    log_info "Processing instance: $instance"
    
    local httpd_file ssl_file mod_wl_file
    
    if [[ "$instance" == "DEFAULT" ]]; then
        httpd_file="$OHS_CONFIG_DIR/httpd.conf"
        ssl_file="$OHS_CONFIG_DIR/ssl.conf"
        mod_wl_file="$OHS_CONFIG_DIR/mod_wl_ohs.conf"
    else
        httpd_file="$OHS_CONFIG_DIR/${instance}_httpd.conf"
        ssl_file="$OHS_CONFIG_DIR/${instance}_ssl.conf"
        mod_wl_file="$OHS_CONFIG_DIR/${instance}_mod_wl_ohs.conf"
    fi
    
    # Parse each configuration file
    parse_listen_directives "$httpd_file"
    parse_listen_directives "$ssl_file"
    
    parse_virtual_hosts "$httpd_file" "$instance"
    parse_virtual_hosts "$ssl_file" "$instance"
    
    parse_weblogic_config "$mod_wl_file" "$instance"
}

# Consolidate all temporary files into final output
consolidate_config() {
    log_info "Consolidating configuration files..."
    
    # Generate upstream blocks for WebLogic servers
    local upstreams_generated=false
    
    # Collect all unique upstream servers from upstream files
    if compgen -G "$TEMP_DIR/upstreams_*" > /dev/null 2>&1; then
        log_info "Generating upstream configurations..."
        
        # Create a temporary file for unique upstreams
        local unique_upstreams="$TEMP_DIR/unique_upstreams"
        
        # Concatenate all upstream files and get unique entries
        cat "$TEMP_DIR"/upstreams_* 2>/dev/null | sort -u > "$unique_upstreams"
        
        if [[ -s "$unique_upstreams" ]]; then
            echo "" >> "$OUTPUT_FILE"
            echo "    # Upstream servers for WebLogic" >> "$OUTPUT_FILE"
            
            while IFS= read -r upstream_server; do
                if [[ -n "$upstream_server" ]]; then
                    local upstream_name="backend_$(echo "$upstream_server" | tr '.:' '_')"
                    echo "    upstream $upstream_name {" >> "$OUTPUT_FILE"
                    echo "        server $upstream_server max_fails=3 fail_timeout=30s;" >> "$OUTPUT_FILE"
                    echo "        keepalive 32;" >> "$OUTPUT_FILE"
                    echo "    }" >> "$OUTPUT_FILE"
                    echo "" >> "$OUTPUT_FILE"
                    upstreams_generated=true
                    log_info "Generated upstream: $upstream_name -> $upstream_server"
                fi
            done < "$unique_upstreams"
        fi
    fi
    
    if [[ "$upstreams_generated" == false ]]; then
        log_warn "No WebLogic upstream configurations found"
    fi
    
    # Add server blocks
    echo "" >> "$OUTPUT_FILE"
    echo "    # Server blocks" >> "$OUTPUT_FILE"
    
    # Consolidate all server blocks
    local server_blocks_found=false
    for file in "$TEMP_DIR"/vhosts_*; do
        if [[ -f "$file" && -s "$file" ]]; then
            cat "$file" >> "$OUTPUT_FILE"
            server_blocks_found=true
        fi
    done
    
    # Add WebLogic location blocks to server blocks
    # Note: These should ideally be integrated into server blocks above
    # For now, we'll add them as separate server blocks if no others exist
    local weblogic_configs_found=false
    for file in "$TEMP_DIR"/weblogic_*; do
        if [[ -f "$file" && -s "$file" ]]; then
            weblogic_configs_found=true
            
            if [[ "$server_blocks_found" == false ]]; then
                # Create a default server block with WebLogic locations
                echo "" >> "$OUTPUT_FILE"
                echo "    # Default server with WebLogic locations" >> "$OUTPUT_FILE"
                echo "    server {" >> "$OUTPUT_FILE"
                echo "        listen 80;" >> "$OUTPUT_FILE"
                echo "        server_name _;" >> "$OUTPUT_FILE"
                echo "" >> "$OUTPUT_FILE"
                cat "$file" >> "$OUTPUT_FILE"
                echo "    }" >> "$OUTPUT_FILE"
                server_blocks_found=true
            fi
        fi
    done
    
    if [[ "$weblogic_configs_found" == true ]]; then
        log_info "WebLogic proxy configurations added"
    fi
    
    # Close http block
    echo "}" >> "$OUTPUT_FILE"
}

# Add default server block if no virtual hosts found
add_default_server() {
    if ! grep -q "server {" "$OUTPUT_FILE"; then
        log_warn "No virtual hosts found, adding default server block"
        
        cat >> "$OUTPUT_FILE" << 'EOF'

    # Default server block
    server {
        listen 80 default_server;
        listen [::]:80 default_server;
        server_name _;
        root /var/www/html;
        index index.html index.htm;
        
        location / {
            try_files $uri $uri/ =404;
        }
    }
EOF
    fi
}

# Validate generated configuration
validate_config() {
    log_info "Validating generated Nginx configuration..."
    
    if nginx -t -c "$OUTPUT_FILE" 2>/dev/null; then
        log_success "Configuration validation passed!"
    else
        log_warn "Configuration validation failed. Please review the generated file manually."
        log_info "You can test it with: nginx -t -c $OUTPUT_FILE"
    fi
}

# Generate summary report
generate_report() {
    local instances=("$@")
    
    echo ""
    log_success "Conversion completed!"
    echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
    echo "📊 CONVERSION SUMMARY"
    echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
    echo "📁 Source Directory: $OHS_CONFIG_DIR"
    echo "📄 Output File: $OUTPUT_FILE"
    echo "🔢 Instances Processed: ${#instances[@]}"
    
    for instance in "${instances[@]}"; do
        echo "   └── $instance"
    done
    
    echo ""
    echo "📋 NEXT STEPS:"
    echo "1. Review the generated nginx.conf file"
    echo "2. Test configuration: nginx -t -c $OUTPUT_FILE"
    echo "3. Adjust paths, certificates, and upstream servers as needed"
    echo "4. Consider security settings and rate limiting"
    echo ""
    echo "⚠️  IMPORTANT NOTES:"
    echo "• SSL certificate paths may need adjustment"
    echo "• WebLogic upstream servers should be verified"
    echo "• Test thoroughly before production use"
    echo "• Some Apache-specific features may need manual conversion"
}

# Main execution
main() {
    init
    
    local instances
    read -ra instances <<< "$(find_instances)"
    
    if [[ ${#instances[@]} -eq 0 ]]; then
        log_error "No OHS configuration files found in $OHS_CONFIG_DIR"
        log_info "Expected files: httpd.conf, ssl.conf, mod_wl_ohs.conf"
        log_info "Or instance-specific files like: OHS1_httpd.conf, OHS2_ssl.conf, etc."
        exit 1
    fi
    
    log_info "Found ${#instances[@]} instance(s): ${instances[*]}"
    
    # Process each instance
    for instance in "${instances[@]}"; do
        process_instance "$instance"
    done
    
    # Consolidate all configurations
    consolidate_config
    
    # Add default server if needed
    add_default_server
    
    # Validate if nginx is available
    if command -v nginx &> /dev/null; then
        validate_config
    else
        log_warn "nginx command not found. Skipping validation."
    fi
    
    # Generate report
    generate_report "${instances[@]}"
}

# Script usage
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    main "$@"
fi
Subscribe
Notify of
0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments