Some checks failed
Deploy to Phoenix / deploy (push) Has been cancelled
- Config, docs, scripts, and backup manifests - Submodule refs unchanged (m = modified content in submodules) Made-with: Cursor
200 lines
5.3 KiB
Bash
Executable File
200 lines
5.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
# Load IP configuration
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
source "${PROJECT_ROOT}/config/ip-addresses.conf" 2>/dev/null || true
|
|
|
|
|
|
# Add VLAN 11 secondary IP address using netplan (persistent)
|
|
# This makes the configuration persistent across reboots
|
|
|
|
set -e
|
|
|
|
# Configuration
|
|
VLAN11_IP="${IP_SERVICE_23:-${IP_SERVICE_23:-192.168.11.23}}"
|
|
VLAN11_NETMASK="24"
|
|
VLAN11_GATEWAY="${NETWORK_GATEWAY:-192.168.11.1}"
|
|
|
|
echo "🔧 Adding VLAN 11 Secondary IP Address (Persistent via Netplan)"
|
|
echo ""
|
|
|
|
# Check if running as root
|
|
if [ "$EUID" -ne 0 ]; then
|
|
echo "❌ This script must be run with sudo"
|
|
echo " Usage: sudo $0"
|
|
exit 1
|
|
fi
|
|
|
|
# Detect primary interface
|
|
PRIMARY_IF=$(ip route show | grep default | awk '{print $5}' | head -1)
|
|
if [ -z "$PRIMARY_IF" ]; then
|
|
echo "❌ Could not detect primary network interface"
|
|
exit 1
|
|
fi
|
|
|
|
CURRENT_IP=$(ip -4 addr show $PRIMARY_IF 2>/dev/null | grep -oP 'inet \K[\d.]+' | head -1)
|
|
CURRENT_GW=$(ip route show | grep default | awk '{print $3}' | head -1)
|
|
|
|
echo "📋 Configuration:"
|
|
echo " Primary Interface: $PRIMARY_IF"
|
|
echo " Current IP: $CURRENT_IP"
|
|
echo " Current Gateway: $CURRENT_GW"
|
|
echo " VLAN 11 IP: $VLAN11_IP/$VLAN11_NETMASK"
|
|
echo " VLAN 11 Gateway: $VLAN11_GATEWAY"
|
|
echo ""
|
|
|
|
# Check if netplan is available
|
|
if ! command -v netplan &> /dev/null; then
|
|
echo "❌ netplan is not installed"
|
|
echo " Install with: sudo apt install netplan.io"
|
|
exit 1
|
|
fi
|
|
|
|
# Find netplan config file
|
|
NETPLAN_DIR="/etc/netplan"
|
|
NETPLAN_FILE=$(ls $NETPLAN_DIR/*.yaml 2>/dev/null | head -1)
|
|
|
|
if [ -z "$NETPLAN_FILE" ]; then
|
|
echo "❌ No netplan configuration file found in $NETPLAN_DIR"
|
|
exit 1
|
|
fi
|
|
|
|
echo "📋 Found netplan config: $NETPLAN_FILE"
|
|
echo ""
|
|
|
|
# Backup
|
|
BACKUP_FILE="${NETPLAN_FILE}.backup.$(date +%Y%m%d_%H%M%S)"
|
|
cp "$NETPLAN_FILE" "$BACKUP_FILE"
|
|
echo "✅ Backup created: $BACKUP_FILE"
|
|
echo ""
|
|
|
|
# Check if VLAN 11 IP already configured
|
|
if grep -q "$VLAN11_IP" "$NETPLAN_FILE"; then
|
|
echo "✅ VLAN 11 IP ($VLAN11_IP) already configured in netplan"
|
|
echo " Applying configuration..."
|
|
netplan apply
|
|
exit 0
|
|
fi
|
|
|
|
echo "🔄 Updating netplan configuration..."
|
|
echo ""
|
|
|
|
# Use Python to safely modify YAML
|
|
python3 << EOF
|
|
import yaml
|
|
import sys
|
|
|
|
# Read current config
|
|
with open("$NETPLAN_FILE", 'r') as f:
|
|
config = yaml.safe_load(f)
|
|
|
|
# Ensure network structure exists
|
|
if 'network' not in config:
|
|
config['network'] = {}
|
|
|
|
if 'ethernets' not in config['network']:
|
|
config['network']['ethernets'] = {}
|
|
|
|
if '$PRIMARY_IF' not in config['network']['ethernets']:
|
|
config['network']['ethernets']['$PRIMARY_IF'] = {}
|
|
|
|
# Get current addresses
|
|
interface = config['network']['ethernets']['$PRIMARY_IF']
|
|
current_addresses = interface.get('addresses', [])
|
|
|
|
# Add VLAN 11 IP if not present
|
|
vlan11_address = "$VLAN11_IP/$VLAN11_NETMASK"
|
|
if vlan11_address not in current_addresses:
|
|
if not isinstance(current_addresses, list):
|
|
current_addresses = [current_addresses] if current_addresses else []
|
|
current_addresses.append(vlan11_address)
|
|
interface['addresses'] = current_addresses
|
|
print(f"✅ Added VLAN 11 IP: {vlan11_address}")
|
|
else:
|
|
print(f"✅ VLAN 11 IP already present: {vlan11_address}")
|
|
|
|
# Add routes for VLAN 11 if needed
|
|
if 'routes' not in interface:
|
|
interface['routes'] = []
|
|
|
|
# Check if route to VLAN 11 network exists
|
|
vlan11_route = {
|
|
'to': '${NETWORK_192_168_11_0:-192.168.11.0}/24',
|
|
'via': '$VLAN11_GATEWAY'
|
|
}
|
|
|
|
route_exists = any(
|
|
r.get('to') == '${NETWORK_192_168_11_0:-192.168.11.0}/24'
|
|
for r in interface['routes']
|
|
)
|
|
|
|
if not route_exists:
|
|
interface['routes'].append(vlan11_route)
|
|
print(f"✅ Added route to VLAN 11 network")
|
|
else:
|
|
print(f"✅ Route to VLAN 11 network already exists")
|
|
|
|
# Write updated config
|
|
with open("$NETPLAN_FILE", 'w') as f:
|
|
yaml.dump(config, f, default_flow_style=False, sort_keys=False)
|
|
|
|
print("✅ Netplan configuration updated")
|
|
EOF
|
|
|
|
if [ $? -ne 0 ]; then
|
|
echo "❌ Failed to update netplan configuration"
|
|
echo " Restoring backup..."
|
|
cp "$BACKUP_FILE" "$NETPLAN_FILE"
|
|
exit 1
|
|
fi
|
|
|
|
echo ""
|
|
echo "📋 Updated configuration:"
|
|
cat "$NETPLAN_FILE"
|
|
echo ""
|
|
|
|
# Apply netplan configuration
|
|
echo "🔄 Applying netplan configuration..."
|
|
if netplan try --timeout 5 >/dev/null 2>&1; then
|
|
netplan apply
|
|
echo "✅ Configuration applied successfully"
|
|
else
|
|
echo "⚠️ Validation failed. Restoring backup..."
|
|
cp "$BACKUP_FILE" "$NETPLAN_FILE"
|
|
netplan apply
|
|
exit 1
|
|
fi
|
|
|
|
# Wait for network
|
|
sleep 3
|
|
|
|
# Verify
|
|
echo ""
|
|
echo "🔍 Verifying configuration..."
|
|
NEW_IPS=$(ip -4 addr show $PRIMARY_IF | grep "inet " | awk '{print $2}')
|
|
echo " Current IP addresses on $PRIMARY_IF:"
|
|
echo "$NEW_IPS" | sed 's/^/ /'
|
|
|
|
if echo "$NEW_IPS" | grep -q "$VLAN11_IP"; then
|
|
echo " ✅ VLAN 11 IP ($VLAN11_IP) is configured"
|
|
else
|
|
echo " ⚠️ VLAN 11 IP not found (may need to check configuration)"
|
|
fi
|
|
|
|
# Test connectivity
|
|
echo ""
|
|
echo "🧪 Testing Connectivity..."
|
|
if ping -c 1 -W 2 $VLAN11_GATEWAY >/dev/null 2>&1; then
|
|
echo " ✅ VLAN 11 gateway ($VLAN11_GATEWAY) is reachable"
|
|
else
|
|
echo " ⚠️ VLAN 11 gateway ($VLAN11_GATEWAY) is not reachable"
|
|
fi
|
|
|
|
echo ""
|
|
echo "✅ Configuration complete and persistent!"
|
|
echo ""
|
|
echo "💡 The configuration will persist across reboots."
|
|
echo ""
|