#!/bin/bash
# ==============================================================================
# 脚本名称: add_pub2_ip.sh
# 功能描述: 
#   1. 根据输入的 IP/掩码 配置公网网卡 (默认 eth1)
#   2. 获取管理网网关，并为内网网段添加静态路由
#   3. 移除管理网卡的默认网关，将默认网关切换至公网网卡
#   4. 进行公网连通性测试
# 
# 使用方法: ./add_pub_ip2.sh <IP/Mask> [Interface]
#   例如: ./add_pub_ip2.sh 106.75.x.x/24 eth1
#
# 作者: owen.he
# 日期: 2026-02-06
# ==============================================================================

# ------------------------------------------------------------------------------
# 1. 全局配置与常量 (Configuration)
# ------------------------------------------------------------------------------
# 用于探测管理网路由的目标 IP (通常是内网的一个稳定 IP)
PROBE_IP_FOR_ROUTE='192.168.168.106'

# 需要添加到管理网关的内网网段列表
INTERNAL_NETWORKS=("172.16.0.0/12" "192.168.0.0/16" "10.0.0.0/8" "100.96.0.0/11")

# 颜色定义
GREEN='\033[0;32m'
RED='\033[0;31m'
NC='\033[0m' # No Color

# ------------------------------------------------------------------------------
# 2. 帮助与检查函数 (Helpers)
# ------------------------------------------------------------------------------

# 打印使用说明
usage() {
    echo -e "${GREEN}Usage: $0 IP/mask [ethX]${NC}"
    echo "Example: $0 1.2.3.4/24 eth1"
}

# 检查命令是否执行成功
check_error() {
    if [[ $? -ne 0 ]]; then
        echo -e "${RED}Error: $1${NC}"
        exit 1
    fi
}

# ------------------------------------------------------------------------------
# 3. 核心功能函数 (Core Functions)
# ------------------------------------------------------------------------------

# 函数: 验证输入参数和环境
# 参数: $1=IP_CIDR, $2=INTERFACE
validate_input() {
    local ip_cidr="$1"
    local iface="$2"

    if [[ -z "$ip_cidr" ]]; then
        usage
        exit 1
    fi

    # 检查 ipcalc 工具
    if ! command -v ipcalc &> /dev/null; then
        echo -e "${RED}Error: ipcalc command not found. Please install initscripts or ipcalc.${NC}"
        exit 1
    fi

    # 验证 IP 格式
    ipcalc -c "$ip_cidr" &> /dev/null
    check_error "Validate IP address $ip_cidr failed"

    # 验证网卡是否存在
    ethtool "$iface" &> /dev/null
    if [[ $? -ne 0 ]]; then
        echo -e "${RED}Error: Network interface '$iface' not exist!${NC}"
        exit 2
    fi
}

# 函数: 计算网络信息 (掩码、网关)
# 参数: $1=IP_CIDR
# 返回: 设置全局变量 IPADDR, NETMASK, GATEWAY
calc_network_info() {
    local ip_cidr="$1"
    
    IPADDR=$(echo "$ip_cidr" | cut -f1 -d'/')
    local cidr_prefix=$(echo "$ip_cidr" | cut -f2 -d'/')
    
    # 计算子网掩码
    NETMASK=$(ipcalc -m "$ip_cidr" | awk -F '=' '{print $2}')
    
    # 计算网关 (默认取网段的第1个可用IP作为网关，逻辑延续原脚本)
    # 原逻辑：
    # ga1 = 前三段 (e.g., 106.75.123)
    # ga2 = 第四段的网络地址部分 (e.g., 0)
    # ga3 = ga2 + 1 (e.g., 1)
    # gateway = ga1.ga3
    
    local network_base=$(ipcalc -n "$ip_cidr" | awk -F '=' '{print $2}')
    local base_prefix=$(echo "$network_base" | awk -F '.' '{print $1"."$2"."$3}')
    local host_part=$(echo "$network_base" | awk -F '.' '{print $4}')
    
    if [[ -z "$base_prefix" || -z "$host_part" ]]; then
        echo -e "${RED}Error: Failed to calculate network info from $ip_cidr${NC}"
        exit 1
    fi

    local gateway_host=$((host_part + 1))
    GATEWAY="${base_prefix}.${gateway_host}"
    
    echo "----------------------------------------"
    echo "IP Info:"
    echo "  IP Address: $IPADDR"
    echo "  Netmask:    $NETMASK"
    echo "  Gateway:    $GATEWAY"
    echo "----------------------------------------"
}

