#!/usr/bin/env bash set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" INVENTORY_FILE="${1:-$SCRIPT_DIR/inventory.env}" if [ ! -f "$INVENTORY_FILE" ]; then echo "Missing inventory file: $INVENTORY_FILE" echo "Copy $SCRIPT_DIR/inventory.example.env to $SCRIPT_DIR/inventory.env and edit node mappings." exit 1 fi # shellcheck disable=SC1090 source "$INVENTORY_FILE" SSH_USER="${SSH_USER:-micqdf}" SSH_KEY_PATH="${SSH_KEY_PATH:-$HOME/.ssh/id_ed25519}" SSH_OPTS="${SSH_OPTS:--o BatchMode=yes -o IdentitiesOnly=yes -o StrictHostKeyChecking=accept-new -i $SSH_KEY_PATH}" SSH_USER_CANDIDATES="${SSH_USER_CANDIDATES:-root $SSH_USER}" declare -A NODE_IPS=() add_pair() { local pair="$1" local name="${pair%%=*}" local ip="${pair#*=}" if [ -z "$name" ] || [ -z "$ip" ] || [ "$name" = "$ip" ]; then echo "Invalid node pair '$pair' (expected name=ip)." exit 1 fi NODE_IPS["$name"]="$ip" } if [ -n "${CONTROL_PLANES:-}" ]; then for pair in $CONTROL_PLANES; do add_pair "$pair" done else while IFS= read -r var_name; do idx="${var_name#CP_}" add_pair "cp-$idx=${!var_name}" done < <(compgen -A variable | grep -E '^CP_[0-9]+$' | sort -V) fi if [ -n "${WORKERS:-}" ]; then for pair in $WORKERS; do add_pair "$pair" done else while IFS= read -r var_name; do idx="${var_name#WK_}" add_pair "wk-$idx=${!var_name}" done < <(compgen -A variable | grep -E '^WK_[0-9]+$' | sort -V) fi if [ "${#NODE_IPS[@]}" -eq 0 ]; then echo "No nodes found in inventory." exit 1 fi detect_ssh_user() { local probe_ip="$1" local candidate for candidate in $SSH_USER_CANDIDATES; do if ssh $SSH_OPTS "$candidate@$probe_ip" "true" >/dev/null 2>&1; then ACTIVE_SSH_USER="$candidate" echo "==> Using SSH user '$ACTIVE_SSH_USER'" return 0 fi done echo "Unable to authenticate to $probe_ip with candidates: $SSH_USER_CANDIDATES" return 1 } mkdir -p "$HOME/.ssh" chmod 700 "$HOME/.ssh" touch "$HOME/.ssh/known_hosts" chmod 600 "$HOME/.ssh/known_hosts" for node_name in "${!NODE_IPS[@]}"; do ssh-keygen -R "${NODE_IPS[$node_name]}" >/dev/null 2>&1 || true ssh-keyscan -H "${NODE_IPS[$node_name]}" >> "$HOME/.ssh/known_hosts" 2>/dev/null || true done reset_node() { local node_name="$1" local node_ip="$2" echo "==> Resetting $node_name ($node_ip)" local cmd="sudo kubeadm reset -f && sudo systemctl stop kubelet && sudo rm -rf /etc/kubernetes /var/lib/etcd /var/lib/cni /etc/cni/net.d" local quoted_cmd quoted_cmd="$(printf '%q' "$cmd")" ssh $SSH_OPTS "$ACTIVE_SSH_USER@$node_ip" "bash -lc $quoted_cmd" } FIRST_NODE_IP="${NODE_IPS[$(printf '%s\n' "${!NODE_IPS[@]}" | sort -V | head -n1)]}" ACTIVE_SSH_USER="$SSH_USER" detect_ssh_user "$FIRST_NODE_IP" while IFS= read -r node_name; do reset_node "$node_name" "${NODE_IPS[$node_name]}" done < <(printf '%s\n' "${!NODE_IPS[@]}" | sort -V) echo "Cluster components reset on all listed nodes."