208 lines
5.1 KiB
Bash
208 lines
5.1 KiB
Bash
|
|
#!/bin/bash
|
||
|
|
|
||
|
|
# Enterprise Infrastructure Scaling Simulation Script
|
||
|
|
# Simulates scaling operations for infrastructure nodes
|
||
|
|
|
||
|
|
set -euo pipefail
|
||
|
|
|
||
|
|
# Configuration
|
||
|
|
DOCKER_COMPOSE_FILE="docker-compose.yml"
|
||
|
|
INVENTORY_FILE="inventory/hosts.ini"
|
||
|
|
LOG_FILE="logs/scaling_simulation.log"
|
||
|
|
|
||
|
|
# Default values
|
||
|
|
DIRECTION="${1:-up}"
|
||
|
|
COUNT="${2:-1}"
|
||
|
|
NODE_TYPE="${3:-web}"
|
||
|
|
SIMULATION_MODE="${SIMULATION_MODE:-false}"
|
||
|
|
|
||
|
|
# Logging function
|
||
|
|
log() {
|
||
|
|
echo "$(date '+%Y-%m-%d %H:%M:%S') - $*" | tee -a "$LOG_FILE"
|
||
|
|
}
|
||
|
|
|
||
|
|
# Error handling
|
||
|
|
error_exit() {
|
||
|
|
log "ERROR: $1"
|
||
|
|
exit 1
|
||
|
|
}
|
||
|
|
|
||
|
|
# Validate inputs
|
||
|
|
validate_inputs() {
|
||
|
|
if [[ "$DIRECTION" != "up" && "$DIRECTION" != "down" ]]; then
|
||
|
|
error_exit "Invalid direction: $DIRECTION. Must be 'up' or 'down'"
|
||
|
|
fi
|
||
|
|
|
||
|
|
if ! [[ "$COUNT" =~ ^[0-9]+$ ]] || [ "$COUNT" -lt 1 ]; then
|
||
|
|
error_exit "Invalid count: $COUNT. Must be a positive integer"
|
||
|
|
fi
|
||
|
|
|
||
|
|
case "$NODE_TYPE" in
|
||
|
|
web|db|lb|monitor) ;;
|
||
|
|
*) error_exit "Invalid node type: $NODE_TYPE. Must be web, db, lb, or monitor" ;;
|
||
|
|
esac
|
||
|
|
}
|
||
|
|
|
||
|
|
# Get current node count
|
||
|
|
get_current_count() {
|
||
|
|
local type="$1"
|
||
|
|
case "$type" in
|
||
|
|
web) docker-compose ps web | grep -c "Up" ;;
|
||
|
|
db) docker-compose ps db | grep -c "Up" ;;
|
||
|
|
lb) docker-compose ps lb | grep -c "Up" ;;
|
||
|
|
monitor) docker-compose ps monitor | grep -c "Up" ;;
|
||
|
|
esac
|
||
|
|
}
|
||
|
|
|
||
|
|
# Scale up infrastructure
|
||
|
|
scale_up() {
|
||
|
|
local type="$1"
|
||
|
|
local count="$2"
|
||
|
|
|
||
|
|
log "Scaling up $count $type nodes"
|
||
|
|
|
||
|
|
# Update docker-compose replica count
|
||
|
|
sed -i.bak "s/replicas: [0-9]\+/replicas: $(( $(get_current_count "$type") + count ))/" "$DOCKER_COMPOSE_FILE"
|
||
|
|
|
||
|
|
# Deploy new containers
|
||
|
|
docker-compose up -d --scale "${type}=${count}"
|
||
|
|
|
||
|
|
# Wait for containers to be ready
|
||
|
|
log "Waiting for containers to be ready..."
|
||
|
|
sleep 30
|
||
|
|
|
||
|
|
# Update inventory
|
||
|
|
update_inventory "$type" "$count" "add"
|
||
|
|
|
||
|
|
# Run provisioning playbook on new nodes
|
||
|
|
if [ "$SIMULATION_MODE" = false ]; then
|
||
|
|
ansible-playbook -i "$INVENTORY_FILE" playbooks/provision.yml --limit "${type}*"
|
||
|
|
fi
|
||
|
|
|
||
|
|
log "Successfully scaled up $count $type nodes"
|
||
|
|
}
|
||
|
|
|
||
|
|
# Scale down infrastructure
|
||
|
|
scale_down() {
|
||
|
|
local type="$1"
|
||
|
|
local count="$2"
|
||
|
|
|
||
|
|
local current_count=$(get_current_count "$type")
|
||
|
|
if [ "$current_count" -lt "$count" ]; then
|
||
|
|
error_exit "Cannot scale down $count nodes. Only $current_count $type nodes currently running"
|
||
|
|
fi
|
||
|
|
|
||
|
|
log "Scaling down $count $type nodes"
|
||
|
|
|
||
|
|
# Select nodes to remove (oldest first)
|
||
|
|
local nodes_to_remove=$(docker-compose ps "$type" | grep "Up" | head -n "$count" | awk '{print $1}')
|
||
|
|
|
||
|
|
# Decommission nodes
|
||
|
|
for node in $nodes_to_remove; do
|
||
|
|
if [ "$SIMULATION_MODE" = false ]; then
|
||
|
|
ansible-playbook -i "$INVENTORY_FILE" playbooks/decommission.yml --limit "$node"
|
||
|
|
fi
|
||
|
|
docker stop "$node"
|
||
|
|
docker rm "$node"
|
||
|
|
done
|
||
|
|
|
||
|
|
# Update docker-compose replica count
|
||
|
|
sed -i.bak "s/replicas: [0-9]\+/replicas: $(( current_count - count ))/" "$DOCKER_COMPOSE_FILE"
|
||
|
|
|
||
|
|
# Update inventory
|
||
|
|
update_inventory "$type" "$count" "remove"
|
||
|
|
|
||
|
|
log "Successfully scaled down $count $type nodes"
|
||
|
|
}
|
||
|
|
|
||
|
|
# Update Ansible inventory
|
||
|
|
update_inventory() {
|
||
|
|
local type="$1"
|
||
|
|
local count="$2"
|
||
|
|
local action="$3"
|
||
|
|
|
||
|
|
log "Updating inventory for $action $count $type nodes"
|
||
|
|
|
||
|
|
# This would be more complex in a real implementation
|
||
|
|
# For simulation, we'll just log the action
|
||
|
|
case "$action" in
|
||
|
|
add)
|
||
|
|
log "Added $count $type nodes to inventory"
|
||
|
|
;;
|
||
|
|
remove)
|
||
|
|
log "Removed $count $type nodes from inventory"
|
||
|
|
;;
|
||
|
|
esac
|
||
|
|
}
|
||
|
|
|
||
|
|
# Health check after scaling
|
||
|
|
health_check() {
|
||
|
|
log "Running health checks after scaling"
|
||
|
|
|
||
|
|
# Check container status
|
||
|
|
if ! docker-compose ps | grep -q "Up"; then
|
||
|
|
error_exit "Some containers failed to start"
|
||
|
|
fi
|
||
|
|
|
||
|
|
# Ansible ping check
|
||
|
|
if [ "$SIMULATION_MODE" = false ]; then
|
||
|
|
if ! ansible -i "$INVENTORY_FILE" all -m ping >/dev/null 2>&1; then
|
||
|
|
log "WARNING: Some nodes failed Ansible ping check"
|
||
|
|
fi
|
||
|
|
fi
|
||
|
|
|
||
|
|
log "Health checks completed"
|
||
|
|
}
|
||
|
|
|
||
|
|
# Generate scaling report
|
||
|
|
generate_report() {
|
||
|
|
local report_file="reports/scaling_report_$(date +%Y%m%d_%H%M%S).txt"
|
||
|
|
|
||
|
|
cat > "$report_file" << EOF
|
||
|
|
Scaling Simulation Report
|
||
|
|
========================
|
||
|
|
|
||
|
|
Timestamp: $(date)
|
||
|
|
Direction: $DIRECTION
|
||
|
|
Node Type: $NODE_TYPE
|
||
|
|
Count: $COUNT
|
||
|
|
Simulation Mode: $SIMULATION_MODE
|
||
|
|
|
||
|
|
Current Status:
|
||
|
|
$(docker-compose ps)
|
||
|
|
|
||
|
|
Inventory Status:
|
||
|
|
$(ansible -i "$INVENTORY_FILE" --list-hosts all 2>/dev/null || echo "Ansible inventory check failed")
|
||
|
|
|
||
|
|
Log File: $LOG_FILE
|
||
|
|
EOF
|
||
|
|
|
||
|
|
log "Scaling report generated: $report_file"
|
||
|
|
}
|
||
|
|
|
||
|
|
# Main execution
|
||
|
|
main() {
|
||
|
|
log "Starting scaling simulation: $DIRECTION $COUNT $NODE_TYPE nodes"
|
||
|
|
|
||
|
|
validate_inputs
|
||
|
|
|
||
|
|
case "$DIRECTION" in
|
||
|
|
up)
|
||
|
|
scale_up "$NODE_TYPE" "$COUNT"
|
||
|
|
;;
|
||
|
|
down)
|
||
|
|
scale_down "$NODE_TYPE" "$COUNT"
|
||
|
|
;;
|
||
|
|
esac
|
||
|
|
|
||
|
|
health_check
|
||
|
|
generate_report
|
||
|
|
|
||
|
|
log "Scaling simulation completed successfully"
|
||
|
|
}
|
||
|
|
|
||
|
|
# Initialize logging
|
||
|
|
mkdir -p logs reports
|
||
|
|
|
||
|
|
# Run main function
|
||
|
|
main "$@"
|