config_rename.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. package config
  2. import (
  3. "context"
  4. "encoding/json"
  5. "os"
  6. "path/filepath"
  7. "strings"
  8. "github.com/0xJacky/Nginx-UI/internal/config"
  9. "github.com/0xJacky/Nginx-UI/internal/helper"
  10. "github.com/0xJacky/Nginx-UI/internal/nginx"
  11. "github.com/0xJacky/Nginx-UI/model"
  12. "github.com/0xJacky/Nginx-UI/query"
  13. "github.com/mark3labs/mcp-go/mcp"
  14. )
  15. const nginxConfigRenameToolName = "nginx_config_rename"
  16. var nginxConfigRenameTool = mcp.NewTool(
  17. nginxConfigRenameToolName,
  18. mcp.WithDescription("Rename a file or directory in the Nginx configuration path"),
  19. mcp.WithString("base_path", mcp.Description("The base path where the file or directory is located")),
  20. mcp.WithString("orig_name", mcp.Description("The original name of the file or directory")),
  21. mcp.WithString("new_name", mcp.Description("The new name for the file or directory")),
  22. mcp.WithArray("sync_node_ids", mcp.Description("IDs of nodes to sync the rename operation to")),
  23. )
  24. func handleNginxConfigRename(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
  25. args := request.Params.Arguments
  26. basePath := args["base_path"].(string)
  27. origName := args["orig_name"].(string)
  28. newName := args["new_name"].(string)
  29. // Convert sync_node_ids from []interface{} to []uint64
  30. syncNodeIdsInterface, ok := args["sync_node_ids"].([]interface{})
  31. syncNodeIds := make([]uint64, 0)
  32. if ok {
  33. for _, id := range syncNodeIdsInterface {
  34. if idFloat, ok := id.(float64); ok {
  35. syncNodeIds = append(syncNodeIds, uint64(idFloat))
  36. }
  37. }
  38. }
  39. if origName == newName {
  40. result := map[string]interface{}{
  41. "message": "No changes needed, names are identical",
  42. }
  43. jsonResult, _ := json.Marshal(result)
  44. return mcp.NewToolResultText(string(jsonResult)), nil
  45. }
  46. origFullPath := nginx.GetConfPath(basePath, origName)
  47. newFullPath := nginx.GetConfPath(basePath, newName)
  48. if !helper.IsUnderDirectory(origFullPath, nginx.GetConfPath()) ||
  49. !helper.IsUnderDirectory(newFullPath, nginx.GetConfPath()) {
  50. return nil, config.ErrPathIsNotUnderTheNginxConfDir
  51. }
  52. stat, err := os.Stat(origFullPath)
  53. if err != nil {
  54. return nil, err
  55. }
  56. if helper.FileExists(newFullPath) {
  57. return nil, ErrFileAlreadyExists
  58. }
  59. err = os.Rename(origFullPath, newFullPath)
  60. if err != nil {
  61. return nil, err
  62. }
  63. // update ChatGPT records
  64. g := query.ChatGPTLog
  65. q := query.Config
  66. cfg, err := q.Where(q.Filepath.Eq(origFullPath)).FirstOrInit()
  67. if err != nil {
  68. return nil, err
  69. }
  70. if !stat.IsDir() {
  71. _, _ = g.Where(g.Name.Eq(newFullPath)).Delete()
  72. _, _ = g.Where(g.Name.Eq(origFullPath)).Update(g.Name, newFullPath)
  73. // for file, the sync policy for this file is used
  74. syncNodeIds = cfg.SyncNodeIds
  75. } else {
  76. // is directory, update all records under the directory
  77. _, _ = g.Where(g.Name.Like(origFullPath+"%")).Update(g.Name, g.Name.Replace(origFullPath, newFullPath))
  78. }
  79. _, err = q.Where(q.Filepath.Eq(origFullPath)).Updates(&model.Config{
  80. Filepath: newFullPath,
  81. Name: newName,
  82. })
  83. if err != nil {
  84. return nil, err
  85. }
  86. b := query.ConfigBackup
  87. _, _ = b.Where(b.FilePath.Eq(origFullPath)).Updates(map[string]interface{}{
  88. "filepath": newFullPath,
  89. "name": newName,
  90. })
  91. if len(syncNodeIds) > 0 {
  92. err = config.SyncRenameOnRemoteServer(origFullPath, newFullPath, syncNodeIds)
  93. if err != nil {
  94. return nil, err
  95. }
  96. }
  97. result := map[string]interface{}{
  98. "path": strings.TrimLeft(filepath.Join(basePath, newName), "/"),
  99. }
  100. jsonResult, _ := json.Marshal(result)
  101. return mcp.NewToolResultText(string(jsonResult)), nil
  102. }