# 函数: 获取管理网信息
# 返回: 设置全局变量 MAN_ETH, MAN_GATEWAY
get_management_info() {
    # 通过探测 IP 获取路由信息
    # 提取 dev (网卡) 和 via (网关)
    
    MAN_ETH=$(ip -o r get "$PROBE_IP_FOR_ROUTE" | sed -n 's/.*dev \([a-z0-9]*\) .*/\1/p')
    if [[ -z "$MAN_ETH" ]]; then
        echo -e "${RED}Error: Cannot detect management interface (route to $PROBE_IP_FOR_ROUTE)${NC}"
        exit 1
    fi

    MAN_GATEWAY=$(ip -o r get "$PROBE_IP_FOR_ROUTE" | sed -n 's/.*via \([0-9\.]*\).*/\1/p')
    if [[ -z "$MAN_GATEWAY" ]]; then
        echo -e "${RED}Error: Cannot detect management gateway (route to $PROBE_IP_FOR_ROUTE)${NC}"
        exit 1
    fi

    echo "Management Network: Interface=$MAN_ETH, Gateway=$MAN_GATEWAY"
}

# 函数: 配置内网静态路由
configure_internal_routes() {
    local route_file="/etc/sysconfig/network-scripts/route-$MAN_ETH"
    echo "Configuring internal routes in $route_file..."

    for route in "${INTERNAL_NETWORKS[@]}"; do
        # 检查是否已存在路由配置 (避免重复添加)
        if [[ $(grep -c "$route" "$route_file" 2>/dev/null) -eq 0 ]]; then
            echo "$route via $MAN_GATEWAY" >> "$route_file"
            # 立即添加临时路由
            ip r add "$route" via "$MAN_GATEWAY" 2>/dev/null
            echo "  Added route: $route via $MAN_GATEWAY"
        else
            echo "  Route exists: $route"
        fi
    done
}

# 函数: 配置公网网卡并切换默认路由
# 参数: $1=INTERFACE
configure_public_interface() {
    local iface="$1"
    local man_ifcfg="/etc/sysconfig/network-scripts/ifcfg-$MAN_ETH"
    local pub_ifcfg="/etc/sysconfig/network-scripts/ifcfg-$iface"

    echo "Switching default gateway..."
    
    # 1. 从管理网卡配置中移除 GATEWAY 项 (防止重启后冲突)
    if [ -f "$man_ifcfg" ]; then
        sed -i '/GATEWAY/d' "$man_ifcfg"
        echo "  Removed GATEWAY from $man_ifcfg"
    fi
    
    # 2. 删除当前的默认路由
    ip r del default 2>/dev/null
    
    # 3. 创建公网网卡配置文件
    echo "Creating configuration for $iface..."
    cat > "$pub_ifcfg" <<EOF
DEVICE=$iface
TYPE=Ethernet
ONBOOT=yes
NM_CONTROLLED=no
BOOTPROTO=static
IPADDR=$IPADDR
NETMASK=$NETMASK
GATEWAY=$GATEWAY
EOF

    # 4. 启动网卡
    echo "Bringing up $iface..."
    ifup "$iface"
    if [[ $? -ne 0 ]]; then
        echo -e "${RED}Warning: 'ifup $iface' returned error. Checking connectivity anyway...${NC}"
    fi
    
    sleep 5 # 等待网络建立
}

# 函数: 测试网络连通性
test_connectivity() {
    local dns_list=("8.8.8.8" "119.29.29.29" "223.5.5.5" "1.1.1.1" "1.2.4.8")
    local success_count=0
    
    echo "Testing connectivity..."
    for dns in "${dns_list[@]}"; do
        if ping -w3 -c1 "$dns" &>/dev/null; then
            echo -e "  Ping $dns: ${GREEN}Success${NC}"
            success_count=$((success_count + 1))
        else
            echo -e "  Ping $dns: ${RED}Failed${NC}"
        fi
    done

    if (( success_count >= 1 )); then
        echo -e "${GREEN}==> Network check passed! ($success_count/${#dns_list[@]} success)${NC}"
    else
        echo -e "${RED}==> Network check failed! Please check your configuration.${NC}"
        exit 3
    fi
}

# ------------------------------------------------------------------------------
# 4. 主流程 (Main)
# ------------------------------------------------------------------------------
main() {
    # 参数解析
    local input_ip="$1"
    local input_node="$2"
    
    # 如果未指定网卡，默认使用 eth1
    local target_iface="${input_node:-eth1}"

    # 1. 基础验证
    validate_input "$input_ip" "$target_iface"
    
    # 2. 计算新IP的网络参数
    calc_network_info "$input_ip"
    
    # 3. 获取现有管理网环境信息
    get_management_info
    
    # 4. 配置内网路由 (确保切网关后内网互通)
    configure_internal_routes
    
    # 5. 配置公网网卡并切换网关
    configure_public_interface "$target_iface"
    
    # 6. 测试
    test_connectivity
}

# 执行入口
main "$@"
