mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-08-29 03:51:54 +08:00
fix(region): support query public cloud vm modification types (#24655)
This commit is contained in:
@@ -131,6 +131,7 @@ func init() {
|
||||
cmd.BatchPerform("set-root-disk-matcher", &options.ServerSetRootDiskMatcher{})
|
||||
cmd.Perform("disable-auto-merge-snapshot", &options.ServerDisableAutoMergeSnapshot{})
|
||||
cmd.Get("vnc", new(options.ServerVncOptions))
|
||||
cmd.Get("modification-types", new(options.ServerIdOptions))
|
||||
cmd.Get("desc", new(options.ServerIdOptions))
|
||||
cmd.Get("status", new(options.ServerIdOptions))
|
||||
cmd.Get("iso", new(options.ServerIdOptions))
|
||||
|
||||
@@ -94,7 +94,7 @@ require (
|
||||
k8s.io/client-go v0.26.1
|
||||
k8s.io/cluster-bootstrap v0.19.3
|
||||
moul.io/http2curl/v2 v2.3.0
|
||||
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20260409072655-7f5827365741
|
||||
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20260409123851-7b55f5f3ad92
|
||||
yunion.io/x/executor v0.0.0-20260312022053-f538abd2b005
|
||||
yunion.io/x/jsonutils v1.0.1-0.20250507052344-1abcf4f443b1
|
||||
yunion.io/x/log v1.0.1-0.20240305175729-7cf2d6cd5a91
|
||||
|
||||
@@ -1090,8 +1090,8 @@ sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
||||
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
|
||||
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
|
||||
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20260409072655-7f5827365741 h1:F+I9SeZJpH477cIGTbjHiRT+hry+o3CnWbfwkiFG8LQ=
|
||||
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20260409072655-7f5827365741/go.mod h1:GdAwZ78fiqj13i2r1zNuE/D6YOlhh2q4jZjuyHiZTq8=
|
||||
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20260409123851-7b55f5f3ad92 h1:tklE5QK6iUhIeZiSmY8IVUjCcXNgQ1xfH8EaUgrZEDk=
|
||||
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20260409123851-7b55f5f3ad92/go.mod h1:GdAwZ78fiqj13i2r1zNuE/D6YOlhh2q4jZjuyHiZTq8=
|
||||
yunion.io/x/executor v0.0.0-20260312022053-f538abd2b005 h1:3sWwcjGXGjG9mLBWa7AyLq+QSi0udTAx21pfVQRFMBE=
|
||||
yunion.io/x/executor v0.0.0-20260312022053-f538abd2b005/go.mod h1:Uxuou9WQIeJXNpy7t2fPLL0BYLvLiMvGQwY7Qc6aSws=
|
||||
yunion.io/x/jsonutils v0.0.0-20190625054549-a964e1e8a051/go.mod h1:4N0/RVzsYL3kH3WE/H1BjUQdFiWu50JGCFQuuy+Z634=
|
||||
|
||||
@@ -1400,3 +1400,11 @@ type ServerChangeBillingTypeInput struct {
|
||||
// required: true
|
||||
BillingType string `json:"billing_type"`
|
||||
}
|
||||
|
||||
type ServerModificationType struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type ServerModificationTypesOutput struct {
|
||||
ModificationTypes []ServerModificationType `json:"modification_types"`
|
||||
}
|
||||
|
||||
@@ -93,6 +93,29 @@ func (self *SGuest) GetDetailsVnc(ctx context.Context, userCred mcclient.TokenCr
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// 获取公有云可变更配置
|
||||
// 目前支持: 阿里云,腾讯云,华为云
|
||||
func (guest *SGuest) GetDetailsModificationTypes(ctx context.Context, userCred mcclient.TokenCredential, input jsonutils.JSONObject) (*api.ServerModificationTypesOutput, error) {
|
||||
if len(guest.ExternalId) == 0 {
|
||||
return nil, httperrors.NewNotFoundError("guest external id is empty")
|
||||
}
|
||||
vm, err := guest.GetIVM(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "GetIVM")
|
||||
}
|
||||
|
||||
ret := &api.ServerModificationTypesOutput{}
|
||||
ret.ModificationTypes = make([]api.ServerModificationType, 0)
|
||||
modificationTypes, err := vm.GetModificationTypes()
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "GetModificationTypes")
|
||||
}
|
||||
for _, modificationType := range modificationTypes {
|
||||
ret.ModificationTypes = append(ret.ModificationTypes, api.ServerModificationType{Name: modificationType.InstanceType})
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SGuest) PreCheckPerformAction(
|
||||
ctx context.Context, userCred mcclient.TokenCredential,
|
||||
action string, query jsonutils.JSONObject, data jsonutils.JSONObject,
|
||||
|
||||
Vendored
+1
-1
@@ -1830,7 +1830,7 @@ sigs.k8s.io/structured-merge-diff/v4/value
|
||||
# sigs.k8s.io/yaml v1.3.0
|
||||
## explicit; go 1.12
|
||||
sigs.k8s.io/yaml
|
||||
# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20260409072655-7f5827365741
|
||||
# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20260409123851-7b55f5f3ad92
|
||||
## explicit; go 1.21
|
||||
yunion.io/x/cloudmux/pkg/apis
|
||||
yunion.io/x/cloudmux/pkg/apis/billing
|
||||
|
||||
+4
@@ -377,3 +377,7 @@ type SInstanceDeployOptions struct {
|
||||
DeleteKeypair bool
|
||||
UserData string
|
||||
}
|
||||
|
||||
type SInstanceModificationType struct {
|
||||
InstanceType string
|
||||
}
|
||||
|
||||
+2
@@ -379,6 +379,8 @@ type ICloudVM interface {
|
||||
DeployVM(ctx context.Context, opts *SInstanceDeployOptions) error
|
||||
|
||||
ChangeConfig(ctx context.Context, config *SManagedVMChangeConfig) error
|
||||
// 获取实例可变更类型
|
||||
GetModificationTypes() ([]SInstanceModificationType, error)
|
||||
|
||||
GetVNCInfo(input *ServerVncInput) (*ServerVncOutput, error)
|
||||
// 若有跟随主机删除的选项,需要设置为True
|
||||
|
||||
+55
@@ -522,6 +522,61 @@ func (self *SInstance) ChangeConfig(ctx context.Context, config *cloudprovider.S
|
||||
return fmt.Errorf("Failed to change vm config, specification not supported")
|
||||
}
|
||||
|
||||
func (self *SInstance) GetModificationTypes() ([]cloudprovider.SInstanceModificationType, error) {
|
||||
return self.host.zone.region.GetInstanceModificationTypes(self.InstanceId)
|
||||
}
|
||||
|
||||
func (self *SRegion) GetInstanceModificationTypes(instanceId string) ([]cloudprovider.SInstanceModificationType, error) {
|
||||
params := map[string]string{
|
||||
"RegionId": self.RegionId,
|
||||
"ResourceId": instanceId,
|
||||
"DestinationResource": "InstanceType",
|
||||
}
|
||||
body, err := self.ecsRequest("DescribeResourcesModification", params)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "DescribeResourcesModification")
|
||||
}
|
||||
|
||||
parsed := struct {
|
||||
AvailableZones struct {
|
||||
AvailableZone []struct {
|
||||
AvailableResources struct {
|
||||
AvailableResource []struct {
|
||||
SupportedResources struct {
|
||||
SupportedResource []struct {
|
||||
Value string
|
||||
Status string
|
||||
StatusCategory string
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}{}
|
||||
if err := body.Unmarshal(&parsed); err != nil {
|
||||
return nil, errors.Wrapf(err, "body.Unmarshal")
|
||||
}
|
||||
|
||||
ret := make([]cloudprovider.SInstanceModificationType, 0)
|
||||
seen := map[string]struct{}{}
|
||||
for _, zone := range parsed.AvailableZones.AvailableZone {
|
||||
for _, resource := range zone.AvailableResources.AvailableResource {
|
||||
for _, supportedResource := range resource.SupportedResources.SupportedResource {
|
||||
if len(supportedResource.Value) == 0 || len(supportedResource.Status) == 0 || strings.ToLower(supportedResource.Status) != "available" {
|
||||
continue
|
||||
}
|
||||
if _, ok := seen[supportedResource.Value]; ok {
|
||||
continue
|
||||
}
|
||||
seen[supportedResource.Value] = struct{}{}
|
||||
ret = append(ret, cloudprovider.SInstanceModificationType{InstanceType: supportedResource.Value})
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SInstance) AttachDisk(ctx context.Context, diskId string) error {
|
||||
return self.host.zone.region.AttachDisk(self.InstanceId, diskId)
|
||||
}
|
||||
|
||||
+25
@@ -682,6 +682,31 @@ func (self *SInstance) ChangeConfig(ctx context.Context, config *cloudprovider.S
|
||||
return fmt.Errorf("Failed to change vm config, specification not supported")
|
||||
}
|
||||
|
||||
func (self *SInstance) GetModificationTypes() ([]cloudprovider.SInstanceModificationType, error) {
|
||||
return self.host.zone.region.GetInstanceModificationTypes(self.GetId())
|
||||
}
|
||||
|
||||
// https://console.huaweicloud.com/apiexplorer/#/openapi/ECS/doc?api=ListResizeFlavors
|
||||
func (self *SRegion) GetInstanceModificationTypes(instanceId string) ([]cloudprovider.SInstanceModificationType, error) {
|
||||
params := url.Values{}
|
||||
params.Set("instance_uuid", instanceId)
|
||||
resp, err := self.list(SERVICE_ECS, "cloudservers/resize_flavors", params)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "ListResizeFlavors(%s)", instanceId)
|
||||
}
|
||||
flavors := []SInstanceType{}
|
||||
err = resp.Unmarshal(&flavors, "flavors")
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "resp.Unmarshal(flavors)")
|
||||
}
|
||||
|
||||
ret := make([]cloudprovider.SInstanceModificationType, 0, len(flavors))
|
||||
for _, flavor := range flavors {
|
||||
ret = append(ret, cloudprovider.SInstanceModificationType{InstanceType: flavor.ID})
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SInstance) GetVNCInfo(input *cloudprovider.ServerVncInput) (*cloudprovider.ServerVncOutput, error) {
|
||||
return self.host.zone.region.GetInstanceVNCUrl(self.GetId())
|
||||
}
|
||||
|
||||
+4
@@ -98,3 +98,7 @@ func (ins *SInstanceBase) GetHealthStatus() string {
|
||||
func (instance *SInstanceBase) GetError() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (instance *SInstanceBase) GetModificationTypes() ([]cloudprovider.SInstanceModificationType, error) {
|
||||
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetModificationTypes")
|
||||
}
|
||||
|
||||
+44
@@ -496,6 +496,50 @@ func (self *SInstance) ChangeConfig(ctx context.Context, opts *cloudprovider.SMa
|
||||
return self.host.zone.region.ChangeVMConfig(self.InstanceId, opts.InstanceType)
|
||||
}
|
||||
|
||||
func (self *SInstance) GetModificationTypes() ([]cloudprovider.SInstanceModificationType, error) {
|
||||
return self.host.zone.region.GetInstanceModificationTypes(self.InstanceId)
|
||||
}
|
||||
|
||||
func (self *SRegion) GetInstanceModificationTypes(instanceId string) ([]cloudprovider.SInstanceModificationType, error) {
|
||||
params := map[string]string{
|
||||
"Region": self.Region,
|
||||
"InstanceIds.0": instanceId,
|
||||
}
|
||||
body, err := self.cvmRequest("DescribeInstancesModification", params, true)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "DescribeInstancesModification")
|
||||
}
|
||||
|
||||
resp := struct {
|
||||
InstanceTypeConfigStatusSet []struct {
|
||||
InstanceTypeConfig struct {
|
||||
InstanceType string
|
||||
Zone string
|
||||
}
|
||||
Status string
|
||||
}
|
||||
}{}
|
||||
|
||||
if err := body.Unmarshal(&resp); err != nil {
|
||||
return nil, errors.Wrapf(err, "body.Unmarshal")
|
||||
}
|
||||
|
||||
ret := make([]cloudprovider.SInstanceModificationType, 0)
|
||||
seen := map[string]struct{}{}
|
||||
for _, cfg := range resp.InstanceTypeConfigStatusSet {
|
||||
if !strings.EqualFold(cfg.Status, "SELL") {
|
||||
continue
|
||||
}
|
||||
|
||||
if _, ok := seen[cfg.InstanceTypeConfig.InstanceType]; ok {
|
||||
continue
|
||||
}
|
||||
seen[cfg.InstanceTypeConfig.InstanceType] = struct{}{}
|
||||
ret = append(ret, cloudprovider.SInstanceModificationType{InstanceType: cfg.InstanceTypeConfig.InstanceType})
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SInstance) AttachDisk(ctx context.Context, diskId string) error {
|
||||
return self.host.zone.region.AttachDisk(self.InstanceId, diskId)
|
||||
}
|
||||
|
||||
+4
@@ -288,3 +288,7 @@ func (self *SInstance) GetPowerStates() string {
|
||||
func (self *SInstance) GetHealthStatus() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SInstance) GetModificationTypes() ([]cloudprovider.SInstanceModificationType, error) {
|
||||
return nil, cloudprovider.ErrNotSupported
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user