package main import ( "encoding/json" "fmt" "net" "net/http" "os/exec" "strings" ) // 执行shell命令,返回完整输出 func runShell(cmdStr string) (string, error) { args := strings.Fields(cmdStr) cmd := exec.Command(args[0], args[1:]...) out, err := cmd.CombinedOutput() return string(out), err } // 统一返回JSON结构 type Resp struct { Code int `json:"code"` Msg string `json:"msg"` Err string `json:"err,omitempty"` } // 单节点安装接口 func singleInstallHandler(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") w.Header().Set("Access-Control-Allow-Origin", "*") r.ParseForm() host := r.Form.Get("host") sshPort := r.Form.Get("ssh_port") user := r.Form.Get("user") pwd := r.Form.Get("pwd") cmd := fmt.Sprintf("./install_node_exporter.sh --cli --action single-install --host %s --ssh-port %s --user %s --pwd %s", host, sshPort, user, pwd) output, err := runShell(cmd) resp := Resp{Code: 0, Msg: output} if err != nil { resp.Code = 1 resp.Err = err.Error() } json.NewEncoder(w).Encode(resp) } // 单节点卸载接口 func singleUninstallHandler(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") w.Header().Set("Access-Control-Allow-Origin", "*") r.ParseForm() host := r.Form.Get("host") sshPort := r.Form.Get("ssh_port") user := r.Form.Get("user") pwd := r.Form.Get("pwd") cmd := fmt.Sprintf("./install_node_exporter.sh --cli --action single-uninstall --host %s --ssh-port %s --user %s --pwd %s", host, sshPort, user, pwd) output, err := runShell(cmd) resp := Resp{Code: 0, Msg: output} if err != nil { resp.Code = 1 resp.Err = err.Error() } json.NewEncoder(w).Encode(resp) } // 批量安装接口 func batchInstallHandler(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") w.Header().Set("Access-Control-Allow-Origin", "*") cmd := "./install_node_exporter.sh --cli --action batch-install" output, err := runShell(cmd) resp := Resp{Code: 0, Msg: output} if err != nil { resp.Code = 1 resp.Err = err.Error() } json.NewEncoder(w).Encode(resp) } // 批量卸载接口 func batchUninstallHandler(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") w.Header().Set("Access-Control-Allow-Origin", "*") cmd := "./install_node_exporter.sh --cli --action batch-uninstall" output, err := runShell(cmd) resp := Resp{Code: 0, Msg: output} if err != nil { resp.Code = 1 resp.Err = err.Error() } json.NewEncoder(w).Encode(resp) } // 获取hosts主机列表 func getHostsHandler(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") w.Header().Set("Access-Control-Allow-Origin", "*") cmd := "./install_node_exporter.sh --cli --action get-hosts" output, err := runShell(cmd) resp := Resp{Code: 0, Msg: output} if err != nil { resp.Code = 1 resp.Err = err.Error() } json.NewEncoder(w).Encode(resp) } // 重启Prometheus func restartPromHandler(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") w.Header().Set("Access-Control-Allow-Origin", "*") cmd := "./install_node_exporter.sh --cli --action restart-prom" output, err := runShell(cmd) resp := Resp{Code: 0, Msg: output} if err != nil { resp.Code = 1 resp.Err = err.Error() } json.NewEncoder(w).Encode(resp) } // SSH诊断接口 func diagSshHandler(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") w.Header().Set("Access-Control-Allow-Origin", "*") r.ParseForm() host := r.Form.Get("host") sshPort := r.Form.Get("ssh_port") user := r.Form.Get("user") pwd := r.Form.Get("pwd") cmd := fmt.Sprintf("./install_node_exporter.sh --cli --action diag-ssh --host %s --ssh-port %s --user %s --pwd %s", host, sshPort, user, pwd) output, err := runShell(cmd) resp := Resp{Code: 0, Msg: output} if err != nil { resp.Code = 1 resp.Err = err.Error() } json.NewEncoder(w).Encode(resp) } func main() { // API路由 http.HandleFunc("/api/single/install", singleInstallHandler) http.HandleFunc("/api/single/uninstall", singleUninstallHandler) http.HandleFunc("/api/batch/install", batchInstallHandler) http.HandleFunc("/api/batch/uninstall", batchUninstallHandler) http.HandleFunc("/api/hosts/list", getHostsHandler) http.HandleFunc("/api/prom/restart", restartPromHandler) http.HandleFunc("/api/ssh/diag", diagSshHandler) // 静态前端页面 http.Handle("/", http.FileServer(http.Dir("./static"))) localIP := getLocalIP() fmt.Printf("Web管理面板启动成功,监听 0.0.0.0:808\n访问地址:http://%s:808\n", localIP) err := http.ListenAndServe("0.0.0.0:808", nil) if err != nil { fmt.Println("服务启动失败:", err) } } // 获取本机内网IP(简易工具) func getLocalIP() string { addrs, err := net.InterfaceAddrs() if err != nil { return "服务器IP" } for _, addr := range addrs { if ipNet, ok := addr.(*net.IPNet); ok && !ipNet.IP.IsLoopback() { if ipNet.IP.To4() != nil { return ipNet.IP.String() } } } return "服务器IP" }