#!/bin/bash # 功能实现:根据指定的域名,查询对于应域名所在解析组的相关信息 # 依赖文件:dna/ # 存在问题: # # 自定义控制台颜色显示 c_br='\e[1;31m' # bold red c_bg='\e[1;32m' # bold green c_bc='\e[1;36m' # bold cyan c_by='\e[1;33m' # bold yellow c_bp='\e[1;35m' # bold purple c_bir='\e[1;3;31m' # bold italic red c_big='\e[1;3;32m' # bold italic green c_biy='\e[1;3;33m' # bold italic yellow c_bib='\e[1;3;34m' # bold italic blue c_bip='\e[1;3;35m' # bold italic purple c_bic='\e[1;3;36m' # bold italic cyan c_biw='\e[1;3;30m' # bold italic gray c_e='\e[0m' # reset # 使用说明 function usage { echo -e "${c_bib}Usage: ${c_e}" echo -e "${c_bib} map -d domain vip # 从域名解析组中随机获取一个VIP ${c_e}" echo -e "${c_bib} map -d domain rip # 从域名解析组中随机获取一个RIP ${c_e}" echo -e "${c_bib} map -d domain ip # 验证一个IP是否属于域名解析组中的VIP或者RIP ${c_e}" echo -e "${c_bib} map -d domain label # 验证一个节点中/英文标签名是否包含在域名解析组中 ${c_e}" echo -e "${c_bib} map -d domain label # 打印域名解析组中所有的节点信息 ${c_e}" echo -e "${c_bib} map -d domain cover # 输出域名边缘解析组节点资源覆盖情况,可指定区域查询 ${c_e}" echo -e "${c_bib} map -d domain parent # 输出域名父解析组节点资源覆盖情况,可指定区域查询 ${c_e}\n" echo -e "${c_bic}[MAP-100] 该脚本工具会根据指定的域名,查询对于应域名所在解析组的相关信息,其中vip/rip/pool/cover/parent均是字符串参数,domain/ip是实际要输入真实值的参数,label既可以是字符串参数,也可以是实际节点中/英文标签名称。${c_e}\n" exit 100 } function onCtrlC () { # while capture Ctrl+C, kill all background processes silently and exit exec 3>&2 # 3 is now a copy of 2 exec 2> /dev/null # 2 now points to /dev/null sleep 1 # sleep to wait for process to die exec 2>&3 # restore stderr to saved exec 3>&- # close saved version echo echo -e "${c_bir}[MAP-101] Ctrl+C is captured, exiting...\n${c_e}" exit 101 } # 随机获取域名对应解析组的一个VIP function random_vip() { # 其实支持的不仅如下,只要输入正确,其他网络运营商也是可以查询的 echo -ne "${c_bg}请输入ISP类型--【ct|cu|cm|bgp|ctbgp|cubgp|cmbgp】:${c_e}" read -t 60 isp [[ $? -ne 0 ]] && { echo -e "${c_br}[MAP-102] 60s内无任何输入,退出...${c_e}\n"; exit 102; } # do a check to see if isp is correct or not [[ $isp == '' ]] && isp='ct' # 从解析组VIP列过滤以运营商标识开头的节点和VIP ip_list=`cat map.log | awk '{print $4, $5}' | grep "^${isp}_" | awk '{print $2}' | sort | uniq` [[ $ip_list == '' ]] && { echo -e "${c_br}[MAP-103] 在解析组$map中,没有找到$isp的网络运营商,退出...${c_e}"; exit 103; } # 匹配v6和v4的子集 v6_list=`echo $ip_list | grep -Eo "[0-9a-fA-F:]{11,39}"` v4_list=`echo $ip_list | grep -Eo "([0-9]{1,3}\.){3}[0-9]{1,3}"` # 计算分别有多少个 num_v6=`echo $v6_list | awk '{print NF}'` num_v4=`echo $v4_list | awk '{print NF}'` # 获取随机的IP,注意用$RANDOM取模之后,结果有可能是0,最大值不超过总数,所以需要 +1 [[ num_v6 -ne 0 ]] && rand6=$(( $RANDOM % $num_v6 )) && vip_v6=`echo $v6_list | awk -v v6=$rand6 '{print $(v6+1)}'` [[ num_v4 -ne 0 ]] && rand4=$(( $RANDOM % $num_v4 )) && vip_v4=`echo $v4_list | awk -v v4=$rand4 '{print $(v4+1)}'` echo "vip_v6: $vip_v6" echo "vip_v4: $vip_v4" echo -e "${c_bip}MAP: $map\n${c_e}" } # 随机获取域名对应解析组的一个RIP function random_rip() { # 其实支持的不仅如下,只要输入正确,其他网络运营商也是可以查询的 echo -ne "${c_bg}请输入ISP类型--【ct|cu|cm|bgp|ctbgp|cubgp|cmbgp】:${c_e}" read -t 60 isp [[ $? -ne 0 ]] && { echo -e "${c_br}[MAP-104] 60s内无任何输入,退出...${c_e}\n"; exit 104; } # do a check to see if isp is correct or not [[ $isp == '' ]] && isp='ct' # 从解析组VIP列过滤以运营商标识开头的节点和VIP ip_list=`cat map.log | awk '{print $4, $5}' | grep "^${isp}_" | awk '{print $2}' | sort | uniq` [[ $ip_list == '' ]] && { echo -e "${c_br}[MAP-106] 在解析组$map中,没有找到$isp的网络运营商,退出...${c_e}"; exit 105; } # 匹配v6和v4的子集 v6_list=`echo $ip_list | grep -Eo "[0-9a-fA-F:]{11,39}"` v4_list=`echo $ip_list | grep -Eo "([0-9]{1,3}\.){3}[0-9]{1,3}"` # 计算分别有多少个 num_v6=`echo $v6_list | awk '{print NF}'` num_v4=`echo $v4_list | awk '{print NF}'` # 获取随机的IP,注意用$RANDOM取模之后,结果有可能是0,最大值不超过总数,所以需要 +1 [[ num_v6 -ne 0 ]] && rand6=$(( $RANDOM % $num_v6 )) && vip_v6=`echo $v6_list | awk -v v6=$rand6 '{print $(v6+1)}'` [[ num_v4 -ne 0 ]] && rand4=$(( $RANDOM % $num_v4 )) && vip_v4=`echo $v4_list | awk -v v4=$rand4 '{print $(v4+1)}'` # 拿到VPI之后,使用`ips`获取RIP列表 [[ num_v6 -ne 0 ]] && v6_list=`ips $vip_v6 | sed -n '/RIP/, /VIP/ p' | grep -Eo '([0-9]{1,3}.){3}[0-9]{1,3}'` [[ num_v4 -ne 0 ]] && v4_list=`ips $vip_v4 | sed -n '/RIP/, /VIP/ p' | grep -Eo '([0-9]{1,3}.){3}[0-9]{1,3}'` # 计算分别有多少个 num_v6=`echo $v6_list | awk '{print NF}'` num_v4=`echo $v4_list | awk '{print NF}'` # 获取随机的IP,注意用$RANDOM取模之后,结果有可能是0,最大值不超过总数,所以需要 +1 [[ num_v6 -ne 0 ]] && rand6=$(( $RANDOM % $num_v6 )) && rip_v6=`echo $v6_list | awk -v v6=$rand6 '{print $(v6+1)}'` [[ num_v4 -ne 0 ]] && rand4=$(( $RANDOM % $num_v4 )) && rip_v4=`echo $v4_list | awk -v v4=$rand4 '{print $(v4+1)}'` echo "rip_v6: $rip_v6" echo "rip_v4: $rip_v4" echo -e "${c_bip}MAP: $map\n${c_e}" } # 判断一个IP是否归属域名的解析组,可以是VIP,也可以是RIP function ip_inmap() { # 使用`ips`判断IP是否在天翼平台 ips $item > ips.log 2>&1 [[ $? -ne 0 ]] && { cat ips.log; echo -e "${c_br}[MAP-106]${c_e}"; exit 106; } # 判断IP是否是RIP cat $data/ip.group | awk '{print $1}' | grep -wq $item is_rip=$? # 如果是RIP if [[ $is_rip -eq 0 ]]; then # 获取对应RIP的英文节点标签名,并判断该节点是否在域名的解析组中 label=`cat ips.log | grep -Eo "(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|e|m|n)[0-9]{0,2}" | head -n 1` cat map.log | awk '{print $4}' | sort | uniq | grep -wq $label if [[ $? -eq 0 ]]; then echo -e "${c_big}$item是域名$domain对应解析组$map中的IP,并且是一个RIP。\n${c_e}" else echo -e "${c_bir}[MAP-107] $item${c_biy}不是${c_bir}域名$domain对应解析组中的IP。\n${c_e}" exit 107 fi # 如果不是RIP,那就是VIP else # 直接判断该IP是否在域名的解析组 cat map.log | awk '{print $5}' | sort | uniq | grep -wq $item if [[ $? -eq 0 ]]; then echo -e "${c_big}$item是域名$domain对应解析组$map中的IP,并且是一个VIP。\n${c_e}" else echo -e "${c_bir}[MAP-108] $item${c_biy}不是${c_bir}域名$domain对应解析组中的IP。\n${c_e}" exit 108 fi fi } # 判断一个标签是否在域名的解析组中 function label_inmap() { # 输出改解析组所有的节点中英文对应标签信息 cat map.log | awk '{print $14, $4}' | sed '1d' | sort | uniq | awk '{if(NR%3==0) print " | "$0" | "; else printf "%s", " | "$0;} END{print ""}' | column -t # 查询节点中英文标签名称是否在域名的解析组中,在的话并输出相应信息 cat map.log | awk '{print $14, $4}' | sort | uniq | grep -wq $item if [[ $? -eq 0 ]]; then node=`cat map.log | awk '{print $14, $4}' | sort | uniq | grep -w $item` echo -e "${c_big}$node${c_by} 是域名 $domain 对应解析组 $map 中的节点,如上是该解析组所有节点列表汇总,可参考。\n${c_e}" else echo -e "${c_bir}[MAP-109] $item${c_biy} 不是${c_bir}域名 $domain 对应解析组 $map 中的节点,如上是该解析组所有节点列表汇总,可参考。\n${c_e}" exit 109 fi } # 打印域名对应解析组所有节点信息 function labels_inmap() { cat map.log | awk '{print $14, $4}' | sed '1d' | sort | uniq | awk '{if(NR%3==0) print " | "$0" | "; else printf "%s", " | "$0;} END{print ""}' | column -t echo -e "${c_big}如上是域名 $domain 对应解析组 $map 所有节点列表汇总,可参考。\n${c_e}" } # 输出域名对应解析组的覆盖情况,可指定地区 function cover() { # 宽度提示 width=`tput cols` if [[ $width -lt 170 ]]; then echo -e "${c_biy}因该选项输出的每行数据比较多,需要终端宽度大于170,当前终端宽度为$width,输出的界面会不整齐,是否继续(Y/n):${c_e}" read -t 60 YON [[ $? -ne 0 ]] && { echo -e "${c_br}[MAP-110] 60s内无任何输入,退出...${c_e}\n"; exit 110; } if [[ $YON != '' && $YON != 'y' && $YON != 'Y' && $YON != 'Yes' && $YON != 'yes' && $YON != 'YES' ]]; then echo -e "${c_br}[MAP-111] 请调整终端宽度之后,重新运行,退出...${c_e}\n" exit 111 fi fi # 将需要保留的的字段过滤出来 cat map.log | sed '1d' | awk '{print $1, $2, $3, $4, $5, $14, $16, $22, $16-$22, $23, $24}' | sort -k 2 > res.map echo -e "${c_bib}1. 省份维度:31个省市自治区 + 电信|移动|联通,例如-内蒙古电信${c_e}" echo -e "${c_bib}2. 大区维度:东北|华北|华东|华南|华中|西北|西南 + 电信|移动|联通|长宽|铁通|广电,例如-东北移动${c_e}" echo -e "${c_bib}3. 全国维度:中国 + 电信|移动|联通|长宽|铁通|广电|其他/香港/澳门/台湾/教育网,例如-中国移动${c_e}" echo -e "${c_bib}4. 国际维度:日本/韩国/蒙古国/北朝鲜/澳洲/欧洲/非洲/北美洲/南美洲/中亚/西亚/南亚/东南亚/亚洲其他等${c_e}" echo -e "${c_bib}5. 其他维度:全球/其他/其他广电/其他电信/其他移动/其他联通/其他铁通/其他长宽${c_e}" echo -ne "${c_bg}请按照如上规则,输入查询条件:${c_e}\n" read -t 60 query [[ $? -ne 0 ]] && { echo -e "${c_br}[MAP-112] 60s内无任何输入,退出...${c_e}\n"; exit 112; } # 无任何输入,则默认打印所有资源 if [[ ${query} == '' ]]; then python3 /usr/local/script/fanmf11/get_infos.py --format-global res.map # python3 /home/fanmf11/fanmf11/get_infos.py --format-global res.map # 否则打印指定地区的资源覆盖情况 else cat $data/area | grep $query| awk '{print $1}' > view python3 /usr/local/script/fanmf11/get_infos.py --format-partial $query view res.map $domain $map # python3 /home/fanmf11/fanmf11/get_infos.py --format-partial $query view res.map $domain $map fi } # 输出域名对应父解析组的覆盖情况,可指定地区 function parent() { # 宽度提示 width=`tput cols` if [[ $width -lt 170 ]]; then echo -e "${c_biy}因该选项输出的每行数据比较多,需要终端宽度大于170,当前终端宽度为$width,输出的界面会不整齐,是否继续(Y/n):${c_e}" read -t 60 YON [[ $? -ne 0 ]] && { echo -e "${c_br}[MAP-113] 60s内无任何输入,退出...${c_e}\n"; exit 113; } if [[ $YON != '' && $YON != 'y' && $YON != 'Y' && $YON != 'Yes' && $YON != 'yes' && $YON != 'YES' ]]; then echo -e "${c_br}[MAP-114] 请调整终端宽度之后,重新运行,退出...${c_e}\n" exit 114 fi fi # 获取域名的父解析组 # python3 /usr/local/script/fanmf11/get_infos.py --domain_config_accid map_info.log $domain infos --parent $domain $TS cat cmap && echo -e "${c_bg}请选择要查看的父方案序号(e.g. 1, 2, 3...):${c_e}" read -t 60 index [[ $? -ne 0 ]] && { echo -e "${c_br}[MAP-115] 60s内无任何输入,退出...${c_e}\n"; exit 115; } cat cmap | grep -Eq "^$index\." [[ $? -ne 0 ]] && { echo -e "${c_br}[MAp-116] 请输入正确的序号,退出...${c_e}\n"; exit 116; } cmap=`cat cmap | grep -E "^$index\." | awk '{print $2}'` getlastcover $cmap > cmap.log 2>&1 # 将需要保留的的字段过滤出来 cat cmap.log | sed '1d' | awk '{print $1, $2, $3, $4, $5, $14, $16, $22, $16-$22, $23, $24}' | sort -k 2 > res.map echo -e "${c_bib}1. 省份维度:31个省市自治区 + 电信|移动|联通,例如-内蒙古电信${c_e}" echo -e "${c_bib}2. 大区维度:东北|华北|华东|华南|华中|西北|西南 + 电信|移动|联通|长宽|铁通|广电,例如-东北移动${c_e}" echo -e "${c_bib}3. 全国维度:中国 + 电信|移动|联通|长宽|铁通|广电|其他/香港/澳门/台湾/教育网,例如-中国移动${c_e}" echo -e "${c_bib}4. 国际维度:日本/韩国/蒙古国/北朝鲜/澳洲/欧洲/非洲/北美洲/南美洲/中亚/西亚/南亚/东南亚/亚洲其他等${c_e}" echo -e "${c_bib}5. 其他维度:全球/其他/其他广电/其他电信/其他移动/其他联通/其他铁通/其他长宽${c_e}" echo -ne "${c_bg}请按照如上规则,输入查询条件:${c_e}\n" read -t 60 query [[ $? -ne 0 ]] && { echo -e "${c_br}[MAP-117] 60s内无任何输入,退出...${c_e}\n"; exit 117; } # 无任何输入,则默认打印所有资源 if [[ ${query} == '' ]]; then python3 /usr/local/script/fanmf11/get_infos.py --format-global res.map # python3 /home/fanmf11/fanmf11/get_infos.py --format-global res.map # 否则打印指定地区的资源覆盖情况 else cat $data/area | grep $query| awk '{print $1}' > view python3 /usr/local/script/fanmf11/get_infos.py --format-partial $query view res.map $domain $map # python3 /home/fanmf11/fanmf11/get_infos.py --format-partial $query view res.map $domain $map fi } function logfile() { if [[ -d $trash ]]; then echo -e "${c_br}[MAP-118]对于同一个用户,同一时间只能运行一个实例,请重新运行...${c_e}" exit 118 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 map fi } # -------------------------------------------------------------------------------- # set a trap for Ctrl+C trap 'onCtrlC' INT # -------------------------------------------------------------------------------- # 初始化设定 stty erase '^H' # allow backspace data='/usr/local/script/fanmf11/data' # set data directory path toolbox='/usr/local/script/fanmf11/' # set toobbox directory path map='' accid='' TS=`date +%s%N` # document the start time of the script host=`whoami` # who use this script trash="/usr/local/script/fanmf11/trash/$host/$TS" # set trash directory path # -------------------------------------------------------------------------------- # 入参正确性检测 let NumOP=$# # number of parameter OP="prefix "$@ # do a prefix cause '-' char may damage echo command dash_d=`echo $OP | awk '{print $2}'` # get first param -d domain=`echo $OP | awk '{print $3}'` # get second param domain item=`echo $OP | awk '{print $4}'` # get third param item, can be vip, rip, testip, pool, cover etc. [[ $NumOP -ne 3 || $dash_d != '-d' ]] && usage || logfile # -------------------------------------------------------------------------------- # 检查域名是否在平台注册 res=`cat $data/domain.list | grep -w "$domain"` [[ $res == '' ]] && { echo -e "${c_br}[MAp-119] 该域名未在天翼平台配置,一个小时内新增的域名无法查询,退出...${c_e}"; exit 119; } # -------------------------------------------------------------------------------- # 获取域名解析组信息 infos --map $domain $TS [[ $? -eq 205 || $? -eq 231 ]] && { echo -e "${c_br}[MAP-120] exiting...${c_e}"; exit 120; } # cd $trash && map=`cat map.log` && getlastcover $map > map.log cd $trash if [[ `cat map.log | wc -l` -eq 1 ]]; then map=`cat map.log` else maps=`cat map.log | sort | uniq` count=1 && > remap.log for map in $maps; do echo $count": "$map | tee -a remap.log let count=count+1 done echo -ne "${c_bg}存在分区域解析,需确定解析组名称(默认是1):${c_e}\n" read -t 60 imap [[ $? -ne 0 ]] && { echo -e "${c_br}[MAP-121] 60s内无任何输入,退出...${c_e}\n"; exit 121; } # do a check to see if isp is correct or not [[ $imap == '' ]] && let imap=1 map=`cat remap.log | awk -F ':' -v imap=$imap '$1==imap {print $2}'` [[ $map == '' ]] && { echo -e "${c_br}[MAP-122] 请输入正确的序号,退出...${c_e}"; exit 122; } fi getlastcover $map > map.log cat map.log | grep -q 'can not find sys_id' [[ $? -eq 0 ]] && { echo -e "${c_br}[MAP-123] 该解析组未在平台配置,退出...${c_e}"; exit 123; } # -------------------------------------------------------------------------------- # 随机获取VIP if [[ $item == 'vip' ]]; then random_vip elif [[ $item == 'rip' ]]; then random_rip elif [[ $item =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ || $item =~ ^[0-9a-fA-F:]{11,39}$ ]]; then ip_inmap elif [[ $item =~ ^(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 label_inmap elif [[ $item == 'label' ]]; then labels_inmap elif [[ $item == 'cover' ]]; then cover elif [[ $item == 'parent' ]]; then parent # 兜底是中文节点名的查询 else label_inmap fi