diff --git a/plugin/http_server/dto/etcnet_config.go b/plugin/http_server/dto/etcnet_config.go new file mode 100644 index 000000000..19ff76081 --- /dev/null +++ b/plugin/http_server/dto/etcnet_config.go @@ -0,0 +1,11 @@ +package service + +type EtcNetworkConfig struct { + Name string `json:"name,omitempty"` + Interface string `json:"interface,omitempty"` + Address string `json:"address,omitempty"` + Netmask string `json:"netmask,omitempty"` + Gateway string `json:"gateway,omitempty"` + DNS []string `json:"dns,omitempty"` + DHCPEnabled bool `json:"dhcp_enabled,omitempty"` +} diff --git a/plugin/http_server/dto/netplan_config.go b/plugin/http_server/dto/netplan_config.go new file mode 100644 index 000000000..fafcf1ab3 --- /dev/null +++ b/plugin/http_server/dto/netplan_config.go @@ -0,0 +1,16 @@ +package service + +type hwInterface struct { + Dhcp4 bool `yaml:"dhcp4" json:"dhcp4,omitempty"` + Addresses []string `yaml:"addresses" json:"addresses,omitempty"` + Gateway4 string `yaml:"gateway4" json:"gateway4,omitempty"` + Nameservers []string `yaml:"nameservers" json:"nameservers,omitempty"` +} +type network struct { + Version int `yaml:"version" json:"version,omitempty"` + Renderer string `yaml:"renderer" json:"renderer,omitempty"` + Ethernets map[string]hwInterface `yaml:"ethernets" json:"ethernets,omitempty"` +} +type NetplanConfigDto struct { + Network network `yaml:"network" json:"network,omitempty"` +} diff --git a/plugin/http_server/http_api_server.go b/plugin/http_server/http_api_server.go index 212c46943..1a648c3ba 100644 --- a/plugin/http_server/http_api_server.go +++ b/plugin/http_server/http_api_server.go @@ -65,6 +65,7 @@ func (s *HttpApiServer) registerModel() { &model.MGenericGroup{}, &model.MGenericGroupRelation{}, &model.MProtocolApp{}, + &model.MNetworkConfig{}, ) } diff --git a/plugin/http_server/model/dto.go b/plugin/http_server/model/dto.go deleted file mode 100644 index f707f6d94..000000000 --- a/plugin/http_server/model/dto.go +++ /dev/null @@ -1,8 +0,0 @@ -package model - -// NetInterfaceInfo 网络适配器信息 -type NetInterfaceInfo struct { - Name string `json:"name,omitempty"` - Mac string `json:"mac,omitempty"` - Addr string `json:"addr,omitempty"` -} diff --git a/plugin/http_server/model/model.go b/plugin/http_server/model/model.go index be9656415..b7893836c 100644 --- a/plugin/http_server/model/model.go +++ b/plugin/http_server/model/model.go @@ -230,3 +230,12 @@ type MProtocolApp struct { Type string `gorm:"not null"` // 类型: IN OUT DEVICE APP Content string `gorm:"not null"` // 协议包的内容 } + +/* +* +* 系统配置参数, 直接以String保存,完了以后再加工成Dto结构体 +* + */ +type MNetworkConfig struct { + Network string `yaml:"network" json:"network,omitempty"` +} diff --git a/plugin/http_server/service/system_config_service.go b/plugin/http_server/service/system_config_service.go deleted file mode 100644 index 8c92631b0..000000000 --- a/plugin/http_server/service/system_config_service.go +++ /dev/null @@ -1,207 +0,0 @@ -package service - -import ( - "encoding/json" - "fmt" - "os" - "strings" - - "gopkg.in/yaml.v2" -) - -/* -* Ubuntu 18 以后的版本才支持 -/etc/netplan/01-netcfg.yaml -network: - version: 2 - renderer: networkd - ethernets: - enp0s9: - dhcp4: no - addresses: - - 192.168.121.221/24 - gateway4: 192.168.121.1 - nameservers: - addresses: [8.8.8.8, 1.1.1.1] -* -*/ -// -// 读取Ip状态(静态/动态) yaml -type Interface struct { - Dhcp4 string `yaml:"dhcp4" json:"dhcp4,omitempty"` - Addresses []string `yaml:"addresses" json:"addresses,omitempty"` - Gateway4 string `yaml:"gateway4" json:"gateway4,omitempty"` - Nameservers []string `yaml:"nameservers" json:"nameservers,omitempty"` -} -type Network struct { - Version int `yaml:"version" json:"version,omitempty"` - Renderer string `yaml:"renderer" json:"renderer,omitempty"` - Ethernets map[string]Interface `yaml:"ethernets" json:"ethernets,omitempty"` -} -type NetplanConfig struct { - Network Network `yaml:"network" json:"network,omitempty"` -} - -func NewNetplanConfig() *NetplanConfig { - return &NetplanConfig{ - Network: Network{ - Version: 2, - Renderer: "NetworkManager", - Ethernets: map[string]Interface{ - "eth0": { - Dhcp4: "no", - Addresses: []string{"192.168.128.1/24"}, - Gateway4: "192.168.128.1", - Nameservers: []string{"114.114.114.114"}, - }, - "eth1": { - Dhcp4: "no", - Addresses: []string{"192.168.128.1/24"}, - Gateway4: "192.168.128.2", - Nameservers: []string{"114.114.114.114"}, - }, - }, - }, - } -} -func (nc *NetplanConfig) FromJson(jsons string) error { - return json.Unmarshal([]byte(jsons), nc) -} - -func (nc *NetplanConfig) FromYaml(jsons string) error { - return yaml.Unmarshal([]byte(jsons), nc) -} - -func (nc *NetplanConfig) JsonString() string { - b, _ := json.Marshal(nc) - return string(b) -} -func (nc *NetplanConfig) YAMLString() string { - b, _ := yaml.Marshal(nc) - return string(b) -} - -// # /etc/network/interfaces -//------------------------------------------- -// Static -//------------------------------------------- -// auto lo -// iface lo inet loopback -// auto eth0 -// iface eth0 inet static -// address 192.168.1.100 -// netmask 255.255.255.0 -// gateway 192.168.1.1 -// dns-nameservers 8.8.8.8 8.8.4.4 - -//------------------------------------------- -// DHCP -//------------------------------------------- -// auto lo -// iface lo inet loopback -// auto eth0 -// iface eth0 inet dhcp - -type EtcNetworkConfig struct { - Name string `json:"name,omitempty"` - Interface string `json:"interface,omitempty"` - Address string `json:"address,omitempty"` - Netmask string `json:"netmask,omitempty"` - Gateway string `json:"gateway,omitempty"` - DNS []string `json:"dns,omitempty"` - DHCPEnabled bool `json:"dhcp_enabled,omitempty"` -} - -func (nc *EtcNetworkConfig) JsonString() string { - b, _ := json.Marshal(nc) - return string(b) -} - -/* -* -* 解析配置文件 -* - */ -func ParseEtcFile(content string) []EtcNetworkConfig { - lines := strings.Split(content, "\n") - - var interfaces []EtcNetworkConfig - var currentInterface EtcNetworkConfig - - for _, line := range lines { - fields := strings.Fields(line) - if len(fields) == 0 { - continue - } - - switch fields[0] { - case "auto": - currentInterface = EtcNetworkConfig{Name: fields[1]} - case "iface": - if len(fields) < 3 { - continue - } - currentInterface.Interface = fields[2] - case "address": - if len(fields) < 2 { - continue - } - currentInterface.Address = fields[1] - case "netmask": - if len(fields) < 2 { - continue - } - currentInterface.Netmask = fields[1] - case "gateway": - if len(fields) < 2 { - continue - } - currentInterface.Gateway = fields[1] - case "dns-nameservers": - if len(fields) < 2 { - continue - } - currentInterface.DNS = fields[1:] - case "dhcp": - if len(fields) > 1 && fields[1] == "dhcp" { - currentInterface.DHCPEnabled = true - } - } - - if len(currentInterface.Interface) > 0 { - interfaces = append(interfaces, currentInterface) - } - } - - return interfaces -} - -/* -* -* 将结构体写入配置文件 -* - */ -func WriteInterfaceConfig(filePath string, iface EtcNetworkConfig) error { - configLines := []string{ - "auto lo", - "iface lo inet loopback", - fmt.Sprintf("auto %s", iface.Name), - fmt.Sprintf("iface %s inet %s", iface.Interface, getInetType(iface.DHCPEnabled)), - } - - if !iface.DHCPEnabled { - configLines = append(configLines, fmt.Sprintf(" address %s", iface.Address)) - configLines = append(configLines, fmt.Sprintf(" netmask %s", iface.Netmask)) - configLines = append(configLines, fmt.Sprintf(" gateway %s", iface.Gateway)) - configLines = append(configLines, fmt.Sprintf(" dns-nameservers %s", strings.Join(iface.DNS, " "))) - } - - configText := strings.Join(configLines, "\n") - return os.WriteFile(filePath, []byte(configText), 0644) -} -func getInetType(dhcpEnabled bool) string { - if dhcpEnabled { - return "dhcp" - } - return "static" -} diff --git a/plugin/http_server/service/ubuntu16_network_service.go b/plugin/http_server/service/ubuntu16_network_service.go new file mode 100644 index 000000000..84a7c86cb --- /dev/null +++ b/plugin/http_server/service/ubuntu16_network_service.go @@ -0,0 +1,75 @@ +package service + +import ( + "encoding/json" + "fmt" + "os" + "strings" +) + +// # /etc/network/interfaces +//------------------------------------------- +// Static +//------------------------------------------- +// auto lo +// iface lo inet loopback +// auto eth0 +// iface eth0 inet static +// address 192.168.1.100 +// netmask 255.255.255.0 +// gateway 192.168.1.1 +// dns-nameservers 8.8.8.8 8.8.4.4 + +//------------------------------------------- +// DHCP +//------------------------------------------- +// auto lo +// iface lo inet loopback +// auto eth0 +// iface eth0 inet dhcp + +type EtcNetworkConfig struct { + Name string `json:"name,omitempty"` + Interface string `json:"interface,omitempty"` + Address string `json:"address,omitempty"` + Netmask string `json:"netmask,omitempty"` + Gateway string `json:"gateway,omitempty"` + DNS []string `json:"dns,omitempty"` + DHCPEnabled bool `json:"dhcp_enabled,omitempty"` +} + +func (nc *EtcNetworkConfig) JsonString() string { + b, _ := json.Marshal(nc) + return string(b) +} + +/* +* +* 将结构体写入配置文件 +sudo systemctl restart networking +sudo service networking restart +* +*/ +func ApplyConfig(iface EtcNetworkConfig) error { + configLines := []string{ + "auto lo", + "iface lo inet loopback", + fmt.Sprintf("auto %s", iface.Name), + fmt.Sprintf("iface %s inet %s", iface.Interface, func(dhcpEnabled bool) string { + if dhcpEnabled { + return "dhcp" + } + return "static" + }(iface.DHCPEnabled)), + } + + if !iface.DHCPEnabled { + configLines = append(configLines, fmt.Sprintf(" address %s", iface.Address)) + configLines = append(configLines, fmt.Sprintf(" netmask %s", iface.Netmask)) + configLines = append(configLines, fmt.Sprintf(" gateway %s", iface.Gateway)) + configLines = append(configLines, fmt.Sprintf(" dns-nameservers %s\n", strings.Join(iface.DNS, " "))) + } + + configText := strings.Join(configLines, "\n") + return os.WriteFile("/etc/network/interfaces", []byte(configText), 0644) +} diff --git a/plugin/http_server/service/ubuntu_netplan_network_service.go b/plugin/http_server/service/ubuntu_netplan_network_service.go new file mode 100644 index 000000000..a8b6af953 --- /dev/null +++ b/plugin/http_server/service/ubuntu_netplan_network_service.go @@ -0,0 +1,129 @@ +package service + +import ( + "encoding/json" + "os" + + "gopkg.in/yaml.v2" +) + +/* +* Ubuntu 18 以后的版本才支持 +/etc/netplan/01-netcfg.yaml +network: + version: 2 + renderer: networkd + ethernets: + enp0s9: + dhcp4: no + addresses: + - 192.168.121.221/24 + gateway4: 192.168.121.1 + nameservers: + addresses: [8.8.8.8, 1.1.1.1] +* +*/ +// +// 读取Ip状态(静态/动态) yaml +type Interface struct { + Dhcp4 bool `yaml:"dhcp4" json:"dhcp4,omitempty"` + Addresses []string `yaml:"addresses" json:"addresses,omitempty"` + Gateway4 string `yaml:"gateway4" json:"gateway4,omitempty"` + Nameservers []string `yaml:"nameservers" json:"nameservers,omitempty"` +} +type Network struct { + Version int `yaml:"version" json:"version,omitempty"` + Renderer string `yaml:"renderer" json:"renderer,omitempty"` + Ethernets map[string]Interface `yaml:"ethernets" json:"ethernets,omitempty"` +} +type NetplanConfig struct { + Network Network `yaml:"network" json:"network,omitempty"` +} + +/* +* + - 默认静态IP + 114DNS: + IPv4: 114.114.114.114, 114.114.115.115 + IPv6: 2400:3200::1, 2400:3200:baba::1 + 阿里云DNS: + IPv4: 223.5.5.5, 223.6.6.6 + 腾讯DNS: + IPv4: 119.29.29.29, 119.28.28.28 + 百度DNS: + IPv4: 180.76.76.76 + DNSPod DNS (也称为Dnspod Public DNS): + IPv4: 119.29.29.29, 182.254.116.116 +*/ +func DefaultStaticNetplanConfig() *NetplanConfig { + return &NetplanConfig{ + Network: Network{ + Version: 2, + Renderer: "NetworkManager", + Ethernets: map[string]Interface{ + "eth0": { + Dhcp4: false, + Addresses: []string{"192.168.128.1/24"}, + Gateway4: "192.168.128.1", + Nameservers: []string{"114.114.114.114", "8.8.8.8", "180.76.76.76"}, + }, + "eth1": { + Dhcp4: false, + Addresses: []string{"192.168.128.1/24"}, + Gateway4: "192.168.128.2", + Nameservers: []string{"114.114.114.114", "8.8.8.8", "180.76.76.76"}, + }, + }, + }, + } +} + +/* +* +* 默认 DHCP +* + */ +func DefaultDHCPNetplanConfig() *NetplanConfig { + return &NetplanConfig{ + Network: Network{ + Version: 2, + Renderer: "NetworkManager", + Ethernets: map[string]Interface{ + "eth0": { + Dhcp4: true, + }, + "eth1": { + Dhcp4: true, + }, + }, + }, + } +} +func (nc *NetplanConfig) FromJson(jsons string) error { + return json.Unmarshal([]byte(jsons), nc) +} + +func (nc *NetplanConfig) FromYaml(jsons string) error { + return yaml.Unmarshal([]byte(jsons), nc) +} + +func (nc *NetplanConfig) JsonString() string { + b, _ := json.Marshal(nc) + return string(b) +} +func (nc *NetplanConfig) YAMLString() string { + b, _ := yaml.Marshal(nc) + return string(b) +} + +/* +* +* 将配置写入文件并且重启网卡 +* + */ +func (nc *NetplanConfig) ApplyConfig() error { + // sudo netplan apply + // sudo systemctl restart systemd-networkd + // sudo service networking restart + return os.WriteFile("/etc/netplan/001-cfg.yaml", []byte(nc.YAMLString()), 0755) +} diff --git a/plugin/http_server/system_api.go b/plugin/http_server/system_api.go index d137ad8b1..1398e627d 100644 --- a/plugin/http_server/system_api.go +++ b/plugin/http_server/system_api.go @@ -2,7 +2,6 @@ package httpserver import ( "fmt" - "github.com/hootrhino/rulex/plugin/http_server/model" "net" "runtime" "strconv" @@ -286,15 +285,21 @@ func calculateCpuPercent(cpus []float64) float64 { return value } -func getAvailableInterfaces() ([]*model.NetInterfaceInfo, error) { +type NetInterfaceInfo struct { + Name string `json:"name,omitempty"` + Mac string `json:"mac,omitempty"` + Addr string `json:"addr,omitempty"` +} + +func getAvailableInterfaces() ([]NetInterfaceInfo, error) { interfaces, err := net.Interfaces() if err != nil { return nil, err } - netInterfaces := make([]*model.NetInterfaceInfo, 0, len(interfaces)) + netInterfaces := make([]NetInterfaceInfo, 0, len(interfaces)) for _, inter := range interfaces { - info := &model.NetInterfaceInfo{ + info := NetInterfaceInfo{ Name: inter.Name, Mac: inter.HardwareAddr.String(), } diff --git a/test/data/etcnet-static.conf b/test/data/etcnet-static.conf index 71e89f64b..83db178d0 100644 --- a/test/data/etcnet-static.conf +++ b/test/data/etcnet-static.conf @@ -1,8 +1,17 @@ +# local loopback auto lo iface lo inet loopback +# eth0 auto eth0 iface eth0 inet static address 192.168.1.100 netmask 255.255.255.0 gateway 192.168.1.1 - dns-nameservers 8.8.8.8 8.8.4.4 \ No newline at end of file + dns-nameservers 8.8.8.8 +# eth1 +auto eth1 +iface eth1 inet static + address 192.168.100.100 + netmask 255.255.255.0 + gateway 192.168.100.1 + dns-nameservers 8.8.8.8 114.114.114.114 \ No newline at end of file diff --git a/test/data/netplan-dhcp.yaml b/test/data/netplan-dhcp.yaml new file mode 100644 index 000000000..8520adcfb --- /dev/null +++ b/test/data/netplan-dhcp.yaml @@ -0,0 +1,8 @@ +network: + version: 2 + renderer: networkd + ethernets: + eth0: + dhcp4: true + eth1: + dhcp4: true diff --git a/test/data/netplan-static.yaml b/test/data/netplan-static.yaml new file mode 100644 index 000000000..b12c37025 --- /dev/null +++ b/test/data/netplan-static.yaml @@ -0,0 +1,16 @@ +network: + version: 2 + renderer: networkd + ethernets: + eth0: + addresses: + - 192.168.1.100/24 + gateway4: 192.168.1.1 + nameservers: + addresses: [8.8.8.8, 8.8.4.4] + eth1: + addresses: + - 10.0.0.100/24 + gateway4: 10.0.0.1 + nameservers: + addresses: [8.8.8.8, 8.8.4.4] diff --git a/test/data/netplan.yaml b/test/data/netplan.yaml deleted file mode 100644 index 5b8732661..000000000 --- a/test/data/netplan.yaml +++ /dev/null @@ -1,11 +0,0 @@ -network: - version: 2 - renderer: networkd - ethernets: - enp0s9: - dhcp4: no - addresses: - - 192.168.121.221/24 - gateway4: 192.168.121.1 - nameservers: - addresses: [8.8.8.8, 1.1.1.1] \ No newline at end of file diff --git a/test/linux_network_config_test.go b/test/linux_network_config_test.go index 6be17a524..712e55718 100644 --- a/test/linux_network_config_test.go +++ b/test/linux_network_config_test.go @@ -2,6 +2,7 @@ package test import ( "fmt" + "os" "strings" "testing" ) @@ -22,12 +23,19 @@ type NetworkInterface struct { DHCPEnabled bool } +func readConfig(path string) string { + b, err := os.ReadFile(path) + if err != nil { + return "" + } + return string(b) + +} func writeInterfaceConfig(filePath string, ifaces []NetworkInterface) { configText := "" for _, iface := range ifaces { configLines := []string{ - "auto lo", - "iface lo inet loopback", + fmt.Sprintf("# %s", iface.Name), fmt.Sprintf("auto %s", iface.Name), fmt.Sprintf("iface %s inet %s", iface.Interface, getInetType(iface.DHCPEnabled)), } @@ -36,11 +44,13 @@ func writeInterfaceConfig(filePath string, ifaces []NetworkInterface) { configLines = append(configLines, fmt.Sprintf(" address %s", iface.Address)) configLines = append(configLines, fmt.Sprintf(" netmask %s", iface.Netmask)) configLines = append(configLines, fmt.Sprintf(" gateway %s", iface.Gateway)) - configLines = append(configLines, fmt.Sprintf(" dns-nameservers %s", strings.Join(iface.DNS, " "))) + configLines = append(configLines, fmt.Sprintf(" dns-nameservers %s\n", strings.Join(iface.DNS, " "))) } configText += strings.Join(configLines, "\n") + } - fmt.Println(configText) + + fmt.Println("# local loopback\nauto lo\niface lo inet loopback\n" + configText) // return os.WriteFile(filePath, []byte(configText), 0644) } @@ -63,23 +73,40 @@ func TestWriteNetplanConfig(t *testing.T) { * 读写ubuntu16的配置 * */ +// go test -timeout 30s -run ^TestReadEtcNetConfig github.com/hootrhino/rulex/test -v -count=1 + func TestReadEtcNetConfig(t *testing.T) { } +/* +* +* 解析配置文件 +* + */ + // go test -timeout 30s -run ^TestWriteFEtcNetConfig github.com/hootrhino/rulex/test -v -count=1 func TestWriteFEtcNetConfig(t *testing.T) { - interfaceConfig := NetworkInterface{ + eth0 := NetworkInterface{ Name: "eth0", Interface: "eth0", Address: "192.168.1.100", Netmask: "255.255.255.0", Gateway: "192.168.1.1", + DNS: []string{"8.8.8.8"}, + DHCPEnabled: false, + } + eth1 := NetworkInterface{ + Name: "eth1", + Interface: "eth1", + Address: "192.168.100.100", + Netmask: "255.255.255.0", + Gateway: "192.168.100.1", DNS: []string{"8.8.8.8", "114.114.114.114"}, DHCPEnabled: false, } - writeInterfaceConfig("/etc/network/interfaces", []NetworkInterface{interfaceConfig, interfaceConfig}) + writeInterfaceConfig("/etc/network/interfaces", []NetworkInterface{eth0, eth1}) fmt.Println("Configuration written successfully.") } diff --git a/typex/version.go b/typex/version.go index a91958919..ea43bc447 100644 --- a/typex/version.go +++ b/typex/version.go @@ -12,7 +12,7 @@ type Version struct { var DefaultVersion = Version{ Version: `v0.6.1`, - ReleaseTime: "2023-08-14 20:29:54", + ReleaseTime: "2023-08-16 15:47:08", } var Banner = ` ** Welcome to RULEX framework world <'_'>