package util import ( "context" "crypto/tls" "flag" "fmt" "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" "net/http" "os" "path/filepath" "time" "golang.org/x/crypto/ssh" ) // homeDir 获取当前用户的家目录路径 func HomeDir() string { if h := os.Getenv("HOME"); h != "" { return h } return os.Getenv("USERPROFILE") // Windows 环境下获取用户目录 } func SSHExec(nodeIP, sshUsername, sshPassword, remoteSSHCommand string, sshPort int) (string, error) { // SSH 连接配置 config := &ssh.ClientConfig{ User: sshUsername, Auth: []ssh.AuthMethod{ ssh.Password(sshPassword), }, HostKeyCallback: ssh.InsecureIgnoreHostKey(), } // 连接到远程服务器 client, err := ssh.Dial("tcp", fmt.Sprintf("%s:%d", nodeIP, sshPort), config) if err != nil { return "", fmt.Errorf("failed to connect to node %s: %v", nodeIP, err) } defer client.Close() // 创建会话 session, err := client.NewSession() if err != nil { return "", fmt.Errorf("failed to create SSH session: %v", err) } defer session.Close() // 创建一个具有超时的上下文 ctx, cancel := context.WithTimeout(context.Background(), 300*time.Second) defer cancel() // 通过会话执行远程命令 outputChan := make(chan string) errorChan := make(chan error) go func() { // 创建一个连接标准输入的管道 stdinPipe, err := session.StdinPipe() if err != nil { errorChan <- fmt.Errorf("failed to create stdin pipe: %v", err) return } // 启动会话 if err := session.Start(fmt.Sprintf("sudo -SE %s", remoteSSHCommand)); err != nil { errorChan <- fmt.Errorf("failed to start command: %v err:%v", remoteSSHCommand, err) return } // 将密码写入标准输入管道 _, err = fmt.Fprintf(stdinPipe, "%s\n", sshPassword) if err != nil { errorChan <- fmt.Errorf("failed to write password to stdin: %v", err) return } // 等待会话结束 if err := session.Wait(); err != nil { errorChan <- fmt.Errorf("command execution failed: %v err:%v", remoteSSHCommand, err) return } outputChan <- "" }() // 等待结果或超时 select { case <-ctx.Done(): // 关闭会话以终止远程命令 session.Close() // 等待会话关闭的 goroutine 结束 <-outputChan return "", fmt.Errorf("SSH command execution timed out") case err := <-errorChan: return "", err case <-outputChan: fmt.Printf("Command: %v executed on the remote server: %s\n", remoteSSHCommand, nodeIP) return "", nil } } // 安装Docker func InstallDocker(nodeIP, sshUsername, sshPassword string, sshPort int) error { // 检查Docker是否已安装 checkCommand := "which docker" _, err := SSHExec(nodeIP, sshUsername, sshPassword, checkCommand, sshPort) if err == nil { fmt.Println("Docker is already installed on the remote server.") return nil } // 安装Docker installCommand := "sudo curl -fsSL https://get.docker.com -o get-docker.sh && sudo sh get-docker.sh && sudo systemctl start docker && sudo systemctl enable docker" _, err = SSHExec(nodeIP, sshUsername, sshPassword, installCommand, sshPort) if err != nil { return fmt.Errorf("failed to install Docker on the remote server:%v %v", nodeIP, err) } fmt.Println("Docker has been installed on the remote server.") return nil } // Create an HTTP client with insecure TLS configuration func CreateHTTPClient() *http.Client { transport := &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, } return &http.Client{Transport: transport} } // 安装kubectl func InstallKubectl(nodeIP, sshUsername, sshPassword string, sshPort int) error { // 检查kubectl是否已安装 checkCommand := "which kubectl" _, err := SSHExec(nodeIP, sshUsername, sshPassword, checkCommand, sshPort) if err == nil { fmt.Println("kubectl is already installed on the remote server.") return nil } // 安装kubectl installCommand := "sudo curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl && sudo chmod +x kubectl && sudo mv kubectl /usr/local/bin/" _, err = SSHExec(nodeIP, sshUsername, sshPassword, installCommand, sshPort) if err != nil { return fmt.Errorf("failed to install kubectl on the remote server: %v", err) } fmt.Println("kubectl has been installed on the remote server.") return nil } func GetClient() (*kubernetes.Clientset, error) { // 配置 Kubernetes 集群的 kubeconfig 路径 kubeconfig := flag.String("kubeconfig", filepath.Join(HomeDir(), ".kube", "config"), "kubeconfig file") flag.Parse() // 创建 Kubernetes 客户端 config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig) if err != nil { panic(err.Error()) } clientset, err := kubernetes.NewForConfig(config) if err != nil { panic(err.Error()) } return clientset, nil }