#!/usr/bin/env bash # verify-iscsi.sh # # Verifies iSCSI configuration on Talos worker nodes # Run after applying the fixed configuration set -euo pipefail GREEN='\033[0;32m' RED='\033[0;31m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' WORKER_NODES=( "jungle-cruise:10.1.71.69" "haunted-mansion:10.1.71.70" "peter-pans-flight:10.1.71.71" ) FLASHARRAY_ISCSI_IP="${1:-}" if [[ -z "$FLASHARRAY_ISCSI_IP" ]]; then echo -e "${YELLOW}Usage: $0 ${NC}" echo "Example: $0 10.1.75.100" echo echo "Testing without FlashArray connectivity check..." echo fi echo -e "${BLUE}╔════════════════════════════════════════════════════════════╗${NC}" echo -e "${BLUE}║ Talos iSCSI Configuration Verification Report ║${NC}" echo -e "${BLUE}╚════════════════════════════════════════════════════════════╝${NC}" echo for node_spec in "${WORKER_NODES[@]}"; do IFS=':' read -r hostname ip <<< "$node_spec" echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" echo -e "${BLUE}Node: $hostname ($ip)${NC}" echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" echo # Check node is Ready echo -n " Kubernetes node status: " if kubectl get node "$hostname" -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}' 2>/dev/null | grep -q "True"; then echo -e "${GREEN}✓ Ready${NC}" else echo -e "${RED}✗ Not Ready${NC}" fi # Check node IP echo -n " Node internal IP: " node_ip=$(kubectl get node "$hostname" -o jsonpath='{.status.addresses[?(@.type=="InternalIP")].address}' 2>/dev/null) if [[ "$node_ip" == "10.1.71."* ]]; then echo -e "${GREEN}✓ $node_ip (correct network)${NC}" else echo -e "${RED}✗ $node_ip (expected 10.1.71.x)${NC}" fi # Check system extensions echo -n " iscsi-tools extension: " if talosctl -n "$ip" get extensions 2>/dev/null | grep -q "iscsi-tools"; then echo -e "${GREEN}✓ installed${NC}" else if talosctl -n "$ip" read /proc/modules 2>/dev/null | grep -q "iscsi_tcp"; then echo -e "${GREEN}✓ active (module loaded)${NC}" else echo -e "${RED}✗ not found${NC}" fi fi # Check kernel modules echo -n " Kernel modules: " modules_ok=true for mod in iscsi_tcp dm_multipath dm_round_robin; do if ! talosctl -n "$ip" read /proc/modules 2>/dev/null | grep -q "^$mod "; then modules_ok=false echo -e "${RED}✗ $mod not loaded${NC}" echo -n " " fi done if $modules_ok; then echo -e "${GREEN}✓ all loaded${NC}" fi # Check iscsid service echo -n " iscsid service: " service_status=$(talosctl -n "$ip" service iscsid 2>/dev/null | grep "STATE" | awk '{print $2}' || echo "Unknown") if [[ "$service_status" == "Running" ]]; then echo -e "${GREEN}✓ Running${NC}" elif [[ "$service_status" == "Finished" ]]; then echo -e "${YELLOW}⚠ Finished (starts on-demand)${NC}" else echo -e "${YELLOW}⚠ $service_status${NC}" fi # Check initiator name echo -n " iSCSI initiator: " initiator=$(talosctl -n "$ip" read /etc/iscsi/initiatorname.iscsi 2>/dev/null | grep "InitiatorName=" | cut -d= -f2 || echo "") if [[ -n "$initiator" ]]; then echo -e "${GREEN}✓ ${initiator:0:40}...${NC}" else echo -e "${RED}✗ not configured${NC}" fi # Check /var/lib/iscsi echo -n " iSCSI data directory: " if talosctl -n "$ip" ls /var/lib/iscsi >/dev/null 2>&1; then file_count=$(talosctl -n "$ip" ls /var/lib/iscsi 2>/dev/null | wc -l) echo -e "${GREEN}✓ accessible ($file_count entries)${NC}" else echo -e "${RED}✗ not accessible${NC}" fi # Check multipath echo -n " Multipath config: " if talosctl -n "$ip" read /etc/multipath.conf >/dev/null 2>&1; then if talosctl -n "$ip" read /etc/multipath.conf 2>/dev/null | grep -q "PURE"; then echo -e "${GREEN}✓ configured for Pure Storage${NC}" else echo -e "${YELLOW}⚠ present but missing Pure config${NC}" fi else echo -e "${YELLOW}⚠ not found (will be created by DaemonSet)${NC}" fi echo -n " Multipath devices: " mp_devices=$(talosctl -n "$ip" exec -- multipath -ll 2>/dev/null | grep -c "^[a-z0-9]" || echo "0") if [[ "$mp_devices" -gt 0 ]]; then echo -e "${GREEN}✓ $mp_devices device(s)${NC}" else echo -e "${YELLOW}⚠ none (expected until iSCSI volumes attached)${NC}" fi # Check network connectivity on iSCSI interface echo -n " iSCSI network (ens19): " if talosctl -n "$ip" read /sys/class/net/ens19/operstate 2>/dev/null | grep -q "up"; then iscsi_ip=$(talosctl -n "$ip" exec -- ip addr show ens19 2>/dev/null | grep "inet " | awk '{print $2}' | cut -d/ -f1) echo -e "${GREEN}✓ up ($iscsi_ip)${NC}" else echo -e "${RED}✗ down${NC}" fi # Test FlashArray connectivity if IP provided if [[ -n "$FLASHARRAY_ISCSI_IP" ]]; then echo -n " FlashArray ping: " if talosctl -n "$ip" exec -- ping -c 1 -W 2 "$FLASHARRAY_ISCSI_IP" >/dev/null 2>&1; then echo -e "${GREEN}✓ reachable${NC}" else echo -e "${RED}✗ not reachable${NC}" fi echo -n " iSCSI discovery: " if discovery_out=$(talosctl -n "$ip" exec -- iscsiadm -m discovery -t st -p "$FLASHARRAY_ISCSI_IP" 2>&1); then target_count=$(echo "$discovery_out" | grep -c "iqn\." || echo "0") echo -e "${GREEN}✓ found $target_count target(s)${NC}" else echo -e "${RED}✗ failed${NC}" fi fi echo done echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" echo -e "${BLUE}DaemonSet Status${NC}" echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" echo if kubectl get daemonset iscsi-multipath-init -n kube-system >/dev/null 2>&1; then kubectl get daemonset iscsi-multipath-init -n kube-system echo kubectl get pods -n kube-system -l app=iscsi-multipath-init -o wide else echo -e "${YELLOW}⚠ iscsi-multipath-init DaemonSet not deployed${NC}" echo " Deploy with: kubectl apply -f iscsi-multipath-init.yaml" fi echo echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" echo -e "${GREEN}Verification complete!${NC}" echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"