#!/bin/bash
set -euo pipefail

# ========================== 全局配置 ==========================
#  a颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'

# 打印工具函数
info() { echo -e "${YELLOW}[INFO]${NC} $1"; }
success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
error() { echo -e "${RED}[ERROR]${NC} $1"; exit 1; }
step() { echo -e "\n${BLUE}>> $1${NC}"; }

# 配置参数
ACTION=""
VIP=""
PRIORITY=150
INTERFACE=""
KEEPALIVED_CONF="/etc/keepalived/keepalived.conf"
CHECK_SCRIPT="/usr/local/bin/check_haproxy.sh"


# ========================== 帮助信息 ==========================
usage() {
    cat << EOF
Keepalived 高可用配置脚本（适配K8s VIP管理）
功能：安装/卸载Keepalived，配置虚拟IP(VIP)及HAProxy健康检查

用法: $0 [操作] [选项]

操作:
  --install   安装并配置Keepalived
  --uninstall 卸载Keepalived及清理配置

安装选项:
  --vip <VIP>          必选，虚拟IP（格式：192.168.1.100/24）
  --priority <数值>    可选，节点优先级（默认150，主节点建议150+，备节点140-）

示例:
  主节点安装: $0 --install --vip 192.168.61.200/24 --priority 150
  备节点安装: $0 --install --vip 192.168.61.200/24 --priority 140
  卸载: $0 --uninstall
EOF
    exit 1
}


# ========================== 工具函数 ==========================
# 获取默认网卡（非回环，第一个激活的网卡）
get_default_interface() {
    INTERFACE=$(ip -br link show up | grep -v LOOPBACK | awk '{print $1}' | head -n1)
    [[ -z "$INTERFACE" ]] && error "无法获取有效网卡，请检查网络接口状态"
    info "自动获取网卡：$INTERFACE"
}


# ========================== 安装逻辑 ==========================
install_keepalived() {
    # 参数校验
    [[ -z "$VIP" ]] && error "必须通过--vip指定虚拟IP（格式：IP/子网掩码，如192.168.61.200/24）"
    [[ ! "$VIP" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/[0-9]+$ ]] && error "VIP格式无效，正确格式：192.168.61.200/24"
    [[ ! "$PRIORITY" =~ ^[0-9]+$ ]] && error "优先级必须是整数（如150）"

    step "开始安装Keepalived"
    
    # 获取网卡
    get_default_interface

    # 安装软件（静默模式，去除apt警告）
    info "安装Keepalived软件包..."
    apt update -qq >/dev/null 2>&1
    apt update  >/dev/null 2>&1
    #apt install -y -qq keepalived >/dev/null 2>&1 || error "Keepalived安装失败"
    apt install -y  keepalived >/dev/null 2>&1 || error "Keepalived安装失败"
    success "Keepalived软件包安装完成"

    # 备份原有配置
    if [[ -f "$KEEPALIVED_CONF" ]]; then
        local backup="${KEEPALIVED_CONF}.bak.$(date +%F_%H%M%S)"
        mv "$KEEPALIVED_CONF" "$backup"
        info "原有配置已备份至：$backup"
    fi

    # 创建健康检查脚本（监控HAProxy状态）
    info "创建HAProxy健康检查脚本..."
    cat > "$CHECK_SCRIPT" << 'EOF'
#!/bin/bash
pgrep -x "haproxy" >/dev/null 2>&1 || { systemctl stop keepalived; exit 1; }
exit 0
EOF
    chmod +x "$CHECK_SCRIPT" || error "健康检查脚本权限设置失败"
    success "健康检查脚本已创建：$CHECK_SCRIPT"

    # 生成配置文件
    info "生成Keepalived配置..."
    local state="BACKUP"
    [[ "$PRIORITY" -ge 150 ]] && state="MASTER"  # 优先级≥150默认为主节点

    cat > "$KEEPALIVED_CONF" << EOF
global_defs {
    router_id LVS_K8S_$(hostname)
    script_security 2
    enable_script_security
}

vrrp_script check_haproxy {
    script "$CHECK_SCRIPT"
    interval 2
    weight -5
}

vrrp_instance VI_1 {
    state $state
    interface $INTERFACE
    virtual_router_id 51
    priority $PRIORITY
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass k8s_ha_auth_2024
    }
    virtual_ipaddress {
        $VIP
    }
    track_script {
        check_haproxy
    }
}
EOF
    [[ -f "$KEEPALIVED_CONF" ]] || error "配置文件生成失败"
    success "配置文件已生成：$KEEPALIVED_CONF"

    # 启动服务
    info "启动并设置开机自启..."
    systemctl enable --now keepalived >/dev/null 2>&1 || error "Keepalived启动失败（日志：journalctl -u keepalived）"
    [[ "$(systemctl is-active keepalived)" == "active" ]] || error "Keepalived启动后状态异常"

    # 安装完成汇总
    echo -e "\n${GREEN}===== 安装完成 =====${NC}"
    echo "  VIP:         $VIP"
    echo "  节点角色:    $state（优先级: $PRIORITY）"
    echo "  绑定网卡:    $INTERFACE"
    echo "  健康检查:    $CHECK_SCRIPT"
    echo "  服务状态:    运行中"
}


# ========================== 卸载逻辑 ==========================
uninstall_keepalived() {
    step "开始卸载Keepalived"

    # 停止服务
    if systemctl is-active --quiet keepalived; then
        info "停止Keepalived服务..."
        systemctl stop keepalived >/dev/null 2>&1 || info "服务停止失败，继续卸载"
        success "服务已停止"
    else
        info "Keepalived未运行，跳过停止步骤"
    fi

    # 卸载软件
    if dpkg -l keepalived &>/dev/null; then
        info "卸载软件包..."
        apt purge -y -qq keepalived >/dev/null 2>&1 || error "软件包卸载失败"
        apt autoremove -y -qq >/dev/null 2>&1
        success "软件包已卸载"
    else
        info "Keepalived未安装，跳过卸载"
    fi

    # 清理配置
    if [[ -d /etc/keepalived/ ]]; then
        local backup="/etc/keepalived.bak.$(date +%F_%H%M%S)"
        mv /etc/keepalived/ "$backup"
        success "配置目录已备份至：$backup"
    fi

    # 清理健康检查脚本
    if [[ -f "$CHECK_SCRIPT" ]]; then
        rm -f "$CHECK_SCRIPT"
        success "健康检查脚本已删除：$CHECK_SCRIPT"
    fi

    # 卸载完成
    echo -e "\n${GREEN}===== 卸载完成 =====${NC}"
}


# ========================== 主逻辑 ==========================
main() {
    # 解析参数
    while [[ $# -gt 0 ]]; do
        case "$1" in
            --install|--uninstall) ACTION="$1"; shift ;;
            --vip) [[ $# -lt 2 ]] && error "--vip需指定IP/子网掩码"; VIP="$2"; shift 2 ;;
            --priority) [[ $# -lt 2 ]] && error "--priority需指定数值"; PRIORITY="$2"; shift 2 ;;
            *) error "未知参数：$1" ;;
        esac
    done

    # 校验操作
    [[ -z "$ACTION" ]] && error "必须指定--install（安装）或--uninstall（卸载）"

    # 检查root权限
    [[ $EUID -ne 0 ]] && error "请使用root权限运行（sudo $0 ...）"

    # 执行操作
    case "$ACTION" in
        --install) install_keepalived ;;
        --uninstall) uninstall_keepalived ;;
    esac
}

main "$@"
