#!/bin/bash # Change MockAPI port configuration # Run this script to change the port MockAPI runs on set -e echo "=== MockAPI Port Change Utility ===" echo APP_DIR="/opt/mockapi" ENV_FILE="${APP_DIR}/.env" SERVICE_FILE="/etc/systemd/system/mockapi.service" # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color print_status() { echo -e "${GREEN}[+]${NC} $1" } print_warning() { echo -e "${YELLOW}[!]${NC} $1" } print_error() { echo -e "${RED}[!]${NC} $1" } print_info() { echo -e "${BLUE}[i]${NC} $1" } # Check if running as root or with sudo if [[ $EUID -ne 0 ]]; then print_error "This script requires sudo privileges." print_info "Run with: sudo bash $0" exit 1 fi # Step 1: Check if files exist if [[ ! -f "$ENV_FILE" ]]; then print_error ".env file not found: $ENV_FILE" exit 1 fi if [[ ! -f "$SERVICE_FILE" ]]; then print_error "Service file not found: $SERVICE_FILE" exit 1 fi # Step 2: Show current configuration print_status "Current configuration:" CURRENT_PORT=$(grep "^PORT=" "$ENV_FILE" | cut -d'=' -f2 || echo "8000") CURRENT_HOST=$(grep "^HOST=" "$ENV_FILE" | cut -d'=' -f2 || echo "0.0.0.0") CURRENT_ISSUER=$(grep "^OAUTH2_ISSUER=" "$ENV_FILE" | cut -d'=' -f2 || echo "http://localhost:${CURRENT_PORT}") echo " Current PORT: $CURRENT_PORT" echo " Current HOST: $CURRENT_HOST" echo " Current OAUTH2_ISSUER: $CURRENT_ISSUER" echo # Step 3: Ask for new port read -p "Enter new port number [$CURRENT_PORT]: " NEW_PORT NEW_PORT=${NEW_PORT:-$CURRENT_PORT} # Validate new port if [[ ! "$NEW_PORT" =~ ^[0-9]+$ ]]; then print_error "Invalid port number: '$NEW_PORT'. Must be numeric." exit 1 fi if [[ "$NEW_PORT" -lt 1 ]] || [[ "$NEW_PORT" -gt 65535 ]]; then print_error "Port number must be between 1 and 65535." exit 1 fi # Check if port is already in use if command -v netstat &> /dev/null; then if netstat -tuln | grep -q ":$NEW_PORT "; then print_warning "Port $NEW_PORT appears to be in use!" read -p "Continue anyway? (y/N): " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then exit 1 fi fi elif command -v ss &> /dev/null; then if ss -tuln | grep -q ":$NEW_PORT "; then print_warning "Port $NEW_PORT appears to be in use!" read -p "Continue anyway? (y/N): " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then exit 1 fi fi fi # Step 4: Ask for host (optional) read -p "Enter host address [$CURRENT_HOST]: " NEW_HOST NEW_HOST=${NEW_HOST:-$CURRENT_HOST} # Step 5: Backup files print_status "Creating backups..." BACKUP_DIR="${APP_DIR}/backup_port_change_$(date +%Y%m%d_%H%M%S)" mkdir -p "$BACKUP_DIR" cp "$ENV_FILE" "$BACKUP_DIR/.env.backup" cp "$SERVICE_FILE" "$BACKUP_DIR/mockapi.service.backup" print_status "Backups saved to: $BACKUP_DIR" # Step 6: Update .env file print_status "Updating .env file..." # Update PORT if grep -q "^PORT=" "$ENV_FILE"; then sed -i "s/^PORT=.*/PORT=$NEW_PORT/" "$ENV_FILE" else echo "PORT=$NEW_PORT" >> "$ENV_FILE" fi # Update HOST if grep -q "^HOST=" "$ENV_FILE"; then sed -i "s/^HOST=.*/HOST=$NEW_HOST/" "$ENV_FILE" else echo "HOST=$NEW_HOST" >> "$ENV_FILE" fi # Update OAUTH2_ISSUER NEW_ISSUER="http://localhost:${NEW_PORT}" if grep -q "^OAUTH2_ISSUER=" "$ENV_FILE"; then sed -i "s|^OAUTH2_ISSUER=.*|OAUTH2_ISSUER=$NEW_ISSUER|" "$ENV_FILE" else echo "OAUTH2_ISSUER=$NEW_ISSUER" >> "$ENV_FILE" fi print_status "Updated .env file:" echo " PORT=$NEW_PORT" echo " HOST=$NEW_HOST" echo " OAUTH2_ISSUER=$NEW_ISSUER" # Step 7: Update service file print_status "Updating service file..." # Get virtual environment path VENV_DIR=$(grep 'Environment="PATH=' "$SERVICE_FILE" | cut -d'=' -f2 | cut -d':' -f1 | sed 's/"//g' || echo "/opt/mockapi/venv") # Get user and group from current service file SERVICE_USER=$(grep "^User=" "$SERVICE_FILE" | cut -d'=' -f2) SERVICE_GROUP=$(grep "^Group=" "$SERVICE_FILE" | cut -d'=' -f2) # Create updated service file cat > /tmp/mockapi_new.service << EOF [Unit] Description=Mock API Service After=network.target Wants=network.target [Service] Type=simple User=$SERVICE_USER Group=$SERVICE_GROUP WorkingDirectory=$APP_DIR Environment="PATH=$VENV_DIR/bin" Environment="PYTHONPATH=$APP_DIR" EnvironmentFile=$APP_DIR/.env # Hardcoded port from .env (updated) ExecStart=$VENV_DIR/bin/waitress-serve --host=$NEW_HOST --port=$NEW_PORT wsgi:wsgi_app Restart=always RestartSec=10 StandardOutput=syslog StandardError=syslog SyslogIdentifier=mockapi # Security hardening NoNewPrivileges=true PrivateTmp=true ProtectSystem=strict ReadWritePaths=$APP_DIR [Install] WantedBy=multi-user.target EOF # Replace service file cp /tmp/mockapi_new.service "$SERVICE_FILE" rm -f /tmp/mockapi_new.service print_status "Service file updated with new port $NEW_PORT." # Step 8: Reload systemd print_status "Reloading systemd daemon..." systemctl daemon-reload # Step 9: Restart service print_status "Restarting MockAPI service..." if systemctl restart mockapi; then print_status "Service restart initiated." # Wait for service to start sleep 3 if systemctl is-active --quiet mockapi; then print_status "✓ Service is running on port $NEW_PORT!" # Test health endpoint print_status "Testing health endpoint..." if curl -f -s --max-time 10 http://localhost:$NEW_PORT/health > /dev/null 2>&1; then print_status "✓ Health check passed!" echo echo "=== Port Change Successful ===" echo echo "MockAPI is now running on:" echo " URL: http://localhost:$NEW_PORT" echo " Admin: http://localhost:$NEW_PORT/admin/login" echo " Docs: http://localhost:$NEW_PORT/docs" echo " Health: http://localhost:$NEW_PORT/health" echo echo "If accessing remotely, use:" echo " http://$(hostname -I | awk '{print $1}'):$NEW_PORT" else print_warning "Service is running but health check failed." print_info "This might be normal during initial startup." echo print_status "Service status:" systemctl status mockapi --no-pager -l fi else print_error "Service failed to start after port change." echo print_warning "Checking service logs..." journalctl -u mockapi -n 30 --no-pager echo print_warning "Restoring from backup..." cp "$BACKUP_DIR/.env.backup" "$ENV_FILE" cp "$BACKUP_DIR/mockapi.service.backup" "$SERVICE_FILE" systemctl daemon-reload systemctl restart mockapi print_status "Restored original configuration." fi else print_error "Failed to restart service." systemctl status mockapi --no-pager -l fi echo print_status "=== Port Change Complete ===" echo "Backup files are in: $BACKUP_DIR" echo "If you need to revert, copy files from backup directory."