Go实现配置CentOS7.8网络
二级标题设计原理:
使用命令行的形式指定 网络地址,子网掩码,网关,网卡,以及是否开启日志显示,这里我们需要采用go标准库中的"flag"库来实现,命令实现对程序的传参。
-
网络地址 -n:必填参数,没填直接使用panic报错
-
网关参数 -g:默认值:参数没输入则默认使用ip地址的默认网关(x.x.x.1),网关的修改决定直接删除
rm -rf /etc/sysconfig/network
文件,并使用echo命令配合重定向来追加(这里有个坑后续会提到) -
网卡名 -c:默认值:公司硬件不同型号/虚拟机
设备管理网卡名口eth0/eth1/mgmt1/enp1s0
决定采取遍历的形式先遍历一遍如果找到了
就直接使用,如果没找到则需要输入网卡名参数。 -
子网掩码 -m:默认值:255.255.255.0,如果不是则输入参数。
-
debug模式 -d: 默认值:n ,如果需要开启则输入y
确定以上自己的程序需求之后开始书写代码
1.定义六个变量用来接受五个参数的传入
var network string
var netmask string
var netcard string
var gateway string
var debug_mode_temp string
var debug_mode bool
2.开始设置传入传输的键,默认值以及帮助中的提示
函数说明:flag.StringVar(接收到值赋值到内存中的变量,命令行中的键,默认值,帮助提示)
flag.StringVar(&network, "n", "x.x.x.x", "网络地址 | ip address")
flag.StringVar(&netmask, "m", "255.255.255.0", "子网掩码 | network mask")
flag.StringVar(&netcard, "c", "eth1/eth1/mgmt1", "网卡名 | network card ")
flag.StringVar(&gateway, "g", "x.x.x.1", "网关 | gateway")
flag.StringVar(&debug_mode_temp, "d", "n", "开启debug模式 y/s |start debug mode y/s")
//开始解析所有参数的并赋值
flag.Parse()
//打印传入的参数方便我们调试使用
fmt.Println(network,netmask,netcard,gateway,debug_mode_temp)
3.到这里我们就处理了命令行传参,我们就应该处理下得到的参数
比如如果没传网关我们就默认使用网络地址转化成网关(x.x.x.1),没有传网卡名我们尝试在机器上读取是否存在eth0/eth1/mgmt1/enp1s0
这些网卡
show code!
//如果网络地址为默认值就是没传参,直接报错并退出程序
if string(network) == "x.x.x.x" {
panic("请指定 -n 必须输" + "入网络地址")
}
if string(gateway) == "x.x.x.1" {
//寻找最后一个点切片并追加.1
gateway = network[:strings.LastIndex(network, ".")] + ".1"
}
//如果网卡名为默认值,就是没传参数,然后取匹配{"zeth1", "eth0", "eth1", "mgmt1", "enp1s0"},如果没找到则报错并退出
if string(netcard) == "eth1/eth1/mgmt1" {
//这里踩到一个坑:最后直接封装成一个函数了
netcard_temp, err := find_netcard_name()
if err == nil {
netcard = netcard_temp
} else {
panic("请指定 -c 并输入网卡名称")
}
}
//输入值为y则后续执行的时候打印执行过程,否则不答应
if string(debug_mode_temp)!="y" {
debug_mode = false
}else {
debug_mode = true
}
//打印预期结果
fmt.Println("修改预期目标:\n")
fmt.Println(" 网络地址:" + network)
fmt.Println(" 子网掩码:" + netmask)
fmt.Println(" 网卡名:" + netcard)
fmt.Println(" 网关:" + gateway + "\n")
//所有使用run_cmd函数执行命令,
fmt.Println("1.开始修改网关")
run_cmd("rm -rf /etc/sysconfig/network", debug_mode)
run_cmd("touch /etc/sysconfig/network", debug_mode)
run_cmd("echo GATEWAY="+gateway+">> /etc/sysconfig/network", debug_mode)
fmt.Println("2.开始修改网络")
card_path := "/etc/sysconfig/network-scripts/ifcfg-" + netcard
run_cmd("mv "+card_path+" "+card_path+".bak", debug_mode)
run_cmd("touch "+card_path, debug_mode)
run_cmd("echo DEVICE="+netcard+" >> "+card_path, debug_mode)
run_cmd("echo TYPE=Ethernet >> "+card_path, debug_mode)
run_cmd("echo ONBOOT=yes >> "+card_path, debug_mode)
run_cmd("echo IPV4_FAILURE_FATAL=yes >> "+card_path, debug_mode)
run_cmd("echo IPV6INIT=yes >> "+card_path, debug_mode)
run_cmd("echo IPADDR="+network+" >> "+card_path, debug_mode)
run_cmd("echo NETMASK="+netmask+" >> "+card_path, debug_mode)
fmt.Println("3.开始重启网卡")
run_cmd("ifdown "+netcard, debug_mode)
run_cmd("ifup "+netcard, debug_mode)
//函数执行ip a用来获取是否存在预置的网卡名,如果存在则返回网卡名,如果不存在则返回错误
func find_netcard_name() (string, error) {
cmd := exec.Command("ip", "a")
out, _ := cmd.CombinedOutput()
name_list := []string{"zeth1", "eth0", "eth1", "mgmt1", "enp1s0"}
for _, v := range name_list {
if strings.Contains(string(out), v) {
return v, nil
}
}
//返回错误
return "", errors.New("未自动捕获到网卡名,请手动输入网卡。")
}
设备执行命令的函数:
func run_cmd(cmd string, mode bool) {
if mode == true {
fmt.Println(" 执行命令:" + cmd)
}
err := exec.Command("bash", "-c", cmd).Run()
if err != nil {
fmt.Println(err)
}
}
附:
编译linux的二进制可执行文件
set CGO_ENABLED=0
set GOOS=linux
go build main.go
github:
https://github.com/Xarby/ModifyNetwork
所有代码可查看附件main.go
实现效果:
- 帮助
- 执行修改网络
- 切换效果