package middleware import ( "fmt" "io/fs" "path/filepath" "xg_dba/api" "xg_dba/internal/middleware/utils" "xg_dba/internal/models" "github.com/spf13/viper" ) type ServerDbCache struct { Cache map[string]models.Cache } // InitCache 初始化缓存,从指定目录中读取 TOML 文件内容并存储到 packageModels 映射中。 func InitCache(folderPath string) (*ServerDbCache, error) { serverDb := ServerDbCache{} serverDb.Cache = make(map[string]models.Cache) err := filepath.WalkDir(folderPath, func(path string, d fs.DirEntry, err error) error { if err != nil { return err } if d.IsDir() { //包含一组集群信息 cacheTemp := models.Cache{} //一组集群的连接信息 connects := make(map[string]models.ConnectInfo) //一组集群的系统元信息 systemMeta := make(map[string]models.SystemMetaInfo) // 如果 listen.toml 文件存在,解析它到 connectInfoMap 结构体中 listenFilePath := filepath.Join(path, "listen.toml") if utils.FileExists(listenFilePath) { //解析 listen.toml 文件 parseListen(listenFilePath, connects) cacheTemp.Connect = connects } /* 获取目录中最新的 os_info.toml 文件 这里会有多个节点的 os_info.toml 文件,需要找到每个节点最新的一个*/ systemMeta, err = utils.GetLatestOsInfoFiles(path) if err != nil { return fmt.Errorf("获取目录中最新的 os_info.toml 文件时出错: %v", err) } // 如果找到最新的 os_info.toml 文件,解析它到 systemMetaInfo 结构体中 // if latestOsInfoFilePath != "" { // var systemMetaInfo models.SystemMetaInfo // if err := utils.ParseTomlFile(latestOsInfoFilePath, &systemMetaInfo); err != nil { // return err // } // fmt.Println("获取目录中最新的 os_info.toml 文件:", systemMetaInfo) // } if cacheTemp.Connect != nil { // 获取 listen.toml 文件所在的文件夹名,父文件名字 folderName := filepath.Base(path) cacheTemp.FileInfo.BaseFileName = folderName //操作系统环境信息 if systemMeta != nil { cacheTemp.System = systemMeta } //将一组集群放入缓存中 serverDb.Cache[folderName] = cacheTemp } } return nil }) if err != nil { return nil, fmt.Errorf("遍历路径 %q 时出错: %v", folderPath, err) } // 打印每个主机的缓存数据 // for key, connectInfo := range serverDb.Cache { // fmt.Printf("主机: %s, 缓存: %+v ,父文件: %s\n", key, connectInfo.Connect, connectInfo.FileInfo.BaseFileName) // } return &serverDb, nil } func parseListen(listenFilePath string, config map[string]models.ConnectInfo) { // 设置配置文件名和路径 vp := viper.New() vp.SetConfigFile(listenFilePath) vp.SetConfigType("toml") if err := vp.ReadInConfig(); err != nil { panic(fmt.Errorf("parseListen fatal error reading config file: %w", err)) } // 遍历读取 server_db 中的各个配置 serverDBs := vp.GetStringMap("server_db") for key := range serverDBs { dbConfig := vp.Sub(fmt.Sprintf("server_db.%s", key)) if dbConfig == nil { continue } // 创建结构体实例并存储到 config 中 config[key] = models.ConnectInfo{ Ssh: models.SshInfo{ Username: dbConfig.GetString("ssh_username"), Password: dbConfig.GetString("ssh_password"), Host: dbConfig.GetString("ssh_ip"), Port: dbConfig.GetString("ssh_port"), }, Db: models.DbInfo{ User: dbConfig.GetString("db_user"), Password: dbConfig.GetString("db_password"), Database: dbConfig.GetString("db_database"), Port: dbConfig.GetString("db_port"), }, } } } // 刷新缓存 func (cache *ServerDbCache) RefreshCache() error { var err error cache, err = InitCache("./config") if err != nil { return err } return nil } func (cache *ServerDbCache) LoadCache(folderPath string) error { return nil } func (cache *ServerDbCache) GetConnectCache() (map[string]map[string]api.ConnectInfoResopnse, error) { // 获取所有 Connect 数据 // allConnects := make(map[string]map[string]models.ConnectInfo) // for group, cache := range cache.Cache { // allConnects[group] = cache.Connect // } allConnects := make(map[string]map[string]api.ConnectInfoResopnse) for group, cacheV := range cache.Cache { TempMap := make(map[string]api.ConnectInfoResopnse) connInfoMap := make(map[string]api.ConnectInfo) for key, cache := range cacheV.Connect { //fmt.Printf("group: %s, key: %s, cachhe: %#v \n", group, key, cachhe) connInfoMap[key] = api.SetConnectInfo(cache.Ssh.Username, cache.Ssh.Password, cache.Ssh.Host, cache.Ssh.Port, cache.Db.User, cache.Db.Password, cache.Db.Database, cache.Db.Port) } //cacheV.FileInfo.BaseFileName connRes := api.ConnectInfoResopnse{ ConnInfo: connInfoMap, BaseFileName: cacheV.FileInfo.BaseFileName, } TempMap[group] = connRes // TempMap[group].ConnInfo = connInfoMap //fmt.Println("父文件夹名字 :", cacheV.FileInfo.BaseFileName, conncetInfoTemp.BaseFileName) allConnects[group] = TempMap } return allConnects, nil } // 获取指定服务器信息 func (cache *ServerDbCache) GetSingleSystemInfoCache(BaseFileName, ip string) (models.SystemMetaInfo, error) { info := cache.Cache[BaseFileName].System[ip] fmt.Println("单个系统的信息info:", info) return info, nil }