Files
cloudpods/pkg/webconsole/session/remote_console.go
2021-08-27 16:41:57 +08:00

206 lines
5.4 KiB
Go

// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package session
import (
"fmt"
"net/url"
"os/exec"
api "yunion.io/x/onecloud/pkg/apis/webconsole"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/modules"
"yunion.io/x/onecloud/pkg/webconsole/options"
)
const (
VNC = api.VNC
ALIYUN = api.ALIYUN
QCLOUD = api.QCLOUD
OPENSTACK = api.OPENSTACK
SPICE = api.SPICE
WMKS = api.WMKS
VMRC = api.VMRC
ZSTACK = api.ZSTACK
CTYUN = api.CTYUN
HUAWEI = api.HUAWEI
APSARA = api.APSARA
JDCLOUD = api.JDCLOUD
CLOUDPODS = api.CLOUDPODS
)
type RemoteConsoleInfo struct {
Host string `json:"host"`
Port int64 `json:"port"`
Protocol string `json:"protocol"`
Id string `json:"id"`
OsName string `json:"osName"`
VncPassword string `json:"vncPassword"`
// used by aliyun server
InstanceId string `json:"instance_id"`
InstanceName string `json:"instance_name"`
Url string `json:"url"`
Password string `json:"password"`
ConnectParams string `json:"connect_params"`
ApiServer string `json:"api_server"`
}
func NewRemoteConsoleInfoByCloud(s *mcclient.ClientSession, serverId string) (*RemoteConsoleInfo, error) {
ret, err := modules.Servers.GetSpecific(s, serverId, "vnc", nil)
if err != nil {
return nil, err
}
vncInfo := RemoteConsoleInfo{}
err = ret.Unmarshal(&vncInfo)
if err != nil {
return nil, err
}
if len(vncInfo.OsName) == 0 || len(vncInfo.VncPassword) == 0 {
metadata, err := modules.Servers.GetSpecific(s, serverId, "metadata", nil)
if err != nil {
return nil, err
}
osName, _ := metadata.GetString("os_name")
vncPasswd, _ := metadata.GetString("__vnc_password")
vncInfo.OsName = osName
vncInfo.VncPassword = vncPasswd
}
return &vncInfo, nil
}
// GetProtocol implements ISessionData interface
func (info *RemoteConsoleInfo) GetProtocol() string {
return info.Protocol
}
// GetCommand implements ISessionData interface
func (info *RemoteConsoleInfo) GetCommand() *exec.Cmd {
return nil
}
// Cleanup implements ISessionData interface
func (info *RemoteConsoleInfo) Cleanup() error {
return nil
}
// Connect implements ISessionData interface
func (info *RemoteConsoleInfo) Connect() error {
return nil
}
// IsNeedShowInfo implements ISessionData interface
func (info *RemoteConsoleInfo) IsNeedShowInfo() bool {
return false
}
// Reconnect implements ISessionData interface
func (info *RemoteConsoleInfo) Reconnect() {
return
}
// Scan implements ISessionData interface
func (info *RemoteConsoleInfo) Scan(byte, func(string)) {
return
}
// ShowInfo implements ISessionData interface
func (info *RemoteConsoleInfo) ShowInfo() string {
return ""
}
func (info *RemoteConsoleInfo) GetConnectParams() (string, error) {
switch info.Protocol {
case ALIYUN:
return info.getAliyunURL()
case APSARA:
return info.getApsaraURL()
case QCLOUD:
return info.getQcloudURL()
case CLOUDPODS:
return info.getCloudpodsURL()
case OPENSTACK, VMRC, ZSTACK, CTYUN, HUAWEI, JDCLOUD:
return info.Url, nil
default:
return "", fmt.Errorf("Can't convert protocol %s to connect params", info.Protocol)
}
}
func (info *RemoteConsoleInfo) GetPassword() string {
if len(info.Password) != 0 {
return info.Password
}
return info.VncPassword
}
func (info *RemoteConsoleInfo) GetId() string {
return info.Id
}
func (info *RemoteConsoleInfo) getConnParamsURL(baseURL string, params url.Values) string {
if params == nil {
params = url.Values{}
}
params.Set("protocol", info.Protocol)
queryURL := params.Encode()
return fmt.Sprintf("%s?%s", baseURL, queryURL)
}
func (info *RemoteConsoleInfo) getQcloudURL() (string, error) {
base := "https://img.qcloud.com/qcloud/app/active_vnc/index.html?InstanceVncUrl=" + info.Url
return info.getConnParamsURL(base, nil), nil
}
func (info *RemoteConsoleInfo) getAliyunURL() (string, error) {
isWindows := "false"
if info.OsName == "Windows" {
isWindows = "true"
}
base := fmt.Sprintf("https://g.alicdn.com/aliyun/ecs-console-vnc2/%s/index.html", options.Options.AliyunVncVersion)
params := url.Values{
"vncUrl": {info.Url},
"instanceId": {info.InstanceId},
"isWindows": {isWindows},
"password": {info.Password},
}
return info.getConnParamsURL(base, params), nil
}
func (info *RemoteConsoleInfo) getCloudpodsURL() (string, error) {
base := fmt.Sprintf("%s/web-console/no-vnc", info.ApiServer)
params := url.Values{
"data": {info.ConnectParams},
"instanceId": {info.InstanceId},
"instanceName": {info.InstanceName},
}
return info.getConnParamsURL(base, params), nil
}
func (info *RemoteConsoleInfo) getApsaraURL() (string, error) {
isWindows := "False"
if info.OsName == "Windows" {
isWindows = "True"
}
params := url.Values{
"vncUrl": {info.Url},
"instanceId": {info.InstanceId},
"isWindows": {isWindows},
"password": {info.Password},
}
return info.getConnParamsURL(options.Options.ApsaraConsoleAddr, params), nil
}