#!/bin/bash
# 功能实现：判定一个IP或者组是否是天翼平台的
# 依赖文件：ip.group/lakes
# 存在问题：
# 整体逻辑：
# 1. 输入有四种可能：IPv4/IPv6/英文标签/中文标签
# 2. 以上四种可能，最终使用一个函数来完成——ipvx_check
# 3. ipvx_check的作用就是检查一个IP是否属于天翼
# 4. 首先根据IP找出所在的节点英文标签，再根据英文标签后缀不同，进行逐一判别
# 5. ip.group文件：
#  对于缓存服务器（边缘/父层/中心）节点 - 第一列是RIP，第二列是英文标签，第三列是VIP，第八列是LVS（全都一样）
#  对于LVS节点 - 第一列是IP。第二列是英文标签
#  对于其他节点，同LVS
# 6. lakes文件：文件开头有介绍每一列的含义
# 7. 英文标签的特点可以通过`cat ip.group | awk '{print $2}' | awk -F '_' '{print $4}' | sort | uniq`来筛选

# 自定义颜色显示
c_br="\e[1;31m"  # bold red
c_bg="\e[1;32m"  # bold green
c_by="\e[1;33m"  # bold yellow
c_bp="\e[1;35m"  # bold purple
c_iy="\e[3;33m"  # italic yellow
c_bir='\e[1;3;31m'  # * bold italic red
c_big='\e[1;3;32m'  # bold italic cyan
c_bib='\e[1;3;34m'  # * bold italic cyan
c_bip='\e[1;3;35m'  # bold italic cyan
c_bic='\e[1;3;36m'  # bold italic cyan
c_e="\e[0m"      # reset

# 使用说明
function usage {
    echo -e "${c_bg}1. 查找V(R)IP/集群中文名/集群英文名是否是归属天翼云平台${c_e}"
    echo -e "${c_bg}2. 查询IP对应的内网IP和主机名，只支持IPv4地址${c_e}"
    echo -e "${c_iy}实例：${c_e}"
    echo -e "${c_iy}    ips 59.56.177.149${c_e}"
    echo -e "${c_iy}    ips ct_fj_fuzhou3_e1${c_e}"
    echo -e "${c_iy}    ips 福州3${c_e}"
    echo -e "${c_iy}    ips -m 59.56.177.149${c_e}\n"
    echo -e "${c_bp}查询内网IP对应关系功能，因线上IPv6的机器没有加白，暂不支持获取IPv6主机内网IP...${c_e}"
    exit 1
}

