From 064c0874e5fd041c4641ef873d1bf72ac98a184d Mon Sep 17 00:00:00 2001 From: wangpengfei <274878379@qq.com> Date: 星期五, 02 六月 2023 16:26:09 +0800 Subject: [PATCH] Merge branch 'master' into fly_develop --- src/cluster/cluster.go | 398 +++++++++++++++++--------------------------------------- 1 files changed, 120 insertions(+), 278 deletions(-) diff --git a/src/cluster/cluster.go b/src/cluster/cluster.go index 68686a0..3af2437 100644 --- a/src/cluster/cluster.go +++ b/src/cluster/cluster.go @@ -1,18 +1,18 @@ -package main +package cluster import ( "bytes" - "context" - "crypto/tls" "encoding/json" "fmt" + "io/ioutil" "log" "net/http" "os" + "path/filepath" "strings" - "time" - "golang.org/x/crypto/ssh" + "basic.com/aps/aps_deploy.git/src/rancher" + "basic.com/aps/aps_deploy.git/src/util" ) type Cluster struct { @@ -24,6 +24,12 @@ Data []Cluster `json:"data"` } +type KubectlConfigResponse struct { + BaseType string `json:"baseType"` + Config string `json:"config"` + Type string `json:"type"` +} + type RegistrationTokenResponse struct { Command string `json:"command"` } @@ -32,7 +38,7 @@ NodeCommand string `json:"nodeCommand"` } -func createRegistrationToken(serverURL, bearerToken, clusterID string) (string, error) { +func CreateRegistrationToken(serverURL, bearerToken, clusterID string) (string, error) { url := fmt.Sprintf("%s/v3/clusterregistrationtokens", serverURL) payload := strings.NewReader(fmt.Sprintf(`{ @@ -47,7 +53,7 @@ req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", bearerToken)) req.Header.Set("Content-Type", "application/json") - client := createHTTPClient() + client := util.CreateHTTPClient() resp, err := client.Do(req) if err != nil { @@ -68,7 +74,7 @@ return tokenResp.Command, nil } -func getNodeCommand(serverURL, bearerToken, clusterID string) (string, error) { +func GetNodeCommand(serverURL, bearerToken, clusterID string) (string, error) { url := fmt.Sprintf("%s/v3/clusterregistrationtokens", serverURL) payload := map[string]interface{}{ @@ -88,7 +94,7 @@ req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", bearerToken)) req.Header.Set("Content-Type", "application/json") - client := createHTTPClient() + client := util.CreateHTTPClient() resp, err := client.Do(req) if err != nil { @@ -109,17 +115,17 @@ return nodeCommandResponse.NodeCommand, nil } -func getClusterID(serverURL, bearerToken, clusterName string) (string, error) { +func GetClusterID(serverURL, bearerToken, clusterName string) (string, error) { url := fmt.Sprintf("%s/v3/clusters", serverURL) req, err := http.NewRequest("GET", url, nil) if err != nil { - return "", fmt.Errorf("failed to create cluster list request: %v", err) + return "", fmt.Errorf("failed to get cluster list request: %v", err) } req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", bearerToken)) - client := createHTTPClient() + client := util.CreateHTTPClient() resp, err := client.Do(req) if err != nil { @@ -149,131 +155,99 @@ return "", fmt.Errorf("cluster '%s' not found", clusterName) } -// Create an HTTP client with insecure TLS configuration -func createHTTPClient() *http.Client { - transport := &http.Transport{ - TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, +func GetClusters(serverURL, bearerToken string) ([]string, error) { + + url := fmt.Sprintf("%s/v3/clusters", serverURL) + + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return nil, fmt.Errorf("failed to get cluster list request: %v", err) } - return &http.Client{Transport: transport} + + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", bearerToken)) + + client := util.CreateHTTPClient() + + resp, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("failed to get cluster list: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("failed to get cluster list: unexpected status code %d", resp.StatusCode) + } + + // Parse the API response + var clustersResponse ClustersResponse + err = json.NewDecoder(resp.Body).Decode(&clustersResponse) + + log.Println("3333333333333333333333333") + log.Printf("%v", resp.Body) + if err != nil { + return nil, fmt.Errorf("failed to decode cluster list response: %v", err) + } + + var clusters = make([]string, 0) + // Print cluster names + for _, cluster := range clustersResponse.Data { + clusters = append(clusters, cluster.ID) + fmt.Printf("Cluster ID: %s, Name: %s\n", cluster.ID, cluster.Name) + } + + return clusters, nil } -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(), - } +func GetKubectlConfig(serverURL, bearerToken, clusterName string) (string, error) { - // 杩炴帴鍒拌繙绋嬫湇鍔″櫒 - client, err := ssh.Dial("tcp", fmt.Sprintf("%s:%d", nodeIP, sshPort), config) + url := fmt.Sprintf("%s/v3/clusters/%s?action=generateKubeconfig", serverURL, clusterName) + + req, err := http.NewRequest("POST", url, nil) if err != nil { - return "", fmt.Errorf("failed to connect to node %s: %v", nodeIP, err) + return "", fmt.Errorf("failed to get cluster list request: %v", err) } - defer client.Close() - // 鍒涘缓浼氳瘽 - session, err := client.NewSession() + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", bearerToken)) + req.Header.Set("Content-Type", "application/json") + req.Header.Set("Accept", "application/json") + + client := util.CreateHTTPClient() + + resp, err := client.Do(req) if err != nil { - return "", fmt.Errorf("failed to create SSH session: %v", err) + return "", fmt.Errorf("failed to get cluster list: %v", err) } - defer session.Close() + defer resp.Body.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 { - // 妫�鏌ocker鏄惁宸插畨瑁� - 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 + if resp.StatusCode != http.StatusOK { + return "", fmt.Errorf("failed to get cluster list: unexpected status code %d", resp.StatusCode) } - // 瀹夎Docker - installCommand := "sudo curl -fsSL https://get.docker.com -o get-docker.sh && sudo sh get-docker.sh" - _, err = sshExec(nodeIP, sshUsername, sshPassword, installCommand, sshPort) + // Parse the API response + var kubectlConfig KubectlConfigResponse + err = json.NewDecoder(resp.Body).Decode(&kubectlConfig) + if err != nil { - return fmt.Errorf("failed to install Docker on the remote server: %v", err) + return "", fmt.Errorf("failed to decode cluster list response: %v", err) } - fmt.Println("Docker has been installed on the remote server.") - return nil -} - -// 瀹夎kubectl -func installKubectl(nodeIP, sshUsername, sshPassword string, sshPort int) error { - // 妫�鏌ubectl鏄惁宸插畨瑁� - 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) + // 淇濆瓨 kubeconfig 鍒版枃浠� + homeDir, err := os.UserHomeDir() if err != nil { - return fmt.Errorf("failed to install kubectl on the remote server: %v", err) + log.Fatalf("Failed to get home directory: %v", err) + } + kubeconfigDir := filepath.Join(homeDir, ".kube") + err = os.MkdirAll(kubeconfigDir, 0700) + if err != nil { + log.Fatalf("Failed to create .kube directory: %v", err) + } + kubeconfigPath := filepath.Join(kubeconfigDir, "config") + err = ioutil.WriteFile(kubeconfigPath, []byte(kubectlConfig.Config), 0600) + if err != nil { + log.Fatalf("Failed to save kubeconfig: %v", err) } - fmt.Println("kubectl has been installed on the remote server.") - return nil + return kubectlConfig.Config, nil } type Node struct { @@ -283,11 +257,6 @@ SSHUsername string `json:"sshUsername"` SSHPassword string `json:"sshPassword"` SSHPort int `json:"sshPort"` -} - -type RancherConfig struct { - RancherURL string `json:"rancherURL"` - BearerToken string `json:"bearerToken"` } type ClusterCreateRequest struct { @@ -328,38 +297,39 @@ } // Deploy Kubernetes roles on a node using SSH -func deployk8sRolesOnNode(nodeIP, sshUsername, sshPassword, remoteSSHCommand string, sshPort int, roles []string) error { - rancherAgentInstalled, err := isRancherAgentInstalled(nodeIP, sshUsername, sshPassword, sshPort) +func Deployk8sRolesOnNode(nodeIP, sshUsername, sshPassword, remoteSSHCommand string, sshPort int, roles []string) error { + rancherAgentInstalled, err := IsRancherAgentInstalled(nodeIP, sshUsername, sshPassword, sshPort) if err == nil { return nil } if !rancherAgentInstalled { - // Add role parameters to nodeCommand - for _, role := range roles { - switch role { - case "etcd": - remoteSSHCommand += " --etcd" - case "controlplane": - remoteSSHCommand += " --controlplane" - case "worker": - remoteSSHCommand += " --worker" - default: - log.Fatalf("invalid role specified : %s", role) + // Add role parameters to nodeCommand + for _, role := range roles { + switch role { + case "etcd": + remoteSSHCommand += " --etcd" + case "controlplane": + remoteSSHCommand += " --controlplane" + case "worker": + remoteSSHCommand += " --worker" + default: + log.Fatalf("invalid role specified : %s", role) + } } - } - _, err := sshExec(nodeIP, sshUsername, sshPassword, remoteSSHCommand, sshPort) - if err != nil { - return fmt.Errorf("failed to deploy Kubernetes roles on the remote server: %v", err) + _, err := util.SSHExec(nodeIP, sshUsername, sshPassword, remoteSSHCommand, sshPort) + if err != nil { + return fmt.Errorf("failed to deploy Kubernetes roles on the remote server: %v", err) + } } return nil } -func isRancherInstalled(ip, username, password string, sshPort int) (bool, error) { +func IsRancherInstalled(ip, username, password string, sshPort int) (bool, error) { // 妫�鏌ancher瀹瑰櫒鏄惁宸茶繍琛� checkRancherCommand := "sudo docker ps --format '{{.Image}}' | grep -q rancher/rancher:v2.5.17" - _, err := sshExec(ip, username, password, checkRancherCommand, sshPort) + _, err := util.SSHExec(ip, username, password, checkRancherCommand, sshPort) if err != nil { // 濡傛灉鎵ц鍛戒护鍑洪敊锛屽垯璇存槑Rancher鏈畨瑁呮垨鍙戠敓鍏朵粬閿欒 return false, fmt.Errorf("failed to check Rancher installation: %v", err) @@ -368,10 +338,10 @@ return true, nil } -func isRancherAgentInstalled(ip, username, password string, sshPort int) (bool, error) { +func IsRancherAgentInstalled(ip, username, password string, sshPort int) (bool, error) { // 妫�鏌ancher瀹瑰櫒鏄惁宸茶繍琛� checkRancherCommand := "sudo docker ps --format '{{.Image}}' | grep -q rancher/rancher-agent:v2.5." - _, err := sshExec(ip, username, password, checkRancherCommand, sshPort) + _, err := util.SSHExec(ip, username, password, checkRancherCommand, sshPort) if err != nil { // 濡傛灉鎵ц鍛戒护鍑洪敊锛屽垯璇存槑Rancher鏈畨瑁呮垨鍙戠敓鍏朵粬閿欒 return false, fmt.Errorf("failed to check Rancher installation: %v", err) @@ -380,55 +350,20 @@ return true, nil } -func installRancher(ip, username, password string, sshPort int) error { - rancherInstalled, err := isRancherInstalled(ip, username, password, sshPort) - if err == nil { - return nil - } - - if !rancherInstalled { - // 瀹夎Rancher鍛戒护 - rancherCommand := "sudo docker run --privileged -d --restart=unless-stopped -p 8081:80 -p 8443:443 -v /opt/rancher:/var/lib/rancher registry.cn-hangzhou.aliyuncs.com/rancher/rancher:v2.5.17" - _, err = sshExec(ip, username, password, rancherCommand, sshPort) - if err != nil { - return fmt.Errorf("failed to install Rancher: %v", err) - } - } else { - fmt.Println("Rancher is already installed on the remote server.") - } - - return nil -} - -func installDockerAndRancher(ip, username, password string, sshPort int) error { - // 瀹夎Docker鍛戒护 - err := installDocker(ip, username, password, sshPort) - if err != nil { - return err - } - - // 瀹夎Rancher鍛戒护 - err = installRancher(ip, username, password, sshPort) - if err != nil { - return err - } - - return nil -} - -func createCluster(rancherConfig RancherConfig, clusterName string) error { +func CreateCluster(rancherClusterConfig rancher.RancherClusterConfig, clusterName string) error { requestBody := createClusterData(clusterName) + fmt.Println(rancherClusterConfig.RancherURL) - url := fmt.Sprintf("%s/v3/clusters", rancherConfig.RancherURL) + url := fmt.Sprintf("%s/v3/clusters", rancherClusterConfig.RancherURL) req, err := http.NewRequest("POST", url, bytes.NewBuffer(requestBody)) if err != nil { return fmt.Errorf("Failed to create HTTP request: %v", err) } - req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", rancherConfig.BearerToken)) + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", rancherClusterConfig.BearerToken)) req.Header.Set("Content-Type", "application/json") - client := createHTTPClient() + client := util.CreateHTTPClient() resp, err := client.Do(req) if err != nil { @@ -449,97 +384,4 @@ fmt.Printf("Cluster created: ID=%s, Name=%s\n", responseBody.ID, responseBody.Name) return nil -} - -func main() { - clusterName := "kubernetus" - nodes := []Node{ - { - ClusterName: clusterName, - Roles: []string{"etcd", "controlplane", "worker"}, - IP: "192.168.20.189", - SSHUsername: "basic", - SSHPassword: "123", - SSHPort: 22, - }, - { - ClusterName: clusterName, - Roles: []string{"worker"}, - IP: "192.168.20.10", - SSHUsername: "basic", - SSHPassword: "123", - SSHPort: 22, - }, - { - ClusterName: clusterName, - Roles: []string{"worker"}, - IP: "192.168.20.115", - SSHUsername: "basic", - SSHPassword: "alien123", - SSHPort: 22, - }, - // Add more nodes here if needed - } - - //install rancher on master node - err := installDockerAndRancher(nodes[0].IP, nodes[0].SSHUsername, nodes[0].SSHPassword, nodes[0].SSHPort) - if err != nil { - log.Fatalf("Failed to install Rancher: %v", err) - } - - // Create the cluster - // Rancher configuration - /*rancherConfig := RancherConfig{ - RancherURL: "https://192.168.20.119:8443", - BearerToken: "token-nnrsc:w68zdt8s47fnpjd5xqdl5hhzpz4j2d56kt5nx49nsswcbpdzc28kh5", - }*/ - - rancherConfig := RancherConfig{ - RancherURL: "https://192.168.20.189:8443", - BearerToken: "token-t4cdf:h7zhmbvbzdvd9mmjw8zmt8rh4m7rl5gtqpqljlhl9tlr2z26j9lf4l", - } - - // Deploy clusterId - clusterID, err := getClusterID(rancherConfig.RancherURL, rancherConfig.BearerToken, clusterName) - if err != nil { - log.Fatal(err) - err = createCluster(rancherConfig, clusterName) - if err != nil { - log.Fatalf("Failed to create cluster: %v", err) - } - fmt.Printf("Cluster created: %s\n", clusterName) - clusterID, err = getClusterID(rancherConfig.RancherURL, rancherConfig.BearerToken, clusterName) - if err != nil { - log.Fatal(err) - } - } - fmt.Println(clusterID) - - // Deploy nodeCommand - nodeCommand, err := getNodeCommand(rancherConfig.RancherURL, rancherConfig.BearerToken, clusterID) - if err != nil { - log.Fatal(err) - } - fmt.Println(nodeCommand) - - for _, node := range nodes { - //Deploy Docker on each node - err = installDocker(node.IP, node.SSHUsername, node.SSHPassword, node.SSHPort) - if err != nil { - log.Fatal(err) - } - - // Deploy Kubectl on each node - err = installKubectl(node.IP, node.SSHUsername, node.SSHPassword, node.SSHPort) - if err != nil { - log.Fatal(err) - } - - // Deploy Kubernetes roles on each node - err = deployk8sRolesOnNode(node.IP, node.SSHUsername, node.SSHPassword, nodeCommand, node.SSHPort, node.Roles) - if err != nil { - log.Fatal(err) - } - } - os.Exit(0) } -- Gitblit v1.8.0