fix(webconsole): support vnc for openstack

This commit is contained in:
Qu Xuan
2021-11-04 19:24:52 +08:00
parent da8f6c7f56
commit 5f497f2d6a
30 changed files with 216 additions and 174 deletions
+36
View File
@@ -227,3 +227,39 @@ func (vmConfig *SManagedVMCreateConfig) InjectPasswordByCloudInit() error {
vmConfig.UserData = cloudconfig.UserData()
return nil
}
// +onecloud:model-api-gen
type ServerVncInput struct {
// 是否使用原生vnc控制台,此选项仅对openstack有效
// default: false
Origin bool `json:"origin"`
}
// +onecloud:model-api-gen
type ServerVncOutput struct {
Id string
// baremetal
HostId string
Zone string
// kvm host ip
Host string
Protocol string
Port int64
Url string
InstanceId string
InstanceName string
Password string
VncPassword string
OsName string
// cloudpods
ApiServer string
ConnectParams string
Session string
Hypervisor string
}
+1 -1
View File
@@ -366,7 +366,7 @@ type ICloudVM interface {
ChangeConfig(ctx context.Context, config *SManagedVMChangeConfig) error
GetVNCInfo() (jsonutils.JSONObject, error)
GetVNCInfo(input *ServerVncInput) (*ServerVncOutput, error)
AttachDisk(ctx context.Context, diskId string) error
DetachDisk(ctx context.Context, diskId string) error
+5 -5
View File
@@ -433,12 +433,12 @@ func (self *SBaremetalGuestDriver) GetJsonDescAtHost(ctx context.Context, userCr
return jsonutils.Marshal(desc), nil
}
func (self *SBaremetalGuestDriver) GetGuestVncInfo(ctx context.Context, userCred mcclient.TokenCredential, guest *models.SGuest, host *models.SHost) (*jsonutils.JSONDict, error) {
data := jsonutils.NewDict()
data.Add(jsonutils.NewString(host.Id), "host_id")
func (self *SBaremetalGuestDriver) GetGuestVncInfo(ctx context.Context, userCred mcclient.TokenCredential, guest *models.SGuest, host *models.SHost, input *cloudprovider.ServerVncInput) (*cloudprovider.ServerVncOutput, error) {
ret := &cloudprovider.ServerVncOutput{}
ret.HostId = host.Id
zone, _ := host.GetZone()
data.Add(jsonutils.NewString(zone.Name), "zone")
return data, nil
ret.Zone = zone.Name
return ret, nil
}
func (self *SBaremetalGuestDriver) RequestRebuildRootDisk(ctx context.Context, guest *models.SGuest, task taskman.ITask) error {
+1 -1
View File
@@ -127,7 +127,7 @@ func (self *SContainerDriver) CanKeepDetachDisk() bool {
return false
}
func (self *SContainerDriver) GetGuestVncInfo(ctx context.Context, userCred mcclient.TokenCredential, guest *models.SGuest, host *models.SHost) (*jsonutils.JSONDict, error) {
func (self *SContainerDriver) GetGuestVncInfo(ctx context.Context, userCred mcclient.TokenCredential, guest *models.SGuest, host *models.SHost, input *cloudprovider.ServerVncInput) (*cloudprovider.ServerVncOutput, error) {
return nil, self.newUnsupportOperationError("VNC")
}
+11 -12
View File
@@ -162,7 +162,7 @@ func findVNCPort2(results string) int {
return -1
}
func (self *SKVMGuestDriver) GetGuestVncInfo(ctx context.Context, userCred mcclient.TokenCredential, guest *models.SGuest, host *models.SHost) (*jsonutils.JSONDict, error) {
func (self *SKVMGuestDriver) GetGuestVncInfo(ctx context.Context, userCred mcclient.TokenCredential, guest *models.SGuest, host *models.SHost, input *cloudprovider.ServerVncInput) (*cloudprovider.ServerVncOutput, error) {
url := fmt.Sprintf("/servers/%s/monitor", guest.Id)
body := jsonutils.NewDict()
var cmd string
@@ -174,14 +174,11 @@ func (self *SKVMGuestDriver) GetGuestVncInfo(ctx context.Context, userCred mccli
body.Add(jsonutils.NewString(cmd), "cmd")
ret, err := host.Request(ctx, userCred, "POST", url, nil, body)
if err != nil {
err = fmt.Errorf("Fail to request VNC info %s", err)
log.Errorln(err)
return nil, err
return nil, errors.Wrapf(err, "Fail to request VNC info")
}
results, _ := ret.GetString("results")
results, err := ret.GetString("results")
if len(results) == 0 {
err = fmt.Errorf("Can't get vnc information from host.")
return nil, err
return nil, errors.Wrapf(err, "Can't get vnc information from host.")
}
// info_vnc = result['results'].split('\n')
// port = int(info_vnc[1].split(':')[-1].split()[0])
@@ -207,11 +204,13 @@ func (self *SKVMGuestDriver) GetGuestVncInfo(ctx context.Context, userCred mccli
port = findVNCPort(results)
}
retval := jsonutils.NewDict()
retval.Add(jsonutils.NewString(host.AccessIp), "host")
retval.Add(jsonutils.NewString(guest.GetVdi()), "protocol")
retval.Add(jsonutils.NewInt(int64(port)), "port")
return retval, nil
result := &cloudprovider.ServerVncOutput{
Host: host.AccessIp,
Protocol: guest.GetVdi(),
Port: int64(port),
Hypervisor: api.HYPERVISOR_ESXI,
}
return result, nil
}
func (self *SKVMGuestDriver) RequestStopOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, task taskman.ITask) error {
+2 -9
View File
@@ -805,7 +805,7 @@ func (self *SManagedVirtualizedGuestDriver) RequestSyncstatusOnHost(ctx context.
return body, nil
}
func (self *SManagedVirtualizedGuestDriver) GetGuestVncInfo(ctx context.Context, userCred mcclient.TokenCredential, guest *models.SGuest, host *models.SHost) (*jsonutils.JSONDict, error) {
func (self *SManagedVirtualizedGuestDriver) GetGuestVncInfo(ctx context.Context, userCred mcclient.TokenCredential, guest *models.SGuest, host *models.SHost, input *cloudprovider.ServerVncInput) (*cloudprovider.ServerVncOutput, error) {
ihost, err := host.GetIHost()
if err != nil {
return nil, err
@@ -817,14 +817,7 @@ func (self *SManagedVirtualizedGuestDriver) GetGuestVncInfo(ctx context.Context,
return nil, err
}
data, err := iVM.GetVNCInfo()
if err != nil {
return nil, err
}
dataDict := data.(*jsonutils.JSONDict)
return dataDict, nil
return iVM.GetVNCInfo(input)
}
func (self *SManagedVirtualizedGuestDriver) RequestRebuildRootDisk(ctx context.Context, guest *models.SGuest, task taskman.ITask) error {
+12 -12
View File
@@ -71,21 +71,21 @@ func (self *SGuest) AllowGetDetailsVnc(ctx context.Context, userCred mcclient.To
return self.IsOwner(userCred) || db.IsAdminAllowGetSpec(userCred, self, "vnc")
}
func (self *SGuest) GetDetailsVnc(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (jsonutils.JSONObject, error) {
func (self *SGuest) GetDetailsVnc(ctx context.Context, userCred mcclient.TokenCredential, input *cloudprovider.ServerVncInput) (*cloudprovider.ServerVncOutput, error) {
ret := &cloudprovider.ServerVncOutput{}
if utils.IsInStringArray(self.Status, []string{api.VM_RUNNING, api.VM_BLOCK_STREAM}) {
host, _ := self.GetHost()
if host == nil {
return nil, httperrors.NewInternalServerError("Host missing")
host, err := self.GetHost()
if err != nil {
return nil, httperrors.NewInternalServerError(errors.Wrapf(err, "GetHost").Error())
}
retval, err := self.GetDriver().GetGuestVncInfo(ctx, userCred, self, host)
ret, err = self.GetDriver().GetGuestVncInfo(ctx, userCred, self, host, input)
if err != nil {
return nil, err
}
retval.Add(jsonutils.NewString(self.Id), "id")
return retval, nil
} else {
return jsonutils.NewDict(), nil
ret.Id = self.Id
return ret, nil
}
return ret, nil
}
func (self *SGuest) PreCheckPerformAction(
@@ -4150,13 +4150,13 @@ func (self *SGuest) GetDetailsVirtInstall(
host, _ := self.GetHost()
if utils.IsInStringArray(self.Status, []string{api.VM_RUNNING, api.VM_BLOCK_STREAM}) {
vncInfo, err := self.GetDriver().GetGuestVncInfo(ctx, userCred, self, host)
vncInfo, err := self.GetDriver().GetGuestVncInfo(ctx, userCred, self, host, nil)
if err != nil {
log.Errorln(err)
return nil, err
}
vdiProtocol, _ = vncInfo.GetString("protocol")
vdiListenPort, _ = vncInfo.Int("port")
vdiProtocol = vncInfo.Protocol
vdiListenPort = int64(vncInfo.Port)
}
extraCmdline, _ := query.GetArray("extra_cmdline")
+1 -1
View File
@@ -130,7 +130,7 @@ type IGuestDriver interface {
CheckDiskTemplateOnStorage(ctx context.Context, userCred mcclient.TokenCredential, imageId string, format string, storageId string, task taskman.ITask) error
GetGuestVncInfo(ctx context.Context, userCred mcclient.TokenCredential, guest *SGuest, host *SHost) (*jsonutils.JSONDict, error)
GetGuestVncInfo(ctx context.Context, userCred mcclient.TokenCredential, guest *SGuest, host *SHost, input *cloudprovider.ServerVncInput) (*cloudprovider.ServerVncOutput, error)
RequestAttachDisk(ctx context.Context, guest *SGuest, disk *SDisk, task taskman.ITask) error
RequestDetachDisk(ctx context.Context, guest *SGuest, disk *SDisk, task taskman.ITask) error
+8 -6
View File
@@ -408,7 +408,7 @@ func (self *SInstance) StopVM(ctx context.Context, opts *cloudprovider.ServerSto
return cloudprovider.WaitStatus(self, api.VM_READY, 10*time.Second, 300*time.Second) // 5mintues
}
func (self *SInstance) GetVNCInfo() (jsonutils.JSONObject, error) {
func (self *SInstance) GetVNCInfo(input *cloudprovider.ServerVncInput) (*cloudprovider.ServerVncOutput, error) {
url, err := self.host.zone.region.GetInstanceVNCUrl(self.InstanceId)
if err != nil {
return nil, err
@@ -418,11 +418,13 @@ func (self *SInstance) GetVNCInfo() (jsonutils.JSONObject, error) {
if err != nil {
return nil, err
}
ret := jsonutils.NewDict()
ret.Add(jsonutils.NewString(url), "url")
ret.Add(jsonutils.NewString(passwd), "password")
ret.Add(jsonutils.NewString("aliyun"), "protocol")
ret.Add(jsonutils.NewString(self.InstanceId), "instance_id")
ret := &cloudprovider.ServerVncOutput{
Url: url,
Password: passwd,
Protocol: "aliyun",
InstanceId: self.InstanceId,
Hypervisor: api.HYPERVISOR_ALIYUN,
}
return ret, nil
}
+8 -6
View File
@@ -391,7 +391,7 @@ func (self *SInstance) StopVM(ctx context.Context, opts *cloudprovider.ServerSto
return cloudprovider.WaitStatus(self, api.VM_READY, 10*time.Second, 300*time.Second) // 5mintues
}
func (self *SInstance) GetVNCInfo() (jsonutils.JSONObject, error) {
func (self *SInstance) GetVNCInfo(input *cloudprovider.ServerVncInput) (*cloudprovider.ServerVncOutput, error) {
url, err := self.host.zone.region.GetInstanceVNCUrl(self.InstanceId)
if err != nil {
return nil, err
@@ -401,11 +401,13 @@ func (self *SInstance) GetVNCInfo() (jsonutils.JSONObject, error) {
if err != nil {
return nil, err
}
ret := jsonutils.NewDict()
ret.Add(jsonutils.NewString(url), "url")
ret.Add(jsonutils.NewString(passwd), "password")
ret.Add(jsonutils.NewString("apsara"), "protocol")
ret.Add(jsonutils.NewString(self.InstanceId), "instance_id")
ret := &cloudprovider.ServerVncOutput{
Url: url,
Password: passwd,
Protocol: "apsara",
InstanceId: self.InstanceId,
Hypervisor: api.HYPERVISOR_APSARA,
}
return ret, nil
}
+1 -1
View File
@@ -502,7 +502,7 @@ func (self *SInstance) ChangeConfig2(ctx context.Context, instanceType string) e
return self.host.zone.region.ChangeVMConfig2(self.ZoneId, self.InstanceId, instanceType, nil)
}
func (self *SInstance) GetVNCInfo() (jsonutils.JSONObject, error) {
func (self *SInstance) GetVNCInfo(input *cloudprovider.ServerVncInput) (*cloudprovider.ServerVncOutput, error) {
return nil, cloudprovider.ErrNotSupported
}
+2 -3
View File
@@ -394,9 +394,8 @@ func (self *SClassicInstance) GetVmemSizeMB() int {
return 0
}
func (self *SClassicInstance) GetVNCInfo() (jsonutils.JSONObject, error) {
ret := jsonutils.NewDict()
return ret, nil
func (self *SClassicInstance) GetVNCInfo(input *cloudprovider.ServerVncInput) (*cloudprovider.ServerVncOutput, error) {
return nil, cloudprovider.ErrNotSupported
}
func (self *SClassicInstance) StartVM(ctx context.Context) error {
+2 -3
View File
@@ -951,9 +951,8 @@ func (self *SInstance) GetVmemSizeMB() int {
return int(self.vmSize.MemoryInMB)
}
func (self *SInstance) GetVNCInfo() (jsonutils.JSONObject, error) {
ret := jsonutils.NewDict()
return ret, nil
func (self *SInstance) GetVNCInfo(input *cloudprovider.ServerVncInput) (*cloudprovider.ServerVncOutput, error) {
return nil, cloudprovider.ErrNotSupported
}
func (self *SRegion) StartVM(instanceId string) error {
+6 -12
View File
@@ -267,25 +267,19 @@ func (self *SInstance) ChangeConfig(ctx context.Context, opts *cloudprovider.SMa
return err
}
func (self *SInstance) GetVNCInfo() (jsonutils.JSONObject, error) {
func (self *SInstance) GetVNCInfo(input *cloudprovider.ServerVncInput) (*cloudprovider.ServerVncOutput, error) {
s := self.host.zone.region.cli.s
resp, err := webconsole.WebConsole.DoServerConnect(s, self.Id, nil)
if err != nil {
return nil, errors.Wrapf(err, "DoServerConnect")
}
data := struct {
ConnectParams string
ApiServer string
Session string
Protocol string
InstanceId string
InstanceName string
}{
result := &cloudprovider.ServerVncOutput{
Protocol: "cloudpods",
InstanceId: self.Id,
InstanceName: self.Name,
Hypervisor: api.HYPERVISOR_CLOUDPODS,
}
err = resp.Unmarshal(&data)
err = resp.Unmarshal(&result)
if err != nil {
return nil, errors.Wrapf(err, "resp.Unmarshal")
}
@@ -293,8 +287,8 @@ func (self *SInstance) GetVNCInfo() (jsonutils.JSONObject, error) {
if err != nil {
return nil, errors.Wrapf(err, "GetSpecific")
}
data.ApiServer, _ = resp.GetString("config", "default", "api_server")
return jsonutils.Marshal(data), nil
result.ApiServer, _ = resp.GetString("config", "default", "api_server")
return result, nil
}
func (self *SInstance) AttachDisk(ctx context.Context, diskId string) error {
+7 -5
View File
@@ -597,15 +597,17 @@ func (self *SInstance) ChangeConfig(ctx context.Context, config *cloudprovider.S
}
// http://ctyun-api-url/apiproxy/v3/queryVncUrl
func (self *SInstance) GetVNCInfo() (jsonutils.JSONObject, error) {
func (self *SInstance) GetVNCInfo(input *cloudprovider.ServerVncInput) (*cloudprovider.ServerVncOutput, error) {
url, err := self.host.zone.region.GetInstanceVNCUrl(self.GetId())
if err != nil {
return nil, err
}
ret := jsonutils.NewDict()
ret.Add(jsonutils.NewString(url), "url")
ret.Add(jsonutils.NewString("ctyun"), "protocol")
ret.Add(jsonutils.NewString(self.GetId()), "instance_id")
ret := &cloudprovider.ServerVncOutput{
Url: url,
Protocol: "ctyun",
InstanceId: self.GetId(),
Hypervisor: api.HYPERVISOR_CTYUN,
}
return ret, nil
}
+7 -6
View File
@@ -19,7 +19,6 @@ import (
"fmt"
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/sets"
@@ -307,15 +306,17 @@ func (in *SInstance) ChangeConfig(ctx context.Context, config *cloudprovider.SMa
return errors.ErrNotImplemented
}
func (in *SInstance) GetVNCInfo() (jsonutils.JSONObject, error) {
func (in *SInstance) GetVNCInfo(input *cloudprovider.ServerVncInput) (*cloudprovider.ServerVncOutput, error) {
url, err := in.host.zone.region.GetInstanceVNCUrl(in.GetId())
if err != nil {
return nil, err
}
ret := jsonutils.NewDict()
ret.Add(jsonutils.NewString(url), "url")
ret.Add(jsonutils.NewString("ecloud"), "protocol")
ret.Add(jsonutils.NewString(in.GetId()), "instance_id")
ret := &cloudprovider.ServerVncOutput{
Url: url,
Protocol: "ecloud",
InstanceId: in.GetId(),
Hypervisor: api.HYPERVISOR_ECLOUD,
}
return ret, nil
}
+4 -5
View File
@@ -21,7 +21,6 @@ import (
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/multicloud/esxi"
"yunion.io/x/onecloud/pkg/util/printutils"
"yunion.io/x/onecloud/pkg/util/shellutils"
)
@@ -300,11 +299,11 @@ func init() {
if err != nil {
return err
}
info, err := vm.GetVNCInfo()
info, err := vm.GetVNCInfo(nil)
if err != nil {
return err
}
printutils.PrintJSONObject(info)
printObject(info)
return nil
})
@@ -317,7 +316,7 @@ func init() {
if err != nil {
return err
}
printutils.PrintJSONObject(info)
printObject(info)
return nil
})
@@ -330,7 +329,7 @@ func init() {
if err != nil {
return err
}
printutils.PrintJSONObject(info)
printObject(info)
return nil
})
+14 -13
View File
@@ -606,7 +606,7 @@ func (self *SVirtualMachine) doDetachDisk(ctx context.Context, vdisk *SVirtualDi
return vdisk.Delete(ctx)
}
func (self *SVirtualMachine) GetVNCInfo() (jsonutils.JSONObject, error) {
func (self *SVirtualMachine) GetVNCInfo(input *cloudprovider.ServerVncInput) (*cloudprovider.ServerVncOutput, error) {
hostVer := self.GetIHost().GetVersion()
if version.GE(hostVer, "6.5") {
info, err := self.acquireWebmksTicket("webmks")
@@ -617,21 +617,20 @@ func (self *SVirtualMachine) GetVNCInfo() (jsonutils.JSONObject, error) {
return self.acquireVmrcUrl()
}
func (self *SVirtualMachine) GetVmrcInfo() (jsonutils.JSONObject, error) {
func (self *SVirtualMachine) GetVmrcInfo() (*cloudprovider.ServerVncOutput, error) {
return self.acquireVmrcUrl()
}
func (self *SVirtualMachine) GetWebmksInfo() (jsonutils.JSONObject, error) {
func (self *SVirtualMachine) GetWebmksInfo() (*cloudprovider.ServerVncOutput, error) {
return self.acquireWebmksTicket("webmks")
}
func (self *SVirtualMachine) acquireWebmksTicket(ticketType string) (jsonutils.JSONObject, error) {
func (self *SVirtualMachine) acquireWebmksTicket(ticketType string) (*cloudprovider.ServerVncOutput, error) {
vm := object.NewVirtualMachine(self.manager.client.Client, self.getVirtualMachine().Self)
ticket, err := vm.AcquireTicket(self.manager.context, ticketType)
if err != nil {
return nil, err
}
ret := jsonutils.NewDict()
host := ticket.Host
if len(host) == 0 {
@@ -644,25 +643,27 @@ func (self *SVirtualMachine) acquireWebmksTicket(ticketType string) (jsonutils.J
if port == 0 {
port = 443
}
url := fmt.Sprintf("wss://%s:%d/ticket/%s", host, port, ticket.Ticket)
ret.Add(jsonutils.NewString("wmks"), "protocol")
ret.Add(jsonutils.NewString(url), "url")
ret := &cloudprovider.ServerVncOutput{
Url: fmt.Sprintf("wss://%s:%d/ticket/%s", host, port, ticket.Ticket),
Protocol: "wmks",
Hypervisor: api.HYPERVISOR_ESXI,
}
return ret, nil
}
func (self *SVirtualMachine) acquireVmrcUrl() (jsonutils.JSONObject, error) {
func (self *SVirtualMachine) acquireVmrcUrl() (*cloudprovider.ServerVncOutput, error) {
ticket, err := self.manager.acquireCloneTicket()
if err != nil {
return nil, err
}
ret := jsonutils.NewDict()
ret.Add(jsonutils.NewString("vmrc"), "protocol")
port := self.manager.port
if port == 0 {
port = 443
}
url := fmt.Sprintf("vmrc://clone:%s@%s:%d/?moid=%s", ticket, self.manager.host, port, self.GetId())
ret.Add(jsonutils.NewString(url), "url")
ret := &cloudprovider.ServerVncOutput{
Url: fmt.Sprintf("vmrc://clone:%s@%s:%d/?moid=%s", ticket, self.manager.host, port, self.GetId()),
Protocol: "vmrc",
}
return ret, nil
}
+1 -1
View File
@@ -499,7 +499,7 @@ func (instance *SInstance) ChangeConfig(ctx context.Context, config *cloudprovid
return instance.host.zone.region.ChangeInstanceConfig(instance.SelfLink, instance.host.zone.Name, config.InstanceType, config.Cpu, config.MemoryMB)
}
func (instance *SInstance) GetVNCInfo() (jsonutils.JSONObject, error) {
func (instance *SInstance) GetVNCInfo(input *cloudprovider.ServerVncInput) (*cloudprovider.ServerVncOutput, error) {
return nil, cloudprovider.ErrNotImplemented
}
+7 -6
View File
@@ -678,7 +678,7 @@ func (self *SInstance) ChangeConfig(ctx context.Context, config *cloudprovider.S
}
// todo:// 返回jsonobject感觉很诡异。不能直接知道内部细节
func (self *SInstance) GetVNCInfo() (jsonutils.JSONObject, error) {
func (self *SInstance) GetVNCInfo(input *cloudprovider.ServerVncInput) (*cloudprovider.ServerVncOutput, error) {
return self.host.zone.region.GetInstanceVNCUrl(self.GetId())
}
@@ -1244,22 +1244,23 @@ func (self *SRegion) ChangeVMConfig(instanceId string, instanceType string) erro
// https://support.huaweicloud.com/api-ecs/zh-cn_topic_0142763126.html 微版本2.6及以上?
// https://support.huaweicloud.com/api-ecs/ecs_02_0208.html
func (self *SRegion) GetInstanceVNCUrl(instanceId string) (jsonutils.JSONObject, error) {
func (self *SRegion) GetInstanceVNCUrl(instanceId string) (*cloudprovider.ServerVncOutput, error) {
params := jsonutils.NewDict()
vncObj := jsonutils.NewDict()
vncObj.Add(jsonutils.NewString("novnc"), "type")
vncObj.Add(jsonutils.NewString("vnc"), "protocol")
params.Add(vncObj, "remote_console")
ret, err := self.ecsClient.Servers.PerformAction2("remote_console", instanceId, params, "remote_console")
resp, err := self.ecsClient.Servers.PerformAction2("remote_console", instanceId, params, "remote_console")
if err != nil {
return nil, err
}
if retDict, ok := ret.(*jsonutils.JSONDict); ok {
retDict.Set("protocol", jsonutils.NewString("huawei"))
ret := &cloudprovider.ServerVncOutput{
Hypervisor: api.HYPERVISOR_HCSO,
}
resp.Unmarshal(ret)
ret.Protocol = "huawei"
return ret, nil
}
+7 -6
View File
@@ -687,7 +687,7 @@ func (self *SInstance) ChangeConfig(ctx context.Context, config *cloudprovider.S
}
// todo:// 返回jsonobject感觉很诡异。不能直接知道内部细节
func (self *SInstance) GetVNCInfo() (jsonutils.JSONObject, error) {
func (self *SInstance) GetVNCInfo(input *cloudprovider.ServerVncInput) (*cloudprovider.ServerVncOutput, error) {
return self.host.zone.region.GetInstanceVNCUrl(self.GetId())
}
@@ -1273,7 +1273,7 @@ func (self *SRegion) ChangeVMConfig(instanceId string, instanceType string) erro
// https://support.huaweicloud.com/api-ecs/zh-cn_topic_0142763126.html 微版本2.6及以上?
// https://support.huaweicloud.com/api-ecs/ecs_02_0208.html
func (self *SRegion) GetInstanceVNCUrl(instanceId string) (jsonutils.JSONObject, error) {
func (self *SRegion) GetInstanceVNCUrl(instanceId string) (*cloudprovider.ServerVncOutput, error) {
params := jsonutils.NewDict()
vncObj := jsonutils.NewDict()
vncObj.Add(jsonutils.NewString("novnc"), "type")
@@ -1285,11 +1285,12 @@ func (self *SRegion) GetInstanceVNCUrl(instanceId string) (jsonutils.JSONObject,
return nil, err
}
if retDict, ok := ret.(*jsonutils.JSONDict); ok {
retDict.Set("protocol", jsonutils.NewString("huawei"))
result := &cloudprovider.ServerVncOutput{
Hypervisor: api.HYPERVISOR_HUAWEI,
}
return ret, nil
ret.Unmarshal(result)
result.Protocol = "huawei"
return result, nil
}
// https://support.huaweicloud.com/api-ecs/zh-cn_topic_0022472987.html
+7 -7
View File
@@ -24,7 +24,6 @@ import (
"github.com/jdcloud-api/jdcloud-sdk-go/services/vm/client"
"github.com/jdcloud-api/jdcloud-sdk-go/services/vm/models"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/sets"
@@ -309,7 +308,7 @@ func (in *SInstance) ChangeConfig(ctx context.Context, config *cloudprovider.SMa
return cloudprovider.ErrNotImplemented
}
func (in *SInstance) GetVNCInfo() (jsonutils.JSONObject, error) {
func (in *SInstance) GetVNCInfo(input *cloudprovider.ServerVncInput) (*cloudprovider.ServerVncOutput, error) {
region := in.host.zone.region
req := apis.NewDescribeInstanceVncUrlRequest(region.ID, in.InstanceId)
client := client.NewVmClient(region.Credential)
@@ -318,12 +317,13 @@ func (in *SInstance) GetVNCInfo() (jsonutils.JSONObject, error) {
if err != nil {
return nil, err
}
url := resp.Result.VncUrl
ret := jsonutils.NewDict()
ret.Add(jsonutils.NewString(url), "url")
ret.Add(jsonutils.NewString("jdcloud"), "protocol")
ret.Add(jsonutils.NewString(in.GetId()), "instance_id")
ret := &cloudprovider.ServerVncOutput{
Url: resp.Result.VncUrl,
Protocol: "jdcloud",
InstanceId: in.GetId(),
Hypervisor: api.HYPERVISOR_JDCLOUD,
}
return ret, nil
}
+27 -12
View File
@@ -419,7 +419,7 @@ func (instance *SInstance) StopVM(ctx context.Context, opts *cloudprovider.Serve
return cloudprovider.WaitStatus(instance, api.VM_READY, 10*time.Second, 8*time.Minute)
}
func (region *SRegion) GetInstanceVNCUrl(instanceId string) (string, error) {
func (region *SRegion) GetInstanceVNCUrl(instanceId string, origin bool) (*cloudprovider.ServerVncOutput, error) {
params := map[string]map[string]string{
"remote_console": {
"protocol": "vnc",
@@ -429,21 +429,36 @@ func (region *SRegion) GetInstanceVNCUrl(instanceId string) (string, error) {
resource := fmt.Sprintf("/servers/%s/remote-consoles", instanceId)
resp, err := region.ecsPost(resource, params)
if err != nil {
return "", errors.Wrap(err, "ecsPost")
return nil, errors.Wrap(err, "ecsPost")
}
return resp.GetString("remote_console", "url")
ret := &cloudprovider.ServerVncOutput{
Protocol: "openstack",
InstanceId: instanceId,
Hypervisor: api.HYPERVISOR_OPENSTACK,
}
ret.Url, err = resp.GetString("remote_console", "url")
if err != nil {
return nil, errors.Wrapf(err, "remote_console")
}
if origin {
return ret, nil
}
token := string([]byte(ret.Url)[len(ret.Url)-36:])
vncUrl, _ := url.Parse(ret.Url)
ret.Url = fmt.Sprintf("ws://%s?token=%s", vncUrl.Host, token)
ret.Protocol = "vnc"
return ret, nil
}
func (instance *SInstance) GetVNCInfo() (jsonutils.JSONObject, error) {
url, err := instance.host.zone.region.GetInstanceVNCUrl(instance.Id)
if err != nil {
return nil, errors.Wrap(err, "GetInstanceVNCUrl")
func (instance *SInstance) GetVNCInfo(input *cloudprovider.ServerVncInput) (*cloudprovider.ServerVncOutput, error) {
origin := false
if input != nil {
origin = input.Origin
}
ret := jsonutils.NewDict()
ret.Add(jsonutils.NewString(url), "url")
ret.Add(jsonutils.NewString("openstack"), "protocol")
ret.Add(jsonutils.NewString(instance.Id), "instance_id")
return ret, nil
return instance.host.zone.region.GetInstanceVNCUrl(instance.Id, origin)
}
func (instance *SInstance) DeployVM(ctx context.Context, name string, username string, password string, publicKey string, deleteKeypair bool, description string) error {
+1 -1
View File
@@ -66,7 +66,7 @@ func init() {
})
shellutils.R(&InstanceOptions{}, "instance-vnc", "Show instance vnc url", func(cli *openstack.SRegion, args *InstanceOptions) error {
url, err := cli.GetInstanceVNCUrl(args.ID)
url, err := cli.GetInstanceVNCUrl(args.ID, false)
if err != nil {
return err
}
+7 -5
View File
@@ -427,15 +427,17 @@ func (self *SInstance) StopVM(ctx context.Context, opts *cloudprovider.ServerSto
return cloudprovider.WaitStatus(self, api.VM_READY, 10*time.Second, 8*time.Minute) // 8 mintues, 腾讯云有时关机比较慢
}
func (self *SInstance) GetVNCInfo() (jsonutils.JSONObject, error) {
func (self *SInstance) GetVNCInfo(input *cloudprovider.ServerVncInput) (*cloudprovider.ServerVncOutput, error) {
url, err := self.host.zone.region.GetInstanceVNCUrl(self.InstanceId)
if err != nil {
return nil, err
}
ret := jsonutils.NewDict()
ret.Add(jsonutils.NewString(url), "url")
ret.Add(jsonutils.NewString("qcloud"), "protocol")
ret.Add(jsonutils.NewString(self.InstanceId), "instance_id")
ret := &cloudprovider.ServerVncOutput{
Url: url,
Protocol: "qcloud",
InstanceId: self.InstanceId,
Hypervisor: api.HYPERVISOR_QCLOUD,
}
return ret, nil
}
+9 -9
View File
@@ -524,7 +524,7 @@ func (self *SInstance) ChangeConfig2(ctx context.Context, instanceType string) e
return self.host.zone.region.ResizeVM(self.GetId(), i.CPU, i.MemoryMB)
}
func (self *SInstance) GetVNCInfo() (jsonutils.JSONObject, error) {
func (self *SInstance) GetVNCInfo(input *cloudprovider.ServerVncInput) (*cloudprovider.ServerVncOutput, error) {
return self.host.zone.region.GetInstanceVNCUrl(self.GetId())
}
@@ -566,7 +566,7 @@ func (self *SInstance) GetSecurityGroups() ([]SSecurityGroup, error) {
}
// https://docs.ucloud.cn/api/uhost-api/get_uhost_instance_vnc_info
func (self *SRegion) GetInstanceVNCUrl(instanceId string) (jsonutils.JSONObject, error) {
func (self *SRegion) GetInstanceVNCUrl(instanceId string) (*cloudprovider.ServerVncOutput, error) {
params := NewUcloudParams()
params.Set("UHostId", instanceId)
vnc := SVncInfo{}
@@ -575,13 +575,13 @@ func (self *SRegion) GetInstanceVNCUrl(instanceId string) (jsonutils.JSONObject,
return nil, err
}
vncInfo := jsonutils.NewDict()
vncInfo.Add(jsonutils.NewString(vnc.VNCIP), "host")
vncInfo.Add(jsonutils.NewInt(vnc.VNCPort), "port")
vncInfo.Add(jsonutils.NewString("vnc"), "protocol")
vncInfo.Add(jsonutils.NewString(vnc.VNCPassword), "vncPassword")
vncInfo.Add(jsonutils.NewString(vnc.VNCIP), "host")
return vncInfo, nil
ret := &cloudprovider.ServerVncOutput{
Host: vnc.VNCIP,
Port: vnc.VNCPort,
Password: vnc.VNCPassword,
Hypervisor: api.HYPERVISOR_UCLOUD,
}
return ret, nil
}
// https://docs.ucloud.cn/api/unet-api/grant_firewall
+8 -6
View File
@@ -299,7 +299,7 @@ func (region *SRegion) StopVM(instanceId string, isForce bool) error {
return err
}
func (instance *SInstance) GetVNCInfo() (jsonutils.JSONObject, error) {
func (instance *SInstance) GetVNCInfo(input *cloudprovider.ServerVncInput) (*cloudprovider.ServerVncOutput, error) {
info, err := instance.host.zone.region.GetInstanceConsoleInfo(instance.UUID)
if err != nil {
return nil, err
@@ -315,11 +315,13 @@ func (instance *SInstance) GetVNCInfo() (jsonutils.JSONObject, error) {
if len(password) > 0 {
url = url + fmt.Sprintf("&password=%s", password)
}
return jsonutils.Marshal(map[string]string{
"url": url,
"protocol": "zstack",
"instance_id": instance.UUID,
}), nil
ret := &cloudprovider.ServerVncOutput{
Url: url,
Protocol: "zstack",
InstanceId: instance.UUID,
Hypervisor: api.HYPERVISOR_ZSTACK,
}
return ret, nil
}
func (instance *SInstance) UpdateVM(ctx context.Context, name string) error {
+1 -1
View File
@@ -204,7 +204,7 @@ func handleServerRemoteConsole(ctx context.Context, w http.ResponseWriter, r *ht
return
}
srvId := env.Params["<id>"]
info, err := session.NewRemoteConsoleInfoByCloud(env.ClientSessin, srvId)
info, err := session.NewRemoteConsoleInfoByCloud(env.ClientSessin, srvId, env.Query)
if err != nil {
httperrors.GeneralServerError(ctx, w, err)
return
+7 -1
View File
@@ -21,6 +21,7 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/log"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/i18n"
"yunion.io/x/onecloud/pkg/webconsole/session"
@@ -54,9 +55,14 @@ func (s *ConnectionServer) ServeHTTP(w http.ResponseWriter, req *http.Request) {
}
var srv http.Handler
protocol := sessionObj.GetProtocol()
info := sessionObj.ISessionData.(*session.RemoteConsoleInfo)
switch protocol {
case session.VNC, session.SPICE:
srv, err = NewWebsockifyServer(sessionObj)
if info.Hypervisor == api.HYPERVISOR_OPENSTACK {
srv, err = NewWebsocketProxyServer(sessionObj)
} else {
srv, err = NewWebsockifyServer(sessionObj)
}
case session.WMKS:
srv, err = NewWebsocketProxyServer(sessionObj)
default:
+6 -18
View File
@@ -19,7 +19,10 @@ import (
"net/url"
"os/exec"
"yunion.io/x/jsonutils"
api "yunion.io/x/onecloud/pkg/apis/webconsole"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/modules"
"yunion.io/x/onecloud/pkg/webconsole/options"
@@ -41,25 +44,10 @@ const (
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"`
type RemoteConsoleInfo cloudprovider.ServerVncOutput
// 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)
func NewRemoteConsoleInfoByCloud(s *mcclient.ClientSession, serverId string, query jsonutils.JSONObject) (*RemoteConsoleInfo, error) {
ret, err := modules.Servers.GetSpecific(s, serverId, "vnc", query)
if err != nil {
return nil, err
}