439 lines
14 KiB
Bash
439 lines
14 KiB
Bash
|
|
#!/bin/bash
|
||
|
|
|
||
|
|
# Calejo Control Adapter - One-Click Server Setup Script
|
||
|
|
# Automatically reads from existing deployment configuration files
|
||
|
|
|
||
|
|
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
|
||
|
|
|
||
|
|
# Default configuration
|
||
|
|
ENVIRONMENT="production"
|
||
|
|
SERVER_HOST=""
|
||
|
|
SSH_USERNAME=""
|
||
|
|
SSH_KEY_FILE=""
|
||
|
|
DRY_RUN=false
|
||
|
|
VERBOSE=false
|
||
|
|
|
||
|
|
# Function to print colored output
|
||
|
|
print_status() {
|
||
|
|
echo -e "${BLUE}[INFO]${NC} $1"
|
||
|
|
}
|
||
|
|
|
||
|
|
print_success() {
|
||
|
|
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
||
|
|
}
|
||
|
|
|
||
|
|
print_warning() {
|
||
|
|
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||
|
|
}
|
||
|
|
|
||
|
|
print_error() {
|
||
|
|
echo -e "${RED}[ERROR]${NC} $1"
|
||
|
|
}
|
||
|
|
|
||
|
|
# Function to display usage
|
||
|
|
usage() {
|
||
|
|
echo "Calejo Control Adapter - One-Click Server Setup"
|
||
|
|
echo "=================================================="
|
||
|
|
echo ""
|
||
|
|
echo "Usage: $0 [OPTIONS]"
|
||
|
|
echo ""
|
||
|
|
echo "Options:"
|
||
|
|
echo " -e, --environment Deployment environment (production, staging) [default: auto-detect]"
|
||
|
|
echo " -h, --host Server hostname or IP address [default: auto-detect]"
|
||
|
|
echo " -u, --user SSH username [default: auto-detect]"
|
||
|
|
echo " -k, --key SSH private key file [default: auto-detect]"
|
||
|
|
echo " --verbose Enable verbose output"
|
||
|
|
echo " --dry-run Show what would be done without making changes"
|
||
|
|
echo " --help Show this help message"
|
||
|
|
echo ""
|
||
|
|
echo "Examples:"
|
||
|
|
echo " $0 # Auto-detect and setup using existing config"
|
||
|
|
echo " $0 --dry-run # Show setup steps without executing"
|
||
|
|
echo " $0 -h custom-server.com # Override host from config"
|
||
|
|
echo ""
|
||
|
|
}
|
||
|
|
|
||
|
|
# Function to read deployment configuration from existing files
|
||
|
|
read_deployment_config() {
|
||
|
|
local config_dir="deploy"
|
||
|
|
|
||
|
|
print_status "Reading existing deployment configuration..."
|
||
|
|
|
||
|
|
# Read from production.yml if it exists
|
||
|
|
if [[ -f "$config_dir/config/production.yml" ]]; then
|
||
|
|
print_status "Found production configuration: $config_dir/config/production.yml"
|
||
|
|
|
||
|
|
# Extract values from production.yml
|
||
|
|
if [[ -z "$SSH_HOST" ]]; then
|
||
|
|
SSH_HOST=$(grep -E "^\s*host:\s*" "$config_dir/config/production.yml" | head -1 | sed 's/^[[:space:]]*host:[[:space:]]*//' | sed 's/^"//' | sed 's/"$//' | tr -d '\r')
|
||
|
|
[[ -n "$SSH_HOST" ]] && print_status " Host: $SSH_HOST"
|
||
|
|
fi
|
||
|
|
|
||
|
|
if [[ -z "$SSH_USERNAME" ]]; then
|
||
|
|
SSH_USERNAME=$(grep -E "^\s*username:\s*" "$config_dir/config/production.yml" | head -1 | sed 's/^[[:space:]]*username:[[:space:]]*//' | sed 's/^"//' | sed 's/"$//' | tr -d '\r')
|
||
|
|
[[ -n "$SSH_USERNAME" ]] && print_status " Username: $SSH_USERNAME"
|
||
|
|
fi
|
||
|
|
|
||
|
|
if [[ -z "$SSH_KEY_FILE" ]]; then
|
||
|
|
SSH_KEY_FILE=$(grep -E "^\s*key_file:\s*" "$config_dir/config/production.yml" | head -1 | sed 's/^[[:space:]]*key_file:[[:space:]]*//' | sed 's/^"//' | sed 's/"$//' | tr -d '\r')
|
||
|
|
[[ -n "$SSH_KEY_FILE" ]] && print_status " Key file: $SSH_KEY_FILE"
|
||
|
|
fi
|
||
|
|
fi
|
||
|
|
|
||
|
|
# Read from staging.yml if it exists
|
||
|
|
if [[ -f "$config_dir/config/staging.yml" ]]; then
|
||
|
|
print_status "Found staging configuration: $config_dir/config/staging.yml"
|
||
|
|
|
||
|
|
# Only use staging config if environment is staging
|
||
|
|
if [[ "$ENVIRONMENT" == "staging" ]]; then
|
||
|
|
if [[ -z "$SSH_HOST" ]]; then
|
||
|
|
SSH_HOST=$(grep -E "^\s*host:\s*" "$config_dir/config/staging.yml" | head -1 | sed 's/^[[:space:]]*host:[[:space:]]*//' | sed 's/^"//' | sed 's/"$//' | tr -d '\r')
|
||
|
|
[[ -n "$SSH_HOST" ]] && print_status " Host: $SSH_HOST"
|
||
|
|
fi
|
||
|
|
fi
|
||
|
|
fi
|
||
|
|
|
||
|
|
# Check for existing remote deployment script configuration
|
||
|
|
if [[ -f "$config_dir/ssh/deploy-remote.sh" ]]; then
|
||
|
|
print_status "Found remote deployment script: $config_dir/ssh/deploy-remote.sh"
|
||
|
|
|
||
|
|
# Extract default values from deploy-remote.sh
|
||
|
|
if [[ -z "$SSH_HOST" ]]; then
|
||
|
|
SSH_HOST=$(grep -E "SSH_HOST=" "$config_dir/ssh/deploy-remote.sh" | head -1 | cut -d'=' -f2 | tr -d '\"' | tr -d "\'")
|
||
|
|
[[ -n "$SSH_HOST" ]] && print_status " Host from script: $SSH_HOST"
|
||
|
|
fi
|
||
|
|
|
||
|
|
if [[ -z "$SSH_USERNAME" ]]; then
|
||
|
|
SSH_USERNAME=$(grep -E "SSH_USER=" "$config_dir/ssh/deploy-remote.sh" | head -1 | cut -d'=' -f2 | tr -d '\"' | tr -d "\'")
|
||
|
|
[[ -n "$SSH_USERNAME" ]] && print_status " Username from script: $SSH_USERNAME"
|
||
|
|
fi
|
||
|
|
|
||
|
|
if [[ -z "$SSH_KEY_FILE" ]]; then
|
||
|
|
SSH_KEY_FILE=$(grep -E "SSH_KEY=" "$config_dir/ssh/deploy-remote.sh" | head -1 | cut -d'=' -f2 | tr -d '\"' | tr -d "\'")
|
||
|
|
[[ -n "$SSH_KEY_FILE" ]] && print_status " Key file from script: $SSH_KEY_FILE"
|
||
|
|
fi
|
||
|
|
fi
|
||
|
|
|
||
|
|
# Set defaults if still empty
|
||
|
|
ENVIRONMENT=${ENVIRONMENT:-production}
|
||
|
|
SSH_HOST=${SSH_HOST:-localhost}
|
||
|
|
SSH_USERNAME=${SSH_USERNAME:-$USER}
|
||
|
|
SSH_KEY_FILE=${SSH_KEY_FILE:-~/.ssh/id_rsa}
|
||
|
|
|
||
|
|
# Use SSH_HOST as SERVER_HOST if not specified
|
||
|
|
SERVER_HOST=${SERVER_HOST:-$SSH_HOST}
|
||
|
|
|
||
|
|
print_success "Configuration loaded successfully"
|
||
|
|
}
|
||
|
|
|
||
|
|
# Function to parse command line arguments
|
||
|
|
parse_arguments() {
|
||
|
|
while [[ $# -gt 0 ]]; do
|
||
|
|
case $1 in
|
||
|
|
-e|--environment)
|
||
|
|
ENVIRONMENT="$2"
|
||
|
|
shift 2
|
||
|
|
;;
|
||
|
|
-h|--host)
|
||
|
|
SERVER_HOST="$2"
|
||
|
|
shift 2
|
||
|
|
;;
|
||
|
|
-u|--user)
|
||
|
|
SSH_USERNAME="$2"
|
||
|
|
shift 2
|
||
|
|
;;
|
||
|
|
-k|--key)
|
||
|
|
SSH_KEY_FILE="$2"
|
||
|
|
shift 2
|
||
|
|
;;
|
||
|
|
--verbose)
|
||
|
|
VERBOSE=true
|
||
|
|
shift
|
||
|
|
;;
|
||
|
|
--dry-run)
|
||
|
|
DRY_RUN=true
|
||
|
|
shift
|
||
|
|
;;
|
||
|
|
--help)
|
||
|
|
usage
|
||
|
|
exit 0
|
||
|
|
;;
|
||
|
|
*)
|
||
|
|
print_error "Unknown option: $1"
|
||
|
|
usage
|
||
|
|
exit 1
|
||
|
|
;;
|
||
|
|
esac
|
||
|
|
done
|
||
|
|
}
|
||
|
|
|
||
|
|
# Function to detect if running locally or needs remote setup
|
||
|
|
detect_deployment_type() {
|
||
|
|
if [[ -n "$SERVER_HOST" && "$SERVER_HOST" != "localhost" && "$SERVER_HOST" != "127.0.0.1" ]]; then
|
||
|
|
echo "remote"
|
||
|
|
else
|
||
|
|
echo "local"
|
||
|
|
fi
|
||
|
|
}
|
||
|
|
|
||
|
|
# Function to check prerequisites
|
||
|
|
check_prerequisites() {
|
||
|
|
print_status "Checking prerequisites..."
|
||
|
|
|
||
|
|
if [[ "$DRY_RUN" == "true" ]]; then
|
||
|
|
echo " [DRY RUN] Would check prerequisites"
|
||
|
|
return 0
|
||
|
|
fi
|
||
|
|
|
||
|
|
# For local deployment, check local Docker
|
||
|
|
if [[ "$DEPLOYMENT_TYPE" == "local" ]]; then
|
||
|
|
# Check Docker
|
||
|
|
if ! command -v docker &> /dev/null; then
|
||
|
|
print_error "Docker is not installed"
|
||
|
|
echo "Please install Docker first: https://docs.docker.com/get-docker/"
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
# Check Docker Compose
|
||
|
|
if ! command -v docker-compose &> /dev/null; then
|
||
|
|
print_error "Docker Compose is not installed"
|
||
|
|
echo "Please install Docker Compose first: https://docs.docker.com/compose/install/"
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
fi
|
||
|
|
|
||
|
|
# For remote deployment, we'll handle Docker installation automatically
|
||
|
|
if [[ "$DEPLOYMENT_TYPE" == "remote" ]]; then
|
||
|
|
print_status "Remote deployment - Docker will be installed automatically if needed"
|
||
|
|
fi
|
||
|
|
|
||
|
|
print_success "Prerequisites check passed"
|
||
|
|
}
|
||
|
|
|
||
|
|
# Function to setup local deployment
|
||
|
|
setup_local_deployment() {
|
||
|
|
print_status "Setting up local deployment..."
|
||
|
|
|
||
|
|
if [[ "$DRY_RUN" == "true" ]]; then
|
||
|
|
echo " [DRY RUN] Would setup local deployment"
|
||
|
|
return 0
|
||
|
|
fi
|
||
|
|
|
||
|
|
# Create necessary directories
|
||
|
|
mkdir -p ./data/postgres ./logs ./certs
|
||
|
|
|
||
|
|
# Generate default configuration if not exists
|
||
|
|
if [[ ! -f ".env" ]]; then
|
||
|
|
print_status "Creating default configuration..."
|
||
|
|
cp config/.env.example .env
|
||
|
|
print_success "Default configuration created"
|
||
|
|
fi
|
||
|
|
|
||
|
|
# Setup monitoring with secure credentials
|
||
|
|
print_status "Setting up monitoring with secure credentials..."
|
||
|
|
./setup-monitoring.sh
|
||
|
|
|
||
|
|
# Build and start services
|
||
|
|
print_status "Building and starting services..."
|
||
|
|
docker-compose up --build -d
|
||
|
|
|
||
|
|
print_success "Local deployment completed"
|
||
|
|
}
|
||
|
|
|
||
|
|
# Function to install Docker on remote server
|
||
|
|
install_docker_remote() {
|
||
|
|
local host="$1"
|
||
|
|
local user="$2"
|
||
|
|
local key_file="$3"
|
||
|
|
|
||
|
|
print_status "Installing Docker on remote server $host..."
|
||
|
|
|
||
|
|
if [[ "$DRY_RUN" == "true" ]]; then
|
||
|
|
echo " [DRY RUN] Would install Docker on $host"
|
||
|
|
return 0
|
||
|
|
fi
|
||
|
|
|
||
|
|
# Check if Docker is already installed
|
||
|
|
if ssh -o StrictHostKeyChecking=no -i "$key_file" "$user@$host" "command -v docker" &> /dev/null; then
|
||
|
|
print_success "Docker is already installed"
|
||
|
|
return 0
|
||
|
|
fi
|
||
|
|
|
||
|
|
# Install Docker using official script
|
||
|
|
print_status "Installing Docker using official script..."
|
||
|
|
ssh -o StrictHostKeyChecking=no -i "$key_file" "$user@$host" \
|
||
|
|
"curl -fsSL https://get.docker.com -o get-docker.sh && sh get-docker.sh"
|
||
|
|
|
||
|
|
# Add user to docker group
|
||
|
|
print_status "Adding user to docker group..."
|
||
|
|
ssh -o StrictHostKeyChecking=no -i "$key_file" "$user@$host" \
|
||
|
|
"usermod -aG docker $user"
|
||
|
|
|
||
|
|
# Install Docker Compose
|
||
|
|
print_status "Installing Docker Compose..."
|
||
|
|
ssh -o StrictHostKeyChecking=no -i "$key_file" "$user@$host" \
|
||
|
|
"curl -L \"https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)\" -o /usr/local/bin/docker-compose && chmod +x /usr/local/bin/docker-compose"
|
||
|
|
|
||
|
|
# Verify installation
|
||
|
|
if ssh -o StrictHostKeyChecking=no -i "$key_file" "$user@$host" "docker --version && docker-compose --version"; then
|
||
|
|
print_success "Docker and Docker Compose installed successfully"
|
||
|
|
return 0
|
||
|
|
else
|
||
|
|
print_error "Docker installation failed"
|
||
|
|
return 1
|
||
|
|
fi
|
||
|
|
}
|
||
|
|
|
||
|
|
# Function to setup remote deployment
|
||
|
|
setup_remote_deployment() {
|
||
|
|
print_status "Setting up remote deployment on $SERVER_HOST..."
|
||
|
|
|
||
|
|
if [[ "$DRY_RUN" == "true" ]]; then
|
||
|
|
echo " [DRY RUN] Would setup remote deployment on $SERVER_HOST"
|
||
|
|
return 0
|
||
|
|
fi
|
||
|
|
|
||
|
|
# Install Docker if needed
|
||
|
|
if ! ssh -o StrictHostKeyChecking=no -i "$SSH_KEY_FILE" "$SSH_USERNAME@$SERVER_HOST" "command -v docker" &> /dev/null; then
|
||
|
|
install_docker_remote "$SERVER_HOST" "$SSH_USERNAME" "$SSH_KEY_FILE"
|
||
|
|
fi
|
||
|
|
|
||
|
|
# Use existing deployment script
|
||
|
|
if [[ -f "deploy/ssh/deploy-remote.sh" ]]; then
|
||
|
|
print_status "Using existing remote deployment script..."
|
||
|
|
./deploy/ssh/deploy-remote.sh -e "$ENVIRONMENT"
|
||
|
|
else
|
||
|
|
print_error "Remote deployment script not found"
|
||
|
|
return 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
print_success "Remote deployment completed"
|
||
|
|
}
|
||
|
|
|
||
|
|
# Function to validate setup
|
||
|
|
validate_setup() {
|
||
|
|
local host="$1"
|
||
|
|
|
||
|
|
print_status "Validating setup..."
|
||
|
|
|
||
|
|
if [[ "$DRY_RUN" == "true" ]]; then
|
||
|
|
echo " [DRY RUN] Would validate setup"
|
||
|
|
return 0
|
||
|
|
fi
|
||
|
|
|
||
|
|
# Test health endpoint
|
||
|
|
if curl -s "http://$host:8080/health" > /dev/null; then
|
||
|
|
print_success "Health check passed"
|
||
|
|
else
|
||
|
|
print_warning "Health check failed - service may still be starting"
|
||
|
|
fi
|
||
|
|
|
||
|
|
return 0
|
||
|
|
}
|
||
|
|
|
||
|
|
# Function to display setup completion message
|
||
|
|
display_completion_message() {
|
||
|
|
local deployment_type="$1"
|
||
|
|
local host="$2"
|
||
|
|
|
||
|
|
echo ""
|
||
|
|
echo "=================================================="
|
||
|
|
echo " SETUP COMPLETED SUCCESSFULLY!"
|
||
|
|
echo "=================================================="
|
||
|
|
echo ""
|
||
|
|
echo "🎉 Calejo Control Adapter is now running!"
|
||
|
|
echo ""
|
||
|
|
echo "🌍 Access URLs:"
|
||
|
|
echo " Dashboard: http://$host:8080/dashboard"
|
||
|
|
echo " REST API: http://$host:8080"
|
||
|
|
echo " Health Check: http://$host:8080/health"
|
||
|
|
echo " Grafana: http://$host:3000 (admin/admin)"
|
||
|
|
echo " Prometheus: http://$host:9091 (credentials auto-generated)"
|
||
|
|
echo ""
|
||
|
|
echo "🔧 Next Steps:"
|
||
|
|
echo " 1. Open the dashboard in your browser"
|
||
|
|
echo " 2. Configure your SCADA systems and hardware"
|
||
|
|
echo " 3. Set up safety limits and user accounts"
|
||
|
|
echo " 4. Integrate with your existing infrastructure"
|
||
|
|
echo ""
|
||
|
|
|
||
|
|
if [[ "$deployment_type" == "local" ]]; then
|
||
|
|
echo "💡 Local Development Tips:"
|
||
|
|
echo " - View logs: docker-compose logs -f"
|
||
|
|
echo " - Stop services: docker-compose down"
|
||
|
|
echo " - Restart: docker-compose up -d"
|
||
|
|
else
|
||
|
|
echo "💡 Remote Server Tips:"
|
||
|
|
echo " - View logs: ssh -i $SSH_KEY_FILE $SSH_USERNAME@$host 'cd /opt/calejo-control-adapter && docker-compose logs -f'"
|
||
|
|
echo " - Stop services: ssh -i $SSH_KEY_FILE $SSH_USERNAME@$host 'cd /opt/calejo-control-adapter && docker-compose down'"
|
||
|
|
echo " - Restart: ssh -i $SSH_KEY_FILE $SSH_USERNAME@$host 'cd /opt/calejo-control-adapter && docker-compose up -d'"
|
||
|
|
fi
|
||
|
|
|
||
|
|
echo ""
|
||
|
|
echo "=================================================="
|
||
|
|
echo ""
|
||
|
|
}
|
||
|
|
|
||
|
|
# Main setup function
|
||
|
|
main() {
|
||
|
|
echo ""
|
||
|
|
echo "🚀 Calejo Control Adapter - One-Click Server Setup"
|
||
|
|
echo "=================================================="
|
||
|
|
echo ""
|
||
|
|
|
||
|
|
# Parse command line arguments
|
||
|
|
parse_arguments "$@"
|
||
|
|
|
||
|
|
# Read deployment configuration from files
|
||
|
|
read_deployment_config
|
||
|
|
|
||
|
|
# Detect deployment type
|
||
|
|
local deployment_type=$(detect_deployment_type)
|
||
|
|
|
||
|
|
# Display setup information
|
||
|
|
echo "Setup Configuration:"
|
||
|
|
echo " Environment: $ENVIRONMENT"
|
||
|
|
echo " Deployment: $deployment_type"
|
||
|
|
if [[ "$deployment_type" == "remote" ]]; then
|
||
|
|
echo " Server: $SERVER_HOST"
|
||
|
|
echo " User: $SSH_USERNAME"
|
||
|
|
else
|
||
|
|
echo " Server: localhost"
|
||
|
|
fi
|
||
|
|
if [[ "$DRY_RUN" == "true" ]]; then
|
||
|
|
echo " Mode: DRY RUN"
|
||
|
|
fi
|
||
|
|
echo ""
|
||
|
|
|
||
|
|
# Check prerequisites
|
||
|
|
check_prerequisites
|
||
|
|
|
||
|
|
# Perform deployment
|
||
|
|
if [[ "$deployment_type" == "local" ]]; then
|
||
|
|
setup_local_deployment
|
||
|
|
local final_host="localhost"
|
||
|
|
else
|
||
|
|
setup_remote_deployment
|
||
|
|
local final_host="$SERVER_HOST"
|
||
|
|
fi
|
||
|
|
|
||
|
|
# Validate setup
|
||
|
|
validate_setup "$final_host"
|
||
|
|
|
||
|
|
# Display completion message
|
||
|
|
display_completion_message "$deployment_type" "$final_host"
|
||
|
|
|
||
|
|
echo ""
|
||
|
|
print_success "One-click setup completed!"
|
||
|
|
echo ""
|
||
|
|
}
|
||
|
|
|
||
|
|
# Run main function
|
||
|
|
main "$@"
|