#!/bin/bash

#
#巡检S3 DNS服务状态
#只在HA主节点上检查

#设置查询的LS数据配置信息
LOG_FILE="/var/log/inspect.log"
QUERY_CLUSTER_LOG="${LOG_DIR}/addCluster.log"
gaussDbPath="/opt/huawei/gaussdb/app/"
snasPath="/opt/huawei/snas/etc/snas.ini"
hamapPath="/proc/monc_hamap"
mdcPath="/var/uds/user/data_mdc"
localexecPath="/opt/huawei/deploy/script"
shellPath="/opt/obs/service/osc"
readonly PARAM_DB_PORT=5679
readonly databasename=mydb
#设置sqlite环境
export LD_LIBRARY_PATH=/usr/sqlite3/lib/:/opt/huawei/snas/lib/

#CM_INI_PATH
readonly CM_INI_PATH="/opt/huawei/snas/etc/cm.ini"

G_INSPECT_MMLPATH="/opt/huawei/snas/script/inspect_mml"
source $G_INSPECT_MMLPATH/CheckItems
CurInspectNum="268"
CurInspectFun="$(GetInspectType $CurInspectNum)"
RESULTFILE="/tmp/tmpResult${CurInspectFun}"
>${RESULTFILE}

CHECK_PASSED=0
CHECK_FAILED=1

#重试次数的设置
CONNECTTINME=3
#日志输出
function LOG
{
   time=$(date)
   echo [${time}][$$][$CurInspectFun]$@ >> $LOG_FILE
}
#===================================================
# 函数名称：checkDBisException
# 函数功能：检测数据库是否异常
#返回值：未异常为0, 异常为1
#===================================================
function checkDBisException()
{
        #检查数据是否异常重试次数为三次
        for(( i=1;i<=$CONNECTTINME;i++))
        do
            local isException=$(su - gaussdba -c "${gaussDbPath}/bin/gsql -d \"$databasename\" -p \"$PARAM_DB_PORT\" $mdcdbUserPwdStr -c \"select id from clusterinfotable;\"" |  sed -n '1p' | sed 's/ //g')
            if [ "ID" != "$isException" ];then
                    if [ $i -eq $CONNECTTINME ];then
                        return 1
                    fi
                    continue
            fi
            return 0
        done
}
#查询LS数据库获去本集群集群信息
# 函数名称：queryLocalCluster
# 函数功能：查询集群的信息
# 返回值：
# 成功返回：cname groupip
# 失败返回：1
#===================================================
function queryLocalCluster()
{
    checkDBisException
    if [ $? -ne 0 ];then
            LOG "[$LINENO]ERROR: DB is exception"
            return 1
    fi
    local clusterList=$(su - gaussdba -c "${gaussDbPath}/bin/gsql -d \"$databasename\" -p \"$PARAM_DB_PORT\" $mdcdbUserPwdStr -c \"select CNAME from clusterinfotable;\"" | sed '1,2d' | sed '/row/d' | sed 's/|/ /g')
    if [ -z "$clusterList" ];then
        LOG "[$LINENO]WARN: query Cluster  failed.  cluster is not exist."
        return 1
    fi
    LOG "[$LINENO]INFO: query Cluster success."
    echo $clusterList
    return 0
}
#查询LS数据库获取本区域的区域域名
# 函数名称：queryLocalRegionCname
# 函数功能：本区域的区域域名
# 返回值：
# 成功返回：cname
# 失败返回：1
#===================================================
function queryLocalRegionCname()
{
    #查询本区域的区域域名
    checkDBisException
    if [ $? -ne 0 ];then
            LOG "[$LINENO]ERROR: DB is exception"
            return 1
    fi
    #获取当前区域ID
    mutiazPath="/opt/huawei/snas/etc/multiaz.ini"
    RegionId=$(egrep "^Region=" ${mutiazPath} | awk '{print $1}' | awk -F"=" '{print $2}' | sed 's/,/ /g' | sed 's/\r//g')
    local regionList=$(su - gaussdba -c "${gaussDbPath}/bin/gsql -d \"$databasename\" -p \"$PARAM_DB_PORT\" $mdcdbUserPwdStr -c \"select ENDPOINT from regioninfotable where ID='$RegionId';\"" | sed '1,2d' | sed '/row/d' | sed 's/|/ /g')
    if [ -z "$regionList" ];then
        LOG "[$LINENO]WARN: query region  failed.  region is not exist."
        echo $regionList
        return 1
    fi
    LOG "[$LINENO]INFO: query region success."
    echo $regionList
    return 0
}
#查询LS数据库获取本集群所在集群组域名
# 函数名称：queryLocalCgCname
# 函数功能：本集群所在集群组域名
# 返回值：
# 成功返回：cname
# 失败返回：1
#===================================================
function queryLocalCgCname()
{
    #查询本区域的区域域名
    checkDBisException
    if [ $? -ne 0 ];then
        LOG "[$LINENO]ERROR: DB is exception"
        return 1
    fi
    local cgList=$(su - gaussdba -c "${gaussDbPath}/bin/gsql -d \"$databasename\" -p \"$PARAM_DB_PORT\" $mdcdbUserPwdStr -c \"select CNAME from clustergroupinfotable;\"" | sed '1,2d' | sed '/row/d' | sed 's/|/ /g')
    if [ -z "$cgList" ];then
        LOG "[$LINENO]WARN: query clustergroup failed.  clustergroup is not exist."
        echo $cgList
        return 1
    fi
    LOG "[$LINENO]INFO: query region success."
    echo $cgList
    return 0
}

