mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-06-01 05:22:24 +08:00
fix: validate VM vdi,vga,machine input
This commit is contained in:
@@ -183,6 +183,15 @@ const (
|
||||
const (
|
||||
VM_MACHINE_TYPE_PC = "pc"
|
||||
VM_MACHINE_TYPE_Q35 = "q35"
|
||||
|
||||
VM_MACHINE_TYPE_ARM_VIRT = "virt"
|
||||
|
||||
VM_VDI_PROTOCOL_VNC = "vnc"
|
||||
VM_VDI_PROTOCOL_SPICE = "spice"
|
||||
|
||||
VM_VIDEO_STANDARD = "std"
|
||||
VM_VIDEO_QXL = "qxl"
|
||||
VM_VIDEO_VIRTIO = "virtio"
|
||||
)
|
||||
|
||||
var VM_RUNNING_STATUS = []string{VM_START_START, VM_STARTING, VM_RUNNING, VM_BLOCK_STREAM, VM_BLOCK_STREAM_FAIL}
|
||||
|
||||
@@ -411,8 +411,12 @@ func (self *SBaseGuestDriver) RequestLiveMigrate(ctx context.Context, guest *mod
|
||||
return fmt.Errorf("Not Implement RequestLiveMigrate")
|
||||
}
|
||||
|
||||
func (self *SBaseGuestDriver) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, input api.ServerUpdateInput) error {
|
||||
return nil
|
||||
func (self *SVirtualizedGuestDriver) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, input *api.ServerCreateInput) (*api.ServerCreateInput, error) {
|
||||
return input, nil
|
||||
}
|
||||
|
||||
func (self *SBaseGuestDriver) ValidateUpdateData(ctx context.Context, guest *models.SGuest, userCred mcclient.TokenCredential, input api.ServerUpdateInput) (api.ServerUpdateInput, error) {
|
||||
return input, nil
|
||||
}
|
||||
|
||||
func (self *SBaseGuestDriver) RequestRemoteUpdate(ctx context.Context, guest *models.SGuest, userCred mcclient.TokenCredential, replaceTags bool) error {
|
||||
|
||||
@@ -816,3 +816,102 @@ func (self *SKVMGuestDriver) RequestChangeDiskStorage(ctx context.Context, userC
|
||||
_, _, err = httputils.JSONRequest(httputils.GetDefaultClient(), ctx, "POST", url, header, body, false)
|
||||
return err
|
||||
}
|
||||
|
||||
func (self *SKVMGuestDriver) validateVdiProtocol(vdi string) error {
|
||||
if !utils.IsInStringArray(vdi, []string{api.VM_VDI_PROTOCOL_VNC, api.VM_VDI_PROTOCOL_SPICE}) {
|
||||
return httperrors.NewInputParameterError("unsupported vdi protocol")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SKVMGuestDriver) validateVGA(ovdi, ovga string, nvdi, nvga *string) (vdi, vga string) {
|
||||
vdi = ovdi
|
||||
if nvdi != nil {
|
||||
vdi = *nvdi
|
||||
}
|
||||
if vdi != api.VM_VDI_PROTOCOL_VNC && vdi != api.VM_VDI_PROTOCOL_SPICE {
|
||||
vdi = api.VM_VDI_PROTOCOL_VNC
|
||||
}
|
||||
var candidateVga []string
|
||||
switch vdi {
|
||||
case api.VM_VDI_PROTOCOL_VNC:
|
||||
candidateVga = []string{api.VM_VIDEO_STANDARD, api.VM_VIDEO_QXL, api.VM_VIDEO_VIRTIO}
|
||||
case api.VM_VDI_PROTOCOL_SPICE:
|
||||
candidateVga = []string{api.VM_VIDEO_QXL, api.VM_VIDEO_VIRTIO}
|
||||
}
|
||||
vga = ovga
|
||||
if nvga != nil {
|
||||
vga = *nvga
|
||||
}
|
||||
if !utils.IsInStringArray(vga, candidateVga) {
|
||||
vga = candidateVga[0]
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (self *SKVMGuestDriver) validateMachineType(machine string, osArch string) error {
|
||||
var candidate []string
|
||||
switch osArch {
|
||||
case apis.OS_ARCH_AARCH64:
|
||||
candidate = []string{api.VM_MACHINE_TYPE_ARM_VIRT}
|
||||
default:
|
||||
candidate = []string{api.VM_MACHINE_TYPE_PC, api.VM_MACHINE_TYPE_Q35}
|
||||
}
|
||||
if !utils.IsInStringArray(machine, candidate) {
|
||||
return httperrors.NewInputParameterError("Invalid machine type %s", machine)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SKVMGuestDriver) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, input *api.ServerCreateInput) (*api.ServerCreateInput, error) {
|
||||
input, err := self.SVirtualizedGuestDriver.ValidateCreateData(ctx, userCred, input)
|
||||
if err != nil {
|
||||
return input, errors.Wrap(err, "SVirtualizedGuestDriver.ValidateCreateData")
|
||||
}
|
||||
if input.Vdi != "" {
|
||||
err = self.validateVdiProtocol(input.Vdi)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "validateVdiProtocol")
|
||||
}
|
||||
}
|
||||
|
||||
if input.Vdi != "" || input.Vga != "" {
|
||||
input.Vdi, input.Vga = self.validateVGA("", "", &input.Vdi, &input.Vga)
|
||||
}
|
||||
|
||||
if input.Machine != "" {
|
||||
if err := self.validateMachineType(input.Machine, input.OsArch); err != nil {
|
||||
return nil, errors.Wrap(err, "validateMachineType")
|
||||
}
|
||||
}
|
||||
return input, nil
|
||||
}
|
||||
|
||||
func (self *SKVMGuestDriver) ValidateUpdateData(ctx context.Context, guest *models.SGuest, userCred mcclient.TokenCredential, input api.ServerUpdateInput) (api.ServerUpdateInput, error) {
|
||||
input, err := self.SVirtualizedGuestDriver.ValidateUpdateData(ctx, guest, userCred, input)
|
||||
if err != nil {
|
||||
return input, errors.Wrap(err, "SVirtualizedGuestDriver.ValidateUpdateData")
|
||||
}
|
||||
|
||||
if input.Vdi != nil {
|
||||
err = self.validateVdiProtocol(*input.Vdi)
|
||||
if err != nil {
|
||||
return input, errors.Wrap(err, "validateVdiProtocol")
|
||||
}
|
||||
}
|
||||
|
||||
if input.Vga != nil || input.Vdi != nil {
|
||||
vdi, vga := self.validateVGA(guest.Vdi, guest.Vga, input.Vdi, input.Vga)
|
||||
input.Vdi = &vdi
|
||||
input.Vga = &vga
|
||||
}
|
||||
|
||||
if input.Machine != nil {
|
||||
err := self.validateMachineType(*input.Machine, guest.OsArch)
|
||||
if err != nil {
|
||||
return input, errors.Wrap(err, "ValidateMachineType")
|
||||
}
|
||||
}
|
||||
|
||||
return input, nil
|
||||
}
|
||||
|
||||
@@ -265,31 +265,6 @@ func (self *SVirtualizedGuestDriver) RequestStopGuestForDelete(ctx context.Conte
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SVirtualizedGuestDriver) ValidateMachineType(machine string) error {
|
||||
if !utils.IsInStringArray(machine, []string{api.VM_MACHINE_TYPE_PC, api.VM_MACHINE_TYPE_Q35}) {
|
||||
return httperrors.NewBadRequestError("Invalid machine %q", machine)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SVirtualizedGuestDriver) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, input *api.ServerCreateInput) (*api.ServerCreateInput, error) {
|
||||
if input.Machine != "" {
|
||||
if err := self.ValidateMachineType(input.Machine); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return input, nil
|
||||
}
|
||||
|
||||
func (self *SVirtualizedGuestDriver) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, input api.ServerUpdateInput) error {
|
||||
if input.Machine != nil {
|
||||
if err := self.ValidateMachineType(*input.Machine); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SVirtualizedGuestDriver) ValidateCreateDataOnHost(ctx context.Context, userCred mcclient.TokenCredential, bmName string, host *models.SHost, input *api.ServerCreateInput) (*api.ServerCreateInput, error) {
|
||||
if host.HostStatus != api.HOST_ONLINE {
|
||||
return nil, httperrors.NewInvalidStatusError("Host %s is not online", bmName)
|
||||
|
||||
@@ -205,7 +205,7 @@ type IGuestDriver interface {
|
||||
RequestMigrate(ctx context.Context, guest *SGuest, userCred mcclient.TokenCredential, data *jsonutils.JSONDict, task taskman.ITask) error
|
||||
RequestLiveMigrate(ctx context.Context, guest *SGuest, userCred mcclient.TokenCredential, data *jsonutils.JSONDict, task taskman.ITask) error
|
||||
|
||||
ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, input api.ServerUpdateInput) error
|
||||
ValidateUpdateData(ctx context.Context, guest *SGuest, userCred mcclient.TokenCredential, input api.ServerUpdateInput) (api.ServerUpdateInput, error)
|
||||
RequestRemoteUpdate(ctx context.Context, guest *SGuest, userCred mcclient.TokenCredential, replaceTags bool) error
|
||||
|
||||
RequestOpenForward(ctx context.Context, userCred mcclient.TokenCredential, guest *SGuest, req *guestdriver_types.OpenForwardRequest) (*guestdriver_types.OpenForwardResponse, error)
|
||||
|
||||
@@ -985,43 +985,12 @@ func (self *SGuest) ValidateUpdateData(ctx context.Context, userCred mcclient.To
|
||||
return input, httperrors.NewInputParameterError("name is too short")
|
||||
}
|
||||
|
||||
if input.Vdi != nil {
|
||||
if !utils.IsInStringArray(*input.Vdi, []string{"vnc", "spice"}) {
|
||||
return input, httperrors.NewInputParameterError("unsupported vdi protocol")
|
||||
}
|
||||
}
|
||||
|
||||
if input.Vga != nil || input.Vdi != nil {
|
||||
vdi := self.Vdi
|
||||
if input.Vdi != nil {
|
||||
vdi = *input.Vdi
|
||||
}
|
||||
if vdi != "vnc" && vdi != "spice" {
|
||||
vdi = "vnc"
|
||||
input.Vdi = &vdi
|
||||
}
|
||||
var candidateVga []string
|
||||
switch vdi {
|
||||
case "vnc":
|
||||
candidateVga = []string{"std", "qxl", "virtio"}
|
||||
case "spice":
|
||||
candidateVga = []string{"qxl", "virtio"}
|
||||
}
|
||||
vga := self.Vga
|
||||
if input.Vga != nil {
|
||||
vga = *input.Vga
|
||||
}
|
||||
if !utils.IsInStringArray(vga, candidateVga) {
|
||||
vga = candidateVga[0]
|
||||
input.Vga = &vga
|
||||
}
|
||||
}
|
||||
|
||||
if err := self.GetDriver().ValidateUpdateData(ctx, userCred, input); err != nil {
|
||||
return input, err
|
||||
}
|
||||
|
||||
var err error
|
||||
input, err = self.GetDriver().ValidateUpdateData(ctx, self, userCred, input)
|
||||
if err != nil {
|
||||
return input, errors.Wrap(err, "GetDriver().ValidateUpdateData")
|
||||
}
|
||||
|
||||
input.VirtualResourceBaseUpdateInput, err = self.SVirtualResourceBase.ValidateUpdateData(ctx, userCred, query, input.VirtualResourceBaseUpdateInput)
|
||||
if err != nil {
|
||||
return input, errors.Wrap(err, "SVirtualResourceBase.ValidateUpdateData")
|
||||
|
||||
Reference in New Issue
Block a user