From dcfbc2859c223cf63fc9ba5a57eeb30aac54b324 Mon Sep 17 00:00:00 2001 From: Awuqing <3184394176@qq.com> Date: Sun, 19 Apr 2026 16:34:58 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8A=9F=E8=83=BD:=20=E6=B3=A8=E5=86=8C?= =?UTF-8?q?=E4=B8=80=E9=94=AE=E9=83=A8=E7=BD=B2=E6=96=B0=E8=B7=AF=E7=94=B1?= =?UTF-8?q?=E5=B9=B6=20wire=20InstallTokenService?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/internal/app/app.go | 12 ++++++++++-- server/internal/http/router.go | 20 ++++++++++++++++++-- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/server/internal/app/app.go b/server/internal/app/app.go index fa913f1..57da842 100644 --- a/server/internal/app/app.go +++ b/server/internal/app/app.go @@ -123,6 +123,12 @@ func New(ctx context.Context, cfg config.Config, version string) (*Application, agentCmdRepo := repository.NewAgentCommandRepository(db) agentService := service.NewAgentService(nodeRepo, backupTaskRepo, backupRecordRepo, storageTargetRepo, agentCmdRepo, configCipher) agentService.StartCommandTimeoutMonitor(ctx, 30*time.Second, 10*time.Minute) + + // 一键部署:install token service + 后台 GC + installTokenRepo := repository.NewAgentInstallTokenRepository(db) + installTokenService := service.NewInstallTokenService(installTokenRepo, nodeRepo) + installTokenService.StartGC(ctx, time.Hour) + // 把 Agent 下发能力注入到备份执行服务,实现多节点路由 backupExecutionService.SetClusterDependencies(nodeRepo, agentService) // 启用远程目录浏览:NodeService 通过 AgentService 做同步 RPC @@ -146,8 +152,10 @@ func New(ctx context.Context, cfg config.Config, version string) (*Application, DatabaseDiscoveryService: databaseDiscoveryService, AuditService: auditService, JWTManager: jwtManager, - UserRepository: userRepo, - SystemConfigRepo: systemConfigRepo, + UserRepository: userRepo, + SystemConfigRepo: systemConfigRepo, + InstallTokenService: installTokenService, + MasterExternalURL: "", // 如需覆盖 URL,可扩展 cfg.Server 增字段;目前留空依赖 X-Forwarded-* / Request.Host }) httpServer := &stdhttp.Server{ diff --git a/server/internal/http/router.go b/server/internal/http/router.go index 67c9026..2517853 100644 --- a/server/internal/http/router.go +++ b/server/internal/http/router.go @@ -34,6 +34,8 @@ type RouterDependencies struct { JWTManager *security.JWTManager UserRepository repository.UserRepository SystemConfigRepo repository.SystemConfigRepository + InstallTokenService *service.InstallTokenService + MasterExternalURL string } func NewRouter(deps RouterDependencies) *gin.Engine { @@ -141,8 +143,7 @@ func NewRouter(deps RouterDependencies) *gin.Engine { database.POST("/discover", databaseHandler.Discover) } - // 临时让 build 通过:InstallTokenService 与 externalURL 传 nil 和 "",Task 11 会替换成真实值 - nodeHandler := NewNodeHandler(deps.NodeService, deps.AuditService, nil, "") + nodeHandler := NewNodeHandler(deps.NodeService, deps.AuditService, deps.InstallTokenService, deps.MasterExternalURL) nodes := api.Group("/nodes") nodes.Use(AuthMiddleware(deps.JWTManager)) nodes.GET("", nodeHandler.List) @@ -151,6 +152,10 @@ func NewRouter(deps RouterDependencies) *gin.Engine { nodes.PUT("/:id", nodeHandler.Update) nodes.DELETE("/:id", nodeHandler.Delete) nodes.GET("/:id/fs/list", nodeHandler.ListDirectory) + nodes.POST("/batch", nodeHandler.BatchCreate) + nodes.POST("/:id/install-tokens", nodeHandler.CreateInstallToken) + nodes.POST("/:id/rotate-token", nodeHandler.RotateToken) + nodes.GET("/:id/install-script-preview", nodeHandler.PreviewScript) // Agent API(token 认证,无需 JWT) if deps.AgentService != nil { @@ -161,12 +166,23 @@ func NewRouter(deps RouterDependencies) *gin.Engine { agent.POST("/commands/:id/result", agentHandler.SubmitCommandResult) agent.GET("/tasks/:id", agentHandler.GetTaskSpec) agent.POST("/records/:id", agentHandler.UpdateRecord) + + // Agent v1(安装脚本探活用),仅 Self 端点 + v1Agent := api.Group("/v1/agent") + v1Agent.GET("/self", agentHandler.Self) } else { // 未启用 Agent 服务时,保留原有 heartbeat 端点以兼容 api.POST("/agent/heartbeat", nodeHandler.Heartbeat) } } + // 公开安装路由(不走 JWT 中间件) + if deps.InstallTokenService != nil { + installHandler := NewInstallHandler(deps.InstallTokenService, deps.AuditService, deps.MasterExternalURL) + engine.GET("/install/:token", installHandler.Script) + engine.GET("/install/:token/compose.yml", installHandler.Compose) + } + engine.NoRoute(func(c *gin.Context) { response.Error(c, apperror.New(stdhttp.StatusNotFound, "NOT_FOUND", "接口不存在", errors.New("route not found"))) })