Merge pull request #10370 from ioito/hotfix/qx-prepaid-change-config

Hotfix/qx prepaid change config
This commit is contained in:
Zexi Li
2021-03-11 11:45:10 +08:00
committed by GitHub
6 changed files with 121 additions and 137 deletions
+61 -30
View File
@@ -28,6 +28,7 @@ import (
"yunion.io/x/pkg/util/seclib"
"yunion.io/x/pkg/utils"
billing_api "yunion.io/x/onecloud/pkg/apis/billing"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/multicloud"
@@ -529,10 +530,47 @@ func (self *SInstance) RebuildRoot(ctx context.Context, desc *cloudprovider.SMan
}
func (self *SInstance) ChangeConfig(ctx context.Context, config *cloudprovider.SManagedVMChangeConfig) error {
if len(config.InstanceType) > 0 {
return self.host.zone.region.ChangeVMConfig2(self.ZoneId, self.InstanceId, config.InstanceType, nil)
isDowngrade, isPrepaid := false, self.GetBillingType() == billing_api.BILLING_TYPE_PREPAID
if (self.GetVcpuCount() > config.Cpu && config.Cpu > 0) || (self.GetVmemSizeMB() > config.MemoryMB && config.MemoryMB > 0) {
isDowngrade = true
}
return self.host.zone.region.ChangeVMConfig(self.ZoneId, self.InstanceId, config.Cpu, config.MemoryMB, nil)
instanceTypes := []string{}
if len(config.InstanceType) > 0 {
instanceTypes = []string{config.InstanceType}
} else {
specs, err := self.host.zone.region.GetMatchInstanceTypes(config.Cpu, config.MemoryMB, 0, self.ZoneId)
if err != nil {
return errors.Wrapf(err, "GetMatchInstanceTypes")
}
for _, spec := range specs {
instanceTypes = append(instanceTypes, spec.InstanceTypeId)
}
}
var err error
for _, instanceType := range instanceTypes {
if isPrepaid {
err = self.host.zone.region.ChangePrepaidVMConfig(self.InstanceId, instanceType, isDowngrade)
if err != nil {
log.Errorf("ChangePrepaidVMConfig %s error: %v", instanceType, err)
continue
}
} else {
err = self.host.zone.region.ChangeVMConfig(self.InstanceId, instanceType)
if err != nil {
log.Errorf("ChangeVMConfig %s error: %v", instanceType, err)
continue
}
}
return nil
}
if err != nil {
return errors.Wrapf(err, "ChangeVMConfig")
}
return fmt.Errorf("Failed to change vm config, specification not supported")
}
func (self *SInstance) AttachDisk(ctx context.Context, diskId string) error {
@@ -897,38 +935,31 @@ func (self *SRegion) ReplaceSystemDisk(instanceId string, imageId string, passwd
return body.GetString("DiskId")
}
func (self *SRegion) ChangeVMConfig(zoneId string, instanceId string, ncpu int, vmem int, disks []*SDisk) error {
// todo: support change disk config?
params := make(map[string]string)
instanceTypes, e := self.GetMatchInstanceTypes(ncpu, vmem, 0, zoneId)
if e != nil {
return e
}
for _, instancetype := range instanceTypes {
params["InstanceType"] = instancetype.InstanceTypeId
params["ClientToken"] = utils.GenRequestId(20)
if err := self.instanceOperation(instanceId, "ModifyInstanceSpec", params); err != nil {
log.Errorf("Failed for %s: %s", instancetype.InstanceTypeId, err)
} else {
return nil
}
}
return fmt.Errorf("Failed to change vm config, specification not supported")
}
func (self *SRegion) ChangeVMConfig2(zoneId string, instanceId string, instanceType string, disks []*SDisk) error {
func (self *SRegion) ChangePrepaidVMConfig(instanceId string, instanceType string, isDowngrade bool) error {
// todo: support change disk config?
params := make(map[string]string)
params["InstanceType"] = instanceType
params["ClientToken"] = utils.GenRequestId(20)
if err := self.instanceOperation(instanceId, "ModifyInstanceSpec", params); err != nil {
log.Errorf("Failed for %s: %s", instanceType, err)
return fmt.Errorf("Failed to change vm config, specification not supported")
} else {
return nil
if isDowngrade {
params["OperatorType"] = "downgrade"
}
err := self.instanceOperation(instanceId, "ModifyPrepayInstanceSpec", params)
if err != nil {
return errors.Wrapf(err, "ModifyPrepayInstanceSpec %s", instanceType)
}
return nil
}
func (self *SRegion) ChangeVMConfig(instanceId string, instanceType string) error {
// todo: support change disk config?
params := make(map[string]string)
params["InstanceType"] = instanceType
params["ClientToken"] = utils.GenRequestId(20)
err := self.instanceOperation(instanceId, "ModifyInstanceSpec", params)
if err != nil {
return errors.Wrapf(err, "ModifyInstanceSpec %s", instanceType)
}
return nil
}
func (self *SRegion) DetachDisk(instanceId string, diskId string) error {
+3 -9
View File
@@ -177,18 +177,12 @@ func init() {
})
type InstanceChangeConfigOptions struct {
ID string `help:"instance ID"`
InstanceTypeId string `help:"instance type"`
Disk []int `help:"Data disk sizes int GB"`
ID string `help:"instance ID"`
InstanceType string `help:"instance type"`
}
shellutils.R(&InstanceChangeConfigOptions{}, "instance-change-config", "Deploy keypair/password to a stopped virtual server", func(cli *aliyun.SRegion, args *InstanceChangeConfigOptions) error {
instance, e := cli.GetInstance(args.ID)
if e != nil {
return e
}
err := cli.ChangeVMConfig2(instance.ZoneId, args.ID, args.InstanceTypeId, nil)
err := cli.ChangeVMConfig(args.ID, args.InstanceType)
if err != nil {
return err
}
+25 -43
View File
@@ -692,29 +692,31 @@ func (self *SInstance) DeployVM(ctx context.Context, name string, username strin
}
func (self *SInstance) ChangeConfig(ctx context.Context, config *cloudprovider.SManagedVMChangeConfig) error {
instanceTypes := []string{}
if len(config.InstanceType) > 0 {
return self.ChangeConfig2(ctx, config.InstanceType)
instanceTypes = []string{config.InstanceType}
} else {
flavors, err := self.host.zone.region.GetMatchInstanceTypes(config.Cpu, config.MemoryMB, self.OSEXTAZAvailabilityZone)
if err != nil {
return errors.Wrapf(err, "GetMatchInstanceTypes")
}
for _, flavor := range flavors {
instanceTypes = append(instanceTypes, flavor.ID)
}
}
var err error
for _, instanceType := range instanceTypes {
err = self.host.zone.region.ChangeVMConfig(self.GetId(), instanceType)
if err != nil {
log.Warningf("ChangeVMConfig %s for %s error: %v", self.GetId(), instanceType, err)
} else {
return cloudprovider.WaitStatusWithDelay(self, api.VM_READY, 15*time.Second, 15*time.Second, 180*time.Second)
}
}
err := self.host.zone.region.ChangeVMConfig(self.OSEXTAZAvailabilityZone, self.GetId(), config.Cpu, config.MemoryMB, nil)
if err != nil {
return err
return errors.Wrapf(err, "ChangeVMConfig")
}
return cloudprovider.WaitStatusWithDelay(self, api.VM_READY, 15*time.Second, 15*time.Second, 180*time.Second)
}
func (self *SInstance) ChangeConfig2(ctx context.Context, instanceType string) error {
err := self.host.zone.region.ChangeVMConfig2(self.OSEXTAZAvailabilityZone, self.GetId(), instanceType, nil)
if err != nil {
return errors.Wrap(err, "Instance.ChangeConfig2.ChangeVMConfig2")
}
err = cloudprovider.WaitStatusWithDelay(self, api.VM_READY, 15*time.Second, 15*time.Second, 180*time.Second)
if err != nil {
return errors.Wrap(err, "Instance.ChangeConfig2.WaitStatusWithDelay")
}
return nil
return fmt.Errorf("Failed to change vm config, specification not supported")
}
// todo:// 返回jsonobject感觉很诡异。不能直接知道内部细节
@@ -1290,36 +1292,16 @@ func (self *SRegion) DeployVM(instanceId string, name string, password string, k
}
// https://support.huaweicloud.com/api-ecs/zh-cn_topic_0020212653.html
func (self *SRegion) ChangeVMConfig(zoneId string, instanceId string, ncpu int, vmem int, disks []*SDisk) error {
instanceTypes, err := self.GetMatchInstanceTypes(ncpu, vmem, zoneId)
if err != nil {
return err
}
func (self *SRegion) ChangeVMConfig(instanceId string, instanceType string) error {
self.ecsClient.Servers.SetVersion("v1.1")
defer self.ecsClient.Servers.SetVersion("v1")
for _, t := range instanceTypes {
params := jsonutils.NewDict()
resizeObj := jsonutils.NewDict()
resizeObj.Add(jsonutils.NewString(t.ID), "flavorRef")
params.Add(resizeObj, "resize")
_, err := self.ecsClient.Servers.PerformAction2("resize", instanceId, params, "")
if err != nil {
log.Errorf("Failed for %s: %s", t.ID, err)
} else {
return nil
}
}
return fmt.Errorf("Failed to change vm config, specification not supported")
}
func (self *SRegion) ChangeVMConfig2(zoneId string, instanceId string, instanceType string, disks []*SDisk) error {
params := jsonutils.NewDict()
resizeObj := jsonutils.NewDict()
resizeObj.Add(jsonutils.NewString(instanceType), "flavorRef")
params.Add(resizeObj, "resize")
_, err := self.ecsClient.Servers.PerformAction2("resize", instanceId, params, "")
return err
return errors.Wrapf(err, "PerformAction2(resize)")
}
// https://support.huaweicloud.com/api-ecs/zh-cn_topic_0142763126.html 微版本2.6及以上?
+3 -10
View File
@@ -136,19 +136,12 @@ func init() {
})
type InstanceChangeConfigOptions struct {
ID string `help:"instance ID"`
InstanceTypeId string `help:"instance type"`
Disk []int `help:"Data disk sizes int GB"`
ID string `help:"instance ID"`
InstanceType string `help:"instance type"`
}
shellutils.R(&InstanceChangeConfigOptions{}, "instance-change-config", "Deploy keypair/password to a stopped virtual server", func(cli *huawei.SRegion, args *InstanceChangeConfigOptions) error {
instance, e := cli.GetInstanceByID(args.ID)
if e != nil {
return e
}
// todo : add create disks
err := cli.ChangeVMConfig2(instance.GetId(), args.ID, args.InstanceTypeId, nil)
err := cli.ChangeVMConfig(args.ID, args.InstanceType)
if err != nil {
return err
}
+26 -34
View File
@@ -535,14 +535,33 @@ func (self *SInstance) RebuildRoot(ctx context.Context, desc *cloudprovider.SMan
}
func (self *SInstance) ChangeConfig(ctx context.Context, config *cloudprovider.SManagedVMChangeConfig) error {
instanceTypes := []string{}
if len(config.InstanceType) > 0 {
return self.ChangeConfig2(ctx, config.InstanceType)
instanceTypes = []string{config.InstanceType}
} else {
specs, err := self.host.zone.region.GetMatchInstanceTypes(config.Cpu, config.MemoryMB, 0, self.Placement.Zone)
if err != nil {
return errors.Wrapf(err, "GetMatchInstanceTypes")
}
for _, spec := range specs {
instanceTypes = append(instanceTypes, spec.InstanceType)
}
}
return self.host.zone.region.ChangeVMConfig(self.Placement.Zone, self.InstanceId, config.Cpu, config.MemoryMB, nil)
}
func (self *SInstance) ChangeConfig2(ctx context.Context, instanceType string) error {
return self.host.zone.region.ChangeVMConfig2(self.Placement.Zone, self.InstanceId, instanceType, nil)
var err error
for _, instanceType := range instanceTypes {
err = self.host.zone.region.ChangeVMConfig(self.InstanceId, instanceType)
if err != nil {
log.Errorf("ChangeConfig for %s with %s error: %v", self.InstanceId, instanceType, err)
continue
}
return nil
}
if err != nil {
return err
}
return fmt.Errorf("Failed to change vm config, specification not supported")
}
func (self *SInstance) AttachDisk(ctx context.Context, diskId string) error {
@@ -863,39 +882,12 @@ func (self *SRegion) ReplaceSystemDisk(instanceId string, imageId string, passwd
return err
}
func (self *SRegion) ChangeVMConfig(zoneId string, instanceId string, ncpu int, vmem int, disks []*SDisk) error {
// todo: support change disk config?
params := make(map[string]string)
instanceTypes, e := self.GetMatchInstanceTypes(ncpu, vmem, 0, zoneId)
if e != nil {
return e
}
for _, instancetype := range instanceTypes {
params["InstanceType"] = instancetype.InstanceType
err := self.instanceOperation(instanceId, "ResetInstancesType", params, true)
if err != nil {
log.Errorf("Failed for %s: %s", instancetype.InstanceType, err)
} else {
return nil
}
}
return fmt.Errorf("Failed to change vm config, specification not supported")
}
func (self *SRegion) ChangeVMConfig2(zoneId string, instanceId string, instanceType string, disks []*SDisk) error {
// todo: support change disk config?
func (self *SRegion) ChangeVMConfig(instanceId string, instanceType string) error {
params := make(map[string]string)
params["InstanceType"] = instanceType
err := self.instanceOperation(instanceId, "ResetInstancesType", params, true)
if err != nil {
log.Errorf("Failed for %s: %s", instanceType, err)
return fmt.Errorf("Failed to change vm config, specification not supported")
}
return nil
return errors.Wrapf(err, "ResetInstancesType %s", instanceType)
}
func (self *SRegion) DetachDisk(instanceId string, diskId string) error {
+3 -11
View File
@@ -186,20 +186,12 @@ func init() {
})
type InstanceChangeConfigOptions struct {
ID string `help:"instance ID"`
InstanceTypeId string `help:"instance type"`
Vmem int `help:"MiB of memory"`
Disk []int `help:"Data disk sizes int GB"`
ID string `help:"instance ID"`
InstanceType string `help:"instance type"`
}
shellutils.R(&InstanceChangeConfigOptions{}, "instance-change-config", "Deploy keypair/password to a stopped virtual server", func(cli *qcloud.SRegion, args *InstanceChangeConfigOptions) error {
instance, e := cli.GetInstance(args.ID)
if e != nil {
return e
}
// todo : add create disks
err := cli.ChangeVMConfig2(instance.Placement.Zone, args.ID, args.InstanceTypeId, nil)
err := cli.ChangeVMConfig(args.ID, args.InstanceType)
if err != nil {
return err
}