mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-19 10:46:58 +08:00
fix(webconsole): support vnc for openstack
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
})
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user