#判断该节点是否需要检查,返回：1，需要检查；0，不需要检查
#1.检查本节点是否是S3/Swift节点
#2.检查本节点是否是S3/Swift管理节点
#3.检查本节点是否是S3/Swift管理POE主节点
function isNotNeedCheck()
{
    local multiazLSRole=$(cat /opt/huawei/snas/etc/multiaz.ini | grep "LSRole" | awk -F"=" '{print $2}'| tr -d "")
    local node_service_type=$(egrep '[[]|^'node_service_type'=' /opt/huawei/snas/etc/snas.ini | tr -d '\n' | grep -Po '(?<=[[]'NODE'[]]'node_service_type'=)[0-9]+')
    if [ "X$node_service_type" == "X2" -o "X$node_service_type" == "X3" ];then
        source /opt/obs/scripts/common/s3_config_utility.sh >> /dev/null 2>&1
        is_s3_management_node > /dev/null
        if [ $? -eq 1 ];then
            localNID=$(grep -w NID ${CM_INI_PATH}|awk -F"=" '{print $2}')

            hainfo=$(grep -w "node id(${localNID})" /proc/monc_hamap)
            if [ "$hainfo" = "" ];then
                return 1
            else
                role=${hainfo##*role(}
                role=${role%%)status*}
                if [ "$role" = "1" ];then
                    #不运行集群
                    if [ "$multiazLSRole" = "0" ]; then
                        return 0;
                    fi
                    return 1
                elif [ "$role" = "2" ];then
                    return 0;
                else
                    #非管理节点
                    return 0
                fi
            fi
        fi
    fi
}

