package host_info import ( "agent-wdd/log" "agent-wdd/utils" "fmt" "os" "os/exec" "runtime" "strings" "github.com/spf13/viper" "gopkg.in/yaml.v3" ) var WddConfigFilePath = "/usr/local/etc/wdd/agent-wdd-config.yaml" // ConfigCache 配置缓存 var ConfigCache = &Config{ TimeStamp: "", ModifiedTimes: 0, Agent: Agent{ OS: OS{}, Network: Network{}, CPU: CPU{}, Mem: Memory{}, Swap: Swap{}, Disks: []Disk{}, }, } func init() { // 根据运行的操作系统不同, 修改 WddConfigFilePath 的位置 if runtime.GOOS == "windows" { homedir, _ := os.UserHomeDir() WddConfigFilePath = homedir + "\\agent-wdd\\agent-wdd-config.yaml" } } type Config struct { TimeStamp string `yaml:"timestamp"` ModifiedTimes int `yaml:"modifiedTimes"` Agent Agent `yaml:"agent"` } type Agent struct { OS OS `yaml:"os"` Network Network `yaml:"network"` CPU CPU `yaml:"cpu"` Mem Memory `yaml:"mem"` Swap Swap `yaml:"swap"` Disks []Disk `yaml:"disks"` } type OS struct { Hostname string `mapstructure:"hostname" yaml:"hostname" comment:"主机名"` OsName string `mapstructure:"os_name" yaml:"os_name" comment:"操作系统名称"` OsFamily string `mapstructure:"os_family" yaml:"os_family" comment:"操作系统家族"` OsVersion string `mapstructure:"os_version" yaml:"os_version" comment:"操作系统版本"` OsType string `mapstructure:"os_type" yaml:"os_type" comment:"操作系统类型"` Kernel string `mapstructure:"kernel" yaml:"kernel" comment:"内核版本"` Arch string `mapstructure:"arch" yaml:"arch" comment:"架构"` IsUbuntuType bool `mapstructure:"is_ubuntu_type" yaml:"is_ubuntu_type" comment:"是否是ubuntu类型的操作系统"` PackInit bool `mapstructure:"pack_init" yaml:"pack_init" comment:"是否初始化,ubuntu需要"` OSReleaseCode string `mapstructure:"os_release_code" yaml:"os_release_code" comment:"主机操作系统的发行版代号, focal之类的"` } type Network struct { Internet int `yaml:"internet" comment:"是否能够上网 外网为9 国内为7 不能上网为1"` Public PublicInfo `yaml:"public"` Interfaces []Interface `yaml:"interfaces"` } type PublicInfo struct { IPv4 string `yaml:"ipv4"` IPv6 string `yaml:"ipv6"` Country string `yaml:"country"` City string `yaml:"city"` ASN string `yaml:"asn"` Timezone string `yaml:"timezone"` } type Interface struct { Name string `yaml:"name"` IPv4 string `yaml:"ipv4"` IPv6 string `yaml:"ipv6"` MAC string `yaml:"mac"` MTU int `yaml:"mtu"` } type CPU struct { Cores int `yaml:"cores"` Brand string `yaml:"brand"` Mhz string `yaml:"mhz"` Arch string `yaml:"arch"` Virt string `yaml:"virt"` Hypervisor string `yaml:"hypervisor"` } type Memory struct { Size string `yaml:"size"` Type string `yaml:"type"` Speed int `yaml:"speed"` } type Swap struct { Open bool `yaml:"open"` Size string `yaml:"size"` } type Disk struct { Path string `yaml:"path"` Size string `yaml:"size"` Usage string `yaml:"usage"` Percent string `yaml:"percent"` } func InitConfig() { // 检查配置文件是否存在 if !utils.FileOrFolderExists(WddConfigFilePath) { utils.AppendContentToFile("", WddConfigFilePath) } v := viper.New() v.SetConfigFile(WddConfigFilePath) v.SetConfigType("yaml") if err := v.ReadInConfig(); err != nil { log.Error("读取配置文件失败: %v", err) panic(err) } if err := v.Unmarshal(&ConfigCache); err != nil { log.Error("解析配置失败: %v", err) panic(err) } } // SaveConfig 写入配置文件 func SaveConfig() { // 每次写入新的时间 ConfigCache.TimeStamp = utils.CurrentTimeString() // 每次增加修改文件的次数计数 ConfigCache.ModifiedTimes += 1 data, err := yaml.Marshal(&ConfigCache) if err != nil { log.Error("YAML序列化失败: %v", err) } if err := os.WriteFile(WddConfigFilePath, data, 0644); err != nil { log.Error("写入文件失败: %v", err) } } // NormalizeConfig 归一化配置-重命名主机名 func (c *Config) NormalizeConfig() { // 重命名主机名 log.Info("归一化主机配置") // 重新读取配置 InitConfig() // 主机名称应该为 City(格式为首字母大写)-amd64-内网IP的最后一段(格式化为2位)-公网IPv4(如果公网IPv4为空,则使用内网IPv4; ip的格式为127-0-0-1) // 获取城市(格式为首字母大写) city := strings.Title(ConfigCache.Agent.Network.Public.City) // 获取公网IPv4 ip的格式为127-0-0-1 ipInfo := ConfigCache.Agent.Network.Public.IPv4 if ipInfo == "" { ipInfo = ConfigCache.Agent.Network.Interfaces[0].IPv4 } else { // 可以获取到公网IPv4, 修改IP的格式 innerIpv4 := ConfigCache.Agent.Network.Interfaces[0].IPv4 ipSegments := strings.Split(innerIpv4, ".") prefix := fmt.Sprintf("%02s", ipSegments[len(ipSegments)-1]) ipInfo = prefix + "." + ipInfo } ipInfo = strings.ReplaceAll(ipInfo, ".", "-") // 获取架构 arch := ConfigCache.Agent.CPU.Arch uniformHostname := city + "-" + arch + "-" + ipInfo // 重命名主机名 log.Info("重命名主机名: %s", uniformHostname) cmd := exec.Command("hostnamectl", "set-hostname", uniformHostname) // 执行命令 cmd.Run() // 更新配置 ConfigCache.Agent.OS.Hostname = uniformHostname // 更新配置 SaveConfig() }