feat: Agent一键安装(loading/成功/失败状态无弹框) + 批量安装API
This commit is contained in:
1 parent
48b2d2281b
commit
2fc2a2ae07
5 files changed
+213
-5
No files matched your search
@@ -144,3 +144,113 @@ func (h *AgentInstallHandler) InstallAgent(c *gin.Context) {
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// installOne 安装单个服务器的 Agent(内部方法)
|
||||
func (h *AgentInstallHandler) installOne(server models.Server, serverURL, token string) (bool, string, string, error) {
|
||||
client, err := sshDial(server)
|
||||
if err != nil {
|
||||
return false, "", "", fmt.Errorf("SSH连接失败: %w", err)
|
||||
}
|
||||
defer client.Close()
|
||||
|
||||
if server.Status != "running" {
|
||||
return false, "", "", fmt.Errorf("服务器未运行")
|
||||
}
|
||||
|
||||
installCmd := fmt.Sprintf(
|
||||
`curl -fsSL %s/agent/install.sh | sudo bash -s -- --server %s --token %s`,
|
||||
serverURL, serverURL, token,
|
||||
)
|
||||
|
||||
installOut, err := runSSHCommand(client, installCmd)
|
||||
if err != nil {
|
||||
return false, installOut, "", err
|
||||
}
|
||||
|
||||
verifyOut, _ := runSSHCommand(client, "systemctl is-active aiops-agent 2>/dev/null || echo 'not_found'")
|
||||
installed := contains(verifyOut, "active") || contains(verifyOut, "running")
|
||||
|
||||
if installed {
|
||||
h.db.Model(&server).Updates(map[string]interface{}{
|
||||
"agent_status": "online",
|
||||
"agent_version": "installed",
|
||||
"last_check_at": time.Now(),
|
||||
})
|
||||
}
|
||||
|
||||
return installed, installOut, verifyOut, nil
|
||||
}
|
||||
|
||||
// BatchInstallAgent 批量安装 Agent
|
||||
// POST /servers/install-agent
|
||||
func (h *AgentInstallHandler) BatchInstallAgent(c *gin.Context) {
|
||||
var req struct {
|
||||
ServerIDs []uint `json:"server_ids"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&req); err != nil || len(req.ServerIDs) == 0 {
|
||||
c.JSON(http.StatusBadRequest, models.Response{Code: 400, Message: "请提供要安装的服务器 ID 列表"})
|
||||
return
|
||||
}
|
||||
|
||||
serverURL := fmt.Sprintf("http://%s", c.Request.Host)
|
||||
token := c.Query("token")
|
||||
|
||||
type InstallResult struct {
|
||||
ServerID uint `json:"server_id"`
|
||||
Hostname string `json:"hostname"`
|
||||
IP string `json:"ip"`
|
||||
Success bool `json:"success"`
|
||||
Message string `json:"message"`
|
||||
Installed bool `json:"installed"`
|
||||
}
|
||||
|
||||
results := make([]InstallResult, 0, len(req.ServerIDs))
|
||||
successCount := 0
|
||||
|
||||
for _, sid := range req.ServerIDs {
|
||||
var server models.Server
|
||||
if err := h.db.First(&server, sid).Error; err != nil {
|
||||
results = append(results, InstallResult{
|
||||
ServerID: sid,
|
||||
Success: false,
|
||||
Message: "服务器不存在",
|
||||
})
|
||||
continue
|
||||
}
|
||||
|
||||
installed, _, _, err := h.installOne(server, serverURL, token)
|
||||
if err != nil {
|
||||
results = append(results, InstallResult{
|
||||
ServerID: server.ID,
|
||||
Hostname: server.Hostname,
|
||||
IP: server.IP,
|
||||
Success: false,
|
||||
Message: err.Error(),
|
||||
})
|
||||
} else {
|
||||
successCount++
|
||||
msg := "安装成功"
|
||||
if !installed {
|
||||
msg = "安装命令已执行,Agent 服务未检测到运行"
|
||||
}
|
||||
results = append(results, InstallResult{
|
||||
ServerID: server.ID,
|
||||
Hostname: server.Hostname,
|
||||
IP: server.IP,
|
||||
Success: true,
|
||||
Installed: installed,
|
||||
Message: msg,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, models.Response{
|
||||
Code: 200,
|
||||
Message: fmt.Sprintf("完成 %d/%d 台服务器", successCount, len(req.ServerIDs)),
|
||||
Data: gin.H{
|
||||
"total": len(req.ServerIDs),
|
||||
"success": successCount,
|
||||
"results": results,
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -141,6 +141,7 @@ func Register(r *gin.Engine, db *gorm.DB, log *zap.Logger, cfg *config.Config, c
|
||||
// Agent 远程安装 // Logan.Li
|
||||
agentInstallHandler := handlers.NewAgentInstallHandler(db)
|
||||
servers.POST("/:id/install-agent", agentInstallHandler.InstallAgent)
|
||||
servers.POST("/install-agent", agentInstallHandler.BatchInstallAgent)
|
||||
}
|
||||
|
||||
// 云账号路由
|
||||
|
||||
Reference in new issue
Block a user