func ProxyServer(ws *websocket.Conn) { cloudoneProtocol := beego.AppConfig.String("cloudoneProtocol") cloudoneHost := beego.AppConfig.String("cloudoneHost") cloudonePort := beego.AppConfig.String("cloudonePort") parameterMap := ws.Request().URL.Query() widthSlice := parameterMap["width"] heightSlice := parameterMap["height"] hostIPSlice := parameterMap["hostIP"] containerIDSlice := parameterMap["containerID"] tokenSlice := parameterMap["token"] if len(widthSlice) != 1 { errorMessage := "Parameter width is incorrect" ws.Write([]byte(errorMessage)) ws.Close() return } width, err := strconv.Atoi(widthSlice[0]) if err != nil { errorMessage := "Format of parameter width is incorrect" ws.Write([]byte(errorMessage)) ws.Close() return } if len(heightSlice) != 1 { errorMessage := "Parameter height is incorrect" ws.Write([]byte(errorMessage)) ws.Close() return } height, err := strconv.Atoi(heightSlice[0]) if err != nil { errorMessage := "Format of parameter height is incorrect" ws.Write([]byte(errorMessage)) ws.Close() return } if len(hostIPSlice) != 1 { errorMessage := "Parameter hostIP is incorrect" ws.Write([]byte(errorMessage)) ws.Close() return } hostIP := hostIPSlice[0] if len(containerIDSlice) != 1 { errorMessage := "Parameter containerID is incorrect" ws.Write([]byte(errorMessage)) ws.Close() return } containerID := containerIDSlice[0] // Remove docker protocol prefix docker:// containerID = containerID[9:] if len(tokenSlice) != 1 { errorMessage := "Parameter token is incorrect" ws.Write([]byte(errorMessage)) ws.Close() return } token := tokenSlice[0] headerMap := make(map[string]string) headerMap["token"] = token url := cloudoneProtocol + "://" + cloudoneHost + ":" + cloudonePort + "/api/v1/hosts/credentials/" + hostIP credential := Credential{} _, err = restclient.RequestGetWithStructure(url, &credential, headerMap) if identity.IsTokenInvalid(err) { ws.Write([]byte(err.Error())) ws.Close() return } if err != nil { ws.Write([]byte(err.Error())) ws.Close() return } interactiveMap := make(map[string]string) interactiveMap["[sudo]"] = credential.SSH.Password + "\n" interactiveMap["exit"] = "exit\n" // Command way sshCommandProxy := sshclient.CreateSSHCommandProxy( 2*time.Second, credential.IP, credential.SSH.Port, credential.SSH.User, credential.SSH.Password, height, width, interactiveMap) i, o, _, err := sshCommandProxy.Connect() if err != nil { ws.Write([]byte(err.Error())) ws.Close() return } i <- "sudo docker exec -it " + containerID + " bash\n" go func() { for { data, ok := <-o if ok == false { break } else { ws.Write([]byte(data)) } } ws.Close() }() for { data, _, err := ioutility.ReadText(ws, 256) if err == io.EOF { break } else if err != nil { ws.Write([]byte(err.Error())) break } i <- data } ws.Close() sshCommandProxy.Disconnect() // Stream way /* sshStreamProxy := sshclient.CreateSSHStreamProxy( 2*time.Second, credential.IP, credential.SSH.Port, credential.SSH.User, credential.SSH.Password, height, width) w, r, _, err := sshStreamProxy.Connect() if err != nil { ws.Write([]byte(err.Error())) ws.Close() return } w.Write([]byte("sudo docker exec -it " + containerID + " bash\n")) w.Write([]byte(credential.SSH.Password + "\n")) go func() { // Cancatenate ssh reader to websocket writer io.Copy(ws, r) ws.Close() }() // Cancatenate websocket reader to ssh writer io.Copy(w, ws) ws.Close() sshStreamProxy.Disconnect() */ }
func ProxyServer(ws *websocket.Conn) { cloudoneProtocol := beego.AppConfig.String("cloudoneProtocol") cloudoneHost := beego.AppConfig.String("cloudoneHost") cloudonePort := beego.AppConfig.String("cloudonePort") cloudoneAnalysisProtocol := beego.AppConfig.String("cloudoneAnalysisProtocol") cloudoneAnalysisHost := beego.AppConfig.String("cloudoneAnalysisHost") cloudoneAnalysisPort := beego.AppConfig.String("cloudoneAnalysisPort") parameterMap := ws.Request().URL.Query() upgradeCloudone := getParameter(parameterMap, "upgradeCloudone") upgradeCloudoneImagePath := getParameter(parameterMap, "upgradeCloudoneImagePath") upgradeCloudoneVersion := getParameter(parameterMap, "upgradeCloudoneVersion") upgradeCloudoneGUI := getParameter(parameterMap, "upgradeCloudoneGUI") upgradeCloudoneGUIImagePath := getParameter(parameterMap, "upgradeCloudoneGUIImagePath") upgradeCloudoneGUIVersion := getParameter(parameterMap, "upgradeCloudoneGUIVersion") upgradeCloudoneAnalysis := getParameter(parameterMap, "upgradeCloudoneAnalysis") upgradeCloudoneAnalysisImagePath := getParameter(parameterMap, "upgradeCloudoneAnalysisImagePath") upgradeCloudoneAnalysisVersion := getParameter(parameterMap, "upgradeCloudoneAnalysisVersion") upgradeTopologyConfiguration := getParameter(parameterMap, "upgradeTopologyConfiguration") upgradeNamespace := getParameter(parameterMap, "upgradeNamespace") upgradeReplicationControllerName := getParameter(parameterMap, "upgradeReplicationControllerName") upgradeReplicationControllerContent := getParameter(parameterMap, "upgradeReplicationControllerContent") upgradeServiceName := getParameter(parameterMap, "upgradeServiceName") upgradeServiceContent := getParameter(parameterMap, "upgradeServiceContent") httpsCertFileContent := getParameter(parameterMap, "httpsCertFile") httpsKeyFileContent := getParameter(parameterMap, "httpsKeyFile") token := getParameter(parameterMap, "token") headerMap := make(map[string]string) headerMap["token"] = token // Configre certificate certificateChanged, err := configureCertificate(ws, httpsCertFileContent, httpsKeyFileContent) if err != nil { errorMessage := "Configure certificates with error " + err.Error() + "\n" ws.Write([]byte(errorMessage)) ws.Close() return } if certificateChanged { upgradeCloudoneGUI = "true" } replicationControllerJsonMap := make(map[string]interface{}) serviceJsonMap := make(map[string]interface{}) if upgradeTopologyConfiguration == "true" { if upgradeReplicationControllerContent != "" { err := json.Unmarshal([]byte(upgradeReplicationControllerContent), &replicationControllerJsonMap) if err != nil { errorMessage := "Can't unmarshal upgradeReplicationControllerContent with error " + err.Error() + "\n" ws.Write([]byte(errorMessage)) ws.Close() return } } if upgradeServiceContent != "" { err := json.Unmarshal([]byte(upgradeServiceContent), &serviceJsonMap) if err != nil { errorMessage := "Can't unmarshal upgradeServiceContent with error " + err.Error() + "\n" ws.Write([]byte(errorMessage)) ws.Close() return } } } // Get credential url := cloudoneProtocol + "://" + cloudoneHost + ":" + cloudonePort + "/api/v1/hosts/credentials/" credentialSlice := make([]Credential, 0) _, err = restclient.RequestGetWithStructure(url, &credentialSlice, headerMap) if identity.IsTokenInvalid(err) { ws.Write([]byte(err.Error())) ws.Close() return } if err != nil { errorMessage := "Can't get credential data with error " + err.Error() + "\n" ws.Write([]byte(errorMessage)) ws.Close() return } // Pull images if upgradeCloudone == "true" { err := UpgradeDockerImage(ws, credentialSlice, upgradeCloudoneImagePath, upgradeCloudoneVersion) if err != nil { errorMessage := "Can't upgrade image cloudone with error " + err.Error() + "\n" ws.Write([]byte(errorMessage)) ws.Close() return } } if upgradeCloudoneGUI == "true" { err := UpgradeDockerImage(ws, credentialSlice, upgradeCloudoneGUIImagePath, upgradeCloudoneGUIVersion) if err != nil { errorMessage := "Can't upgrade image cloudone gui with error " + err.Error() + "\n" ws.Write([]byte(errorMessage)) ws.Close() return } } if upgradeCloudoneAnalysis == "true" { err := UpgradeDockerImage(ws, credentialSlice, upgradeCloudoneAnalysisImagePath, upgradeCloudoneAnalysisVersion) if err != nil { errorMessage := "Can't upgrade image cloudone analysis with error " + err.Error() + "\n" ws.Write([]byte(errorMessage)) ws.Close() return } } // Update service if len(serviceJsonMap) > 0 { url := cloudoneProtocol + "://" + cloudoneHost + ":" + cloudonePort + "/api/v1/services/json/" + upgradeNamespace + "/" + upgradeReplicationControllerName ws.Write([]byte("Start to update service\n")) _, err := restclient.RequestPutWithStructure(url, serviceJsonMap, nil, headerMap) if identity.IsTokenInvalid(err) { ws.Write([]byte(err.Error())) ws.Close() return } if err != nil { errorMessage := "Can't upgrade service with error " + err.Error() + "\n" ws.Write([]byte(errorMessage)) ws.Close() return } else { ws.Write([]byte("The service is updated\n")) } } if len(replicationControllerJsonMap) > 0 { // Update replication controller to change all instances url := cloudoneProtocol + "://" + cloudoneHost + ":" + cloudonePort + "/api/v1/replicationcontrollers/json/" + upgradeNamespace + "/" + upgradeServiceName ws.Write([]byte("Stop and recreate the replication controller. Please refresh the page after tens of seconds\n")) _, err := restclient.RequestPutWithStructure(url, replicationControllerJsonMap, nil, headerMap) if identity.IsTokenInvalid(err) { ws.Write([]byte(err.Error())) ws.Close() return } if err != nil { errorMessage := "Can't upgrade replication controller with error " + err.Error() + "\n" ws.Write([]byte(errorMessage)) ws.Close() return } else { ws.Write([]byte("The replication controller is updated\n")) } } else { // Only update the specific docker containers url := cloudoneProtocol + "://" + cloudoneHost + ":" + cloudonePort + "/api/v1/replicationcontrollers/" + upgradeNamespace replicationControllerAndRelatedPodSlice := make([]ReplicationControllerAndRelatedPod, 0) _, err := restclient.RequestGetWithStructure(url, &replicationControllerAndRelatedPodSlice, headerMap) if identity.IsTokenInvalid(err) { ws.Write([]byte(err.Error())) ws.Close() return } if err != nil { errorMessage := "Can't get replication controller and related pod data with error " + err.Error() + "\n" ws.Write([]byte(errorMessage)) ws.Close() return } selectedReplicationControllerAndRelatedPod := ReplicationControllerAndRelatedPod{} for _, replicationControllerAndRelatedPod := range replicationControllerAndRelatedPodSlice { if replicationControllerAndRelatedPod.Name == upgradeReplicationControllerName { selectedReplicationControllerAndRelatedPod = replicationControllerAndRelatedPod } } for _, pod := range selectedReplicationControllerAndRelatedPod.PodSlice { usedCredential := Credential{} for _, credential := range credentialSlice { if credential.IP == pod.HostIP { usedCredential = credential break } } cloudoneContainer := PodContainer{} cloudoneAnalysisContainer := PodContainer{} cloudoneGUIContainer := PodContainer{} for _, container := range pod.ContainerSlice { if container.Name == "cloudone" { cloudoneContainer = container } if container.Name == "cloudone-analysis" { cloudoneAnalysisContainer = container } if container.Name == "cloudone-gui" { cloudoneGUIContainer = container } } if upgradeCloudone == "true" && cloudoneContainer.ContainerID != "" { containerID := cloudoneContainer.ContainerID[9:] ws.Write([]byte("Stop and recreate cloudone\n")) err := stopDockerContainer(usedCredential, containerID) if err != nil { errorMessage := "Can't stop container " + cloudoneContainer.Name + " with error " + err.Error() + "\n" ws.Write([]byte(errorMessage)) ws.Close() return } } if upgradeCloudoneAnalysis == "true" && cloudoneAnalysisContainer.ContainerID != "" { containerID := cloudoneAnalysisContainer.ContainerID[9:] ws.Write([]byte("Stop and recreate cloudone_analysis\n")) err := stopDockerContainer(usedCredential, containerID) if err != nil { errorMessage := "Can't stop container " + cloudoneAnalysisContainer.Name + " with error " + err.Error() + "\n" ws.Write([]byte(errorMessage)) ws.Close() return } } if upgradeCloudoneGUI == "true" && cloudoneGUIContainer.ContainerID != "" { containerID := cloudoneGUIContainer.ContainerID[9:] ws.Write([]byte("Stop and recreate cloudone_gui. Please refresh the page after tens of seconds\n")) err := stopDockerContainer(usedCredential, containerID) if err != nil { errorMessage := "Can't stop container " + cloudoneGUIContainer.Name + " with error " + err.Error() + "\n" ws.Write([]byte(errorMessage)) ws.Close() return } } } if upgradeCloudone == "true" { url := cloudoneProtocol + "://" + cloudoneHost + ":" + cloudonePort + "/api/v1/healthchecks/" cloudoneJsonMap := make(map[string]interface{}, 0) for { time.Sleep(time.Second) _, err := restclient.RequestGetWithStructure(url, &cloudoneJsonMap, headerMap) if identity.IsTokenInvalid(err) { ws.Write([]byte(err.Error())) ws.Close() return } if err == nil { break } else { ws.Write([]byte("Wait for Cloudone to come up\n")) } } } if upgradeCloudoneAnalysis == "true" { url := cloudoneAnalysisProtocol + "://" + cloudoneAnalysisHost + ":" + cloudoneAnalysisPort + "/api/v1/healthchecks/" cloudoneAnalysisJsonMap := make(map[string]interface{}, 0) for { time.Sleep(time.Second) _, err := restclient.RequestGetWithStructure(url, &cloudoneAnalysisJsonMap, headerMap) if identity.IsTokenInvalid(err) { ws.Write([]byte(err.Error())) ws.Close() return } if err == nil { break } else { ws.Write([]byte("Wait for Cloudone Analysis to come up\n")) } } } } ws.Write([]byte("Upgrade is done\n")) ws.Close() }