#!/bin/bash
# Date: 2021-11-18
# Author: Vivi
# Email: wangluwei@uniontech.com
# Description: Tool for checking the cluster fence
# Version: 1.0


function check_pcs() {
    pcs status &>>/dev/null
    if [ "$?" -ne "0" ];then
        error_exit "错误：集群未启动，请检查当前节点是否有集群或启动集群后再尝试"
    fi
}

function check_node() {

    pcs status|grep "Online"|grep "\b$FENCE_NODE\b" &>>/dev/null
    if [ "$?" -ne 0 ]; then
        pcs status|grep "Node List" -A1|grep -v "Online"|grep "\b$FENCE_NODE\b" &>>/dev/null
        if [ "$?" -eq "0" ]; then
            error_exit "错误：节点$FENCE_NODE状态异常,请检查后重试"
        fi
        error_exit "错误：节点$FENCE_NODE不在集群中"
    fi

    grep "\b$FENCE_NODE\b" /etc/hosts|grep -v "#" &>>/dev/null
    if [ "$?" -ne "0" ]; then
        error_exit "错误：请检查/etc/hosts中是否有节点$FENCE_NODE配置"
    fi

    timeout 5 bash -c "</dev/tcp/$FENCE_NODE/22" &>>/dev/null
    if [ "$?" -ne "0" ];then
        error_exit "错误：请检查各节点22端口是否开启"
    fi

}


function check_start_commd() {

    if [ ! "$#" = "2" ]; then
        error_exit "集群fence状态检测命令用法为： ha-health-check --fence-node NODE。"
    elif [ "$1" != "--fence-node" ]; then
        error_exit "集群fence状态检测命令用法为：ha-health-check --fence-node NODE。"
    else
        #echo $2 | grep -E "^[[:alpha:]]+[[:alnum:]]+$" &>/dev/dull
        echo $2 | grep -E "^[[:alnum:]]+$" &>/dev/dull
        if [ "$?" -eq "0" ]; then
            log "输入的节点名格式正确。" >>$ha_check_log
        else
            error_exit "错误：集群节点名应只能包含字母和数字，不能包含特殊字符。"
        fi
 
        if [ $(echo "$FENCE_NODE" | wc -L) -gt 128 ]; then
            error_exit "错误：集群名称不能大于128位。"
        fi
  
        if [ ! -f "$ha_check_log" ]; then
            touch $ha_check_log
            log "$ha_check_log创建完成。" >>$ha_check_log
        else
            log "$ha_check_log已经存在。" >>$ha_check_log
            rm $ha_check_log
            touch $ha_check_log
            log "清空$ha_check_log内容完成。" >>$ha_check_log
        fi
    fi

}

function fence_check(){

    FENCE_ENABLED=$(pcs property config --all |grep stonith-enabled|awk '{print $2}')
    log "stonith-enabled状态为：$FENCE_ENABLED" >>$ha_check_log
    FENCE_TYPE=$(pcs stonith|grep "\bStarted\b"|grep "\bstonith:fence"|awk '{print $3}'|awk -F '[():]' '{print $3}'|grep "fence"|head -1)
    log "当前fence为：$FENCE_TYPE" >>$ha_check_log
    if [ "$FENCE_TYPE" == "" -o "$FENCE_ENABLED" != "true" ]; then
        error_exit "错误：集群stonith不可用，请检查集群是否存在stonith或其配置是否正确"
    fi

    FENCE_ACTION=$(pcs property config --all |grep stonith-action|awk '{print $2}')
    case $FENCE_ACTION in
    reboot);;
    off);;
	#FENCE_ACTION="poweroff";;
    poweroff);;
    *)
	error_exit "错误：集群Stonith Action：$FENCE_ACTION异常";;
    esac

    log "集群Stonith Action为$FENCE_ACTION" >>$ha_check_log

    if [ "$FENCE_ACTION" == "reboot" ];then
        FENCE_ACTION_STRING="重启"
    else
	FENCE_ACTION_STRING="关机" 
    fi

}

