From cd32e03addf234988e6b069f88859612cf1ceae1 Mon Sep 17 00:00:00 2001 From: Qu Xuan Date: Fri, 1 Nov 2019 17:08:16 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=A2=B3=E7=90=86=E7=A3=81=E7=9B=98rese?= =?UTF-8?q?t=E6=9D=A1=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/compute/hostdrivers/aliyun.go | 15 ++++++++++++ pkg/compute/hostdrivers/aws.go | 8 ++++++ pkg/compute/hostdrivers/azure.go | 4 +++ pkg/compute/hostdrivers/base.go | 4 +-- pkg/compute/hostdrivers/huawei.go | 22 +---------------- pkg/compute/hostdrivers/kvm.go | 19 +------------- pkg/compute/hostdrivers/managedvirtual.go | 30 +---------------------- pkg/compute/hostdrivers/openstack.go | 10 ++++++++ pkg/compute/hostdrivers/qcloud.go | 13 ++++++++++ pkg/compute/hostdrivers/ucloud.go | 15 ++++++++++++ pkg/compute/hostdrivers/zstack.go | 15 ++++++++++++ pkg/compute/models/disks.go | 25 ++++++++++++++++--- pkg/compute/models/hostdrivers.go | 2 +- 13 files changed, 107 insertions(+), 75 deletions(-) diff --git a/pkg/compute/hostdrivers/aliyun.go b/pkg/compute/hostdrivers/aliyun.go index fbf659e956..7f4f46e106 100644 --- a/pkg/compute/hostdrivers/aliyun.go +++ b/pkg/compute/hostdrivers/aliyun.go @@ -15,10 +15,16 @@ package hostdrivers import ( + "context" "fmt" + "yunion.io/x/jsonutils" + "yunion.io/x/pkg/utils" + api "yunion.io/x/onecloud/pkg/apis/compute" "yunion.io/x/onecloud/pkg/compute/models" + "yunion.io/x/onecloud/pkg/httperrors" + "yunion.io/x/onecloud/pkg/mcclient" ) type SAliyunHostDriver struct { @@ -62,3 +68,12 @@ func (self *SAliyunHostDriver) ValidateDiskSize(storage *models.SStorage, sizeGb } return nil } + +func (self *SAliyunHostDriver) ValidateResetDisk(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, snapshot *models.SSnapshot, guests []models.SGuest, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { + for _, guest := range guests { + if !utils.IsInStringArray(guest.Status, []string{api.VM_RUNNING, api.VM_READY}) { + return nil, httperrors.NewBadGatewayError("Aliyun reset disk required guest status is running or read") + } + } + return data, nil +} diff --git a/pkg/compute/hostdrivers/aws.go b/pkg/compute/hostdrivers/aws.go index 3f2c673d3a..7fd9657918 100644 --- a/pkg/compute/hostdrivers/aws.go +++ b/pkg/compute/hostdrivers/aws.go @@ -15,12 +15,16 @@ package hostdrivers import ( + "context" "fmt" + "yunion.io/x/jsonutils" "yunion.io/x/pkg/utils" api "yunion.io/x/onecloud/pkg/apis/compute" "yunion.io/x/onecloud/pkg/compute/models" + "yunion.io/x/onecloud/pkg/httperrors" + "yunion.io/x/onecloud/pkg/mcclient" ) type SAwsHostDriver struct { @@ -62,3 +66,7 @@ func (self *SAwsHostDriver) ValidateDiskSize(storage *models.SStorage, sizeGb in } return nil } + +func (self *SAwsHostDriver) ValidateResetDisk(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, snapshot *models.SSnapshot, guests []models.SGuest, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { + return nil, httperrors.NewBadRequestError("Aws not support reset disk, you can create new disk with snapshot") +} diff --git a/pkg/compute/hostdrivers/azure.go b/pkg/compute/hostdrivers/azure.go index 2b6eeb4814..282f0e9ecd 100644 --- a/pkg/compute/hostdrivers/azure.go +++ b/pkg/compute/hostdrivers/azure.go @@ -52,6 +52,10 @@ func (self *SAzureHostDriver) ValidateUpdateDisk(ctx context.Context, userCred m return data, nil } +func (self *SAzureHostDriver) ValidateResetDisk(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, snapshot *models.SSnapshot, guests []models.SGuest, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { + return nil, httperrors.NewBadRequestError("Azure not support reset disk, you can create new disk with snapshot") +} + func (self *SAzureHostDriver) ValidateDiskSize(storage *models.SStorage, sizeGb int) error { if utils.IsInStringArray(storage.StorageType, []string{api.STORAGE_STANDARD_LRS, api.STORAGE_STANDARDSSD_LRS, api.STORAGE_PREMIUM_LRS}) { if sizeGb < 1 || sizeGb > 4095 { diff --git a/pkg/compute/hostdrivers/base.go b/pkg/compute/hostdrivers/base.go index 22e5166675..02d9224288 100644 --- a/pkg/compute/hostdrivers/base.go +++ b/pkg/compute/hostdrivers/base.go @@ -38,8 +38,8 @@ func (self *SBaseHostDriver) ValidateUpdateDisk(ctx context.Context, userCred mc return data, nil } -func (self *SBaseHostDriver) ValidateResetDisk(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { - return data, nil +func (self *SBaseHostDriver) ValidateResetDisk(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, snapshot *models.SSnapshot, guests []models.SGuest, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { + return nil, httperrors.NewNotImplementedError("Not Implement ValidateResetDisk") } func (self *SBaseHostDriver) ValidateAttachStorage(ctx context.Context, userCred mcclient.TokenCredential, host *models.SHost, storage *models.SStorage, data *jsonutils.JSONDict) error { diff --git a/pkg/compute/hostdrivers/huawei.go b/pkg/compute/hostdrivers/huawei.go index bad37574bb..fc21073121 100644 --- a/pkg/compute/hostdrivers/huawei.go +++ b/pkg/compute/hostdrivers/huawei.go @@ -57,29 +57,9 @@ func (self *SHuaweiHostDriver) ValidateDiskSize(storage *models.SStorage, sizeGb return nil } -func (self *SHuaweiHostDriver) ValidateResetDisk(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { - if disk.Status != api.DISK_READY { - return nil, httperrors.NewInvalidStatusError("Cannot reset disk in status %s", disk.Status) - } - snapshotId, err := data.GetString("snapshot_id") - if err != nil { - return nil, httperrors.NewMissingParameterError("snapshot_id") - } - guests := disk.GetGuests() +func (self *SHuaweiHostDriver) ValidateResetDisk(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, snapshot *models.SSnapshot, guests []models.SGuest, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { if len(guests) >= 1 { return nil, httperrors.NewBadRequestError("Disk must be dettached") } - - iSnapshot, err := models.SnapshotManager.FetchById(snapshotId) - if err != nil { - return nil, httperrors.NewNotFoundError("Snapshot %s not found", snapshotId) - } - snapshot := iSnapshot.(*models.SSnapshot) - if snapshot.Status != api.SNAPSHOT_READY { - return nil, httperrors.NewBadRequestError("Cannot reset disk with snapshot in status %s", snapshot.Status) - } else if snapshot.DiskId != disk.Id { - return nil, httperrors.NewBadRequestError("Cannot reset disk %s,Snapshot is belong to disk %s", disk.Id, snapshot.DiskId) - } - return data, nil } diff --git a/pkg/compute/hostdrivers/kvm.go b/pkg/compute/hostdrivers/kvm.go index 09ca8f4ac8..dea330230e 100644 --- a/pkg/compute/hostdrivers/kvm.go +++ b/pkg/compute/hostdrivers/kvm.go @@ -352,15 +352,7 @@ func (self *SKVMHostDriver) RequestDeleteSnapshotsWithStorage(ctx context.Contex return err } -func (self *SKVMHostDriver) ValidateResetDisk(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { - if disk.Status != api.DISK_READY { - return nil, httperrors.NewInvalidStatusError("Cannot reset disk in status %s", disk.Status) - } - snapshotId, err := data.GetString("snapshot_id") - if err != nil { - return nil, httperrors.NewMissingParameterError("snapshot_id") - } - guests := disk.GetGuests() +func (self *SKVMHostDriver) ValidateResetDisk(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, snapshot *models.SSnapshot, guests []models.SGuest, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { if len(guests) > 1 { return nil, httperrors.NewBadRequestError("Disk attach muti guests") } else if len(guests) == 1 { @@ -371,15 +363,6 @@ func (self *SKVMHostDriver) ValidateResetDisk(ctx context.Context, userCred mccl return nil, httperrors.NewBadRequestError("Disk dosen't attach guest") } - iSnapshot, err := models.SnapshotManager.FetchById(snapshotId) - if err != nil { - return nil, httperrors.NewNotFoundError("Snapshot %s not found", snapshotId) - } - snapshot := iSnapshot.(*models.SSnapshot) - if snapshot.Status != api.SNAPSHOT_READY { - return nil, httperrors.NewBadRequestError("Cannot reset disk with snapshot in status %s", snapshot.Status) - } - return data, nil } diff --git a/pkg/compute/hostdrivers/managedvirtual.go b/pkg/compute/hostdrivers/managedvirtual.go index 60d49e09ae..b688d041ec 100644 --- a/pkg/compute/hostdrivers/managedvirtual.go +++ b/pkg/compute/hostdrivers/managedvirtual.go @@ -33,7 +33,6 @@ import ( "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/compute/models" "yunion.io/x/onecloud/pkg/compute/options" - "yunion.io/x/onecloud/pkg/httperrors" "yunion.io/x/onecloud/pkg/mcclient" ) @@ -301,34 +300,7 @@ func (self *SManagedVirtualizationHostDriver) RequestDeallocateDiskOnHost(ctx co return nil } -func (self *SManagedVirtualizationHostDriver) ValidateResetDisk(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { - if disk.Status != api.DISK_READY { - return nil, httperrors.NewInvalidStatusError("Cannot reset disk in status %s", disk.Status) - } - snapshotId, err := data.GetString("snapshot_id") - if err != nil { - return nil, httperrors.NewMissingParameterError("snapshot_id") - } - guests := disk.GetGuests() - if len(guests) > 1 { - return nil, httperrors.NewBadRequestError("Disk attach muti guests") - } else if len(guests) == 1 { - if guests[0].Status != api.VM_READY { - return nil, httperrors.NewServerStatusError("Disk attached guest status must be ready") - } - } else { - return nil, httperrors.NewBadRequestError("Disk dosen't attach guest") - } - - iSnapshot, err := models.SnapshotManager.FetchById(snapshotId) - if err != nil { - return nil, httperrors.NewNotFoundError("Snapshot %s not found", snapshotId) - } - snapshot := iSnapshot.(*models.SSnapshot) - if snapshot.Status != api.SNAPSHOT_READY { - return nil, httperrors.NewBadRequestError("Cannot reset disk with snapshot in status %s", snapshot.Status) - } - +func (self *SManagedVirtualizationHostDriver) ValidateResetDisk(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, snapshot *models.SSnapshot, guests []models.SGuest, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { return data, nil } diff --git a/pkg/compute/hostdrivers/openstack.go b/pkg/compute/hostdrivers/openstack.go index b5321677b6..6fcc294503 100644 --- a/pkg/compute/hostdrivers/openstack.go +++ b/pkg/compute/hostdrivers/openstack.go @@ -15,8 +15,14 @@ package hostdrivers import ( + "context" + + "yunion.io/x/jsonutils" + api "yunion.io/x/onecloud/pkg/apis/compute" "yunion.io/x/onecloud/pkg/compute/models" + "yunion.io/x/onecloud/pkg/httperrors" + "yunion.io/x/onecloud/pkg/mcclient" ) type SOpenStackHostDriver struct { @@ -43,3 +49,7 @@ func (self *SOpenStackHostDriver) ValidateDiskSize(storage *models.SStorage, siz func (driver *SOpenStackHostDriver) GetStoragecacheQuota(host *models.SHost) int { return 100 } + +func (self *SOpenStackHostDriver) ValidateResetDisk(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, snapshot *models.SSnapshot, guests []models.SGuest, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { + return nil, httperrors.NewBadRequestError("OpenStack not support reset disk, you can create new disk with snapshot") +} diff --git a/pkg/compute/hostdrivers/qcloud.go b/pkg/compute/hostdrivers/qcloud.go index cf269fff3e..f4a7a0712a 100644 --- a/pkg/compute/hostdrivers/qcloud.go +++ b/pkg/compute/hostdrivers/qcloud.go @@ -18,10 +18,14 @@ import ( "context" "fmt" + "yunion.io/x/jsonutils" + "yunion.io/x/pkg/utils" + api "yunion.io/x/onecloud/pkg/apis/compute" "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" "yunion.io/x/onecloud/pkg/compute/models" "yunion.io/x/onecloud/pkg/httperrors" + "yunion.io/x/onecloud/pkg/mcclient" ) type SQcloudHostDriver struct { @@ -63,6 +67,15 @@ func (self *SQcloudHostDriver) ValidateDiskSize(storage *models.SStorage, sizeGb return nil } +func (self *SQcloudHostDriver) ValidateResetDisk(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, snapshot *models.SSnapshot, guests []models.SGuest, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { + for _, guest := range guests { + if !utils.IsInStringArray(guest.Status, []string{api.VM_RUNNING, api.VM_READY}) { + return nil, httperrors.NewBadGatewayError("Qcloud reset disk required guest status is running or read") + } + } + return data, nil +} + func (self *SQcloudHostDriver) RequestDeleteSnapshotWithStorage(ctx context.Context, host *models.SHost, snapshot *models.SSnapshot, task taskman.ITask) error { return httperrors.NewNotImplementedError("not implement") } diff --git a/pkg/compute/hostdrivers/ucloud.go b/pkg/compute/hostdrivers/ucloud.go index db456c2859..b53a91f47f 100644 --- a/pkg/compute/hostdrivers/ucloud.go +++ b/pkg/compute/hostdrivers/ucloud.go @@ -15,10 +15,15 @@ package hostdrivers import ( + "context" "fmt" + "yunion.io/x/jsonutils" + api "yunion.io/x/onecloud/pkg/apis/compute" "yunion.io/x/onecloud/pkg/compute/models" + "yunion.io/x/onecloud/pkg/httperrors" + "yunion.io/x/onecloud/pkg/mcclient" ) type SUCloudHostDriver struct { @@ -65,3 +70,13 @@ func (self *SUCloudHostDriver) ValidateDiskSize(storage *models.SStorage, sizeGb return nil } + +func (self *SUCloudHostDriver) ValidateResetDisk(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, snapshot *models.SSnapshot, guests []models.SGuest, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { + if len(guests) > 0 { + return nil, httperrors.NewInputParameterError("Ucloud reset disk operation required disk not be attached") + } + if disk.DiskType != api.DISK_TYPE_DATA { + return nil, httperrors.NewInputParameterError("Ucloud only support data disk reset operation") + } + return data, nil +} diff --git a/pkg/compute/hostdrivers/zstack.go b/pkg/compute/hostdrivers/zstack.go index 736facf7ae..876d783911 100644 --- a/pkg/compute/hostdrivers/zstack.go +++ b/pkg/compute/hostdrivers/zstack.go @@ -15,8 +15,14 @@ package hostdrivers import ( + "context" + + "yunion.io/x/jsonutils" + api "yunion.io/x/onecloud/pkg/apis/compute" "yunion.io/x/onecloud/pkg/compute/models" + "yunion.io/x/onecloud/pkg/httperrors" + "yunion.io/x/onecloud/pkg/mcclient" ) type SZStackHostDriver struct { @@ -39,3 +45,12 @@ func (self *SZStackHostDriver) GetHypervisor() string { func (self *SZStackHostDriver) ValidateDiskSize(storage *models.SStorage, sizeGb int) error { return nil } + +func (self *SZStackHostDriver) ValidateResetDisk(ctx context.Context, userCred mcclient.TokenCredential, disk *models.SDisk, snapshot *models.SSnapshot, guests []models.SGuest, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { + for _, guest := range guests { + if guest.Status != api.VM_READY { + return nil, httperrors.NewBadRequestError("ZStack reset disk operation requried guest status is ready") + } + } + return data, nil +} diff --git a/pkg/compute/models/disks.go b/pkg/compute/models/disks.go index d715dd2a39..b6b4c7f483 100644 --- a/pkg/compute/models/disks.go +++ b/pkg/compute/models/disks.go @@ -41,6 +41,7 @@ import ( "yunion.io/x/onecloud/pkg/cloudcommon/db/quotas" "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" "yunion.io/x/onecloud/pkg/cloudcommon/notifyclient" + "yunion.io/x/onecloud/pkg/cloudcommon/validators" "yunion.io/x/onecloud/pkg/cloudprovider" "yunion.io/x/onecloud/pkg/compute/options" "yunion.io/x/onecloud/pkg/httperrors" @@ -702,6 +703,9 @@ func (self *SDisk) AllowPerformDiskReset(ctx context.Context, userCred mcclient. } func (self *SDisk) PerformDiskReset(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) { + if !utils.IsInStringArray(self.Status, []string{api.DISK_READY}) { + return nil, httperrors.NewInputParameterError("Cannot reset disk in status %s", self.Status) + } storage := self.GetStorage() if storage == nil { return nil, httperrors.NewNotFoundError("failed to find storage for disk %s", self.Name) @@ -712,15 +716,28 @@ func (self *SDisk) PerformDiskReset(ctx context.Context, userCred mcclient.Token return nil, httperrors.NewNotFoundError("failed to find host for storage %s with disk %s", storage.Name, self.Name) } - data, err := host.GetHostDriver().ValidateResetDisk(ctx, userCred, self, data.(*jsonutils.JSONDict)) + snapshotV := validators.NewModelIdOrNameValidator("snapshot", "snapshot", userCred) + err := snapshotV.Validate(data.(*jsonutils.JSONDict)) + if err != nil { + return nil, err + } + snapshot := snapshotV.Model.(*SSnapshot) + if snapshot.Status != api.SNAPSHOT_READY { + return nil, httperrors.NewBadRequestError("Cannot reset disk with snapshot in status %s", snapshot.Status) + } + + if snapshot.DiskId != self.Id { + return nil, httperrors.NewBadRequestError("Cannot reset disk %s(%s),Snapshot is belong to disk %s", self.Name, self.Id, snapshot.DiskId) + } + + guests := self.GetGuests() + data, err = host.GetHostDriver().ValidateResetDisk(ctx, userCred, self, snapshot, guests, data.(*jsonutils.JSONDict)) if err != nil { return nil, err } autoStart := jsonutils.QueryBoolean(data, "auto_start", false) - snapshotId, _ := data.GetString("snapshot_id") - guests := self.GetGuests() - return nil, self.StartResetDisk(ctx, userCred, snapshotId, autoStart, &guests[0], "") + return nil, self.StartResetDisk(ctx, userCred, snapshot.Id, autoStart, &guests[0], "") } func (self *SDisk) StartResetDisk( diff --git a/pkg/compute/models/hostdrivers.go b/pkg/compute/models/hostdrivers.go index 3e76b3524a..38d5838539 100644 --- a/pkg/compute/models/hostdrivers.go +++ b/pkg/compute/models/hostdrivers.go @@ -33,7 +33,7 @@ type IHostDriver interface { RequestUncacheImage(ctx context.Context, host *SHost, storageCache *SStoragecache, task taskman.ITask) error ValidateUpdateDisk(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) - ValidateResetDisk(ctx context.Context, userCred mcclient.TokenCredential, disk *SDisk, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) + ValidateResetDisk(ctx context.Context, userCred mcclient.TokenCredential, disk *SDisk, snapshot *SSnapshot, guests []SGuest, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) ValidateDiskSize(storage *SStorage, sizeGb int) error RequestPrepareSaveDiskOnHost(ctx context.Context, host *SHost, disk *SDisk, imageId string, task taskman.ITask) error RequestSaveUploadImageOnHost(ctx context.Context, host *SHost, disk *SDisk, imageId string, task taskman.ITask, data jsonutils.JSONObject) error