diff --git a/bspsupport/readme.md b/bspsupport/readme.md index e58473fc5..453c13887 100644 --- a/bspsupport/readme.md +++ b/bspsupport/readme.md @@ -22,11 +22,13 @@ ARCHSUPPORT=EEKITH3 rulex run ## 支持硬件列表 -| 硬件名 | 环境参数 | 示例 | -| --------------- | -------- | ------------------------------- | -| EEKITH3版本网关 | EEKITH3 | `ARCHSUPPORT=EEKITH3 rulex run` | -| 树莓派4B、4B+ | RPI4 | `ARCHSUPPORT=RPI4B rulex run` | -| 玩客云S805 | WKYS805 | `ARCHSUPPORT=WKYS805 rulex run` | +| 硬件名 | 环境参数 | 示例 | +| ------------------ | --------- | --------------------------------- | +| EEKIT H3版本网关 | EEKITH3 | `ARCHSUPPORT=EEKITH3 rulex run` | +| EEKIT T507版本网关 | EEKITT507 | `ARCHSUPPORT=EEKITT507 rulex run` | +| EEKIT T113版本网关 | EEKITT113 | `ARCHSUPPORT=EEKITT113 rulex run` | +| 树莓派4B、4B+ | RPI4 | `ARCHSUPPORT=RPI4B rulex run` | +| 玩客云S805 | WKYS805 | `ARCHSUPPORT=WKYS805 rulex run` | > 警告: 这些属于板级高级功能,和硬件架构以及外设有关,默认关闭。 如果你自己需要定制,最好针对自己的硬件进行跨平台适配, 如果没有指定平台,可能会导致预料之外的结果。 diff --git a/plugin/http_server/dao/sqlite/sqlite_dao.go b/plugin/http_server/dao/sqlite/sqlite_dao.go index 0b9912077..3473955e6 100644 --- a/plugin/http_server/dao/sqlite/sqlite_dao.go +++ b/plugin/http_server/dao/sqlite/sqlite_dao.go @@ -32,6 +32,7 @@ type SqliteDAO struct { func Load(dbPath string) { Sqlite = &SqliteDAO{name: "SqliteDAO"} Sqlite.Init(dbPath) + Sqlite.InitializeData() } /* @@ -58,6 +59,15 @@ func (s *SqliteDAO) Init(dbPath string) error { return err } +/* +* +* 给数据库初始化一些数据用 +* + */ +func (s *SqliteDAO) InitializeData() { + +} + /* * * 停止 diff --git a/plugin/http_server/dao/types.go b/plugin/http_server/dao/types.go index f412a8a48..94c615385 100644 --- a/plugin/http_server/dao/types.go +++ b/plugin/http_server/dao/types.go @@ -9,6 +9,7 @@ import "gorm.io/gorm" */ type DAO interface { Init(string) error + InitializeData() RegisterModel(dst ...interface{}) Name() string DB() *gorm.DB diff --git a/plugin/http_server/dto/etcnet_config.go b/plugin/http_server/dto/etcnet_config.go index 19ff76081..3cf0dfba3 100644 --- a/plugin/http_server/dto/etcnet_config.go +++ b/plugin/http_server/dto/etcnet_config.go @@ -1,11 +1,21 @@ -package service +package dto + +// { +// "name": "eth0", +// "interface": "eth0", +// "address": "192.168.1.100", +// "netmask": "255.255.255.0", +// "gateway": "192.168.1.1", +// "dns": ["8.8.8.8", "8.8.4.4"], +// "dhcp_enabled": false +// } 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"` + Name string `json:"name"` // eth1 eth0 + Interface string `json:"interface"` // eth1 eth0 + Address string `json:"address"` + Netmask string `json:"netmask"` + Gateway string `json:"gateway"` + DNS []string `json:"dns"` + DHCPEnabled bool `json:"dhcp_enabled"` } diff --git a/plugin/http_server/dto/netplan_config.go b/plugin/http_server/dto/netplan_config.go index fafcf1ab3..f2120d707 100644 --- a/plugin/http_server/dto/netplan_config.go +++ b/plugin/http_server/dto/netplan_config.go @@ -1,4 +1,4 @@ -package service +package dto type hwInterface struct { Dhcp4 bool `yaml:"dhcp4" json:"dhcp4,omitempty"` diff --git a/plugin/http_server/http_api_server.go b/plugin/http_server/http_api_server.go index 1a648c3ba..9f0305dd8 100644 --- a/plugin/http_server/http_api_server.go +++ b/plugin/http_server/http_api_server.go @@ -10,6 +10,7 @@ import ( common "github.com/hootrhino/rulex/plugin/http_server/common" sqlitedao "github.com/hootrhino/rulex/plugin/http_server/dao/sqlite" "github.com/hootrhino/rulex/plugin/http_server/model" + "github.com/hootrhino/rulex/plugin/http_server/service" "github.com/gin-contrib/static" @@ -93,6 +94,7 @@ func (hs *HttpApiServer) Init(config *ini.Section) error { } hs.registerModel() hs.configHttpServer() + hs.InitializeNwtWorkConfigData() // // WebSocket server // @@ -100,6 +102,17 @@ func (hs *HttpApiServer) Init(config *ini.Section) error { return nil } +/* +* +* 初始化网络配置 +* + */ +func (hs *HttpApiServer) InitializeNwtWorkConfigData() { + if !service.CheckIfAlreadyInitNetWorkConfig() { + service.InitNetWorkConfig() + } +} + /* * * 加载路由 @@ -327,6 +340,16 @@ func (hs *HttpApiServer) LoadRoute() { screenApi.PUT("/update", hs.addRoute(UpdateVisual)) screenApi.GET("/list", hs.addRoute(ListVisual)) } + // + // 大屏应用管理 + // + settingsApi := hs.ginEngine.Group(url("/settings")) + { + settingsApi.POST("/network", hs.addRoute(SetStaticNetwork)) + settingsApi.POST("/time", hs.addRoute(SetTime)) + settingsApi.POST("/wifi", hs.addRoute(SetWifi)) + settingsApi.POST("/volume", hs.addRoute(SetVolume)) + } } diff --git a/plugin/http_server/model/model.go b/plugin/http_server/model/model.go index b7893836c..2f2a80e25 100644 --- a/plugin/http_server/model/model.go +++ b/plugin/http_server/model/model.go @@ -11,14 +11,14 @@ type RulexModel struct { ID uint `gorm:"primarykey"` CreatedAt time.Time } -type stringList []string +type StringList []string /* * * 给GORM用的 * */ -func (f stringList) Value() (driver.Value, error) { +func (f StringList) Value() (driver.Value, error) { b, err := json.Marshal(f) return string(b), err } @@ -28,15 +28,15 @@ func (f stringList) Value() (driver.Value, error) { * 给GORM用的 * */ -func (f *stringList) Scan(data interface{}) error { +func (f *StringList) Scan(data interface{}) error { return json.Unmarshal([]byte(data.(string)), f) } -func (f stringList) String() string { +func (f StringList) String() string { b, _ := json.Marshal(f) return string(b) } -func (f stringList) Len() int { +func (f StringList) Len() int { return len(f) } @@ -45,8 +45,8 @@ type MRule struct { UUID string `gorm:"not null"` Name string `gorm:"not null"` Type string // 脚本类型,目前支持"lua"和"expr"两种 - FromSource stringList `gorm:"not null type:string[]"` - FromDevice stringList `gorm:"not null type:string[]"` + FromSource StringList `gorm:"not null type:string[]"` + FromDevice StringList `gorm:"not null type:string[]"` Expression string `gorm:"not null"` // Expr脚本 Actions string `gorm:"not null"` Success string `gorm:"not null"` @@ -60,7 +60,7 @@ type MInEnd struct { UUID string `gorm:"not null"` Type string `gorm:"not null"` Name string `gorm:"not null"` - BindRules stringList `json:"bindRules"` // 与之关联的规则表["A","B","C"] + BindRules StringList `json:"bindRules"` // 与之关联的规则表["A","B","C"] Description string Config string @@ -110,7 +110,7 @@ type MDevice struct { Name string `gorm:"not null"` Type string `gorm:"not null"` Config string - BindRules stringList `json:"bindRules"` // 与之关联的规则表["A","B","C"] + BindRules StringList `json:"bindRules"` // 与之关联的规则表["A","B","C"] Description string } @@ -132,7 +132,7 @@ type MGoods struct { UUID string `gorm:"not null"` Addr string `gorm:"not null"` Description string `gorm:"not null"` - Args stringList `gorm:"not null"` + Args StringList `gorm:"not null"` } /* @@ -237,5 +237,12 @@ type MProtocolApp struct { * */ type MNetworkConfig struct { - Network string `yaml:"network" json:"network,omitempty"` + RulexModel + Type string `gorm:"not null"` // 类型: ubuntu16, ubuntu18 + Interface string `json:"interface"` // eth1 eth0 + Address string `json:"address"` + Netmask string `json:"netmask"` + Gateway string `json:"gateway"` + DNS StringList `json:"dns"` + DHCPEnabled bool `json:"dhcp_enabled"` } diff --git a/plugin/http_server/service/linux_network_config_service.go b/plugin/http_server/service/linux_network_config_service.go new file mode 100644 index 000000000..4549142d6 --- /dev/null +++ b/plugin/http_server/service/linux_network_config_service.go @@ -0,0 +1,199 @@ +package service + +import ( + "github.com/hootrhino/rulex/glogger" + sqlitedao "github.com/hootrhino/rulex/plugin/http_server/dao/sqlite" + "github.com/hootrhino/rulex/plugin/http_server/model" +) + +/* +* +* 永远只有一个配置,eth0 +* + */ +func GetEth0Config() (model.MNetworkConfig, error) { + MNetworkConfig := model.MNetworkConfig{} + err := sqlitedao.Sqlite.DB(). + Find(&MNetworkConfig). + Where("interface=?", "eth0").Error + return MNetworkConfig, err +} + +/* +* +* 永远只有一个配置,eth1 +* + */ +func GetEth1Config() (model.MNetworkConfig, error) { + MNetworkConfig := model.MNetworkConfig{Interface: "eth0"} + err := sqlitedao.Sqlite.DB(). + Find(&MNetworkConfig). + Where("interface=?", "eth1").Error + return MNetworkConfig, err +} + +/* +* +* 永远只更新id=0的 +* + */ +func UpdateEth0Config(MNetworkConfig model.MNetworkConfig) error { + Model := model.MNetworkConfig{Interface: "eth1"} + return sqlitedao.Sqlite.DB(). + Model(Model). + Where("interface=?", "eth0"). + Updates(MNetworkConfig).Error +} + +/* +* +* 永远只更新id=1的 +* + */ +func UpdateEth1Config(MNetworkConfig model.MNetworkConfig) error { + Model := model.MNetworkConfig{} + return sqlitedao.Sqlite.DB(). + Model(Model). + Where("interface=?", "eth1"). + Updates(MNetworkConfig).Error +} + +/* +* +* 初始化数据,开局的时候插入一条记录 +* + */ +const ubuntu16CfgDHCP string = ` +auto lo +iface lo inet loopback +auto eth0 +iface eth0 inet dhcp +` +const ubuntu16CfgStatic string = ` +# local loopback +auto lo +iface lo inet loopback +# eth0 +auto eth0 +iface eth0 inet static + address 192.168.128.100 + netmask 255.255.255.0 + gateway 192.168.128.1 + dns-nameservers 8.8.8.8 +# eth1 +auto eth1 +iface eth1 inet static + address 192.168.12800.100 + netmask 255.255.255.0 + gateway 192.168.12800.1 + dns-nameservers 8.8.8.8 114.114.114.114 +` +const ubuntuNetplanDHCPCfg string = ` +network: + version: 2 + renderer: networkd + ethernets: + eth0: + dhcp4: true + eth1: + dhcp4: true +` +const ubuntuNetplanStaticCfg string = ` +network: + version: 2 + renderer: networkd + ethernets: + eth0: + addresses: + - 192.168.128.100/24 + gateway4: 192.168.128.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] +` + +/* +* +* 检查一下是否已经初始化过了,避免覆盖配置 +* + */ +func CheckIfAlreadyInitNetWorkConfig() bool { + sql := `SELECT count(*) FROM m_network_configs;` + count := 0 + err := sqlitedao.Sqlite.DB().Raw(sql).Find(&count).Error + if err != nil { + glogger.GLogger.Error(err) + return false + } + if count > 0 { + return true + } + return false +} + +/* +* + - 清空表:DELETE FROM table_name; + DELETE FROM sqlite_sequence WHERE name='m_network_configs'; + +* +*/ +func TruncateConfig() error { + sql := `DELETE FROM m_network_configs;DELETE FROM sqlite_sequence WHERE name='m_network_configs';` + count := 0 + err := sqlitedao.Sqlite.DB().Raw(sql).Find(&count).Error + if err != nil { + glogger.GLogger.Error(err) + return err + } + return nil +} + +/* +* +* 初始化网卡配置参数 +* + */ +func InitNetWorkConfig() error { + + // 默认给DHCP + eth0 := model.MNetworkConfig{ + Interface: "eth0", + Address: "192.168.128.100", + Netmask: "255.255.255.0", + Gateway: "192.168.128.1", + DNS: model.StringList{ + "8.8.8.8", + "114.114.114.114", + }, + DHCPEnabled: true, + } + eth1 := model.MNetworkConfig{ + Interface: "eth1", + Address: "192.168.128.100", + Netmask: "255.255.255.0", + Gateway: "192.168.128.1", + DNS: model.StringList{ + "8.8.8.8", + "114.114.114.114", + }, + DHCPEnabled: false, + } + var err error + err = sqlitedao.Sqlite.DB().Where("interface=? and id=1", "eth0").FirstOrCreate(ð0).Error + if err != nil { + return err + } + err = sqlitedao.Sqlite.DB().Where("interface=? and id=2", "eth1").FirstOrCreate(ð1).Error + if err != nil { + return err + } + return nil +} + + diff --git a/plugin/http_server/service/ubuntu16_network_service.go b/plugin/http_server/service/ubuntu16_network_service.go index 84a7c86cb..8d40bc2f0 100644 --- a/plugin/http_server/service/ubuntu16_network_service.go +++ b/plugin/http_server/service/ubuntu16_network_service.go @@ -3,8 +3,10 @@ package service import ( "encoding/json" "fmt" - "os" "strings" + + sqlitedao "github.com/hootrhino/rulex/plugin/http_server/dao/sqlite" + "github.com/hootrhino/rulex/plugin/http_server/model" ) // # /etc/network/interfaces @@ -29,13 +31,12 @@ import ( // 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"` + Interface string `json:"interface"` + Address string `json:"address"` + Netmask string `json:"netmask"` + Gateway string `json:"gateway"` + DNS []string `json:"dns"` + DHCPEnabled bool `json:"dhcp_enabled"` } func (nc *EtcNetworkConfig) JsonString() string { @@ -50,11 +51,11 @@ sudo systemctl restart networking sudo service networking restart * */ -func ApplyConfig(iface EtcNetworkConfig) error { +func (iface *EtcNetworkConfig) GenEtcConfig() string { configLines := []string{ - "auto lo", - "iface lo inet loopback", - fmt.Sprintf("auto %s", iface.Name), + // "auto lo", + // "iface lo inet loopback", + fmt.Sprintf("auto %s", iface.Interface), fmt.Sprintf("iface %s inet %s", iface.Interface, func(dhcpEnabled bool) string { if dhcpEnabled { return "dhcp" @@ -69,7 +70,21 @@ func ApplyConfig(iface EtcNetworkConfig) error { 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) + // return os.WriteFile("/etc/network/interfaces", []byte(configText), 0644) + return configText +} + +/* +* +* 匹配: /etc/network/interfaces +* + */ +func GetAllNetConfig() ([]model.MNetworkConfig, error) { + // 查出前两个网卡的配置 + ethCfg := []model.MNetworkConfig{} + err := sqlitedao.Sqlite.DB(). + Where("interface=? or interface=?", "eth0", "eth1"). + Find(ðCfg).Error + return ethCfg, err } diff --git a/plugin/http_server/service/ubuntu_netplan_network_service.go b/plugin/http_server/service/ubuntu_netplan_network_service.go index a8b6af953..bc45258a3 100644 --- a/plugin/http_server/service/ubuntu_netplan_network_service.go +++ b/plugin/http_server/service/ubuntu_netplan_network_service.go @@ -25,19 +25,49 @@ network: */ // // 读取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 HwInterface struct { + Dhcp4 bool `yaml:"dhcp4" json:"dhcp4"` + Addresses []string `yaml:"addresses" json:"addresses"` + Gateway4 string `yaml:"gateway4" json:"gateway4"` + Nameservers []string `yaml:"nameservers" json:"nameservers"` +} + +// network: +// +// version: 2 +// renderer: networkd +// wifis: +// wlan0: +// dhcp4: yes +// access-points: +// "YourWiFiSSID": +// password: "YourWiFiPassword" + +type SSIDConfig struct { + Password string `yaml:"password" json:"password"` +} +type AccessPoints struct { + SSIDConfig SSIDConfig `yaml:"ssid" json:"ssid"` +} +type WLANInterface struct { + Dhcp4 bool `yaml:"dhcp4" json:"dhcp4"` + AccessPoints AccessPoints `yaml:"access-points" json:"access-points"` +} +type Wifis struct { + Wlan0 WLANInterface +} +type EthInterface struct { + Eth0 HwInterface `yaml:"eth0" json:"eth0"` + Eth1 HwInterface `yaml:"eth1" json:"eth1"` + Wifis Wifis `yaml:"wifis" json:"wifis"` } 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"` + Version int `yaml:"version" json:"version"` + Renderer string `yaml:"renderer" json:"renderer"` + Ethernets EthInterface `yaml:"ethernets" json:"ethernets"` } type NetplanConfig struct { - Network Network `yaml:"network" json:"network,omitempty"` + Network Network `yaml:"network" json:"network"` } /* @@ -55,50 +85,25 @@ type NetplanConfig struct { 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 DefaultDHCPNetplanConfig() *NetplanConfig { +// return &NetplanConfig{ +// Network: Network{ +// Version: 2, +// Renderer: "NetworkManager", +// Ethernets: EthInterface{ +// Eth0: HwInterface{Dhcp4: true}, +// Eth1: HwInterface{Dhcp4: true}, +// Wlan0: WLANInterface{Dhcp4: true}, +// }, +// }, +// } +// } func (nc *NetplanConfig) FromJson(jsons string) error { return json.Unmarshal([]byte(jsons), nc) } diff --git a/plugin/http_server/system_api.go b/plugin/http_server/system_api.go index 1398e627d..24115c3c5 100644 --- a/plugin/http_server/system_api.go +++ b/plugin/http_server/system_api.go @@ -251,6 +251,11 @@ func GetUarts(c *gin.Context, hh *HttpApiServer) { c.JSON(common.HTTP_OK, common.OkWithData(ports)) } +/* +* +* 本地网卡 +* + */ func GetNetInterfaces(c *gin.Context, hh *HttpApiServer) { interfaces, err := getAvailableInterfaces() if err != nil { diff --git a/plugin/http_server/system_config_api.go b/plugin/http_server/system_config_api.go index dcb5cda07..ce9720651 100644 --- a/plugin/http_server/system_config_api.go +++ b/plugin/http_server/system_config_api.go @@ -1,13 +1,25 @@ package httpserver -import "github.com/gin-gonic/gin" +import ( + "fmt" + "net" + "runtime" + "strconv" + "strings" + + "github.com/gin-gonic/gin" + common "github.com/hootrhino/rulex/plugin/http_server/common" + "github.com/hootrhino/rulex/plugin/http_server/model" + "github.com/hootrhino/rulex/plugin/http_server/service" + "github.com/hootrhino/rulex/utils" +) /* * -* WIFI +* 设置音量 * */ -func SetWifi(c *gin.Context, hh *HttpApiServer) { +func SetVolume(c *gin.Context, hh *HttpApiServer) { type Form struct { } @@ -15,9 +27,21 @@ func SetWifi(c *gin.Context, hh *HttpApiServer) { /* * -* 设置时间、时区 +* WIFI * */ +func SetWifi(c *gin.Context, hh *HttpApiServer) { + type Form struct { + } + +} + +/* +* + - 设置时间、时区 + - sudo date -s "2023-08-07 15:30:00" + 获取时间: date "+%Y-%m-%d %H:%M:%S" -> 2023-08-07 15:30:00 +*/ func SetTime(c *gin.Context, hh *HttpApiServer) { type Form struct { } @@ -26,32 +50,217 @@ func SetTime(c *gin.Context, hh *HttpApiServer) { /* * -* 设置静态网络IP等 +* 设置静态网络IP等, 当前只支持Linux 其他的没测试暂时不予支持 { - "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" - ] - } - } - } - } + "name": "eth0", + "interface": "eth0", + "address": "192.168.1.100", + "netmask": "255.255.255.0", + "gateway": "192.168.1.1", + "dns": ["8.8.8.8", "8.8.4.4"], + "dhcp_enabled": false } */ +func isValidIP(ip string) bool { + parsedIP := net.ParseIP(ip) + return parsedIP != nil +} + func SetStaticNetwork(c *gin.Context, hh *HttpApiServer) { + if runtime.GOOS != "linux" { + c.JSON(common.HTTP_OK, common.Error("Set Static Network Not Support:"+runtime.GOOS)) + return + } type Form struct { + Interface string `json:"interface"` // eth1 eth0 + Address string `json:"address"` + Netmask string `json:"netmask"` + Gateway string `json:"gateway"` + DNS []string `json:"dns"` + DHCPEnabled bool `json:"dhcp_enabled"` + } + + DtoCfg := Form{} + if err0 := c.ShouldBindJSON(&DtoCfg); err0 != nil { + c.JSON(common.HTTP_OK, common.Error400(err0)) + return + } + if !strings.Contains("eth1 eth0", DtoCfg.Interface) { + c.JSON(common.HTTP_OK, + common.Error(("Only have 2 valid interface:eth1 and eth0"))) + return + } + if !isValidIP(DtoCfg.Address) { + c.JSON(common.HTTP_OK, + common.Error(("Invalid IP:" + DtoCfg.Address))) + return + } + if !isValidIP(DtoCfg.Gateway) { + c.JSON(common.HTTP_OK, + common.Error(("Invalid Gateway IP:" + DtoCfg.Address))) + return + } + if !isValidSubnetMask(DtoCfg.Netmask) { + c.JSON(common.HTTP_OK, + common.Error(("Invalid SubnetMask:" + DtoCfg.Address))) + return + } + for _, dns := range DtoCfg.DNS { + if !isValidIP(dns) { + c.JSON(common.HTTP_OK, + common.Error(("Invalid DNS IP:" + DtoCfg.Address))) + return + } + } + UbuntuVersion, err := utils.GetUbuntuVersion() + if err != nil { + c.JSON(common.HTTP_OK, common.Error400(err)) + return + } + NetCfgType := "NETWORK_ETC" + if (UbuntuVersion == "ubuntu18") || + UbuntuVersion == "ubuntu20" || + UbuntuVersion == "ubuntu22" || + (UbuntuVersion == "ubuntu24") { + NetCfgType = "NETPLAN" + } + MNetCfg := model.MNetworkConfig{ + Type: NetCfgType, + Interface: DtoCfg.Interface, + Address: DtoCfg.Address, + Netmask: DtoCfg.Netmask, + Gateway: DtoCfg.Gateway, + DNS: DtoCfg.DNS, + DHCPEnabled: DtoCfg.DHCPEnabled, + } + if DtoCfg.Interface == "eth0" { + if err := service.UpdateEth0Config(MNetCfg); err != nil { + if err != nil { + c.JSON(common.HTTP_OK, common.Error400(err)) + return + } + } + } + if DtoCfg.Interface == "eth1" { + if err := service.UpdateEth1Config(MNetCfg); err != nil { + if err != nil { + c.JSON(common.HTTP_OK, common.Error400(err)) + return + } + } + } + + if NetCfgType == "NETWORK_ETC" { // Ubuntu16 + ApplyNewestEtcConfig() + } + if NetCfgType == "NETPLAN" { // Ubuntu18极其以后 + ApplyNewestNetplanConfig() + } + // 保存到数据库, 并且写入配置 + c.JSON(common.HTTP_OK, common.OkWithData(DtoCfg)) + +} + +/* +* +* 生成YAML +* + */ +func ApplyNewestNetplanConfig() error { + Eth0, err := service.GetEth0Config() + if err != nil { + return err + } + Eth1, err := service.GetEth1Config() + if err != nil { + return err + } + + NetplanConfig := service.NetplanConfig{ + Network: service.Network{ + Version: 2, + Renderer: "NetworkManager", + Ethernets: service.EthInterface{ + Eth0: service.HwInterface{ + Dhcp4: Eth0.DHCPEnabled, + Addresses: []string{Eth0.Address}, + Gateway4: Eth0.Gateway, + Nameservers: Eth0.DNS, + }, + Eth1: service.HwInterface{ + Dhcp4: Eth1.DHCPEnabled, + Addresses: []string{Eth1.Address}, + Gateway4: Eth1.Gateway, + Nameservers: Eth1.DNS, + }, + // WIFI 暂不支持 + //Wlan0: service.WLANInterface{}, + }, + }, + } + fmt.Println(NetplanConfig.YAMLString()) + return nil + +} + +/* +* +* 生成 etc 文件 +* + */ +func ApplyNewestEtcConfig() error { + // 取出最新的配置 + MNetworkConfigs, err := service.GetAllNetConfig() + if err != nil { + return err + } + etcFileContent := "" + for _, MNetworkConfig := range MNetworkConfigs { + NetworkConfig := service.EtcNetworkConfig{ + Interface: MNetworkConfig.Interface, + Address: MNetworkConfig.Address, + Netmask: MNetworkConfig.Netmask, + Gateway: MNetworkConfig.Gateway, + DNS: MNetworkConfig.DNS, + DHCPEnabled: MNetworkConfig.DHCPEnabled, + } + etcFileContent += NetworkConfig.GenEtcConfig() + "\n" + } + fmt.Println(etcFileContent) + return nil +} +func isValidSubnetMask(mask string) bool { + // 分割子网掩码为4个整数 + parts := strings.Split(mask, ".") + if len(parts) != 4 { + return false } + // 将每个部分转换为整数 + var octets [4]int + for i, part := range parts { + octet, err := strconv.Atoi(part) + if err != nil || octet < 0 || octet > 255 { + return false + } + octets[i] = octet + } + + // 判断是否为有效的子网掩码 + var bits int + for _, octet := range octets { + bits += bitsInByte(octet) + } + + return bits >= 1 && bits <= 32 +} + +func bitsInByte(b int) int { + count := 0 + for b > 0 { + count += b & 1 + b >>= 1 + } + return count } diff --git a/typex/version.go b/typex/version.go index ea43bc447..34499bf34 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-16 15:47:08", + ReleaseTime: "2023-08-17 20:29:37", } var Banner = ` ** Welcome to RULEX framework world <'_'> diff --git a/utils/os_common.go b/utils/os_common.go index 64fec16f5..f66c16099 100644 --- a/utils/os_common.go +++ b/utils/os_common.go @@ -118,3 +118,36 @@ func GetOSDistribution() (string, error) { } return runtime.GOOS, nil } + +/* +* +* 获取Ubuntu的版本 +* + */ +func GetUbuntuVersion() (string, error) { + // lsb_release -ds -> Ubuntu 22.04.1 LTS + cmd := exec.Command("lsb_release", "-ds") + output, err := cmd.Output() + if err != nil { + return "", err + } + info := strings.ToLower(strings.TrimSpace(string(output))) + if strings.Contains(info, "ubuntu") { + if strings.Contains(info, "16.") { + return "ubuntu16", nil + } + if strings.Contains(info, "18.") { + return "ubuntu18", nil + } + if strings.Contains(info, "20.") { + return "ubuntu20", nil + } + if strings.Contains(info, "22.") { + return "ubuntu22", nil + } + if strings.Contains(info, "24.") { + return "ubuntu24", nil + } + } + return "", fmt.Errorf("unsupported OS:%s", info) +}