cache.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. package middleware
  2. import (
  3. "fmt"
  4. "io/fs"
  5. "path/filepath"
  6. "xg_dba/api"
  7. "xg_dba/internal/middleware/utils"
  8. "xg_dba/internal/models"
  9. "github.com/spf13/viper"
  10. )
  11. type ServerDbCache struct {
  12. Cache map[string]models.Cache
  13. }
  14. // InitCache 初始化缓存,从指定目录中读取 TOML 文件内容并存储到 packageModels 映射中。
  15. func InitCache(folderPath string) (*ServerDbCache, error) {
  16. serverDb := ServerDbCache{}
  17. serverDb.Cache = make(map[string]models.Cache)
  18. err := filepath.WalkDir(folderPath, func(path string, d fs.DirEntry, err error) error {
  19. if err != nil {
  20. return err
  21. }
  22. if d.IsDir() {
  23. //包含一组集群信息
  24. cacheTemp := models.Cache{}
  25. //一组集群的连接信息
  26. connects := make(map[string]models.ConnectInfo)
  27. //一组集群的系统元信息
  28. systemMeta := make(map[string]models.SystemMetaInfo)
  29. // 如果 listen.toml 文件存在,解析它到 connectInfoMap 结构体中
  30. listenFilePath := filepath.Join(path, "listen.toml")
  31. if utils.FileExists(listenFilePath) {
  32. //解析 listen.toml 文件
  33. parseListen(listenFilePath, connects)
  34. cacheTemp.Connect = connects
  35. }
  36. /* 获取目录中最新的 os_info.toml 文件
  37. 这里会有多个节点的 os_info.toml 文件,需要找到每个节点最新的一个*/
  38. systemMeta, err = utils.GetLatestOsInfoFiles(path)
  39. if err != nil {
  40. return fmt.Errorf("获取目录中最新的 os_info.toml 文件时出错: %v", err)
  41. }
  42. // 如果找到最新的 os_info.toml 文件,解析它到 systemMetaInfo 结构体中
  43. // if latestOsInfoFilePath != "" {
  44. // var systemMetaInfo models.SystemMetaInfo
  45. // if err := utils.ParseTomlFile(latestOsInfoFilePath, &systemMetaInfo); err != nil {
  46. // return err
  47. // }
  48. // fmt.Println("获取目录中最新的 os_info.toml 文件:", systemMetaInfo)
  49. // }
  50. if cacheTemp.Connect != nil {
  51. // 获取 listen.toml 文件所在的文件夹名,父文件名字
  52. folderName := filepath.Base(path)
  53. cacheTemp.FileInfo.BaseFileName = folderName
  54. //操作系统环境信息
  55. if systemMeta != nil {
  56. cacheTemp.System = systemMeta
  57. }
  58. //将一组集群放入缓存中
  59. serverDb.Cache[folderName] = cacheTemp
  60. }
  61. }
  62. return nil
  63. })
  64. if err != nil {
  65. return nil, fmt.Errorf("遍历路径 %q 时出错: %v", folderPath, err)
  66. }
  67. // 打印每个主机的缓存数据
  68. // for key, connectInfo := range serverDb.Cache {
  69. // fmt.Printf("主机: %s, 缓存: %+v ,父文件: %s\n", key, connectInfo.Connect, connectInfo.FileInfo.BaseFileName)
  70. // }
  71. return &serverDb, nil
  72. }
  73. func parseListen(listenFilePath string, config map[string]models.ConnectInfo) {
  74. // 设置配置文件名和路径
  75. vp := viper.New()
  76. vp.SetConfigFile(listenFilePath)
  77. vp.SetConfigType("toml")
  78. if err := vp.ReadInConfig(); err != nil {
  79. panic(fmt.Errorf("parseListen fatal error reading config file: %w", err))
  80. }
  81. // 遍历读取 server_db 中的各个配置
  82. serverDBs := vp.GetStringMap("server_db")
  83. for key := range serverDBs {
  84. dbConfig := vp.Sub(fmt.Sprintf("server_db.%s", key))
  85. if dbConfig == nil {
  86. continue
  87. }
  88. // 创建结构体实例并存储到 config 中
  89. config[key] = models.ConnectInfo{
  90. Ssh: models.SshInfo{
  91. Username: dbConfig.GetString("ssh_username"),
  92. Password: dbConfig.GetString("ssh_password"),
  93. Host: dbConfig.GetString("ssh_ip"),
  94. Port: dbConfig.GetString("ssh_port"),
  95. },
  96. Db: models.DbInfo{
  97. User: dbConfig.GetString("db_user"),
  98. Password: dbConfig.GetString("db_password"),
  99. Database: dbConfig.GetString("db_database"),
  100. Port: dbConfig.GetString("db_port"),
  101. },
  102. }
  103. }
  104. }
  105. // 刷新缓存
  106. func (cache *ServerDbCache) RefreshCache() error {
  107. var err error
  108. cache, err = InitCache("./config")
  109. if err != nil {
  110. return err
  111. }
  112. return nil
  113. }
  114. func (cache *ServerDbCache) LoadCache(folderPath string) error {
  115. return nil
  116. }
  117. func (cache *ServerDbCache) GetConnectCache() (map[string]map[string]api.ConnectInfoResopnse, error) {
  118. // 获取所有 Connect 数据
  119. // allConnects := make(map[string]map[string]models.ConnectInfo)
  120. // for group, cache := range cache.Cache {
  121. // allConnects[group] = cache.Connect
  122. // }
  123. allConnects := make(map[string]map[string]api.ConnectInfoResopnse)
  124. for group, cacheV := range cache.Cache {
  125. TempMap := make(map[string]api.ConnectInfoResopnse)
  126. connInfoMap := make(map[string]api.ConnectInfo)
  127. for key, cache := range cacheV.Connect {
  128. //fmt.Printf("group: %s, key: %s, cachhe: %#v \n", group, key, cachhe)
  129. 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)
  130. }
  131. //cacheV.FileInfo.BaseFileName
  132. connRes := api.ConnectInfoResopnse{
  133. ConnInfo: connInfoMap,
  134. BaseFileName: cacheV.FileInfo.BaseFileName,
  135. }
  136. TempMap[group] = connRes
  137. // TempMap[group].ConnInfo = connInfoMap
  138. //fmt.Println("父文件夹名字 :", cacheV.FileInfo.BaseFileName, conncetInfoTemp.BaseFileName)
  139. allConnects[group] = TempMap
  140. }
  141. return allConnects, nil
  142. }
  143. // 获取指定服务器信息
  144. func (cache *ServerDbCache) GetSingleSystemInfoCache(BaseFileName, ip string) (models.SystemMetaInfo, error) {
  145. info := cache.Cache[BaseFileName].System[ip]
  146. fmt.Println("单个系统的信息info:", info)
  147. return info, nil
  148. }