#检查S3 DNS服务
function checkS3DNSService()
{
    #isPass为0才通过检查
    local isPass=0

    #obs.conf配置项root_domain项要存在
    local dnsDomain_nsd=$(cat /etc/nsd/obs.conf|grep root_domain |awk -F"=" '{print $2}' | sed 's/\ //g')
    if [ "X$dnsDomain_nsd" == "X" ];then
        isPass=1
        echo "Check result:failed" >> ${RESULTFILE} 2>&1
        echo "${CurInspectFun}_Pass ${isPass}" >>${RESULTFILE} 2>&1
        return
    fi

    #obs_sod.properties中obs_api_root_domain_name项要存在
    local dnsDomain_obsconf=$(cat /opt/obs/obsconf/obs_sod.properties|grep obs_api_root_domain_name |awk -F"=" '{print $2}' | sed 's/\ //g')
    if [ "X$dnsDomain_obsconf" == "X" ];then
        isPass=1
        echo "Check result:failed" >> ${RESULTFILE} 2>&1
        echo "${CurInspectFun}_Pass ${isPass}" >>${RESULTFILE} 2>&1
        return
    fi

    #以上两个domain要相等
    if [ "$dnsDomain_nsd" != "$dnsDomain_obsconf" ];then
        isPass=1
        echo "Check result:failed" >> ${RESULTFILE} 2>&1
        echo "${CurInspectFun}_Pass ${isPass}" >>${RESULTFILE} 2>&1
        return
    fi


    #获取前端ip
    source /opt/obs/scripts/mdc/getLocalFrontIp.sh
    localFrontIpString=$(getLocalHaFrontIp)
    if [ "X$localFrontIpString" == "X" ];then
        isPass=1
        echo "Check result:failed" >> ${RESULTFILE} 2>&1
        echo "${CurInspectFun}_Pass ${isPass}" >>${RESULTFILE} 2>&1
        return
    fi
    local multiaz=$(cat /opt/huawei/snas/etc/multiaz.ini | grep "Enable" | awk -F"=" '{print $2}')
    local isDefault=$(grep "DefaultRegion" /opt/huawei/snas/etc/multiaz.ini | awk '{print $1}' | awk -F"=" '{print $2}' | sed 's/,/ /g' | sed 's/\r//g')
    local regionCname=$(queryLocalRegionCname)
    if [ "X${regionCname}" == "X" ]; then
        isPass=1
        echo "Check result:failed" >> ${RESULTFILE} 2>&1
        echo "${CurInspectFun}_Pass ${isPass}" >>${RESULTFILE} 2>&1
        LOG "[$LINENO]INFO: get regionCname failed."
        return
    fi
    local cgCname=$(queryLocalCgCname)
    if [ "X${cgCname}" == "X" ]; then
        isPass=1
        echo "Check result:failed" >> ${RESULTFILE} 2>&1
        echo "${CurInspectFun}_Pass ${isPass}" >>${RESULTFILE} 2>&1
        LOG "[$LINENO]INFO: get cgCname failed."
        return
    fi
    local clusterCanme=$(queryLocalCluster)
    if [ "X${clusterCanme}" == "X" ]; then
        isPass=1
        echo "Check result:failed" >> ${RESULTFILE} 2>&1
        echo "${CurInspectFun}_Pass ${isPass}" >>${RESULTFILE} 2>&1
        LOG "[$LINENO]INFO: get clusterCanme failed."
        return
    fi
    local cnamelist=($clusterCanme $cgCname)
    set_ifs
    localFrontIpList=($localFrontIpString)
    restore_ifs
    for localFrontIp in ${localFrontIpList[*]}
    do
        local cnt=0
        if [ $multiaz -eq 1 ];then
            #多集群,应该匹配域名,否则不通过
            #默认region，需要dig两次
            #第一次dig @本地前端业务iP 全局域名 匹配区域域名，
            #第二次dig @本地前端业务iP 本区域的域名 匹配出集群所在的cg的域名或集群域名
            if [ $isDefault -eq 1 ]; then
                LOG "[$LINENO]INFO: dig frist time start."
                local countFri=$(dig @"$localFrontIp" $dnsDomain_nsd 2>/dev/null |tee -a $LOGFILE|grep -A 2 "ANSWER SECTION"| grep $regionCname -c)
                if [ "X${countFri}" == "X0" ];then
                    isPass=1
                    echo "Check result:failed" >> ${RESULTFILE} 2>&1
                    echo "${CurInspectFun}_Pass ${isPass}" >>${RESULTFILE} 2>&1
                    return
                fi
                LOG "[$LINENO]INFO: dig frist time end."
                LOG "[$LINENO]INFO: dig second time start."
                digResult=$(dig @"$localFrontIp" $regionCname 2>/dev/null |tee -a $LOGFILE |grep -A 2 "ANSWER SECTION")
                if [ $? -ne 0 ]; then
                    isPass=1
                    echo "Check result:failed" >> ${RESULTFILE} 2>&1
                    echo "${CurInspectFun}_Pass ${isPass}" >>${RESULTFILE} 2>&1
                    LOG "[$LINENO]INFO: dig second time failed."
                    return
                fi
                for cameItem in ${cnamelist[*]}
                do
                    countSen=$(echo $digResult | grep $cameItem -c)
                    if [ "X$countSen" == "X0" ];then
                        cnt=$((cnt+1))
                        if [ $cnt -eq ${#cnamelist[*]} ]; then
                            isPass=1
                            echo "Check result:failed" >> ${RESULTFILE} 2>&1
                            echo "${CurInspectFun}_Pass ${isPass}" >>${RESULTFILE} 2>&1
                            return
                        fi
                            continue
                    else
               break
                    fi
                done
                LOG "[$LINENO]INFO: dig second time end."
            else
                #非默认region，只需dig一次
                #dig @本地前端业务iP  区域域名  匹配本集群匹配出集群所在的cg的域名
                digRes=$(dig @"$localFrontIp" $regionCname 2>/dev/null | tee -a $LOGFILE | grep -A 2 "ANSWER SECTION")
                if [ $? -ne 0 ]; then
                    isPass=1
                    echo "Check result:failed" >> ${RESULTFILE} 2>&1
                    echo "${CurInspectFun}_Pass ${isPass}" >>${RESULTFILE} 2>&1
                    LOG "[$LINENO]INFO: dig Not default region failed."
                    return
                fi
                for cameItem in ${cnamelist[*]}
                do
                    count=$(echo $digRes | grep $cameItem -c)
                    if [ "X$count" == "X0" ];then
                        cnt=$((cnt+1))
                        if [ $cnt -eq ${#cnamelist[*]} ]; then
                            isPass=1
                            echo "Check result:failed" >> ${RESULTFILE} 2>&1
                            echo "${CurInspectFun}_Pass ${isPass}" >>${RESULTFILE} 2>&1
                            return
                        fi
                            continue
                    else
                        break
                    fi
                done
            fi
        else
            #单集群,应该匹配ip地址(这里不用严格检查,只检查了ipv4),否则不通过
            dig @"$localFrontIp" $dnsDomain_obsconf 2>/dev/null |grep -A 2 "ANSWER SECTION"| egrep -q '([0-9]+.){3}[0-9]+'
            if [ $? -eq 1 ];then
               isPass=1
               break
            fi
        fi
    done
    if [ 1 -eq ${isPass} ]; then
        echo "Check result:failed" >> ${RESULTFILE} 2>&1
    else
        echo "Check result:succeeded" >> ${RESULTFILE} 2>&1
    fi
    echo "${CurInspectFun}_Pass ${isPass}" >>${RESULTFILE} 2>&1
}

function set_ifs
{
    IFS_OLD=$IFS
    IFS=$';'
}

function restore_ifs
{
    IFS=$IFS_OLD
}
#如果不需要检查，则直接退出脚本执行,输出isCheck:0
if isNotNeedCheck;then
    echo "Check result:Does not involve" >> ${RESULTFILE} 2>&1
    echo "${CurInspectFun}_Pass ${CHECK_PASSED}" >>${RESULTFILE} 2>&1
    LOG "[$LINENO]not need check, pass."
    exit 0;
fi

#SFS没有这个脚本，所以放到检查后执行
mdcdbUserPwdStr=$(/opt/obs/scripts/common/commonfunction.sh getMdcdbUserPwdStr)

#开始检查

checkS3DNSService
