#!/bin/bash


checkip(){
	regex="\b(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[1-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[1-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[1-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[1-9])\b"
	if ! echo $1 | egrep ${regex} >/dev/null; then
		echo "$1 地址不规范"
		exit
	fi
}

cidr_to_mask(){
	set -- $(( 5 - ($1 / 8) )) 255 255 255 255 $(( (255 << (8 - ($1 % 8))) & 255 )) 0 0 0
	[ $1 -gt 1 ] && shift $1 || shift
	echo ${1-0}.${2-0}.${3-0}.${4-0}
}

mask_to_cidr(){
	local x=${1##*255.}
	set -- 0^^^128^192^224^240^248^252^254^ $(( (${#1} - ${#x})*2 )) ${x%%.*}
	x=${1%%$3*}
	echo $(( $2 + (${#x}/4) ))
}

interface_del_ip_range(){
	net_config_line=$(wc -l /etc/network/interfaces | awk '{print$1}')
	for((i=${del_ip_line};i>=1;i--));do
		if sed -n ${i}p /etc/network/interfaces | grep auto > /dev/null;then
			del_start_line=${i}
			break
		fi
	done
	for((n=${del_ip_line};n<=${net_config_line};n++));do
		if sed -n ${n}p /etc/network/interfaces | grep auto > /dev/null;then
			let del_end_line=${n}-1
			break
		fi
	done
	if [ -z ${del_end_line} ];then
		del_end_line=${net_config_line}
	fi
}


interface_del_ip(){
	nic=$1
	ip_info=$2
	ip=$(echo ${ip_info} | awk -F"/" '{print$1}')
	del_ip_line=$(grep -n " ${ip}$" /etc/network/interfaces | awk -F":" '{print$1}')
	interface_del_ip_range
	if sed -n "${del_start_line},${del_end_line}"p /etc/network/interfaces | grep gateway > /dev/null;then
		default_gateway=$(sed -n "${del_start_line},${del_end_line}"p /etc/network/interfaces | awk '/gateway/{print$2}')
		ifname=$(sed -n "${del_start_line},${del_end_line}"p /etc/network/interfaces | awk '/auto/{print$2}')
		sed -i "${del_start_line},${del_end_line}d" /etc/network/interfaces
		new_gw_ifname=$(grep "auto" /etc/network/interfaces | awk '{print$2}' | grep ${nic} | head -n 1)
		new_gw_ifname_line=$(grep -n "${new_gw_ifname}[ ]\{0,\}$" /etc/network/interfaces | awk -F":" '{print$1}')
		net_config_line=$(wc -l /etc/network/interfaces | awk '{print$1}')
		for((n=${new_gw_ifname_line};n<=${net_config_line};n++));do
			if sed -n ${n}p /etc/network/interfaces | grep netmask > /dev/null;then
				add_line=${n}
				break
			fi
		done
		sed -i "${add_line} a      gateway ${default_gateway}" /etc/network/interfaces
		ip addr del ${ip_info} dev ${nic};systemctl restart networking.service
	else
		ifname=$(sed -n ${del_start_line},${del_end_line}p /etc/network/interfaces | awk '/auto/{print$2}')
		ifdown ${ifname}
		sed -i "${del_start_line},${del_end_line}d" /etc/network/interfaces
	fi
}

interface_add_ip(){
	nic=$1
	ip_info=$2
	ip=$(echo ${ip_info} | awk -F"/" '{print$1}')
	cidr=$(echo ${ip_info} | awk -F"/" '{print$2}')
	mask=$(cidr_to_mask ${cidr})
	if grep ${nic} /etc/network/interfaces > /dev/null;then
		if_id_range=($(grep "auto" /etc/network/interfaces | awk -F[\ :] '/'${nic}:'/{print$3}'  | grep -v "^$"))
		for ((n=1;n<=300;n++));do
			if ! echo ${if_id_range[@]} | grep -w ${n} > /dev/null;then
				if_id=${n}
				break
			fi
		done
		cat >> /etc/network/interfaces << EOF
auto ${nic}:${if_id}
iface ${nic}:${if_id} inet static
    address ${ip}
    netmask ${mask}
EOF
	ifup ${nic}:${if_id}
	else
		cat >> /etc/network/interfaces << EOF
auto ${nic}:1
iface ${nic}:1 inet static
    address ${ip}
    netmask ${mask}
EOF
	ifup ${nic}:1
	fi
}

interface_change_default_gw(){
	nic=$1
	ip_info=$2
	sed -i "s/gateway .*/gateway ${ip_info}/" /etc/network/interfaces
}


netplan_add_ip(){
	nic=$1
	ip_info=$2
	net_conf_file=$(ls /etc/netplan/*.yaml)
	yq -i '.network.ethernets.'${nic}'.addresses += ["'${ip_info}'"]' ${net_conf_file}
	netplan apply
}

netplan_del_ip(){
	nic=$1
	ip_info=$2
	net_conf_file=$(ls /etc/netplan/*.yaml)
	yq -i 'del(.network.ethernets.'${nic}'.addresses[] | select(. == "'${ip_info}'"))' ${net_conf_file}
	netplan apply
}

netplan_change_default_gw(){
	nic=$1
	default_gateway=$2
	net_conf_file=$(ls /etc/netplan/*.yaml)
	yq -i '.network.ethernets.'${nic}'.gateway4 = "'${default_gateway}'"' ${net_conf_file}
	netplan apply
}

nmcli_add_ip(){
	nic=$1
	ip_info=$2
	nic_config="/etc/sysconfig/network-scripts/ifcfg-${nic}"
	if [ -e "${nic_config}" ];then
		nmcli connection modify ${nic} +ipv4.addresses ${ip_info} ipv4.method manual ipv6.method link-local
		nmcli connection up ${nic}
	else
		nmcli con add con-name ${nic} autoconnect yes type ethernet ifname ${nic} ipv4.method manual ipv6.method link-local +ipv4.addresses ${ip_info}
		nmcli connection up ${nic}
	fi
}

nmcli_del_ip(){
	nic=$1
	ip_info=$2
	ip_num=$(ip addr show ${nic} | grep -c "inet ")
	if [ ${ip_num} -eq 1 ];then
		nmcli connection modify ${nic} -ipv4.addresses ${ip_info} ipv4.method disabled ipv6.method link-local 
		nmcli connection up ${nic}
	else
		nmcli connection modify ${nic} -ipv4.addresses ${ip_info} ipv6.method link-local
		nmcli connection up ${nic}
	fi
}

nmcli_change_default_gw(){
	nic=$1
	default_gateway=$2
	nmcli connection modify ${nic} ipv4.gateway ${default_gateway}
	nmcli connection up ${nic}
}

change_ssh_port(){
	ssh_port=$1
	sed -i "/Port /s/.*/Port ${ssh_port}/" /etc/ssh/sshd_config
	systemctl restart sshd
}

change_hostname(){
	hostname=$1
	echo ${hostname} > /etc/hostname
	hostname ${hostname}
}



system_version(){
	operate=$1
	nic=$2
	ip_info=$3
	if grep "CentOS" /etc/redhat-release > /dev/null 2>&1; then
		if [ ${operate} == "ip_add" ];then
			nmcli_add_ip ${nic} ${ip_info}
		elif [ ${operate} == "ip_del" ];then
			nmcli_del_ip ${nic} ${ip_info}
		elif [ ${operate} == "change_gw" ];then
			nmcli_change_default_gw ${public_nic} ${gw_ip}
		fi
	elif egrep "ubuntu1~14|Ubuntu 16|ubuntu1~16" /proc/version > /dev/null 2>&1; then
		if [ ${operate} == "ip_add" ];then
			interface_add_ip ${nic} ${ip_info}
		elif [ ${operate} == "ip_del" ];then
			interface_del_ip ${nic} ${ip_info}
		elif [ ${operate} == "change_gw" ];then
			interface_change_default_gw ${public_nic} ${gw_ip}
		fi
	elif egrep "Ubuntu 18|Ubuntu 20|Ubuntu 22|Ubuntu 24" /etc/issue > /dev/null 2>&1; then
		if [ ! -f /usr/local/bin/yq ];then
			wget http://154.39.243.118/Tools/yq_linux_amd64 -O /usr/local/bin/yq > /dev/null 2>&1
			chmod +x /usr/local/bin/yq
		fi
		if [ ! -f /usr/local/bin/yq ];then
			exit 1
		fi
		if [ ${operate} == "ip_add" ];then
			netplan_add_ip ${nic} ${ip_info}
		elif [ ${operate} == "ip_del" ];then
			netplan_del_ip ${nic} ${ip_info}
		elif [ ${operate} == "change_gw" ];then
			netplan_change_default_gw ${public_nic} ${gw_ip}
		fi
	elif egrep "Debian" /proc/version > /dev/null 2>&1; then

		if [ ${operate} == "ip_add" ];then
			interface_add_ip ${nic} ${ip_info}
		elif [ ${operate} == "ip_del" ];then
			interface_del_ip ${nic} ${ip_info}
		elif [ ${operate} == "change_gw" ];then
			interface_change_default_gw ${public_nic} ${gw_ip}
		fi
	fi
}

cat << EOF
1) 增加IP地址
2) 移除IP地址
3) 更换默认网关
4) 修改ssh端口
5) 修改主机名
EOF

check_id(){
	input_id=$1
	max_id=$2
	text=$3
	if ! echo ${input_id} | grep [1-${max_id}] > /dev/null;then
		echo "${text}"
		exit 1
	fi
}

read -p "输入以上功能的序号[1-6]: " input
check_id ${input} 6 "输入序号不在范围内"
if [ ${input} -eq 1 ];then
	ip link show | awk -F[\ \:] '/mtu/{print$3}' | grep -v lo | sort | awk '{print NR") "$1}'
	ip route show | head -n 1| awk '/default/{print"当前公网网卡是: "$5}'
	nic_num=$(ip link show | awk -F[\ \:] '/mtu/{print$3}' | grep -v lo | wc -l)
	read -p "输入需要新增的IP的网卡: " nic_id
	check_id ${nic_id} ${nic_num} "序号不在范围内"
	nic=$(ip link show | awk -F[\ \:] '/mtu/{print$3}' | grep -v lo | sort | sed -n ${nic_id}p)
	read -p "输入需要新增的IP地址: " new_ip
	checkip ${new_ip}
	read -p "输入需要新增的IP的掩码位: " new_dir
	check_id ${new_dir} 32 "掩码位格式不对"
	ip_info="${new_ip}/${new_dir}"
	ip addr show dev ${nic} | awk '/inet /{print$2}' | grep "${ip_info}/" > /dev/null && echo "IP地址已存在" && exit 1
	system_version ip_add ${nic} ${ip_info}
elif [ ${input} -eq 2 ];then
	ip link show | awk -F[\ \:] '/mtu/{print$3}' | grep -v lo | sort | awk '{print NR") "$1}'
	public_nic=$(ip route show | head -n 1| awk '/default/{print$5}')
	echo "当前公网网卡是: ${public_nic}"
	nic_num=$(ip link show | awk -F[\ \:] '/mtu/{print$3}' | grep -v lo | wc -l)
	read -p "输入需要新增的IP的网卡: " nic_id
	check_id ${nic_id} ${nic_num} "序号不在范围内"
	nic=$(ip link show | awk -F[\ \:] '/mtu/{print$3}' | grep -v lo | sort | sed -n ${nic_id}p)
	ip_num=$(ip addr show dev ${nic} | awk '/inet /{print$2}'| wc -l)
	if [ ${nic} == ${public_nic} ];then
		if [ ${ip_num} -eq 1 ];then
			echo "公网网卡只有一个IP不能移除"
			exit 1
		fi
	fi
	ip addr show dev ${nic} | awk '/inet /{print$2}' | awk '{print NR") "$1}'
	read -p "输入需要移除IP的序号: " del_ip_id
	check_id ${del_ip_id} ${ip_num} "序号不在范围内"
	ip_info=$(ip addr show dev ${nic} | awk '/inet /{print$2}' | sed -n ${del_ip_id}p)
	system_version ip_del ${nic} ${ip_info}
elif [ ${input} -eq 3 ];then
	public_nic=$(ip route show | awk '/default/{print$5}' | head -n 1)
	read -p "输入需要更新的网关地址: " gw_ip
	checkip ${gw_ip}
	system_version change_gw
elif [ ${input} -eq 4 ];then
	read -p "输入需要更换的SSH端口[1-65535]: " ssh_port
	check_id ${ssh_port} 65535 "输入端口不在范围内"
	change_ssh_port ${ssh_port}
elif [ ${input} -eq 5 ];then
	read -p "输入需要更换的主机名: " hostname
	if [ -z ${hostname} ];then
		echo "输入为空"
		exit 1
	fi
	change_hostname ${hostname}
fi