# 如果输入是IP，则判断该IP是否属于天翼
# 入参-1：IP
# 入参-2：flg -- 0/1/2
# flg = 0 -- 脚本输入的是IPv4或者IPv6
# flg = 1 -- 脚本输入的是英文节点名
# flg = 2 -- 脚本输入的是中文节点名
function ipvx_check() {
    ipvx=$1
    if [[ $flg -eq 0 ]]; then
        # 同一个IP可能会过滤出来多个英文节点
        labels=`cat $data/ip.group | fgrep -w $ipvx | awk '{print $2}' | sort | uniq`
    elif [[ $flg -eq 1 ]]; then
        # 确保过滤出来的就是输入的节点名，排除其他含有相同IP的节点
        labels=`cat $data/ip.group | fgrep -w $ipvx | awk '$2=="'$tbd'" {print $2}' | sort | uniq`
    elif [[ $flg -eq 2 ]]; then
        # 中文节点名可能对应多个不同节点，全部输出
        labels=`cat $data/ip.group | fgrep -w $ipvx | awk '$2=="'$label_single'" {print $2}' | sort | uniq`
    fi
    [[ $labels == '' ]] && { echo -e "${c_br}$tbd 不是天翼平台的节点/IP，退出...${c_e}"; exit 44; }
    for label in $labels; do
        # 根据后缀输出
        # 后缀如果是 -- e/c/n/lvs，则输出对应的资源池，vip，rip，lvs信息，如果一个lvs对应多个边缘节点，则全部输出
        # 其他后缀则只输出对应节点的信息
        postfix=`echo $label | awk -F'_' '{print $4}'`
        if [[ $postfix =~ ^c[0-9]{0,2}$ ]]; then
            center_name_en=$label
            rip=`cat $data/ip.group | awk '$2=="'$center_name_en'"' | awk '{print $1}' | sort`
            vip=`cat $data/ip.group | awk '$2=="'$center_name_en'"' | awk '{print $3}' | sort | uniq`
            lvs_name=`cat $data/ip.group | awk '$2=="'$center_name_en'"' | awk '{print $8}' | sort | uniq | awk -F ',' '{print $1}'`
            lvs=`cat $data/ip.group | awk '$2=="'$lvs_name'"' | awk '{print $1}' | sort`
            resource=`cat $data/lakes | grep $center_name_en | awk '{print $6}' | sort | uniq`
            center_name_cn=`cat $data/lakes | grep $center_name_en | awk '{print $11}' | sort | uniq`

            echo -e "$c_bp[$center_name_en: ${c_bg}RIP]$c_e"
            echo $rip | awk '{for(i=1;i<=NF;i++) if($i=="'$ipvx'"&&"'$flg'"==0) print "   \033[1;3;36m", $i, "\033[0m"; else print "   ", $i}'
            echo

            echo -e "$c_bp[$center_name_en: ${c_bg}VIP]$c_e"
            echo $vip | awk -F ',' '{for(i=1;i<=NF;i++) if($i=="'$ipvx'" && "'$flg'"==0) print "   \033[1;3;36m", $i, "\033[0m"; else print "   ", $i}'

            echo -e "$c_bp[$lvs_name: ${c_bg}IP]$c_e"
            echo $lvs | awk '{for(i=1;i<=NF;i++) print "   ", $i}'
            echo

            echo -e "$c_by[$center_name_cn($center_name_en)所属资源池]$c_e"
            echo $resource | awk '{for(i=1;i<=NF;i++) print "   ", $i} END{print ""}'

        elif [[ $postfix =~ ^dns[0-9]{0,2}$ ]]; then
            dns_label=$label
            dnsip=`cat $data/ip.group | awk '$2=="'$dns_label'"' | awk '{print $1}' | sort`
            dnsrip=`cat $data/ip.group | awk '$2=="'$dns_label'"' | awk '{print $1}' | sort`
            dnsvip=`cat $data/ip.group | awk '$2=="'$dns_label'"' | awk '{print $3}' | sort | uniq`

            echo -e "$c_bp[$dns_label: ${c_bg}RIP]$c_e"
            echo $dnsip | awk '{for(i=1;i<=NF;i++) if($i=="'$ipvx'" && "'$flg'"==0) print "   \033[1;3;36m", $i, "\033[0m"; else print "   ", $i}'

            echo -e "$c_bp[$dns_label: ${c_bg}VIP]$c_e"
            echo $dnsvip | awk -F ',' '{for(i=1;i<=NF;i++) if($i=="'$ipvx'" && "'$flg'"==0) print "   \033[1;3;36m", $i, "\033[0m"; else print "   ", $i}'
        elif [[ $postfix =~ ^e[0-9]{0,2}$ ]]; then
            edge_name_en=$label
            rip=`cat $data/ip.group | awk '$2=="'$edge_name_en'"' | awk '{print $1}' | sort`
            vip=`cat $data/ip.group | awk '$2=="'$edge_name_en'"' | awk '{print $3}' | sort | uniq`
            lvs_name=`cat $data/ip.group | awk '$2=="'$edge_name_en'"' | awk '{print $8}' | sort | uniq | awk -F ',' '{print $1}'`
            lvs=`cat $data/ip.group | awk '$2=="'$lvs_name'"' | awk '{print $1}' | sort`
            resource=`cat $data/lakes | grep $edge_name_en | awk '{print $6}' | sort | uniq`
            edge_name_cn=`cat $data/lakes | grep $edge_name_en | awk '{print $11}' | sort | uniq`

            echo -e "$c_bp[$edge_name_en: ${c_bg}RIP]$c_e"
            echo $rip | awk '{for(i=1;i<=NF;i++) if($i=="'$ipvx'" && "'$flg'"==0) print "   \033[1;3;36m", $i, "\033[0m"; else print "   ", $i}'
            echo

            echo -e "$c_bp[$edge_name_en: ${c_bg}VIP]$c_e"
            echo $vip | awk -F ',' '{for(i=1;i<=NF;i++) if($i=="'$ipvx'" && "'$flg'"==0) print "   \033[1;3;36m", $i, "\033[0m"; else print "   ", $i}'

            echo -e "$c_bp[$lvs_name: ${c_bg}IP]$c_e"
            echo $lvs | awk '{for(i=1;i<=NF;i++) print "   ", $i}'
            echo

            echo -e "$c_by[$edge_name_cn($edge_name_en)所属资源池]$c_e"
            echo $resource | awk '{for(i=1;i<=NF;i++) print "   ", $i} END{print ""}'

        elif [[ $postfix =~ ^lvs[0-9]{0,2}$ ]]; then
            lvs_name=$label
            lvs=`cat $data/ip.group | awk '$2=="'$lvs_name'"' | awk '{print $1}' | sort`
            level_unknown=`cat $data/ip.group | awk '$8 ~ "'$lvs_name'"' | awk '{print $2}' | sort | uniq`
            for unknown_en in $level_unknown; do
                rip=`cat $data/ip.group | awk '$8 ~ "'$lvs_name'" && $2 == "'$unknown_en'"' | awk '{print $1}' | sort`
                vip=`cat $data/ip.group | awk '$8 ~ "'$lvs_name'" && $2 == "'$unknown_en'"' | awk '{print $3}' | sort | uniq`
                resource=`cat $data/lakes | grep $unknown_en | awk '{print $6}' | sort | uniq`
                unknown_cn=`cat $data/lakes | grep $unknown_en | awk '{print $11}' | sort | uniq`

                echo -e "$c_bp[$unknown_en: ${c_bg}RIP]$c_e"
                echo $rip | awk '{for(i=1;i<=NF;i++) print "   ", $i}'
                echo

                echo -e "$c_bp[$unknown_en: ${c_bg}VIP]$c_e"
                echo $vip | awk -F ',' '{for(i=1;i<=NF;i++) print "   ", $i}'

                echo -e "$c_by[$unknown_cn($unknown_en)所属资源池]$c_e"
                echo $resource | awk '{for(i=1;i<=NF;i++) print "   ", $i} END{print ""}'
            done
            echo -e "$c_bp[$lvs_name: ${c_bg}IP]$c_e"
            echo $lvs | awk '{for(i=1;i<=NF;i++) if($i=="'$ipvx'" && "'$flg'"==0) print "   \033[1;3;36m", $i, "\033[0m"; else print "   ", $i}'
            echo

        elif [[ $postfix =~ ^m[0-9]{0,2}$ ]]; then
            mgt_label=$label
            mgtip=`cat $data/ip.group | awk '$2=="'$mgt_label'"' | awk '{print $1}' | sort`

            echo -e "$c_bp[$mgt_label: ${c_bg}IP]$c_e"
            echo $mgtip | awk '{for(i=1;i<=NF;i++) if($i=="'$ipvx'" && "'$flg'"==0) print "   \033[1;3;36m", $i, "\033[0m"; else print "   ", $i}'
            echo

        elif [[ $postfix =~ ^mysql[0-9]{0,2}$ ]]; then
            mysql_label=$label
            mysqlip=`cat $data/ip.group | awk '$2=="'$mysql_label'"' | awk '{print $1}' | sort`

            echo -e "$c_bp[$mysql_label: ${c_bg}IP]$c_e"
            echo $mysqlip | awk '{for(i=1;i<=NF;i++) if($i=="'$ipvx'" && "'$flg'"==0) print "   \033[1;3;36m", $i, "\033[0m"; else print "   ", $i}'

        elif [[ $postfix =~ ^n[0-9]{0,2}$ ]]; then
            nation_name_en=$label
            rip=`cat $data/ip.group | awk '$2=="'$nation_name_en'"' | awk '{print $1}' | sort`
            vip=`cat $data/ip.group | awk '$2=="'$nation_name_en'"' | awk '{print $3}' | sort | uniq`
            lvs_name=`cat $data/ip.group | awk '$2=="'$nation_name_en'"' | awk '{print $8}' | sort | uniq | awk -F ',' '{print $1}'`
            lvs=`cat $data/ip.group | awk '$2=="'$lvs_name'"' | awk '{print $1}' | sort`
            resource=`cat $data/lakes | grep $nation_name_en | awk '{print $6}' | sort | uniq`
            nation_name_cn=`cat $data/lakes | grep $nation_name_en | awk '{print $11}' | sort | uniq`

            echo -e "$c_bp[$nation_name_en: ${c_bg}RIP]$c_e"
            echo $rip | awk '{for(i=1;i<=NF;i++) if($i=="'$ipvx'" && "'$flg'"==0) print "   \033[1;3;36m", $i, "\033[0m"; else print "   ", $i}'
            echo

            echo -e "$c_bp[$nation_name_en: ${c_bg}VIP]$c_e"
            echo $vip | awk -F ',' '{for(i=1;i<=NF;i++) if($i=="'$ipvx'" && "'$flg'"==0) print "   \033[1;3;36m", $i, "\033[0m"; else print "   ", $i}'

            echo -e "$c_bp[$lvs_name: ${c_bg}IP]$c_e"
            echo $lvs | awk '{for(i=1;i<=NF;i++) print "   ", $i}'
            echo

            echo -e "$c_by[$nation_name_cn($nation_name_en)所属资源池]$c_e"
            echo $resource | awk '{for(i=1;i<=NF;i++) print "   ", $i} END{print ""}'

        elif [[ $postfix =~ ^prets[0-9]{0,2}$ ]]; then
            prets_label=$label
            pretsip=`cat $data/ip.group | awk '$2=="'$prets_label'"' | awk '{print $1}' | sort`

            echo -e "$c_bp[$prets_label: ${c_bg}IP]$c_e"
            echo $pretsip | awk '{for(i=1;i<=NF;i++) if($i=="'$ipvx'" && "'$flg'"==0) print "   \033[1;3;36m", $i, "\033[0m"; else print "   ", $i}'

        elif [[ $postfix =~ ^pretw[0-9]{0,2}$ ]]; then
            pretw_label=$label
            pretwip=`cat $data/ip.group | awk '$2=="'$pretw_label'"' | awk '{print $1}' | sort`

            echo -e "$c_bp[$pretw_label: ${c_bg}IP]$c_e"
            echo $pretwip | awk '{for(i=1;i<=NF;i++) if($i=="'$ipvx'" && "'$flg'"==0) print "   \033[1;3;36m", $i, "\033[0m"; else print "   ", $i}'

        elif [[ $postfix =~ ^redis[0-9]{0,2}$ ]]; then
            redis_label=$label
            redisip=`cat $data/ip.group | awk '$2=="'$redis_label'"' | awk '{print $1}' | sort`

            echo -e "$c_bp[$redis_label: ${c_bg}IP]$c_e"
            echo $redisip | awk '{for(i=1;i<=NF;i++) if($i=="'$ipvx'" && "'$flg'"==0) print "   \033[1;3;36m", $i, "\033[0m"; else print "   ", $i}'

        elif [[ $postfix =~ ^testts[0-9]{0,2}$ ]]; then
            testts_label=$label
            testtsip=`cat $data/ip.group | awk '$2=="'$testts_label'"' | awk '{print $1}' | sort`

            echo -e "$c_bp[$testts_label: ${c_bg}IP]$c_e"
            echo $testtsip | awk '{for(i=1;i<=NF;i++) if($i=="'$ipvx'" && "'$flg'"==0) print "   \033[1;3;36m", $i, "\033[0m"; else print "   ", $i}'

        elif [[ $postfix =~ ^ts[0-9]{0,2}$ ]]; then
            ts_label=$label
            tsip=`cat $data/ip.group | awk '$2=="'$ts_label'"' | awk '{print $1}' | sort`

            echo -e "$c_bp[$ts_label: ${c_bg}IP]$c_e"
            echo $tsip | awk '{for(i=1;i<=NF;i++) if($i=="'$ipvx'" && "'$flg'"==0) print "   \033[1;3;36m", $i, "\033[0m"; else print "   ", $i}'

        elif [[ $postfix =~ ^tw[0-9]{0,2}$ ]]; then
            tw_label=$label
            twip=`cat $data/ip.group | awk '$2=="'$tw_label'"' | awk '{print $1}' | sort`

            echo -e "$c_bp[$tw_label: ${c_bg}IP]$c_e"
            echo $twip | awk '{for(i=1;i<=NF;i++) if($i=="'$ipvx'" && "'$flg'"==0) print "   \033[1;3;36m", $i, "\033[0m"; else print "   ", $i}'

        elif [[ $postfix =~ ^uatts[0-9]{0,2}$ ]]; then
            uatts_label=$label
            uattsip=`cat $data/ip.group | awk '$2=="'$uatts_label'"' | awk '{print $1}' | sort`

            echo -e "$c_bp[$uatts_label: ${c_bg}IP]$c_e"
            echo $uattsip | awk '{for(i=1;i<=NF;i++) if($i=="'$ipvx'" && "'$flg'"==0) print "   \033[1;3;36m", $i, "\033[0m"; else print "   ", $i}'

        else
            echo -e "${c_br}${ipvx}${c_e}不属于我司节点，如有误判，请联系fanmf11@chinatelecom.cn。\n"
            exit 92
        fi
    done
}

