From 60d3fc92d4cc9efe5ffdf7fac74afeb40e400848 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 22 Jun 2022 17:33:29 +0800 Subject: [PATCH] network manager config --- pkg/app/agent/main.go | 79 +++++++- pkg/app/server/agentmanager/agent.go | 54 +++++- .../agentmanager/agentcontroller/file.go | 102 +++++++++- pkg/app/server/router/router.go | 2 + pkg/app/server/service/fileservice.go | 89 +++++++-- pkg/utils/message/protocol/message.go | 10 +- pkg/utils/os/network.go | 183 ++++++++++++++++++ pkg/utils/os/repo.go | 21 +- 8 files changed, 505 insertions(+), 35 deletions(-) diff --git a/pkg/app/agent/main.go b/pkg/app/agent/main.go index 9ed7a761..45f556aa 100644 --- a/pkg/app/agent/main.go +++ b/pkg/app/agent/main.go @@ -1043,10 +1043,10 @@ func regitsterHandler(c *network.SocketClient) { return c.Send(resp_msg) } }) - c.BindHandler(protocol.GetNetWorkFile, func(c *network.SocketClient, msg *protocol.Message) error { + c.BindHandler(protocol.GetNetWorkConnectInfo, func(c *network.SocketClient, msg *protocol.Message) error { fmt.Println("process agent info command:", msg.String()) - network, err := uos.GetFiles(model.NetWorkPath) + network, err := uos.ConfigNetworkConnect() if err != nil { resp_msg := &protocol.Message{ UUID: msg.UUID, @@ -1056,18 +1056,79 @@ func regitsterHandler(c *network.SocketClient) { } return c.Send(resp_msg) } else { - data := make(map[string]string, 0) - for _, n := range network { - if ok := strings.Contains(n, "ifcfg-e"); !ok { - continue - } - data = map[string]string{"path": model.NetWorkPath, "type": "network", "name": n} + + resp_msg := &protocol.Message{ + UUID: msg.UUID, + Type: msg.Type, + Status: 0, + Data: network, } + return c.Send(resp_msg) + } + }) + c.BindHandler(protocol.GetNetWorkConnInfo, func(c *network.SocketClient, msg *protocol.Message) error { + fmt.Println("process agent info command:", msg.String()) + + network, err := uos.GetNetworkConnInfo() + if err != nil { resp_msg := &protocol.Message{ UUID: msg.UUID, Type: msg.Type, Status: 0, - Data: data, + Error: err.Error(), + } + return c.Send(resp_msg) + } else { + resp_msg := &protocol.Message{ + UUID: msg.UUID, + Type: msg.Type, + Status: 0, + Data: network, + } + return c.Send(resp_msg) + } + }) + c.BindHandler(protocol.RestartNetWork, func(c *network.SocketClient, msg *protocol.Message) error { + fmt.Println("process agent info command:", msg.String()) + + msgg := msg.Data.(string) + err := uos.RestartNetwork(msgg) + if err != nil { + resp_msg := &protocol.Message{ + UUID: msg.UUID, + Type: msg.Type, + Status: 0, + Error: err.Error(), + } + return c.Send(resp_msg) + } else { + resp_msg := &protocol.Message{ + UUID: msg.UUID, + Type: msg.Type, + Status: 0, + Data: struct{}{}, + } + return c.Send(resp_msg) + } + }) + c.BindHandler(protocol.GetNICName, func(c *network.SocketClient, msg *protocol.Message) error { + fmt.Println("process agent info command:", msg.String()) + + nic_name, err := uos.GetNICName() + if err != nil { + resp_msg := &protocol.Message{ + UUID: msg.UUID, + Type: msg.Type, + Status: 0, + Error: err.Error(), + } + return c.Send(resp_msg) + } else { + resp_msg := &protocol.Message{ + UUID: msg.UUID, + Type: msg.Type, + Status: 0, + Data: nic_name, } return c.Send(resp_msg) } diff --git a/pkg/app/server/agentmanager/agent.go b/pkg/app/server/agentmanager/agent.go index c1c04435..3be26a8d 100644 --- a/pkg/app/server/agentmanager/agent.go +++ b/pkg/app/server/agentmanager/agent.go @@ -865,11 +865,27 @@ func (a *Agent) GetRepoSource() (interface{}, string, error) { return resp_message.Data, resp_message.Error, nil } -// 远程获取agent端的repo文件 -func (a *Agent) GetNetWorkFile() (interface{}, string, error) { +// 远程获取agent端的网络连接信息 +func (a *Agent) GetNetWorkConnectInfo() (interface{}, string, error) { + msg := &protocol.Message{ + UUID: uuid.New().String(), + Type: protocol.GetNetWorkConnectInfo, + Data: struct{}{}, + } + + resp_message, err := a.sendMessage(msg, true, 0) + if err != nil { + logger.Error("failed to run script on agent") + return nil, "", err + } + return resp_message.Data, resp_message.Error, nil +} + +// 获取agent的基础网络配置 +func (a *Agent) GetNetWorkConnInfo() (interface{}, string, error) { msg := &protocol.Message{ UUID: uuid.New().String(), - Type: protocol.GetNetWorkFile, + Type: protocol.GetNetWorkConnInfo, Data: struct{}{}, } @@ -881,6 +897,38 @@ func (a *Agent) GetNetWorkFile() (interface{}, string, error) { return resp_message.Data, resp_message.Error, nil } +// 获取网卡名字 +func (a *Agent) GetNICName() (interface{}, string, error) { + msg := &protocol.Message{ + UUID: uuid.New().String(), + Type: protocol.GetNICName, + Data: struct{}{}, + } + + resp_message, err := a.sendMessage(msg, true, 0) + if err != nil { + logger.Error("failed to run script on agent") + return nil, "", err + } + return resp_message.Data, resp_message.Error, nil +} + +// 重启网卡配置 +func (a *Agent) RestartNetWork(NIC string) (interface{}, string, error) { + msg := &protocol.Message{ + UUID: uuid.New().String(), + Type: protocol.RestartNetWork, + Data: NIC, + } + + resp_message, err := a.sendMessage(msg, true, 0) + if err != nil { + logger.Error("failed to run script on agent") + return nil, "", err + } + return resp_message.Data, resp_message.Error, nil +} + // 查看配置文件内容 func (a *Agent) ReadFile(filepath string) (interface{}, string, error) { msg := &protocol.Message{ diff --git a/pkg/app/server/agentmanager/agentcontroller/file.go b/pkg/app/server/agentmanager/agentcontroller/file.go index b04ae6ee..9e41edaf 100644 --- a/pkg/app/server/agentmanager/agentcontroller/file.go +++ b/pkg/app/server/agentmanager/agentcontroller/file.go @@ -21,9 +21,11 @@ import ( "github.com/gin-gonic/gin" "openeluer.org/PilotGo/PilotGo/pkg/app/server/agentmanager" + "openeluer.org/PilotGo/PilotGo/pkg/app/server/controller" "openeluer.org/PilotGo/PilotGo/pkg/app/server/dao" "openeluer.org/PilotGo/PilotGo/pkg/app/server/model" "openeluer.org/PilotGo/PilotGo/pkg/app/server/service" + uos "openeluer.org/PilotGo/PilotGo/pkg/utils/os" "openeluer.org/PilotGo/PilotGo/pkg/utils/response" ) @@ -45,7 +47,6 @@ func ReadFile(c *gin.Context) { } func GetAgentRepo(c *gin.Context) { - uuid := c.Query("uuid") agent := agentmanager.GetAgent(uuid) if agent == nil { @@ -61,6 +62,105 @@ func GetAgentRepo(c *gin.Context) { response.JSON(c, http.StatusOK, http.StatusOK, repos, "获取到repo源") } +func GetAgentNetworkConnect(c *gin.Context) { + uuid := c.Query("uuid") + agent := agentmanager.GetAgent(uuid) + if agent == nil { + response.Fail(c, nil, "获取uuid失败!") + return + } + + net, Err, err := agent.GetNetWorkConnInfo() + if len(Err) != 0 || err != nil { + response.Fail(c, nil, Err) + return + } + response.JSON(c, http.StatusOK, http.StatusOK, net, "获取到网络连接信息") +} + +func ConfigNetworkConnect(c *gin.Context) { + var network uos.NetworkConfig + c.Bind(&network) + + ip_assignment := network.BootProto + if len(ip_assignment) == 0 { + response.Fail(c, nil, "ip分配方式不能为空") + return + } + ipv4_addr := network.IPAddr + if len(ip_assignment) == 0 { + response.Fail(c, nil, "ipv4地址不能为空") + return + } + ipv4_netmask := network.NetMask + if len(ip_assignment) == 0 { + response.Fail(c, nil, "ipv4子网掩码不能为空") + return + } + ipv4_gateway := network.GateWay + if len(ip_assignment) == 0 { + response.Fail(c, nil, "ipv4网关不能为空") + return + } + ipv4_dns1 := network.DNS1 + if len(ip_assignment) == 0 { + response.Fail(c, nil, "ipv4 DNS1 不能为空") + return + } + + agent := agentmanager.GetAgent(network.MachineUUID) + if agent == nil { + response.Fail(c, nil, "获取uuid失败!") + return + } + + nic_name, Err, err := agent.GetNICName() + if len(Err) != 0 || err != nil { + response.Fail(c, nil, Err) + return + } + + oldnet, Err, err := agent.GetNetWorkConnectInfo() + if len(Err) != 0 || err != nil { + response.Fail(c, nil, Err) + return + } + oldnets := controller.InterfaceToSlice(oldnet) + + switch ip_assignment { + case "static": + text := service.NetworkStatic(oldnets, ipv4_addr, ipv4_netmask, ipv4_gateway, ipv4_dns1, network.DNS2) + _, Err, err := agent.UpdateFile(model.NetWorkPath, nic_name.(string), text) + if len(Err) != 0 || err != nil { + response.JSON(c, http.StatusOK, http.StatusOK, nil, Err) + return + } + _, Err, err = agent.RestartNetWork(nic_name.(string)) + if len(Err) != 0 || err != nil { + response.JSON(c, http.StatusOK, http.StatusOK, nil, Err) + return + } + response.JSON(c, http.StatusOK, http.StatusOK, nil, "网络配置更新成功") + + case "dhcp": + text := service.NetworkDHCP(oldnets) + _, Err, err := agent.UpdateFile(model.NetWorkPath, nic_name.(string), text) + if len(Err) != 0 || err != nil { + response.JSON(c, http.StatusOK, http.StatusOK, nil, Err) + return + } + _, Err, err = agent.RestartNetWork(nic_name.(string)) + if len(Err) != 0 || err != nil { + response.JSON(c, http.StatusOK, http.StatusOK, nil, Err) + return + } + response.JSON(c, http.StatusOK, http.StatusOK, nil, "网络配置更新成功") + + default: + response.Fail(c, nil, "请重新检查ip分配方式") + } +} + func FileBroadcastToAgents(c *gin.Context) { var fb model.FileBroadcast c.Bind(&fb) diff --git a/pkg/app/server/router/router.go b/pkg/app/server/router/router.go index 5468c3a1..a3b34b4d 100644 --- a/pkg/app/server/router/router.go +++ b/pkg/app/server/router/router.go @@ -78,6 +78,7 @@ func SetupRouter() *gin.Engine { macDetails.GET("/os_basic", agentcontroller.OsBasic) macDetails.GET("/firewall_config", agentcontroller.FirewalldConfig) macDetails.GET("/repos", agentcontroller.GetAgentRepo) + macDetails.GET("/net", agentcontroller.GetAgentNetworkConnect) } macBasicModify := router.Group("cluster/macList/agent") @@ -105,6 +106,7 @@ func SetupRouter() *gin.Engine { macBasicModify.GET("/firewall_stop", agentcontroller.FirewalldStop) macBasicModify.POST("/firewall_addzp", agentcontroller.FirewalldZonePortAdd) macBasicModify.POST("/firewall_delzp", agentcontroller.FirewalldZonePortDel) + macBasicModify.POST("/network", agentcontroller.ConfigNetworkConnect) } monitor := router.Group("prometheus") diff --git a/pkg/app/server/service/fileservice.go b/pkg/app/server/service/fileservice.go index ed87b0cd..9dd17d5f 100644 --- a/pkg/app/server/service/fileservice.go +++ b/pkg/app/server/service/fileservice.go @@ -16,25 +16,10 @@ package service import ( "fmt" + "strings" "time" ) -// ANSI用GBK解码,解决windows => linux 中文乱码 -// func ANSI2Gbk(fileName string) ([]byte, error) { -// fi, err := os.Open(fileName) -// if err != nil { -// return nil, err -// } -// defer fi.Close() - -// decoder := mahonia.NewDecoder("gbk") // 把原来ANSI格式的文本文件里的字符,用gbk进行解码。 -// fd, err := ioutil.ReadAll(decoder.NewReader(fi)) -// if err != nil { -// return nil, err -// } -// return fd, nil -// } - // 获取时间的日期函数 => 20200426-17:36:04 func NowTime() string { time := time.Now() @@ -47,3 +32,75 @@ func NowTime() string { nowtime := fmt.Sprintf("%d%02d%02d-%02d:%02d:%02d", year, month, day, hour, minute, second) return nowtime } + +// dhcp方式配置网络 +func NetworkDHCP(net []interface{}) (text string) { + for _, n := range net { + nn := n.(map[string]interface{}) + for key, value := range nn { + if key == "BOOTPROTO" { + text += key + "=" + "dhcp" + "\n" + } else if key == "IPADDR" { + break + } else if key == "NETMASK" { + break + } else if key == "GATEWAY" { + break + } else if key == "DNS1" { + break + } else if key == "DNS2" { + break + } else { + text += key + "=" + value.(string) + "\n" + } + } + } + return +} + +// static方式配置网络 +func NetworkStatic(net []interface{}, ip string, netmask string, gateway string, dns1 string, dns2 string) (text string) { + for _, n := range net { + nn := n.(map[string]interface{}) + for key, value := range nn { + if key == "BOOTPROTO" { + text += key + "=" + "static" + "\n" + } else if key == "IPADDR" { + text += key + "=" + ip + "\n" + } else if key == "NETMASK" { + text += key + "=" + netmask + "\n" + } else if key == "GATEWAY" { + text += key + "=" + gateway + "\n" + } else if key == "DNS1" { + text += key + "=" + dns1 + "\n" + } else if key == "DNS2" && len(dns2) != 0 { + text += key + "=" + dns2 + "\n" + } else { + text += key + "=" + value.(string) + "\n" + } + } + } + if ok := strings.Contains(text, "IPADDR"); !ok { + t := "IPADDR" + "=" + ip + "\n" + text += t + } + if ok := strings.Contains(text, "NETMASK"); !ok { + t := "NETMASK" + "=" + netmask + "\n" + text += t + } + if ok := strings.Contains(text, "GATEWAY"); !ok { + t := "GATEWAY" + "=" + gateway + "\n" + text += t + } + if ok := strings.Contains(text, "DNS1"); !ok { + t := "DNS1" + "=" + dns1 + "\n" + text += t + } + if ok := strings.Contains(text, "DNS2"); !ok { + if len(dns2) != 0 { + t := "DNS2" + "=" + dns2 + "\n" + text += t + } + } + return +} diff --git a/pkg/utils/message/protocol/message.go b/pkg/utils/message/protocol/message.go index 23c0fa9a..df217d70 100644 --- a/pkg/utils/message/protocol/message.go +++ b/pkg/utils/message/protocol/message.go @@ -118,10 +118,16 @@ const ( ReadFile = 53 // 编辑配置文件 EditFile = 54 - // 获取网络配置文件 - GetNetWorkFile = 55 + // 获取网络连接信息 + GetNetWorkConnectInfo = 55 // 文件修改监控 FileMonitor = 56 + // 基础网络连接配置 + GetNetWorkConnInfo = 57 + //重启网卡 + RestartNetWork = 58 + //获取网卡名字 + GetNICName = 59 ) type Message struct { diff --git a/pkg/utils/os/network.go b/pkg/utils/os/network.go index ef8bdb43..d59e0b78 100644 --- a/pkg/utils/os/network.go +++ b/pkg/utils/os/network.go @@ -21,6 +21,7 @@ import ( "strings" "github.com/shirou/gopsutil/net" + "openeluer.org/PilotGo/PilotGo/pkg/app/server/model" "openeluer.org/PilotGo/PilotGo/pkg/logger" "openeluer.org/PilotGo/PilotGo/pkg/utils" ) @@ -45,6 +46,32 @@ type NetInterfaceCard struct { MacAddr string } +type NetworkConfig struct { + NetworkType string `json:"type"` //以太网、无线网 + ProxyMethod string `json:"proxy_method"` + BrowserOnly string `json:"browser_only"` + DefRoute string `json:"defroute"` + IPV4_Failure_Fatal string `json:"ipv4_failure_fatal"` + Name string `json:"name"` //接口名称 + UUID string `json:"uuid"` //唯一识别码 + Device string `json:"device"` //网卡设备名字 + OnBoot string `json:"onboot"` //是否随网络服务启动当前网卡生效 + + IPV6Init string `json:"ipv6_init"` //ipv6是否启用 + IPV6_Autoconf string `json:"ipv6_autoconf"` + IPV6_DefRoute string `json:"ipv6_defroute"` + IPV6_Failure_Fatal string `json:"ipv6_failure_fatal"` + IPv6_Addr_Gen_Mode string `json:"ipv6_addr_gen_mode"` + + MachineUUID string `json:"macUUID"` + BootProto string `json:"BOOTPROTO"` //dhcp或者static + IPAddr string `json:"IPADDR"` + NetMask string `json:"NETMASK"` + GateWay string `json:"GATEWAY"` + DNS1 string `json:"DNS1"` + DNS2 string `json:"DNS2"` +} + //获取当前TCP网络连接信息 func GetTCP() ([]NetConnect, error) { info, err := net.Connections("tcp") @@ -140,3 +167,159 @@ func GetNICConfig() ([]NetInterfaceCard, error) { } return NICConfig, nil } + +// 配置网络连接 +func ConfigNetworkConnect() (interface{}, error) { + filePath := "/home" + network, err := GetFiles(filePath) + if err != nil { + return "", fmt.Errorf("获取网络配置文件失败:%s", err) + } + var filename string + for _, n := range network { + if ok := strings.Contains(n, "ifcfg-e"); !ok { + continue + } + filename = n + } + + text, err := utils.RunCommand("cat " + filePath + "/" + filename) + if err != nil { + return "", fmt.Errorf("读取网络配置数据失败:%s", err) + } + + var oldnet []map[string]string + lines := strings.Split(text, "\n") + for _, line := range lines { + strSlice := strings.Split(line, "=") + if len(strSlice) == 1 { + continue + } + if strings.Contains(strSlice[0], "#") { + continue + } + net := map[string]string{ + strSlice[0]: strSlice[1], + } + oldnet = append(oldnet, net) + } + return oldnet, nil +} + +func GetNetworkConnInfo() (interface{}, error) { + netPath, err := GetFiles(model.NetWorkPath) + if err != nil { + return nil, fmt.Errorf("获取网络配置源文件失败:%s", err) + } + var filename string + for _, n := range netPath { + if ok := strings.Contains(n, "ifcfg-e"); !ok { + continue + } + filename = n + } + + result, _ := utils.RunCommand("cat " + model.NetWorkPath + "/" + filename + " | egrep 'BOOTPROTO=.*'") + ip_assignment_method := strings.Split(result, "=")[1] + + var network = &NetworkConfig{} + switch strings.Replace(ip_assignment_method, "\n", "", -1) { + case "static": + tmp, err := utils.RunCommand("cat " + model.NetWorkPath + "/" + filename) + if err != nil { + return nil, fmt.Errorf("读取网络配置源数据失败:%s", err) + } + lines := strings.Split(tmp, "\n") + for _, line := range lines { + line = strings.TrimSpace(line) + strSlice := strings.Split(line, "=") + if len(strSlice) == 1 { + continue + } + ModuleMatch(strSlice[0], strSlice[1], network) + } + case "dhcp": + IP, err := utils.RunCommand("hostname -I") + if err != nil { + return nil, fmt.Errorf("获取IP失败:%s", err) + } + str := strings.Split(IP, " ") + ip := str[0] + + gateway, err := utils.RunCommand("route -n |awk '{print $2}' | sed -n '3p'") + if err != nil { + return nil, fmt.Errorf("获取网关失败:%s", err) + } + + DNS, err := utils.RunCommand("cat /etc/resolv.conf | egrep 'nameserver' | awk '{print $2}'") + if err != nil { + return nil, fmt.Errorf("获取DNS失败:%s", err) + } + network.DNS1 = strings.Replace(DNS, "\n", "", -1) + network.BootProto = "dhcp" + network.IPAddr = ip + network.GateWay = strings.Replace(gateway, "\n", "", -1) + + default: + tmp, err := utils.RunCommand("cat " + model.NetWorkPath + "/" + filename) + if err != nil { + return nil, fmt.Errorf("读取网络配置源数据失败:%s", err) + } + lines := strings.Split(tmp, "\n") + for _, line := range lines { + line = strings.TrimSpace(line) + strSlice := strings.Split(line, "=") + if len(strSlice) == 1 { + continue + } + ModuleMatch(strSlice[0], strSlice[1], network) + } + } + return network, nil +} + +func GetNICName() (interface{}, error) { + network, err := GetFiles(model.NetWorkPath) + if err != nil { + return nil, fmt.Errorf("获取网络配置文件失败:%s", err) + } + var filename string + for _, n := range network { + if ok := strings.Contains(n, "ifcfg-e"); !ok { + continue + } + filename = n + } + + return filename, nil +} + +func RestartNetwork(nic string) error { + _, err := utils.RunCommand("nmcli c reload") + if err != nil { + return fmt.Errorf("网络配置文件重载失败:%s", err) + } + + str := "nmcli c up " + strings.Split(nic, "-")[1] + _, err = utils.RunCommand(str) + if err != nil { + return fmt.Errorf("网络配置文件未生效:%s", err) + } + return nil +} + +func ModuleMatch(key string, value string, network *NetworkConfig) { + if key == "IPADDR" { + network.IPAddr = value + } else if key == "NetMask" { + network.NetMask = value + } else if key == "GateWay" { + network.GateWay = value + } else if key == "DNS1" { + network.DNS1 = value + } else if key == "DNS2" { + network.DNS2 = value + } else if key == "BootProto" { + network.BootProto = value + } +} diff --git a/pkg/utils/os/repo.go b/pkg/utils/os/repo.go index 82efb9af..34e92f29 100644 --- a/pkg/utils/os/repo.go +++ b/pkg/utils/os/repo.go @@ -38,6 +38,13 @@ func GetRepoSource() (interface{}, error) { var repo string for _, repo = range repos { + if SysPlatform == "centos" { + reg := regexp.MustCompile(`(?i)(` + SysPlatform + "-base" + `)`) + ok := reg.MatchString(repo) + if ok { + break + } + } reg := regexp.MustCompile(`(?i)(` + SysPlatform + `)`) ok := reg.MatchString(repo) if ok { @@ -51,16 +58,22 @@ func GetRepoSource() (interface{}, error) { } reg1 := regexp.MustCompile(`name=.*`) - reg2 := regexp.MustCompile(`baseurl=.*`) - textType := reg1.FindAllString(text, -1) - BaseURL := reg2.FindAllString(text, -1) + + var reg2 *regexp.Regexp + var BaseURL []string + reg2 = regexp.MustCompile(`mirrorlist=http.*`) + BaseURL = reg2.FindAllString(text, -1) + if len(BaseURL) == 0 { + reg2 = regexp.MustCompile(`baseurl=.*`) + BaseURL = reg2.FindAllString(text, -1) + } datas := make([]map[string]string, 0) for i := 0; i < len(textType); i++ { data := map[string]string{ "name": strings.Split(textType[i], "=")[1], - "baseurl": strings.Split(BaseURL[i], "=")[1], + "baseurl": "http" + strings.Split(BaseURL[i], "http")[1], } datas = append(datas, data) } -- Gitee