function fence_start() {

    printf  "%-15s %-15s \n" 'TASK' "Fence node $FENCE_NODE"
    printf  "%-15s %-15s \n" 'Fence action' "$FENCE_ACTION"

    echo "===================================="
    if [ "$FENCE_NODE" == "$LOCAL_HOSTNAME" ]; then
	log "警告：检查节点为当前节点，将会造成当前节点$FENCE_NODE$FENCE_ACTION_STRING" >>$ha_check_log
        echo "警告：检查节点为当前节点，将会造成当前节点$FENCE_NODE$FENCE_ACTION_STRING"
    else
	log "节点$FENCE_NODE将$FENCE_ACTION_STRING" >>$ha_check_log
	echo "节点$FENCE_NODE将$FENCE_ACTION_STRING"
    fi

    while true; do
        read -p "是否继续(y/n):" OPTION
	case $OPTION in
	y)
	    break;;
	n)
	    echo "===================================="
	    log "fence检测已取消,检测工具退出" >>$ha_check_log
	    echo "fence检测已取消,检测工具退出"
            exit 0;;
	*);;
        esac
    done 

    echo "===================================="
    #pcs stonith fence $FENCE_NODE &>>/dev/null
    crm_attribute -t status -N $FENCE_NODE -n terminate -v true 1>>/dev/null
    if [ "$?" -ne "0" ]; then
        error_exit "错误：fence:$FENCE_TYPE异常"
    fi

    #ping $FENCE_NODE -w 1 &>>/dev/null
    #ssh -v root@node1 -p 80 2>&1|grep "Connection established" &>>/dev/null
    
    log "请等待节点$FENCE_NODE关机" >>$ha_check_log
    echo "请等待节点$FENCE_NODE关机"
    local num=0
    local node_off=0
    local node_online=0
    while true;do
	timeout 1 bash -c "</dev/tcp/$FENCE_NODE/22" &>>/dev/null
        node_off=$?
        pcs status|grep -E 'Online|online'|grep "\b$FENCE_NODE\b" &>>/dev/null
	node_online=$?
        if [ "$node_off" -eq "0" -a "$num" -lt "120" ]; then
	    ((num+=1))
        elif [ "$node_off" -ne "0" ];then
	    echo "节点$FENCE_NODE关机成功"
	    log "节点$FENCE_NODE关机成功" >>$ha_check_log
	    break
        elif [ "$node_online" -eq "0" -a "$num" -ge "120" ];then
	    error_exit "错误：未检测到节点关机，请手动确认节点$FENCE_NODE是否已关机，如仍未关机请检查fence配置。"
	else
            error_exit "错误：节点$FENCE_NODE状态异常"
        fi
    done

    if [ "$FENCE_ACTION" != "reboot" ];then
	echo "=================恭喜==============="
        echo "检测完成！当前fence功能正常"
	log "检测完成！当前fence功能正常" >>$ha_check_log
	exit 0
    fi

    echo "===================================="
    echo "请等待节点$FENCE_NODE重启"
    log "请等待节点$FENCE_NODE重启" >>$ha_check_log

    num=0
    while true;do
        timeout 1 bash -c "</dev/tcp/$FENCE_NODE/22" &>>/dev/null
        if [ $? -ne 0 -a $num -lt 120 ];then
            sleep 5
	    ((num+=1))
        elif [ $num -ge 60 ];then
	    error_exit "错误：节点$FENCE_NODE重启超时"
        else
            echo "节点$FENCE_NODE重启成功"
            log "节点$FENCE_NODE重启成功" >>$ha_check_log
	    break
	fi
    done

    echo "集群状态检测中"
    log "集群状态检测中" >>$ha_check_log

    num=0
    while true; do
        pcs status|grep "\b$FENCE_TYPE\b"|grep "pending" &>>/dev/null
	local status1="$?"
	pcs status|grep "OFFLINE"|grep "\b$FENCE_NODE\b" &>>/dev/null
	local status2="$?"

	if [ "$status1" -eq "0" -o "$status2" -eq "0" ] && [ "$num" -lt "30" ];then
           sleep 10
	   ((num+=1))
        else
	    break
        fi
    done

    pcs status |grep "Online"|grep "\b$FENCE_NODE\b" &>>/dev/null
    if [ "$?" -ne "0" ];then
        error_exit "错误:节点$FENCE_NODE状态异常"
    else
        pcs status |grep "stonith:$FENCE_TYPE" |grep "Started" &>>/dev/null
        if [ "$?" -ne "0" ];then
            error_exit "错误：fence:$FENCE_TYPE状态异常"
        fi
    fi

    echo "=================恭喜==============="
    echo "检测完成！当前fence功能正常"
    log "检测完成！当前fence功能正常" >>$ha_check_log
}



FENCE_NODE=$2
LOCAL_HOSTNAME=$(hostname)