function ip_search() {
    # 判断如果是IPv4，在判断是否合法
    if [[ $tbd =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
        ip_1234=`echo $tbd | awk -F '.' '{print $1, $2, $3, $4}'`
        for num in $ip_1234; do
            if [[ $num -gt 255 ]]; then
                echo -e "${c_br}非法，请输入有效的IPv4地址。${c_e}"
                usage
            fi
        done

        isInner=`echo $ip_1234 | awk '{print $1}'`
        if [[ $isInner == '192' ]]; then
            echo -e "${c_br}$tbd是内网IP，非法，请输入有效的外网IPv4地址。${c_e}"
            usage
        fi
        flg=0
        ipvx_check $tbd $flg

    # 判断如果是IPv6（粗略的匹配规则，最短11，最长39，包含数字大小写字母以及英文冒号）
    elif [[ $tbd =~ ^[0-9a-fA-F:]{11,39}$ ]]; then
        flg=0
        ipvx_check $tbd $flg
    # 判断如果是节点英文标签格式
    elif [[ $tbd =~ ^(ct|cu|cm|bgp|ctbgp|cmbgp|cubgp|as|eu|sa|na|cbn|cern)_[a-z]{2,3}_[a-z]{2,20}[0-9]{1,2}_(c|dns|e|lvs|m|mysql|n|prets|pretw|redis|testts|ts|tw|uatts1)[0-9]{0,2}$ ]]; then
        anyip=`cat $data/ip.group | awk '$2=="'$tbd'"' | head -n 1 | awk '{print $1}'`
        if [[ $anyip == '' ]]; then
            echo -e "${c_br}${tbd}${c_e}不属于我司节点，如有误判，请联系fanmf11@chinatelecom.cn。"
            usage
            exit 90
        fi
        flg=1
        ipvx_check $anyip $flg

    # 剩余的情况一律归结为中文标签格式
    else
        # 一个中文标签可能会对应着多个不同的节点
        label_multi=`cat $data/lakes | awk '$11=="'$tbd'" {print $1}' | sort | uniq`
        if [[ $label_multi == '' ]]; then
            echo -e "${c_br}${tbd}${c_e}不属于我司节点，如有误判，请联系fanmf11@chinatelecom.cn。"
            usage
            exit 91
        fi
        flg=2
        for label_single in $label_multi; do
            anyip=`cat $data/ip.group | awk '$2=="'$label_single'"' | head -n 1 | awk '{print $1}'`
            if [[ $anyip != '' ]]; then
                ipvx_check $anyip $flg
            else
                echo -e "${c_br}${label_single}节点存在，但是无法找到其下IP，可使用rip命令尝试再次查询。${c_e}\n"
            fi
        done
    fi
}

function ip_inner() {
    > res.log
    let number=`cat ips.log | tr -d ' ' | grep -Ev ']' | sed 's/^$/#/g' | awk 'BEGIN{RS="#"} {print NR}' | tail -1`
    cat ips.log | tr -d ' ' | grep -Ev ']' | sed 's/^$/#/g' | awk 'BEGIN{RS="#"} {for(i=1;i<=NR;i++) if(i==NR) print $0 > i}'
    for i in `seq $number`; do
        cat $i | fgrep -q "$tbd"
        [[ $? -ne 0 ]] && continue
        cat $i | grep -Eo "[0-9a-fA-F:]{11,39}" > ip$i
        cat $i | grep -Eo "([0-9]{1,3}\.){3}[0-9]{1,3}" >> ip$i
        # 将每一块的IP重新放回文件i，并将结果追加到res.log
        cat ip$i > $i && cat ip$i >> res.log
    done
    ip_list=`cat res.log | sort | uniq`
    for ipy in $ip_list; do
        echo $ipy | grep -Eq "[0-9a-fA-F:]{11,39}"
        if [[ $? -eq 0 ]]; then
            echo "跳板机无IPv6出口，暂不支持获取IPv6主机内网IP..." > inner_$ipy.log
        else
            ssh -o ConnectTimeout=30 $ipy "hostname; /usr/sbin/ifconfig | grep 'inet 192'" > inner_$ipy.log 2>&1 &
        fi
    done
    wait

    echo '-----------------------------------------------------------------------------------------'
    printf "${c_bic}%-25s%-20s%-50s\n${c_e}" "IP" "Inner IP" "Hostname"
    for ipy in $ip_list; do
        cat inner_$ipy.log |grep -iq 'timed out'
        res1=$?
        cat inner_$ipy.log |grep -iq 'closed by'
        res2=$?
        cat inner_$ipy.log |grep -iq 'IPv6'
        res3=$?
        if [[ $res1 -eq 0 ]]; then
            printf "${c_bir}%-25s%-20s%-40s${c_e}\n" $ipy "===========>" "Connection timed out during banner exchange"
            continue
        elif [[ $res2 -eq 0 ]]; then
            printf "${c_bir}%-25s%-20s%-40s${c_e}\n" $ipy "===========>" "ssh_exchange_identification: Connection closed by remote host"
            continue
        elif [[ $res3 -eq 0 ]]; then
            printf "${c_bir}%-25s%-20s%-40s${c_e}\n" $ipy "===========>" "IPv6的机器没有加白，暂不支持获取IPv6主机内网IP..."
            continue
        else
            host=`cat inner_$ipy.log | fgrep 'in.ctcdn.cn'`
            [[ $host == '' ]] && host='-'
            inner_ip=`cat inner_$ipy.log | grep 'inet 192' | awk '{print $2}'`
            [[ $inner_ip == '' ]] && inner_ip='-'
            printf "%-25s%-20s%-40s\n" $ipy $inner_ip $host
        fi
    done
    printf "${c_bic}%-25s%-20s%-50s\n${c_e}" "IP" "Inner IP" "Hostname"
    echo '-----------------------------------------------------------------------------------------'
}

toolbox='/usr/local/script/fanmf11/'
data='/usr/local/script/fanmf11/data'
label_single=''
TS=`date +%s%N`
host=`whoami`                                        # * 判断执行用户
trash="/usr/local/script/fanmf11/trash/$host/$TS"    # * 每个用户的临时文件存放处

if [[ -d $trash ]]; then
    echo -e "${c_br}对于同一个用户，同一时间只能运行一个实例，请重新运行...${c_e}"
    exit 245
else
    mkdir -p $trash
    cd $trash && cd ..
    docs=`ls`
    for doc in $docs; do
        [[ -f $doc ]] && rm -rf $doc
    done
    folders=`ls -t`
    while [[ `echo $folders | awk '{print NF}'` -gt 29 ]]; do
        folder=`ls -t | tail -1`
        rm -rf $folder
        folders=`ls -t`
    done
    cd $trash && touch ips
fi

# 参数个数必须是一个，并把第一个参数赋值给tbd
if [[ $# -eq 1 ]]; then
    tbd=$1
    ip_search
elif [[ $# -eq 2 && $1 == '-m' ]]; then
    tbd=$2
    ip_search > ips.log 2>&1
    [[ $? -ne 0 ]] && { cat ips.log; exit 211; }
    # 判断如果是IPv4，在判断是否合法
    if [[ $tbd =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
        ip_inner
    else
        echo -e "${c_br}输入只能是IPv4，不接受其他格式的内容。${c_e}\n"
        exit 112
    fi
else
    usage
fi



