scripts/old/ctc/map.sh
2023-06-05 23:04:30 +08:00

350 lines
18 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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