Update vps_manager.sh
This commit is contained in:
parent
048e7c9947
commit
42a3814356
606
vps_manager.sh
606
vps_manager.sh
@ -16,9 +16,14 @@ show_menu() {
|
||||
echo "9. 查看虚拟机列表"
|
||||
echo "10. 创建虚拟机"
|
||||
echo "11. 删除虚拟机"
|
||||
echo "12. 查看该项目下 socks5 配置"
|
||||
echo "13. 配置防火墙"
|
||||
echo "14. 查看防火墙规则"
|
||||
echo "15. 删除防火墙规则"
|
||||
|
||||
echo "0. 退出脚本"
|
||||
echo "====================================="
|
||||
echo "请输入选项(0-11):"
|
||||
echo "请输入选项(0-13):"
|
||||
}
|
||||
|
||||
# 获取当前日期,格式为 YYYYMMDD
|
||||
@ -61,26 +66,81 @@ get_instance_quota() {
|
||||
return 0
|
||||
}
|
||||
|
||||
# 动态获取支持 e2-micro 的区域和可用区,并分组
|
||||
# 动态获取支持 e2-micro 的区域和可用区,并分组(优化版)
|
||||
get_regions_and_zones() {
|
||||
echo "正在获取支持 e2-micro 机器类型的区域和可用区..."
|
||||
zones=$(gcloud compute machine-types list --filter="name=e2-micro" --format="value(ZONE)" --limit=1000 2>/dev/null | sort | uniq)
|
||||
if [ -z "$zones" ]; then
|
||||
echo "无法获取可用区列表,请检查 gcloud 配置或网络连接。"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# 硬编码的支持 e2-micro 的区域和可用区列表,加速获取
|
||||
declare -g -A region_map
|
||||
declare -g -a regions
|
||||
regions=()
|
||||
IFS=$'\n'
|
||||
for zone in $zones; do
|
||||
region=$(echo "$zone" | cut -d'-' -f1)
|
||||
if [[ ! " ${regions[@]} " =~ " ${region} " ]]; then
|
||||
regions+=("$region")
|
||||
regions=("us-central1" "us-east1" "us-east4" "us-east5" "us-east7" "us-west1" "us-west2" "us-west3" "us-west4" "us-west8" "us-south1" "europe-central2" "europe-north1" "europe-north2" "europe-southwest1" "europe-west1" "europe-west2" "europe-west3" "europe-west4" "europe-west6" "europe-west8" "europe-west9" "europe-west10" "europe-west12" "asia-east1" "asia-east2" "asia-northeast1" "asia-northeast2" "asia-northeast3" "asia-south1" "asia-south2" "asia-southeast1" "asia-southeast2" "australia-southeast1" "australia-southeast2" "southamerica-east1" "southamerica-west1" "northamerica-northeast1" "northamerica-northeast2" "northamerica-south1" "me-central1" "me-central2" "me-west1" "africa-south1")
|
||||
|
||||
# 初始化 region_map
|
||||
region_map["us-central1"]="us-central1-a us-central1-b us-central1-c us-central1-d us-central1-f"
|
||||
region_map["us-east1"]="us-east1-a us-east1-b us-east1-c us-east1-d"
|
||||
region_map["us-east4"]="us-east4-a us-east4-b us-east4-c"
|
||||
region_map["us-east5"]="us-east5-a us-east5-b us-east5-c"
|
||||
region_map["us-east7"]="us-east7-a us-east7-b us-east7-c"
|
||||
region_map["us-west1"]="us-west1-a us-west1-b us-west1-c"
|
||||
region_map["us-west2"]="us-west2-a us-west2-b us-west2-c"
|
||||
region_map["us-west3"]="us-west3-a us-west3-b us-west3-c"
|
||||
region_map["us-west4"]="us-west4-a us-west4-b us-west4-c"
|
||||
region_map["us-west8"]="us-west8-a us-west8-b us-west8-c"
|
||||
region_map["us-south1"]="us-south1-a us-south1-b us-south1-c"
|
||||
region_map["europe-central2"]="europe-central2-a europe-central2-b europe-central2-c"
|
||||
region_map["europe-north1"]="europe-north1-a europe-north1-b europe-north1-c"
|
||||
region_map["europe-north2"]="europe-north2-a europe-north2-b europe-north2-c"
|
||||
region_map["europe-southwest1"]="europe-southwest1-a europe-southwest1-b europe-southwest1-c"
|
||||
region_map["europe-west1"]="europe-west1-b europe-west1-c europe-west1-d"
|
||||
region_map["europe-west2"]="europe-west2-a europe-west2-b europe-west2-c"
|
||||
region_map["europe-west3"]="europe-west3-a europe-west3-b europe-west3-c"
|
||||
region_map["europe-west4"]="europe-west4-a europe-west4-b europe-west4-c"
|
||||
region_map["europe-west6"]="europe-west6-a europe-west6-b europe-west6-c"
|
||||
region_map["europe-west8"]="europe-west8-a europe-west8-b europe-west8-c"
|
||||
region_map["europe-west9"]="europe-west9-a europe-west9-b europe-west9-c"
|
||||
region_map["europe-west10"]="europe-west10-a europe-west10-b europe-west10-c"
|
||||
region_map["europe-west12"]="europe-west12-a europe-west12-b europe-west12-c"
|
||||
region_map["asia-east1"]="asia-east1-a asia-east1-b asia-east1-c"
|
||||
region_map["asia-east2"]="asia-east2-a asia-east2-b asia-east2-c"
|
||||
region_map["asia-northeast1"]="asia-northeast1-a asia-northeast1-b asia-northeast1-c"
|
||||
region_map["asia-northeast2"]="asia-northeast2-a asia-northeast2-b asia-northeast2-c"
|
||||
region_map["asia-northeast3"]="asia-northeast3-a asia-northeast3-b asia-northeast3-c"
|
||||
region_map["asia-south1"]="asia-south1-a asia-south1-b asia-south1-c"
|
||||
region_map["asia-south2"]="asia-south2-a asia-south2-b asia-south2-c"
|
||||
region_map["asia-southeast1"]="asia-southeast1-a asia-southeast1-b asia-southeast1-c"
|
||||
region_map["asia-southeast2"]="asia-southeast2-a asia-southeast2-b asia-southeast2-c"
|
||||
region_map["australia-southeast1"]="australia-southeast1-a australia-southeast1-b australia-southeast1-c"
|
||||
region_map["australia-southeast2"]="australia-southeast2-a australia-southeast2-b australia-southeast2-c"
|
||||
region_map["southamerica-east1"]="southamerica-east1-a southamerica-east1-b southamerica-east1-c"
|
||||
region_map["southamerica-west1"]="southamerica-west1-a southamerica-west1-b southamerica-west1-c"
|
||||
region_map["northamerica-northeast1"]="northamerica-northeast1-a northamerica-northeast1-b northamerica-northeast1-c"
|
||||
region_map["northamerica-northeast2"]="northamerica-northeast2-a northamerica-northeast2-b northamerica-northeast2-c"
|
||||
region_map["northamerica-south1"]="northamerica-south1-a northamerica-south1-b northamerica-south1-c"
|
||||
region_map["me-central1"]="me-central1-a me-central1-b me-central1-c"
|
||||
region_map["me-central2"]="me-central2-a me-central2-b me-central2-c"
|
||||
region_map["me-west1"]="me-west1-a me-west1-b me-west1-c"
|
||||
region_map["africa-south1"]="africa-south1-a africa-south1-b africa-south1-c"
|
||||
|
||||
# 检查硬编码列表是否有效(例如,至少有一个区域)
|
||||
if [ ${#regions[@]} -eq 0 ]; then
|
||||
echo "硬编码区域列表为空,尝试动态获取支持 e2-micro 的区域和可用区..."
|
||||
zones=$(gcloud compute machine-types list --filter="name=e2-micro" --format="value(ZONE)" --limit=1000 2>/dev/null | sort | uniq)
|
||||
if [ -z "$zones" ]; then
|
||||
echo "无法获取可用区列表,请检查 gcloud 配置或网络连接。"
|
||||
return 1
|
||||
fi
|
||||
region_map["$region"]="${region_map[$region]} $zone"
|
||||
done
|
||||
unset IFS
|
||||
regions=()
|
||||
IFS=$'\n'
|
||||
for zone in $zones; do
|
||||
region=$(echo "$zone" | cut -d'-' -f1)
|
||||
if [[ ! " ${regions[@]} " =~ " ${region} " ]]; then
|
||||
regions+=("$region")
|
||||
fi
|
||||
region_map["$region"]="${region_map[$region]} $zone"
|
||||
done
|
||||
unset IFS
|
||||
fi
|
||||
|
||||
if [ ${#regions[@]} -eq 0 ]; then
|
||||
echo "未找到支持 e2-micro 的大区域。"
|
||||
return 1
|
||||
@ -93,7 +153,12 @@ show_region_menu() {
|
||||
echo "请选择大区域:"
|
||||
local i=1
|
||||
for region in "${regions[@]}"; do
|
||||
echo "$i. $region"
|
||||
location=${region_location_map["$region"]}
|
||||
if [ -n "$location" ]; then
|
||||
echo "$i. $region($location)"
|
||||
else
|
||||
echo "$i. $region"
|
||||
fi
|
||||
((i++))
|
||||
done
|
||||
echo "0. 取消选择"
|
||||
@ -112,8 +177,13 @@ show_zone_menu() {
|
||||
return 1
|
||||
fi
|
||||
local i=1
|
||||
location=${region_location_map["$region"]}
|
||||
for zone in "${zones_list[@]}"; do
|
||||
echo "$i. $zone"
|
||||
if [ -n "$location" ]; then
|
||||
echo "$i. $zone($location)"
|
||||
else
|
||||
echo "$i. $zone"
|
||||
fi
|
||||
((i++))
|
||||
done
|
||||
echo "0. 取消选择"
|
||||
@ -126,7 +196,13 @@ show_zone_selection_method() {
|
||||
echo "请选择地区选择方式:"
|
||||
local default_zone=$(gcloud config get-value compute/zone 2>/dev/null)
|
||||
if [ -n "$default_zone" ]; then
|
||||
echo "1. 使用默认地区:$default_zone"
|
||||
region=$(echo "$default_zone" | sed 's/-[a-z]$//')
|
||||
location=${region_location_map["$region"]}
|
||||
if [ -n "$location" ]; then
|
||||
echo "1. 使用默认地区:$default_zone($location)"
|
||||
else
|
||||
echo "1. 使用默认地区:$default_zone"
|
||||
fi
|
||||
else
|
||||
echo "1. 使用默认地区(未设置,需手动指定)"
|
||||
fi
|
||||
@ -167,7 +243,13 @@ show_instance_menu() {
|
||||
instance_name=$(echo "$line" | awk '{print $1}')
|
||||
instance_zone=$(echo "$line" | awk '{print $2}')
|
||||
if [ -n "$instance_name" ] && [ -n "$instance_zone" ]; then
|
||||
echo "$i. $instance_name (区域: $instance_zone)"
|
||||
region=$(echo "$instance_zone" | sed 's/-[a-z]$//')
|
||||
location=${region_location_map["$region"]}
|
||||
if [ -n "$location" ]; then
|
||||
echo "$i. $instance_name (区域: $instance_zone($location))"
|
||||
else
|
||||
echo "$i. $instance_name (区域: $instance_zone)"
|
||||
fi
|
||||
instance_array+=("$instance_name|$instance_zone")
|
||||
((i++))
|
||||
fi
|
||||
@ -629,7 +711,6 @@ while true; do
|
||||
read -e -r -n 1
|
||||
continue
|
||||
fi
|
||||
|
||||
# 下载启动脚本
|
||||
echo "正在从远程地址下载启动脚本..."
|
||||
script_url="https://github.com/Lsmoisu/Toolbox/raw/refs/heads/main/enablesshandcreatesocks5.sh"
|
||||
@ -670,7 +751,52 @@ while true; do
|
||||
read -e -r -n 1
|
||||
continue
|
||||
fi
|
||||
|
||||
# 定义区域到地理位置的映射
|
||||
declare -A region_location_map
|
||||
region_location_map["africa-south1"]="南非约翰内斯堡"
|
||||
region_location_map["us-central1"]="美国爱荷华州"
|
||||
region_location_map["us-east1"]="美国南卡罗来纳州"
|
||||
region_location_map["us-east4"]="美国弗吉尼亚州北部"
|
||||
region_location_map["us-east5"]="美国俄亥俄州"
|
||||
region_location_map["us-east7"]="美国弗吉尼亚州"
|
||||
region_location_map["us-west1"]="美国俄勒冈州"
|
||||
region_location_map["us-west2"]="美国加利福尼亚州洛杉矶"
|
||||
region_location_map["us-west3"]="美国犹他州盐湖城"
|
||||
region_location_map["us-west4"]="美国内华达州拉斯维加斯"
|
||||
region_location_map["us-west8"]="美国德克萨斯州达拉斯"
|
||||
region_location_map["us-south1"]="美国得克萨斯州"
|
||||
region_location_map["europe-central2"]="波兰华沙"
|
||||
region_location_map["europe-north1"]="芬兰哈米纳"
|
||||
region_location_map["europe-north2"]="挪威斯塔万格"
|
||||
region_location_map["europe-southwest1"]="西班牙马德里"
|
||||
region_location_map["europe-west1"]="比利时圣吉斯兰"
|
||||
region_location_map["europe-west2"]="英国伦敦"
|
||||
region_location_map["europe-west3"]="德国法兰克福"
|
||||
region_location_map["europe-west4"]="荷兰埃姆斯哈文"
|
||||
region_location_map["europe-west6"]="瑞士苏黎世"
|
||||
region_location_map["europe-west8"]="意大利米兰"
|
||||
region_location_map["europe-west9"]="法国巴黎"
|
||||
region_location_map["europe-west10"]="德国柏林"
|
||||
region_location_map["europe-west12"]="意大利都灵"
|
||||
region_location_map["asia-east1"]="台湾彰化县"
|
||||
region_location_map["asia-east2"]="中国香港"
|
||||
region_location_map["asia-northeast1"]="日本东京"
|
||||
region_location_map["asia-northeast2"]="日本大阪"
|
||||
region_location_map["asia-northeast3"]="韩国首尔"
|
||||
region_location_map["asia-south1"]="印度孟买"
|
||||
region_location_map["asia-south2"]="印度德里"
|
||||
region_location_map["asia-southeast1"]="新加坡"
|
||||
region_location_map["asia-southeast2"]="亚太地区印度尼西亚雅加达"
|
||||
region_location_map["australia-southeast1"]="澳大利亚悉尼"
|
||||
region_location_map["australia-southeast2"]="澳大利亚墨尔本"
|
||||
region_location_map["southamerica-east1"]="巴西圣保罗"
|
||||
region_location_map["southamerica-west1"]="智利圣地亚哥"
|
||||
region_location_map["northamerica-northeast1"]="加拿大蒙特利尔"
|
||||
region_location_map["northamerica-northeast2"]="加拿大多伦多"
|
||||
region_location_map["northamerica-south1"]="美国南卡罗来纳州"
|
||||
region_location_map["me-central1"]="卡塔尔多哈"
|
||||
region_location_map["me-central2"]="沙特阿拉伯达曼"
|
||||
region_location_map["me-west1"]="以色列特拉维夫"
|
||||
# 选择地区选择方式
|
||||
while true; do
|
||||
show_zone_selection_method
|
||||
@ -683,7 +809,13 @@ while true; do
|
||||
elif [ "$method_choice" -eq 1 ]; then
|
||||
default_zone=$(gcloud config get-value compute/zone 2>/dev/null)
|
||||
if [ -n "$default_zone" ]; then
|
||||
echo "使用默认地区:$default_zone"
|
||||
region=$(echo "$default_zone" | cut -d'-' -f1-2)
|
||||
location=${region_location_map["$region"]}
|
||||
if [ -n "$location" ]; then
|
||||
echo "使用默认地区:$default_zone($location)"
|
||||
else
|
||||
echo "使用默认地区:$default_zone"
|
||||
fi
|
||||
zone="$default_zone"
|
||||
break
|
||||
else
|
||||
@ -698,7 +830,13 @@ while true; do
|
||||
echo "正在设置默认地区为 $input_zone..."
|
||||
gcloud config set compute/zone "$input_zone"
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "默认地区已设置为 $input_zone"
|
||||
region=$(echo "$input_zone" | cut -d'-' -f1-2)
|
||||
location=${region_location_map["$region"]}
|
||||
if [ -n "$location" ]; then
|
||||
echo "默认地区已设置为 $input_zone($location)"
|
||||
else
|
||||
echo "默认地区已设置为 $input_zone"
|
||||
fi
|
||||
zone="$input_zone"
|
||||
break
|
||||
else
|
||||
@ -709,6 +847,7 @@ while true; do
|
||||
fi
|
||||
fi
|
||||
elif [ "$method_choice" -eq 2 ]; then
|
||||
echo "正在获取支持 e2-micro 机器类型的区域和可用区..."
|
||||
get_regions_and_zones
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "按任意键返回菜单..."
|
||||
@ -716,7 +855,18 @@ while true; do
|
||||
continue 2
|
||||
fi
|
||||
while true; do
|
||||
show_region_menu
|
||||
echo "请选择大区域:"
|
||||
for i in "${!regions[@]}"; do
|
||||
region="${regions[$i]}"
|
||||
location=${region_location_map["$region"]}
|
||||
if [ -n "$location" ]; then
|
||||
printf "%2d. %s (%s)\n" "$((i+1))" "$region" "$location"
|
||||
else
|
||||
printf "%2d. %s\n" "$((i+1))" "$region"
|
||||
fi
|
||||
done
|
||||
echo "0. 取消选择"
|
||||
echo "请输入选项(0-${#regions[@]}):"
|
||||
read -e -r region_choice
|
||||
if [ "$region_choice" -eq 0 ]; then
|
||||
echo "操作取消。"
|
||||
@ -750,12 +900,36 @@ while true; do
|
||||
fi
|
||||
if [ "$zone_choice" -ge 1 ] && [ "$zone_choice" -le "${#zones_list[@]}" ]; then
|
||||
zone="${zones_list[$((zone_choice-1))]}"
|
||||
# 自动设置选择的区域为默认区域
|
||||
echo "正在设置默认地区为 $zone..."
|
||||
gcloud config set compute/zone "$zone"
|
||||
region=$(echo "$zone" | cut -d'-' -f1-2)
|
||||
location=${region_location_map["$region"]}
|
||||
if [ $? -eq 0 ]; then
|
||||
if [ -n "$location" ]; then
|
||||
echo "默认地区已设置为 $zone($location)"
|
||||
else
|
||||
echo "默认地区已设置为 $zone"
|
||||
fi
|
||||
else
|
||||
if [ -n "$location" ]; then
|
||||
echo "设置默认地区失败,请检查区域格式或权限,但将继续使用 $zone($location) 创建虚拟机。"
|
||||
else
|
||||
echo "设置默认地区失败,请检查区域格式或权限,但将继续使用 $zone 创建虚拟机。"
|
||||
fi
|
||||
fi
|
||||
break
|
||||
else
|
||||
echo "无效选项,请选择 0-${#zones_list[@]} 之间的数字。"
|
||||
fi
|
||||
done
|
||||
echo "选择的可用区:$zone"
|
||||
region=$(echo "$zone" | cut -d'-' -f1-2)
|
||||
location=${region_location_map["$region"]}
|
||||
if [ -n "$location" ]; then
|
||||
echo "选择的可用区:$zone($location)"
|
||||
else
|
||||
echo "选择的可用区:$zone"
|
||||
fi
|
||||
break
|
||||
elif [ "$method_choice" -eq 3 ]; then
|
||||
echo "请输入新的默认地区(如 us-central1-a):"
|
||||
@ -769,7 +943,13 @@ while true; do
|
||||
echo "正在设置默认地区为 $new_zone..."
|
||||
gcloud config set compute/zone "$new_zone"
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "默认地区已更新为 $new_zone"
|
||||
region=$(echo "$new_zone" | cut -d'-' -f1-2)
|
||||
location=${region_location_map["$region"]}
|
||||
if [ -n "$location" ]; then
|
||||
echo "默认地区已更新为 $new_zone($location)"
|
||||
else
|
||||
echo "默认地区已更新为 $new_zone"
|
||||
fi
|
||||
else
|
||||
echo "设置默认地区失败,请检查区域格式或权限。"
|
||||
echo "按任意键返回菜单..."
|
||||
@ -781,7 +961,7 @@ while true; do
|
||||
fi
|
||||
done
|
||||
|
||||
# 直接提示用户输入创建数量
|
||||
# 直接提示用户输入创建数量(保持不变)
|
||||
while true; do
|
||||
echo "请输入要创建的虚拟机数量(大于 0 的整数):"
|
||||
read -e -r instance_count
|
||||
@ -792,7 +972,7 @@ while true; do
|
||||
break
|
||||
done
|
||||
|
||||
# 批量创建虚拟机
|
||||
# 批量创建虚拟机(保持不变)
|
||||
echo "将创建 $instance_count 台虚拟机..."
|
||||
for ((i=1; i<=instance_count; i++)); do
|
||||
random_suffix=$(generate_random_suffix)
|
||||
@ -894,7 +1074,13 @@ while true; do
|
||||
for inst in "${selected_instances[@]}"; do
|
||||
instance_name=$(echo "$inst" | cut -d'|' -f1)
|
||||
instance_zone=$(echo "$inst" | cut -d'|' -f2)
|
||||
echo "- $instance_name (区域: $instance_zone)"
|
||||
region=$(echo "$instance_zone" | sed 's/-[a-z]$//')
|
||||
location=${region_location_map["$region"]}
|
||||
if [ -n "$location" ]; then
|
||||
echo "- $instance_name (区域: $instance_zone($location))"
|
||||
else
|
||||
echo "- $instance_name (区域: $instance_zone)"
|
||||
fi
|
||||
done
|
||||
echo "确认删除这些虚拟机吗?(输入 'yes' 确认,任意其他输入取消):"
|
||||
read -e -r confirm
|
||||
@ -924,12 +1110,370 @@ while true; do
|
||||
echo "按任意键返回菜单..."
|
||||
read -e -r -n 1
|
||||
;;
|
||||
12)
|
||||
echo "正在查看当前项目下所有实例的 socks5 配置..."
|
||||
current_project=$(gcloud config get-value project)
|
||||
if [ -z "$current_project" ]; then
|
||||
echo "未找到默认项目,请先切换默认项目(选项 8)。"
|
||||
echo "按任意键返回菜单..."
|
||||
read -e -r -n 1
|
||||
continue
|
||||
fi
|
||||
echo "当前默认项目:$current_project"
|
||||
instance_data=$(get_instance_list "$current_project")
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "按任意键返回菜单..."
|
||||
read -e -r -n 1
|
||||
continue
|
||||
fi
|
||||
|
||||
# 定义区域到地理位置的映射
|
||||
declare -A region_location_map
|
||||
region_location_map["africa-south1"]="南非约翰内斯堡"
|
||||
region_location_map["us-central1"]="美国爱荷华州"
|
||||
region_location_map["us-east1"]="美国南卡罗来纳州"
|
||||
region_location_map["us-east4"]="美国弗吉尼亚州北部"
|
||||
region_location_map["us-east5"]="美国俄亥俄州"
|
||||
region_location_map["us-east7"]="美国弗吉尼亚州"
|
||||
region_location_map["us-west1"]="美国俄勒冈州"
|
||||
region_location_map["us-west2"]="美国加利福尼亚州洛杉矶"
|
||||
region_location_map["us-west3"]="美国犹他州盐湖城"
|
||||
region_location_map["us-west4"]="美国内华达州拉斯维加斯"
|
||||
region_location_map["us-west8"]="美国德克萨斯州达拉斯"
|
||||
region_location_map["us-south1"]="美国得克萨斯州"
|
||||
region_location_map["europe-central2"]="波兰华沙"
|
||||
region_location_map["europe-north1"]="芬兰哈米纳"
|
||||
region_location_map["europe-north2"]="挪威斯塔万格"
|
||||
region_location_map["europe-southwest1"]="西班牙马德里"
|
||||
region_location_map["europe-west1"]="比利时圣吉斯兰"
|
||||
region_location_map["europe-west2"]="英国伦敦"
|
||||
region_location_map["europe-west3"]="德国法兰克福"
|
||||
region_location_map["europe-west4"]="荷兰埃姆斯哈文"
|
||||
region_location_map["europe-west6"]="瑞士苏黎世"
|
||||
region_location_map["europe-west8"]="意大利米兰"
|
||||
region_location_map["europe-west9"]="法国巴黎"
|
||||
region_location_map["europe-west10"]="德国柏林"
|
||||
region_location_map["europe-west12"]="意大利都灵"
|
||||
region_location_map["asia-east1"]="台湾彰化县"
|
||||
region_location_map["asia-east2"]="中国香港"
|
||||
region_location_map["asia-northeast1"]="日本东京"
|
||||
region_location_map["asia-northeast2"]="日本大阪"
|
||||
region_location_map["asia-northeast3"]="韩国首尔"
|
||||
region_location_map["asia-south1"]="印度孟买"
|
||||
region_location_map["asia-south2"]="印度德里"
|
||||
region_location_map["asia-southeast1"]="新加坡"
|
||||
region_location_map["asia-southeast2"]="亚太地区印度尼西亚雅加达"
|
||||
region_location_map["australia-southeast1"]="澳大利亚悉尼"
|
||||
region_location_map["australia-southeast2"]="澳大利亚墨尔本"
|
||||
region_location_map["southamerica-east1"]="巴西圣保罗"
|
||||
region_location_map["southamerica-west1"]="智利圣地亚哥"
|
||||
region_location_map["northamerica-northeast1"]="加拿大蒙特利尔"
|
||||
region_location_map["northamerica-northeast2"]="加拿大多伦多"
|
||||
region_location_map["northamerica-south1"]="美国南卡罗来纳州"
|
||||
region_location_map["me-central1"]="卡塔尔多哈"
|
||||
region_location_map["me-central2"]="沙特阿拉伯达曼"
|
||||
region_location_map["me-west1"]="以色列特拉维夫"
|
||||
|
||||
# 显示虚拟机列表并获取数组
|
||||
show_instance_menu "$instance_data"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "按任意键返回菜单..."
|
||||
read -e -r -n 1
|
||||
continue
|
||||
fi
|
||||
|
||||
# 遍历每个实例,读取 /opt/socks.txt 文件内容
|
||||
echo "正在读取每个实例的 /opt/socks.txt 文件内容..."
|
||||
for inst in "${instance_array[@]}"; do
|
||||
instance_name=$(echo "$inst" | cut -d'|' -f1)
|
||||
instance_zone=$(echo "$inst" | cut -d'|' -f2)
|
||||
echo "----------------------------------------"
|
||||
region=$(echo "$instance_zone" | sed 's/-[a-z]$//')
|
||||
location=${region_location_map["$region"]}
|
||||
if [ -n "$location" ]; then
|
||||
echo "实例:$instance_name (区域: $instance_zone($location))"
|
||||
else
|
||||
echo "实例:$instance_name (区域: $instance_zone)"
|
||||
fi
|
||||
# 使用 gcloud compute ssh 远程读取文件内容
|
||||
socks_content=$(gcloud compute ssh "$instance_name" \
|
||||
--project="$current_project" \
|
||||
--zone="$instance_zone" \
|
||||
--command="cat /opt/socks.txt" \
|
||||
--quiet 2>/dev/null)
|
||||
if [ $? -eq 0 ] && [ -n "$socks_content" ]; then
|
||||
echo "$socks_content"
|
||||
else
|
||||
echo "无法读取文件内容,可能是文件不存在、权限不足或 SSH 连接失败。"
|
||||
fi
|
||||
echo "----------------------------------------"
|
||||
done
|
||||
echo "按任意键返回菜单..."
|
||||
read -e -r -n 1
|
||||
;;
|
||||
13)
|
||||
echo "正在配置防火墙规则..."
|
||||
current_project=$(gcloud config get-value project)
|
||||
if [ -z "$current_project" ]; then
|
||||
echo "未找到默认项目,请先切换默认项目(选项 8)。"
|
||||
echo "按任意键返回菜单..."
|
||||
read -e -r -n 1
|
||||
continue
|
||||
fi
|
||||
echo "当前默认项目:$current_project"
|
||||
|
||||
# 提示用户输入防火墙规则名称
|
||||
echo "请输入防火墙规则名称(小写字母、数字或短划线组成,留空取消操作):"
|
||||
read -e -r rule_name
|
||||
if [ -z "$rule_name" ]; then
|
||||
echo "未输入规则名称,操作取消。"
|
||||
echo "按任意键返回菜单..."
|
||||
read -e -r -n 1
|
||||
continue
|
||||
fi
|
||||
|
||||
# 验证规则名称格式(仅允许小写字母、数字和短划线)
|
||||
if [[ ! "$rule_name" =~ ^[a-z0-9][a-z0-9-]*[a-z0-9]$ ]] || [[ "$rule_name" =~ ^- ]] || [[ "$rule_name" =~ -$ ]]; then
|
||||
echo "规则名称格式无效,仅允许小写字母、数字和短划线,且不能以短划线开头或结尾。"
|
||||
echo "按任意键返回菜单..."
|
||||
read -e -r -n 1
|
||||
continue
|
||||
fi
|
||||
|
||||
# 检查规则名称是否已存在
|
||||
echo "正在检查规则名称是否已存在..."
|
||||
if gcloud compute firewall-rules list --project="$current_project" | grep -q "^$rule_name "; then
|
||||
echo "规则名称 '$rule_name' 已存在,请使用其他名称。"
|
||||
echo "按任意键返回菜单..."
|
||||
read -e -r -n 1
|
||||
continue
|
||||
fi
|
||||
|
||||
# 提示用户选择协议类型
|
||||
echo "请选择协议类型:"
|
||||
echo "1. TCP"
|
||||
echo "2. UDP"
|
||||
echo "3. TCP 和 UDP"
|
||||
echo "0. 取消操作"
|
||||
read -e -r protocol_choice
|
||||
case $protocol_choice in
|
||||
1)
|
||||
protocol="tcp"
|
||||
;;
|
||||
2)
|
||||
protocol="udp"
|
||||
;;
|
||||
3)
|
||||
protocol="tcp,udp"
|
||||
;;
|
||||
0)
|
||||
echo "操作取消。"
|
||||
echo "按任意键返回菜单..."
|
||||
read -e -r -n 1
|
||||
continue
|
||||
;;
|
||||
*)
|
||||
echo "无效选项,操作取消。"
|
||||
echo "按任意键返回菜单..."
|
||||
read -e -r -n 1
|
||||
continue
|
||||
;;
|
||||
esac
|
||||
|
||||
# 提示用户输入端口号或范围
|
||||
echo "请输入端口号(支持单个端口如 '8080',非连续端口如 '8080,8081',连续端口范围如 '8000-9000'):"
|
||||
read -e -r port_input
|
||||
if [ -z "$port_input" ]; then
|
||||
echo "未输入端口号,操作取消。"
|
||||
echo "按任意键返回菜单..."
|
||||
read -e -r -n 1
|
||||
continue
|
||||
fi
|
||||
|
||||
# 验证端口输入格式
|
||||
if [[ ! "$port_input" =~ ^[0-9]+(-[0-9]+)?([,][0-9]+(-[0-9]+)?)*$ ]]; then
|
||||
echo "端口格式无效,仅支持数字、逗号和短划线(用于范围)。示例:8080 或 8000-9000 或 8080,8081,9000-9100"
|
||||
echo "按任意键返回菜单..."
|
||||
read -e -r -n 1
|
||||
continue
|
||||
fi
|
||||
|
||||
# 拆分端口输入,检查每个端口或范围是否合法
|
||||
IFS=',' read -ra port_entries <<< "$port_input"
|
||||
for entry in "${port_entries[@]}"; do
|
||||
if [[ "$entry" =~ ^[0-9]+-[0-9]+$ ]]; then
|
||||
# 范围端口
|
||||
IFS='-' read -ra range <<< "$entry"
|
||||
start_port=${range[0]}
|
||||
end_port=${range[1]}
|
||||
if [ "$start_port" -lt 1 ] || [ "$start_port" -gt 65535 ] || [ "$end_port" -lt 1 ] || [ "$end_port" -gt 65535 ] || [ "$start_port" -gt "$end_port" ]; then
|
||||
echo "端口范围 $entry 无效,端口必须在 1-65535 之间,且起始端口不能大于结束端口。"
|
||||
echo "按任意键返回菜单..."
|
||||
read -e -r -n 1
|
||||
continue 2
|
||||
fi
|
||||
elif [[ "$entry" =~ ^[0-9]+$ ]]; then
|
||||
# 单个端口
|
||||
if [ "$entry" -lt 1 ] || [ "$entry" -gt 65535 ]; then
|
||||
echo "端口 $entry 无效,端口必须在 1-65535 之间。"
|
||||
echo "按任意键返回菜单..."
|
||||
read -e -r -n 1
|
||||
continue 2
|
||||
fi
|
||||
else
|
||||
echo "端口格式 $entry 无效。"
|
||||
echo "按任意键返回菜单..."
|
||||
read -e -r -n 1
|
||||
continue 2
|
||||
fi
|
||||
done
|
||||
unset IFS
|
||||
|
||||
# 提示用户输入来源 IP 范围(默认为 0.0.0.0/0,即所有来源)
|
||||
echo "请输入允许的来源 IP 范围(CIDR 格式,如 0.0.0.0/0 表示所有 IP,留空使用默认值 0.0.0.0/0):"
|
||||
read -e -r source_ranges
|
||||
if [ -z "$source_ranges" ]; then
|
||||
source_ranges="0.0.0.0/0"
|
||||
fi
|
||||
|
||||
# 验证 CIDR 格式(简单检查)
|
||||
if [[ ! "$source_ranges" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/[0-9]+$ ]]; then
|
||||
echo "来源 IP 范围格式无效,应为 CIDR 格式(如 0.0.0.0/0 或 192.168.1.0/24)。"
|
||||
echo "按任意键返回菜单..."
|
||||
read -e -r -n 1
|
||||
continue
|
||||
fi
|
||||
|
||||
# 确认创建防火墙规则
|
||||
echo "即将创建以下防火墙规则:"
|
||||
echo "规则名称:$rule_name"
|
||||
echo "协议:$protocol"
|
||||
echo "端口:$port_input"
|
||||
echo "来源 IP 范围:$source_ranges"
|
||||
echo "确认创建吗?(输入 'y' 确认,其他取消):"
|
||||
read -e -r -n 1 confirm
|
||||
echo ""
|
||||
if [ "$confirm" != "y" ] && [ "$confirm" != "Y" ]; then
|
||||
echo "创建操作已取消。"
|
||||
echo "按任意键返回菜单..."
|
||||
read -e -r -n 1
|
||||
continue
|
||||
fi
|
||||
|
||||
# 格式化 --rules 参数
|
||||
rules=""
|
||||
IFS=',' read -ra protocols <<< "$protocol"
|
||||
IFS=',' read -ra ports <<< "$port_input"
|
||||
for proto in "${protocols[@]}"; do
|
||||
for port in "${ports[@]}"; do
|
||||
if [ -n "$rules" ]; then
|
||||
rules="$rules,"
|
||||
fi
|
||||
rules="$rules$proto:$port"
|
||||
done
|
||||
done
|
||||
unset IFS
|
||||
|
||||
# 创建防火墙规则
|
||||
echo "正在创建防火墙规则 '$rule_name'..."
|
||||
gcloud compute firewall-rules create "$rule_name" \
|
||||
--project="$current_project" \
|
||||
--direction=INGRESS \
|
||||
--priority=1000 \
|
||||
--network=default \
|
||||
--action=ALLOW \
|
||||
--rules="$rules" \
|
||||
--source-ranges="$source_ranges"
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "防火墙规则 '$rule_name' 创建成功!"
|
||||
else
|
||||
echo "创建防火墙规则失败,可能是规则名称已存在或没有权限。"
|
||||
echo "错误信息如上,请检查。"
|
||||
fi
|
||||
echo "按任意键返回菜单..."
|
||||
read -e -r -n 1
|
||||
;;
|
||||
|
||||
14)
|
||||
echo "正在查看当前防火墙规则..."
|
||||
current_project=$(gcloud config get-value project)
|
||||
if [ -z "$current_project" ]; then
|
||||
echo "未找到默认项目,请先切换默认项目(选项 8)。"
|
||||
echo "按任意键返回菜单..."
|
||||
read -e -r -n 1
|
||||
continue
|
||||
fi
|
||||
echo "当前默认项目:$current_project"
|
||||
echo "列出所有防火墙规则:"
|
||||
# 使用 gcloud 命令列出防火墙规则
|
||||
gcloud compute firewall-rules list --project="$current_project" --format="table(name,network,direction,priority,allow,disabled)" 2>/dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "防火墙规则列表显示完毕。"
|
||||
else
|
||||
echo "无法获取防火墙规则列表,请检查是否有权限或项目是否正确。"
|
||||
fi
|
||||
echo "按任意键返回菜单..."
|
||||
read -e -r -n 1
|
||||
;;
|
||||
15)
|
||||
echo "正在准备删除防火墙规则..."
|
||||
current_project=$(gcloud config get-value project)
|
||||
if [ -z "$current_project" ]; then
|
||||
echo "未找到默认项目,请先切换默认项目(选项 8)。"
|
||||
echo "按任意键返回菜单..."
|
||||
read -e -r -n 1
|
||||
continue
|
||||
fi
|
||||
echo "当前默认项目:$current_project"
|
||||
echo "当前防火墙规则列表:"
|
||||
# 列出所有防火墙规则供用户参考
|
||||
gcloud compute firewall-rules list --project="$current_project" --format="table(name,network,direction,priority,allow,disabled)" 2>/dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "无法获取防火墙规则列表,请检查是否有权限或项目是否正确。"
|
||||
echo "按任意键返回菜单..."
|
||||
read -e -r -n 1
|
||||
continue
|
||||
fi
|
||||
|
||||
# 提示用户输入要删除的规则名称
|
||||
echo "请输入要删除的防火墙规则名称(留空取消操作):"
|
||||
read -e -r rule_name
|
||||
if [ -z "$rule_name" ]; then
|
||||
echo "未输入规则名称,操作取消。"
|
||||
echo "按任意键返回菜单..."
|
||||
read -e -r -n 1
|
||||
continue
|
||||
fi
|
||||
|
||||
# 确认删除操作
|
||||
echo "确认要删除防火墙规则 '$rule_name' 吗?(输入 'y' 确认,其他取消):"
|
||||
read -e -r -n 1 confirm
|
||||
echo ""
|
||||
if [ "$confirm" != "y" ] && [ "$confirm" != "Y" ]; then
|
||||
echo "删除操作已取消。"
|
||||
echo "按任意键返回菜单..."
|
||||
read -e -r -n 1
|
||||
continue
|
||||
fi
|
||||
|
||||
# 执行删除操作
|
||||
echo "正在删除防火墙规则 '$rule_name'..."
|
||||
gcloud compute firewall-rules delete "$rule_name" --project="$current_project" --quiet 2>/dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "防火墙规则 '$rule_name' 删除成功。"
|
||||
else
|
||||
echo "删除防火墙规则失败,可能是规则不存在或没有权限。"
|
||||
fi
|
||||
echo "按任意键返回菜单..."
|
||||
read -e -r -n 1
|
||||
;;
|
||||
|
||||
0)
|
||||
echo "退出脚本..."
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "无效选项,请选择 0-11 之间的数字。"
|
||||
echo "无效选项,请选择 0-12 之间的数字。"
|
||||
echo "按任意键返回菜单..."
|
||||
read -e -r -n 1
|
||||
;;
|
||||
|
Loading…
x
Reference in New Issue
Block a user