mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-01 15:07:17 +08:00
fix(region): vendor update (#24998)
This commit is contained in:
@@ -108,7 +108,7 @@ require (
|
||||
k8s.io/cri-api v0.28.15
|
||||
k8s.io/klog/v2 v2.90.1
|
||||
moul.io/http2curl/v2 v2.3.0
|
||||
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20260608093459-7789fd47ef2b
|
||||
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20260609055727-275f3963d64c
|
||||
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
|
||||
|
||||
@@ -1785,8 +1785,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.20260608093459-7789fd47ef2b h1:/ksenqUkmchwkBsE80p7RMzvsNyPNtPHQHHHJjUoumA=
|
||||
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20260608093459-7789fd47ef2b/go.mod h1:TbMuTWxcTdyL2Usn+WQdIw0jdlBYO66SzPRY8LZ3Wj0=
|
||||
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20260609055727-275f3963d64c h1:XucESU4LflBCCvfiW89YcdG58a0KQ9KPJK/ucFsQcww=
|
||||
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20260609055727-275f3963d64c/go.mod h1:TbMuTWxcTdyL2Usn+WQdIw0jdlBYO66SzPRY8LZ3Wj0=
|
||||
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=
|
||||
|
||||
Vendored
+1
-1
@@ -2603,7 +2603,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.20260608093459-7789fd47ef2b
|
||||
# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20260609055727-275f3963d64c
|
||||
## explicit; go 1.24
|
||||
yunion.io/x/cloudmux/pkg/apis
|
||||
yunion.io/x/cloudmux/pkg/apis/billing
|
||||
|
||||
+5
@@ -207,6 +207,11 @@ var UCLOUD_STORAGES = []string{
|
||||
STORAGE_UCLOUD_CLOUD_RSSD,
|
||||
}
|
||||
|
||||
var UCLOUD_LOCAL_STORAGES = []string{
|
||||
STORAGE_UCLOUD_LOCAL_SSD,
|
||||
STORAGE_UCLOUD_LOCAL_NORMAL,
|
||||
}
|
||||
|
||||
var KSYUN_STORAGES = []string{
|
||||
STORAGE_KSYUN_ESSD_AUTO_PL,
|
||||
STORAGE_KSYUN_ESSD_PL1,
|
||||
|
||||
+19
-28
@@ -23,8 +23,6 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/utils"
|
||||
|
||||
billing_api "yunion.io/x/cloudmux/pkg/apis/billing"
|
||||
api "yunion.io/x/cloudmux/pkg/apis/compute"
|
||||
@@ -163,11 +161,10 @@ func (self *SDisk) GetIsAutoDelete() bool {
|
||||
|
||||
func (self *SDisk) GetTemplateId() string {
|
||||
if strings.Contains(self.DiskType, "SystemDisk") && len(self.UHostID) > 0 {
|
||||
ins, err := self.storage.zone.region.GetInstanceByID(self.UHostID)
|
||||
ins, err := self.storage.zone.region.GetInstance(self.UHostID)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
return ""
|
||||
}
|
||||
|
||||
return ins.ImageID
|
||||
}
|
||||
|
||||
@@ -303,27 +300,23 @@ func (self *SDisk) Rebuild(ctx context.Context) error {
|
||||
}
|
||||
|
||||
func (self *SRegion) GetDisk(diskId string) (*SDisk, error) {
|
||||
if len(diskId) == 0 {
|
||||
return nil, fmt.Errorf("GetDisk id should not empty")
|
||||
}
|
||||
|
||||
disks, err := self.GetDisks("", "", []string{diskId})
|
||||
disks, err := self.GetDisks("", "", "", diskId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(disks) == 1 {
|
||||
return &disks[0], nil
|
||||
} else if len(disks) == 0 {
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
} else {
|
||||
return nil, fmt.Errorf("GetDisk %s %d found", diskId, len(disks))
|
||||
for i := range disks {
|
||||
if disks[i].UDiskID == diskId {
|
||||
return &disks[i], nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "GetDisk %s", diskId)
|
||||
}
|
||||
|
||||
// https://docs.ucloud.cn/api/udisk-api/describe_udisk
|
||||
// diskType DataDisk|SystemDisk (DataDisk表示数据盘,SystemDisk表示系统盘)
|
||||
func (self *SRegion) GetDisks(zoneId string, diskType string, diskIds []string) ([]SDisk, error) {
|
||||
func (self *SRegion) GetDisks(zoneId string, diskType string, isBoot string, diskId string) ([]SDisk, error) {
|
||||
disks := make([]SDisk, 0)
|
||||
params := NewRockbaseParams()
|
||||
if len(zoneId) > 0 {
|
||||
@@ -331,25 +324,23 @@ func (self *SRegion) GetDisks(zoneId string, diskType string, diskIds []string)
|
||||
}
|
||||
|
||||
if len(diskType) > 0 {
|
||||
params.Set("ProtocolVersion", "1")
|
||||
params.Set("DiskType", diskType)
|
||||
}
|
||||
|
||||
if len(diskId) > 0 {
|
||||
params.Set("UDiskId", diskId)
|
||||
}
|
||||
|
||||
if len(isBoot) > 0 {
|
||||
params.Set("IsBoot", isBoot)
|
||||
}
|
||||
|
||||
err := self.DoListAll("DescribeUDisk", params, &disks)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(diskIds) > 0 {
|
||||
filtedDisks := make([]SDisk, 0)
|
||||
for i := range disks {
|
||||
if utils.IsInStringArray(disks[i].UDiskID, diskIds) {
|
||||
filtedDisks = append(filtedDisks, disks[i])
|
||||
}
|
||||
}
|
||||
|
||||
return filtedDisks, nil
|
||||
}
|
||||
|
||||
return disks, nil
|
||||
}
|
||||
|
||||
|
||||
+11
-11
@@ -15,12 +15,12 @@
|
||||
package rockbase
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
billing_api "yunion.io/x/cloudmux/pkg/apis/billing"
|
||||
api "yunion.io/x/cloudmux/pkg/apis/compute"
|
||||
@@ -99,7 +99,7 @@ func (self *SEip) GetGlobalId() string {
|
||||
func (self *SEip) GetStatus() string {
|
||||
switch self.Status {
|
||||
case "used":
|
||||
return api.EIP_STATUS_ASSOCIATE // ?
|
||||
return api.EIP_STATUS_READY
|
||||
case "free":
|
||||
return api.EIP_STATUS_READY
|
||||
case "freeze":
|
||||
@@ -113,9 +113,9 @@ func (self *SEip) Refresh() error {
|
||||
if self.IsEmulated() {
|
||||
return nil
|
||||
}
|
||||
new, err := self.region.GetEipById(self.GetId())
|
||||
new, err := self.region.GetEip(self.GetId())
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.Wrapf(err, "Refresh")
|
||||
}
|
||||
return jsonutils.Update(self, new)
|
||||
}
|
||||
@@ -225,12 +225,15 @@ func (self *SRegion) CreateEIP(eip *cloudprovider.SEip) (cloudprovider.ICloudEIP
|
||||
params.Set("OperatorName", eip.BGPType)
|
||||
params.Set("Bandwidth", eip.BandwidthMbps)
|
||||
params.Set("Name", eip.Name)
|
||||
params.Set("Region", self.GetId())
|
||||
var payMode string
|
||||
switch eip.ChargeType {
|
||||
case api.EIP_CHARGE_TYPE_BY_TRAFFIC:
|
||||
payMode = "Traffic"
|
||||
case api.EIP_CHARGE_TYPE_BY_BANDWIDTH:
|
||||
payMode = "Bandwidth"
|
||||
default:
|
||||
payMode = "Bandwidth"
|
||||
}
|
||||
params.Set("PayMode", payMode)
|
||||
params.Set("ChargeType", "Dynamic") // 按需付费
|
||||
@@ -241,14 +244,11 @@ func (self *SRegion) CreateEIP(eip *cloudprovider.SEip) (cloudprovider.ICloudEIP
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(eips) == 1 {
|
||||
eip := eips[0]
|
||||
eip.region = self
|
||||
eip.Refresh()
|
||||
return &eip, nil
|
||||
} else {
|
||||
return nil, fmt.Errorf("CreateEIP %d eip created", len(eips))
|
||||
for i := range eips {
|
||||
eips[i].region = self
|
||||
return &eips[i], nil
|
||||
}
|
||||
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "CreateEIP %d eip created", len(eips))
|
||||
}
|
||||
|
||||
// https://docs.ucloud.cn/api/unet-api/release_eip
|
||||
|
||||
+59
-68
@@ -17,11 +17,10 @@ package rockbase
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/billing"
|
||||
|
||||
@@ -77,13 +76,13 @@ func (self *SHost) GetIVMs() ([]cloudprovider.ICloudVM, error) {
|
||||
}
|
||||
|
||||
func (self *SHost) GetIVMById(id string) (cloudprovider.ICloudVM, error) {
|
||||
vm, err := self.zone.region.GetInstanceByID(id)
|
||||
vm, err := self.zone.region.GetInstance(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
vm.host = self
|
||||
return &vm, nil
|
||||
return vm, nil
|
||||
}
|
||||
|
||||
func (self *SHost) GetIStorages() ([]cloudprovider.ICloudStorage, error) {
|
||||
@@ -162,19 +161,19 @@ func (self *SHost) GetVersion() string {
|
||||
|
||||
// 不支持user data
|
||||
// 不支持指定keypair
|
||||
func (self *SHost) CreateVM(desc *cloudprovider.SManagedVMCreateConfig) (cloudprovider.ICloudVM, error) {
|
||||
vmId, err := self._createVM(desc.Name, desc.ExternalImageId, desc.SysDisk, desc.Cpu, desc.MemoryMB, desc.InstanceType, desc.ExternalNetworkId, desc.IpAddr, desc.Description, desc.Password, desc.DataDisks, desc.ExternalSecgroupIds, desc.BillingCycle)
|
||||
func (self *SHost) CreateVM(opts *cloudprovider.SManagedVMCreateConfig) (cloudprovider.ICloudVM, error) {
|
||||
vmId, err := self._createVM(opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
vm, err := self.zone.region.GetInstanceByID(vmId)
|
||||
vm, err := self.zone.region.GetInstance(vmId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
vm.host = self
|
||||
return &vm, err
|
||||
return vm, err
|
||||
}
|
||||
|
||||
func (host *SHost) GetIHostNics() ([]cloudprovider.ICloudHostNetInterface, error) {
|
||||
@@ -187,103 +186,92 @@ func (host *SHost) GetIHostNics() ([]cloudprovider.ICloudHostNetInterface, error
|
||||
|
||||
type SInstanceType struct {
|
||||
UHostType string
|
||||
GpuType string
|
||||
CPU int
|
||||
MemoryMB int
|
||||
GPU int
|
||||
}
|
||||
|
||||
// 格式: {机型}.c{cpu}.m{memGB}[.g{gpu}],机型支持 UCloud GpuType 如 T4S、2080Ti-4C、T4/4
|
||||
var instanceTypeRe = regexp.MustCompile(`^([A-Za-z0-9][A-Za-z0-9/_-]*)\.c(\d+)\.m(\d+)(?:\.g(\d+))?$`)
|
||||
|
||||
func ParseInstanceType(instanceType string) (SInstanceType, error) {
|
||||
i := SInstanceType{}
|
||||
segs := strings.Split(instanceType, ".")
|
||||
if len(segs) < 3 {
|
||||
matches := instanceTypeRe.FindStringSubmatch(instanceType)
|
||||
if matches == nil {
|
||||
return i, fmt.Errorf("invalid instance type %s", instanceType)
|
||||
} else if len(segs) >= 4 {
|
||||
gpu, err := strconv.Atoi(strings.TrimLeft(segs[3], "g"))
|
||||
}
|
||||
|
||||
hostType := matches[1]
|
||||
cpu, err := strconv.Atoi(matches[2])
|
||||
if err != nil {
|
||||
return i, err
|
||||
}
|
||||
memGB, err := strconv.Atoi(matches[3])
|
||||
if err != nil {
|
||||
return i, err
|
||||
}
|
||||
|
||||
i.CPU = cpu
|
||||
i.MemoryMB = memGB * 1024
|
||||
if len(matches[4]) > 0 {
|
||||
gpu, err := strconv.Atoi(matches[4])
|
||||
if err != nil {
|
||||
return i, err
|
||||
}
|
||||
|
||||
i.GPU = gpu
|
||||
i.GpuType = hostType
|
||||
i.UHostType = "G"
|
||||
} else {
|
||||
i.UHostType = hostType
|
||||
}
|
||||
|
||||
cpu, err := strconv.Atoi(strings.TrimLeft(segs[1], "c"))
|
||||
if err != nil {
|
||||
return i, err
|
||||
}
|
||||
|
||||
mem, err := strconv.Atoi(strings.TrimLeft(segs[2], "m"))
|
||||
if err != nil {
|
||||
return i, err
|
||||
}
|
||||
|
||||
i.UHostType = segs[0]
|
||||
i.CPU = cpu
|
||||
i.MemoryMB = mem * 1024
|
||||
return i, nil
|
||||
}
|
||||
|
||||
func (self *SHost) _createVM(name, imgId string, sysDisk cloudprovider.SDiskInfo, cpu, memMB int, instanceType string,
|
||||
networkId, ipAddr, desc, passwd string,
|
||||
dataDisks []cloudprovider.SDiskInfo, secgroupIds []string, bc *billing.SBillingCycle) (string, error) {
|
||||
// 网络配置及安全组绑定
|
||||
net, _ := self.zone.region.getNetwork(networkId)
|
||||
if net == nil {
|
||||
return "", fmt.Errorf("invalid network ID %s", networkId)
|
||||
func (self *SHost) _createVM(opts *cloudprovider.SManagedVMCreateConfig) (string, error) {
|
||||
net, err := self.zone.region.getNetwork(opts.ExternalNetworkId)
|
||||
if err != nil {
|
||||
return "", errors.Wrapf(err, "getNetwork %s", opts.ExternalNetworkId)
|
||||
}
|
||||
|
||||
if net.wire == nil {
|
||||
log.Errorf("network's wire is empty")
|
||||
return "", fmt.Errorf("network's wire is empty")
|
||||
}
|
||||
|
||||
if net.wire.vpc == nil {
|
||||
log.Errorf("wire's vpc is empty")
|
||||
return "", fmt.Errorf("wire's vpc is empty")
|
||||
}
|
||||
|
||||
if len(passwd) == 0 {
|
||||
if len(opts.Password) == 0 {
|
||||
return "", fmt.Errorf("CreateVM password should not be emtpty")
|
||||
}
|
||||
|
||||
// 镜像及硬盘配置
|
||||
img, err := self.zone.region.GetImage(imgId)
|
||||
img, err := self.zone.region.GetImage(opts.ExternalImageId)
|
||||
if err != nil {
|
||||
log.Errorf("GetImage %s fail %s", imgId, err)
|
||||
return "", err
|
||||
return "", errors.Wrapf(err, "GetImage %s", opts.ExternalImageId)
|
||||
}
|
||||
|
||||
if img.GetStatus() != api.CACHED_IMAGE_STATUS_ACTIVE {
|
||||
log.Errorf("image %s status %s, expect %s", imgId, img.GetStatus(), api.CACHED_IMAGE_STATUS_ACTIVE)
|
||||
return "", fmt.Errorf("image not ready")
|
||||
return "", errors.Wrapf(cloudprovider.ErrInvalidStatus, "image %s status %s, expect %s", opts.ExternalImageId, img.GetStatus(), api.CACHED_IMAGE_STATUS_ACTIVE)
|
||||
}
|
||||
|
||||
disks := make([]SDisk, len(dataDisks)+1)
|
||||
disks := make([]SDisk, len(opts.DataDisks)+1)
|
||||
disks[0].SizeGB = int(img.ImageSizeGB)
|
||||
if sysDisk.SizeGB > 0 && sysDisk.SizeGB > int(img.ImageSizeGB) {
|
||||
disks[0].SizeGB = sysDisk.SizeGB
|
||||
if opts.SysDisk.SizeGB > 0 && opts.SysDisk.SizeGB > int(img.ImageSizeGB) {
|
||||
disks[0].SizeGB = opts.SysDisk.SizeGB
|
||||
}
|
||||
disks[0].DiskType = sysDisk.StorageType
|
||||
disks[0].DiskType = opts.SysDisk.StorageType
|
||||
|
||||
for i, dataDisk := range dataDisks {
|
||||
for i, dataDisk := range opts.DataDisks {
|
||||
disks[i+1].SizeGB = dataDisk.SizeGB
|
||||
disks[i+1].DiskType = dataDisk.StorageType
|
||||
}
|
||||
|
||||
// 创建实例
|
||||
// https://docs.ucloud.cn/api/uhost-api/uhost_type
|
||||
// https://docs.ucloud.cn/compute/uhost/introduction/uhost/type
|
||||
var vmId string
|
||||
i, err := ParseInstanceType(instanceType)
|
||||
i, err := ParseInstanceType(opts.InstanceType)
|
||||
if err != nil {
|
||||
if cpu <= 0 || memMB <= 0 {
|
||||
if opts.Cpu <= 0 || opts.MemoryMB <= 0 {
|
||||
return "", err
|
||||
} else {
|
||||
i.UHostType = "N2"
|
||||
i.CPU = cpu
|
||||
i.MemoryMB = memMB
|
||||
i.UHostType = "O"
|
||||
i.CPU = opts.Cpu
|
||||
i.MemoryMB = opts.MemoryMB
|
||||
}
|
||||
}
|
||||
|
||||
vmId, err = self.zone.region.CreateInstance(name, imgId, i.UHostType, passwd, net.wire.vpc.GetId(), networkId, secgroupIds, self.zone.ZoneId, desc, ipAddr, i.CPU, i.MemoryMB, i.GPU, disks, bc)
|
||||
vmId, err = self.zone.region.CreateInstance(opts.Name, opts.ExternalImageId, i.UHostType, opts.Password, net.wire.vpc.GetId(), opts.ExternalNetworkId, opts.ExternalSecgroupIds, self.zone.ZoneId, opts.Description, opts.IpAddr, i.CPU, i.MemoryMB, i.GPU, i.GpuType, disks, opts.BillingCycle)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Failed to create: %v", err)
|
||||
}
|
||||
@@ -295,14 +283,14 @@ func (self *SHost) _createVM(name, imgId string, sysDisk cloudprovider.SDiskInfo
|
||||
// https://docs.ucloud.cn/api/uhost-api/specification
|
||||
// 支持8-30位字符, 不能包含[A-Z],[a-z],[0-9]和[()`~!@#$%^&*-+=_|{}[]:;'<>,.?/]之外的非法字符
|
||||
func (self *SRegion) CreateInstance(name, imageId, hostType, password, vpcId, SubnetId string, securityGroupId []string,
|
||||
zoneId, desc, ipAddr string, cpu, memMB, gpu int, disks []SDisk, bc *billing.SBillingCycle) (string, error) {
|
||||
zoneId, desc, ipAddr string, cpu, memMB, gpu int, gpuType string, disks []SDisk, bc *billing.SBillingCycle) (string, error) {
|
||||
params := NewRockbaseParams()
|
||||
params.Set("Zone", zoneId)
|
||||
params.Set("ImageId", imageId)
|
||||
params.Set("Password", base64.StdEncoding.EncodeToString([]byte(password)))
|
||||
params.Set("LoginMode", "Password")
|
||||
params.Set("Name", name)
|
||||
params.Set("UHostType", hostType)
|
||||
params.Set("MachineType", hostType)
|
||||
params.Set("CPU", cpu)
|
||||
params.Set("Memory", memMB)
|
||||
params.Set("VPCId", vpcId)
|
||||
@@ -312,6 +300,9 @@ func (self *SRegion) CreateInstance(name, imageId, hostType, password, vpcId, Su
|
||||
}
|
||||
if gpu > 0 {
|
||||
params.Set("GPU", gpu)
|
||||
if len(gpuType) > 0 {
|
||||
params.Set("GpuType", gpuType)
|
||||
}
|
||||
}
|
||||
|
||||
if bc != nil && bc.GetMonths() >= 1 && bc.GetMonths() < 10 {
|
||||
@@ -347,7 +338,7 @@ func (self *SRegion) CreateInstance(name, imageId, hostType, password, vpcId, Su
|
||||
ret := Ret{}
|
||||
err := self.DoAction("CreateUHostInstance", params, &ret)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "", errors.Wrapf(err, "CreateUHostInstance")
|
||||
}
|
||||
|
||||
if len(ret.UHostIds) == 1 {
|
||||
|
||||
+31
-51
@@ -55,6 +55,8 @@ type SInstance struct {
|
||||
State string `json:"State"`
|
||||
NetworkState string `json:"NetworkState"`
|
||||
HostType string `json:"HostType"`
|
||||
MachineType string `json:"MachineType"`
|
||||
GpuType string `json:"GpuType"`
|
||||
StorageType string `json:"StorageType"`
|
||||
TotalDiskSpace int `json:"TotalDiskSpace"`
|
||||
DiskSet []DiskSet `json:"DiskSet"`
|
||||
@@ -175,7 +177,7 @@ func (self *SInstance) GetStatus() string {
|
||||
}
|
||||
|
||||
func (self *SInstance) Refresh() error {
|
||||
new, err := self.host.zone.region.GetInstanceByID(self.GetId())
|
||||
new, err := self.host.zone.region.GetInstance(self.GetId())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -235,22 +237,17 @@ func (self *SInstance) GetLocalDisk(diskId, storageType string, sizeGB int, isBo
|
||||
|
||||
func (self *SInstance) GetIDisks() ([]cloudprovider.ICloudDisk, error) {
|
||||
localDisks := make([]SDisk, 0)
|
||||
diskIds := make([]string, 0)
|
||||
disks := []SDisk{}
|
||||
for _, disk := range self.DiskSet {
|
||||
if utils.IsInStringArray(disk.DiskType, []string{api.STORAGE_ROCKBASE_LOCAL_NORMAL, api.STORAGE_ROCKBASE_LOCAL_SSD}) {
|
||||
localDisks = append(localDisks, self.GetLocalDisk(disk.DiskID, disk.DiskType, disk.Size, disk.IsBoot))
|
||||
} else {
|
||||
diskIds = append(diskIds, disk.DiskID)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
disks := []SDisk{}
|
||||
var err error
|
||||
if len(diskIds) > 0 {
|
||||
disks, err = self.host.zone.region.GetDisks("", "", diskIds)
|
||||
disk, err := self.host.zone.region.GetDisk(disk.DiskID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
disks = append(disks, *disk)
|
||||
}
|
||||
|
||||
disks = append(disks, localDisks...)
|
||||
@@ -302,12 +299,12 @@ func (self *SInstance) GetINics() ([]cloudprovider.ICloudNic, error) {
|
||||
func (self *SInstance) GetIEIP() (cloudprovider.ICloudEIP, error) {
|
||||
for _, ip := range self.IPSet {
|
||||
if len(ip.IPId) > 0 {
|
||||
eip, err := self.host.zone.region.GetEipById(ip.IPId)
|
||||
eip, err := self.host.zone.region.GetEip(ip.IPId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.Wrapf(err, "GetEip %s", ip.IPId)
|
||||
}
|
||||
|
||||
return &eip, nil
|
||||
return eip, nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -374,13 +371,22 @@ func (self *SInstance) GetMachine() string {
|
||||
return "pc"
|
||||
}
|
||||
|
||||
func (self *SInstance) GetInstanceType() string {
|
||||
// C1.c8.m24
|
||||
if strings.HasPrefix(self.HostType, "G") {
|
||||
return fmt.Sprintf("%s.c%d.m%d.g%d", self.HostType, self.CPU, self.MemoryMB/1014, self.GPU)
|
||||
} else {
|
||||
return fmt.Sprintf("%s.c%d.m%d", self.HostType, self.CPU, self.MemoryMB/1014)
|
||||
func (self *SInstance) instanceTypeHostPrefix() string {
|
||||
if self.GPU > 0 && len(self.GpuType) > 0 {
|
||||
return self.GpuType
|
||||
}
|
||||
if len(self.UHostType) > 0 {
|
||||
return self.UHostType
|
||||
}
|
||||
if len(self.MachineType) > 0 {
|
||||
return self.MachineType
|
||||
}
|
||||
return self.HostType
|
||||
}
|
||||
|
||||
func (self *SInstance) GetInstanceType() string {
|
||||
memGB := self.MemoryMB / 1024
|
||||
return formatInstanceSpec(self.instanceTypeHostPrefix(), self.CPU, memGB, self.GPU)
|
||||
}
|
||||
|
||||
// https://docs.ucloud.cn/api/unet-api/grant_firewall
|
||||
@@ -437,34 +443,7 @@ func (self *SInstance) UpdateUserData(userData string) error {
|
||||
}
|
||||
|
||||
// https://docs.ucloud.cn/api/uhost-api/reinstall_uhost_instance
|
||||
// 1.请确认在重新安装之前,该实例已被关闭;
|
||||
// 2.请确认该实例未挂载UDisk;
|
||||
// todo:// 3.将原系统重装为不同类型的系统时(Linux->Windows),不可选择保留数据盘;
|
||||
// 4.重装不同版本的系统时(CentOS6->CentOS7),若选择保留数据盘,请注意数据盘的文件系统格式;
|
||||
// 5.若主机CPU低于2核,不可重装为Windows系统。
|
||||
func (self *SInstance) RebuildRoot(ctx context.Context, desc *cloudprovider.SManagedVMRebuildRootConfig) (string, error) {
|
||||
if len(desc.PublicKey) > 0 {
|
||||
return "", fmt.Errorf("DeployVM not support assign ssh keypair")
|
||||
}
|
||||
|
||||
if self.GetStatus() != api.VM_READY {
|
||||
return "", fmt.Errorf("DeployVM instance status %s , expected %s.", self.GetStatus(), api.VM_READY)
|
||||
}
|
||||
|
||||
if len(self.DiskSet) > 1 {
|
||||
for _, disk := range self.DiskSet {
|
||||
if disk.Type == "Data" {
|
||||
err := self.host.zone.region.DetachDisk(self.host.zone.GetId(), self.GetId(), disk.DiskID)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("RebuildRoot detach disk %s", err)
|
||||
}
|
||||
|
||||
defer self.host.zone.region.AttachDisk(self.host.zone.GetId(), self.GetId(), disk.DiskID)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
err := self.host.zone.region.RebuildRoot(self.GetId(), desc.ImageId, desc.Password)
|
||||
if err != nil {
|
||||
return "", err
|
||||
@@ -475,12 +454,12 @@ func (self *SInstance) RebuildRoot(ctx context.Context, desc *cloudprovider.SMan
|
||||
return "", errors.Wrap(err, "RebuildRoot")
|
||||
}
|
||||
|
||||
disks, err := self.GetIDisks()
|
||||
if len(disks) > 0 {
|
||||
return disks[0].GetId(), nil
|
||||
} else {
|
||||
return "", fmt.Errorf("RebuildRoot %s", err)
|
||||
for _, disk := range self.DiskSet {
|
||||
if disk.Type == "SystemDisk" {
|
||||
return disk.DiskID, nil
|
||||
}
|
||||
}
|
||||
return "", errors.Wrapf(cloudprovider.ErrNotFound, "SystemDisk not found")
|
||||
}
|
||||
|
||||
func (self *SInstance) DeployVM(ctx context.Context, opts *cloudprovider.SInstanceDeployOptions) error {
|
||||
@@ -614,6 +593,7 @@ func (self *SRegion) DeleteVM(instanceId string) error {
|
||||
params := NewRockbaseParams()
|
||||
params.Set("UHostId", instanceId)
|
||||
params.Set("Destroy", 1) // 跳过回收站,直接删除
|
||||
params.Set("ReleaseUDisk", true)
|
||||
|
||||
return self.DoAction("TerminateUHostInstance", params, nil)
|
||||
}
|
||||
|
||||
+1
-5
@@ -326,11 +326,7 @@ func (self *SRegion) GetZoneStorageTypes(zoneId string) ([]string, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
storageTypes := collectStorageTypesFromInstanceTypes(types, zoneId)
|
||||
if len(storageTypes) == 0 {
|
||||
return nil, fmt.Errorf("no storage types found for zone %s", zoneId)
|
||||
}
|
||||
return storageTypes, nil
|
||||
return collectStorageTypesFromInstanceTypes(types, zoneId), nil
|
||||
}
|
||||
|
||||
// GetAvailableInstanceTypes 获取地域/可用区下可售机型信息。
|
||||
|
||||
+10
-14
@@ -19,6 +19,7 @@ import (
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/netutils"
|
||||
"yunion.io/x/pkg/util/rbacscope"
|
||||
|
||||
@@ -142,9 +143,6 @@ func (self *SRegion) GetNetwork(networkId string) (*SNetwork, error) {
|
||||
}
|
||||
|
||||
func (self *SRegion) getNetwork(networkId string) (*SNetwork, error) {
|
||||
if len(networkId) == 0 {
|
||||
return nil, fmt.Errorf("getNetwork network id should not be empty")
|
||||
}
|
||||
networks := make([]SNetwork, 0)
|
||||
|
||||
params := NewRockbaseParams()
|
||||
@@ -154,19 +152,17 @@ func (self *SRegion) getNetwork(networkId string) (*SNetwork, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(networks) == 1 {
|
||||
network := networks[0]
|
||||
vpc, err := self.GetVpc(network.VpcId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
for i := range networks {
|
||||
if networks[i].SubnetID == networkId {
|
||||
vpc, err := self.GetVpc(networks[i].VpcId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
networks[i].wire = &SWire{vpc: vpc}
|
||||
return &networks[i], nil
|
||||
}
|
||||
network.wire = &SWire{vpc: vpc}
|
||||
return &network, nil
|
||||
} else if len(networks) == 0 {
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
} else {
|
||||
return nil, fmt.Errorf("getNetwork %s %d found", networkId, len(networks))
|
||||
}
|
||||
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "getNetwork %s", networkId)
|
||||
}
|
||||
|
||||
// https://docs.ucloud.cn/api/vpc2.0-api/delete_subnet
|
||||
|
||||
+23
-22
@@ -71,11 +71,11 @@ func (self *SRegion) GetGeographicInfo() cloudprovider.SGeographicInfo {
|
||||
}
|
||||
|
||||
func (self *SRegion) GetIVMById(id string) (cloudprovider.ICloudVM, error) {
|
||||
instance, err := self.GetInstanceByID(id)
|
||||
instance, err := self.GetInstance(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &instance, nil
|
||||
return instance, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) GetIDiskById(id string) (cloudprovider.ICloudDisk, error) {
|
||||
@@ -144,29 +144,30 @@ func (self *SRegion) GetIZoneById(id string) (cloudprovider.ICloudZone, error) {
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
}
|
||||
|
||||
func (self *SRegion) GetEipById(eipId string) (SEip, error) {
|
||||
func (self *SRegion) GetEip(eipId string) (*SEip, error) {
|
||||
params := NewRockbaseParams()
|
||||
params.Set("EIPIds.0", eipId)
|
||||
eips := make([]SEip, 0)
|
||||
err := self.DoListAll("DescribeEIP", params, &eips)
|
||||
if err != nil {
|
||||
return SEip{}, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(eips) == 1 {
|
||||
eip := eips[0]
|
||||
eip.region = self
|
||||
return eip, nil
|
||||
} else if len(eips) == 0 {
|
||||
return SEip{}, cloudprovider.ErrNotFound
|
||||
} else {
|
||||
return SEip{}, fmt.Errorf("GetEipById %d eip found", len(eips))
|
||||
for i := range eips {
|
||||
if eips[i].EIPID == eipId {
|
||||
eips[i].region = self
|
||||
return &eips[i], nil
|
||||
}
|
||||
}
|
||||
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "GetEip %s", eipId)
|
||||
}
|
||||
|
||||
func (self *SRegion) GetIEipById(id string) (cloudprovider.ICloudEIP, error) {
|
||||
eip, err := self.GetEipById(id)
|
||||
return &eip, err
|
||||
eip, err := self.GetEip(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return eip, nil
|
||||
}
|
||||
|
||||
// https://docs.ucloud.cn/api/unet-api/delete_firewall
|
||||
@@ -386,22 +387,22 @@ func (self *SRegion) GetZones() ([]SZone, error) {
|
||||
return zones, err
|
||||
}
|
||||
|
||||
func (self *SRegion) GetInstanceByID(instanceId string) (SInstance, error) {
|
||||
// https://docs.ucloud.cn/api/uhost-api/describe_uhost_instance
|
||||
func (self *SRegion) GetInstance(instanceId string) (*SInstance, error) {
|
||||
params := NewRockbaseParams()
|
||||
params.Set("UHostIds.0", instanceId)
|
||||
instances := make([]SInstance, 0)
|
||||
err := self.DoAction("DescribeUHostInstance", params, &instances)
|
||||
if err != nil {
|
||||
return SInstance{}, err
|
||||
return nil, errors.Wrapf(err, "DescribeUHostInstance")
|
||||
}
|
||||
|
||||
if len(instances) == 1 {
|
||||
return instances[0], nil
|
||||
} else if len(instances) == 0 {
|
||||
return SInstance{}, cloudprovider.ErrNotFound
|
||||
} else {
|
||||
return SInstance{}, fmt.Errorf("GetInstanceByID %s %d found.", instanceId, len(instances))
|
||||
for i := range instances {
|
||||
if instances[i].UHostID == instanceId {
|
||||
return &instances[i], nil
|
||||
}
|
||||
}
|
||||
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "GetInstance %s", instanceId)
|
||||
}
|
||||
|
||||
func (self *SRegion) GetClient() *SRockbaseClient {
|
||||
|
||||
+25
-25
@@ -23,6 +23,7 @@ import (
|
||||
api "yunion.io/x/cloudmux/pkg/apis/compute"
|
||||
"yunion.io/x/cloudmux/pkg/cloudprovider"
|
||||
"yunion.io/x/cloudmux/pkg/multicloud"
|
||||
"yunion.io/x/pkg/utils"
|
||||
)
|
||||
|
||||
type SStorage struct {
|
||||
@@ -65,30 +66,18 @@ func (self *SStorage) GetIZone() cloudprovider.ICloudZone {
|
||||
}
|
||||
|
||||
func (self *SStorage) GetIDisks() ([]cloudprovider.ICloudDisk, error) {
|
||||
disks, err := self.zone.region.GetDisks(self.zone.GetId(), "", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
filtedDisks := make([]SDisk, 0)
|
||||
for _, disk := range disks {
|
||||
// ssd 盘
|
||||
if self.storageType == api.STORAGE_ROCKBASE_CLOUD_SSD && strings.Contains(disk.DiskType, "SSD") {
|
||||
filtedDisks = append(filtedDisks, disk)
|
||||
ret := []cloudprovider.ICloudDisk{}
|
||||
for _, isBoot := range []string{"True", "False"} {
|
||||
disks, err := self.zone.region.GetDisks(self.zone.GetId(), self.storageType, isBoot, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 普通盘
|
||||
if self.storageType == api.STORAGE_ROCKBASE_CLOUD_NORMAL && !strings.Contains(disk.DiskType, "SSD") {
|
||||
filtedDisks = append(filtedDisks, disk)
|
||||
for _, disk := range disks {
|
||||
disk.storage = self
|
||||
ret = append(ret, &disk)
|
||||
}
|
||||
}
|
||||
|
||||
idisks := make([]cloudprovider.ICloudDisk, len(filtedDisks))
|
||||
for i := 0; i < len(filtedDisks); i += 1 {
|
||||
filtedDisks[i].storage = self
|
||||
idisks[i] = &filtedDisks[i]
|
||||
}
|
||||
return idisks, nil
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SStorage) GetStorageType() string {
|
||||
@@ -124,6 +113,10 @@ func (self *SStorage) CreateIDisk(opts *cloudprovider.DiskCreateConfig) (cloudpr
|
||||
switch self.storageType {
|
||||
case api.STORAGE_ROCKBASE_CLOUD_SSD:
|
||||
diskType = "SSDDataDisk"
|
||||
case api.STORAGE_ROCKBASE_CLOUD_ESSD:
|
||||
diskType = "ESSDDataDisk"
|
||||
case api.STORAGE_ROCKBASE_CLOUD_RSSD:
|
||||
diskType = "RSSDDataDisk"
|
||||
}
|
||||
diskId, err := self.zone.region.CreateDisk(self.zone.GetId(), diskType, opts)
|
||||
if err != nil {
|
||||
@@ -140,12 +133,12 @@ func (self *SStorage) CreateIDisk(opts *cloudprovider.DiskCreateConfig) (cloudpr
|
||||
}
|
||||
|
||||
func (self *SStorage) GetIDiskById(idStr string) (cloudprovider.ICloudDisk, error) {
|
||||
if disk, err := self.zone.region.GetDisk(idStr); err != nil {
|
||||
disk, err := self.zone.region.GetDisk(idStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
disk.storage = self
|
||||
return disk, nil
|
||||
}
|
||||
disk.storage = self
|
||||
return disk, nil
|
||||
}
|
||||
|
||||
func (self *SStorage) GetMountPoint() string {
|
||||
@@ -155,3 +148,10 @@ func (self *SStorage) GetMountPoint() string {
|
||||
func (self *SStorage) IsSysDiskStore() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (self *SStorage) DisableSync() bool {
|
||||
return utils.IsInStringArray(self.storageType, []string{
|
||||
api.STORAGE_ROCKBASE_LOCAL_SSD,
|
||||
api.STORAGE_ROCKBASE_LOCAL_NORMAL,
|
||||
})
|
||||
}
|
||||
|
||||
+12
-10
@@ -20,6 +20,7 @@ import (
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
)
|
||||
|
||||
var responseMetaKeys = map[string]bool{
|
||||
@@ -99,24 +100,21 @@ func detectArrayResultKey(resp jsonutils.JSONObject) string {
|
||||
return candidates[0]
|
||||
}
|
||||
|
||||
func unmarshalResult(resp jsonutils.JSONObject, respErr error, result interface{}) error {
|
||||
if respErr != nil {
|
||||
return respErr
|
||||
}
|
||||
|
||||
func unmarshalResult(resp jsonutils.JSONObject, result interface{}) error {
|
||||
if result == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var err error
|
||||
resultKey := detectResultKey(resp, result)
|
||||
if len(resultKey) > 0 {
|
||||
respErr = resp.Unmarshal(result, resultKey)
|
||||
err = resp.Unmarshal(result, resultKey)
|
||||
} else {
|
||||
respErr = resp.Unmarshal(result)
|
||||
err = resp.Unmarshal(result)
|
||||
}
|
||||
|
||||
if respErr != nil {
|
||||
log.Errorf("unmarshal json error %s", respErr)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "unmarshalResult")
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -154,7 +152,11 @@ func doListPart(client *SRockbaseClient, action string, params SParams, result i
|
||||
func DoAction(client *SRockbaseClient, action string, params SParams, result interface{}) error {
|
||||
params.SetAction(action)
|
||||
resp, err := jsonRequest(client, params)
|
||||
return unmarshalResult(resp, err, result)
|
||||
if err != nil {
|
||||
log.Debugf("DoAction %s %s error %s", action, params.PrettyString(), err)
|
||||
return err
|
||||
}
|
||||
return unmarshalResult(resp, result)
|
||||
}
|
||||
|
||||
// 遍历所有结果
|
||||
|
||||
+6
@@ -18,6 +18,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/utils"
|
||||
|
||||
api "yunion.io/x/cloudmux/pkg/apis/compute"
|
||||
"yunion.io/x/cloudmux/pkg/cloudprovider"
|
||||
@@ -52,6 +53,11 @@ func (self *SZone) fetchStorages() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, storageType := range []string{api.STORAGE_ROCKBASE_LOCAL_SSD, api.STORAGE_ROCKBASE_LOCAL_NORMAL} {
|
||||
if !utils.IsInStringArray(storageType, storageTypes) {
|
||||
storageTypes = append(storageTypes, storageType)
|
||||
}
|
||||
}
|
||||
self.storageTypes = storageTypes
|
||||
self.istorages = make([]cloudprovider.ICloudStorage, len(self.storageTypes))
|
||||
for i, sc := range self.storageTypes {
|
||||
|
||||
+19
-28
@@ -23,8 +23,6 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/utils"
|
||||
|
||||
billing_api "yunion.io/x/cloudmux/pkg/apis/billing"
|
||||
api "yunion.io/x/cloudmux/pkg/apis/compute"
|
||||
@@ -163,11 +161,10 @@ func (self *SDisk) GetIsAutoDelete() bool {
|
||||
|
||||
func (self *SDisk) GetTemplateId() string {
|
||||
if strings.Contains(self.DiskType, "SystemDisk") && len(self.UHostID) > 0 {
|
||||
ins, err := self.storage.zone.region.GetInstanceByID(self.UHostID)
|
||||
ins, err := self.storage.zone.region.GetInstance(self.UHostID)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
return ""
|
||||
}
|
||||
|
||||
return ins.ImageID
|
||||
}
|
||||
|
||||
@@ -303,27 +300,23 @@ func (self *SDisk) Rebuild(ctx context.Context) error {
|
||||
}
|
||||
|
||||
func (self *SRegion) GetDisk(diskId string) (*SDisk, error) {
|
||||
if len(diskId) == 0 {
|
||||
return nil, fmt.Errorf("GetDisk id should not empty")
|
||||
}
|
||||
|
||||
disks, err := self.GetDisks("", "", []string{diskId})
|
||||
disks, err := self.GetDisks("", "", "", diskId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(disks) == 1 {
|
||||
return &disks[0], nil
|
||||
} else if len(disks) == 0 {
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
} else {
|
||||
return nil, fmt.Errorf("GetDisk %s %d found", diskId, len(disks))
|
||||
for i := range disks {
|
||||
if disks[i].UDiskID == diskId {
|
||||
return &disks[i], nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "GetDisk %s", diskId)
|
||||
}
|
||||
|
||||
// https://docs.ucloud.cn/api/udisk-api/describe_udisk
|
||||
// diskType DataDisk|SystemDisk (DataDisk表示数据盘,SystemDisk表示系统盘)
|
||||
func (self *SRegion) GetDisks(zoneId string, diskType string, diskIds []string) ([]SDisk, error) {
|
||||
func (self *SRegion) GetDisks(zoneId string, diskType string, isBoot string, diskId string) ([]SDisk, error) {
|
||||
disks := make([]SDisk, 0)
|
||||
params := NewUcloudParams()
|
||||
if len(zoneId) > 0 {
|
||||
@@ -331,25 +324,23 @@ func (self *SRegion) GetDisks(zoneId string, diskType string, diskIds []string)
|
||||
}
|
||||
|
||||
if len(diskType) > 0 {
|
||||
params.Set("ProtocolVersion", "1")
|
||||
params.Set("DiskType", diskType)
|
||||
}
|
||||
|
||||
if len(diskId) > 0 {
|
||||
params.Set("UDiskId", diskId)
|
||||
}
|
||||
|
||||
if len(isBoot) > 0 {
|
||||
params.Set("IsBoot", isBoot)
|
||||
}
|
||||
|
||||
err := self.DoListAll("DescribeUDisk", params, &disks)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(diskIds) > 0 {
|
||||
filtedDisks := make([]SDisk, 0)
|
||||
for i := range disks {
|
||||
if utils.IsInStringArray(disks[i].UDiskID, diskIds) {
|
||||
filtedDisks = append(filtedDisks, disks[i])
|
||||
}
|
||||
}
|
||||
|
||||
return filtedDisks, nil
|
||||
}
|
||||
|
||||
return disks, nil
|
||||
}
|
||||
|
||||
|
||||
+11
-11
@@ -15,12 +15,12 @@
|
||||
package ucloud
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
billing_api "yunion.io/x/cloudmux/pkg/apis/billing"
|
||||
api "yunion.io/x/cloudmux/pkg/apis/compute"
|
||||
@@ -99,7 +99,7 @@ func (self *SEip) GetGlobalId() string {
|
||||
func (self *SEip) GetStatus() string {
|
||||
switch self.Status {
|
||||
case "used":
|
||||
return api.EIP_STATUS_ASSOCIATE // ?
|
||||
return api.EIP_STATUS_READY
|
||||
case "free":
|
||||
return api.EIP_STATUS_READY
|
||||
case "freeze":
|
||||
@@ -113,9 +113,9 @@ func (self *SEip) Refresh() error {
|
||||
if self.IsEmulated() {
|
||||
return nil
|
||||
}
|
||||
new, err := self.region.GetEipById(self.GetId())
|
||||
new, err := self.region.GetEip(self.GetId())
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.Wrapf(err, "Refresh")
|
||||
}
|
||||
return jsonutils.Update(self, new)
|
||||
}
|
||||
@@ -225,12 +225,15 @@ func (self *SRegion) CreateEIP(eip *cloudprovider.SEip) (cloudprovider.ICloudEIP
|
||||
params.Set("OperatorName", eip.BGPType)
|
||||
params.Set("Bandwidth", eip.BandwidthMbps)
|
||||
params.Set("Name", eip.Name)
|
||||
params.Set("Region", self.GetId())
|
||||
var payMode string
|
||||
switch eip.ChargeType {
|
||||
case api.EIP_CHARGE_TYPE_BY_TRAFFIC:
|
||||
payMode = "Traffic"
|
||||
case api.EIP_CHARGE_TYPE_BY_BANDWIDTH:
|
||||
payMode = "Bandwidth"
|
||||
default:
|
||||
payMode = "Bandwidth"
|
||||
}
|
||||
params.Set("PayMode", payMode)
|
||||
params.Set("ChargeType", "Dynamic") // 按需付费
|
||||
@@ -241,14 +244,11 @@ func (self *SRegion) CreateEIP(eip *cloudprovider.SEip) (cloudprovider.ICloudEIP
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(eips) == 1 {
|
||||
eip := eips[0]
|
||||
eip.region = self
|
||||
eip.Refresh()
|
||||
return &eip, nil
|
||||
} else {
|
||||
return nil, fmt.Errorf("CreateEIP %d eip created", len(eips))
|
||||
for i := range eips {
|
||||
eips[i].region = self
|
||||
return &eips[i], nil
|
||||
}
|
||||
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "CreateEIP %d eip created", len(eips))
|
||||
}
|
||||
|
||||
// https://docs.ucloud.cn/api/unet-api/release_eip
|
||||
|
||||
+59
-63
@@ -17,11 +17,10 @@ package ucloud
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/billing"
|
||||
|
||||
@@ -77,13 +76,13 @@ func (self *SHost) GetIVMs() ([]cloudprovider.ICloudVM, error) {
|
||||
}
|
||||
|
||||
func (self *SHost) GetIVMById(id string) (cloudprovider.ICloudVM, error) {
|
||||
vm, err := self.zone.region.GetInstanceByID(id)
|
||||
vm, err := self.zone.region.GetInstance(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
vm.host = self
|
||||
return &vm, nil
|
||||
return vm, nil
|
||||
}
|
||||
|
||||
func (self *SHost) GetIStorages() ([]cloudprovider.ICloudStorage, error) {
|
||||
@@ -162,19 +161,19 @@ func (self *SHost) GetVersion() string {
|
||||
|
||||
// 不支持user data
|
||||
// 不支持指定keypair
|
||||
func (self *SHost) CreateVM(desc *cloudprovider.SManagedVMCreateConfig) (cloudprovider.ICloudVM, error) {
|
||||
vmId, err := self._createVM(desc.Name, desc.ExternalImageId, desc.SysDisk, desc.Cpu, desc.MemoryMB, desc.InstanceType, desc.ExternalNetworkId, desc.IpAddr, desc.Description, desc.Password, desc.DataDisks, desc.ExternalSecgroupIds, desc.BillingCycle)
|
||||
func (self *SHost) CreateVM(opts *cloudprovider.SManagedVMCreateConfig) (cloudprovider.ICloudVM, error) {
|
||||
vmId, err := self._createVM(opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
vm, err := self.zone.region.GetInstanceByID(vmId)
|
||||
vm, err := self.zone.region.GetInstance(vmId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
vm.host = self
|
||||
return &vm, err
|
||||
return vm, err
|
||||
}
|
||||
|
||||
func (host *SHost) GetIHostNics() ([]cloudprovider.ICloudHostNetInterface, error) {
|
||||
@@ -187,83 +186,77 @@ func (host *SHost) GetIHostNics() ([]cloudprovider.ICloudHostNetInterface, error
|
||||
|
||||
type SInstanceType struct {
|
||||
UHostType string
|
||||
GpuType string
|
||||
CPU int
|
||||
MemoryMB int
|
||||
GPU int
|
||||
}
|
||||
|
||||
// 格式: {机型}.c{cpu}.m{memGB}[.g{gpu}],机型支持 UCloud GpuType 如 T4S、2080Ti-4C、T4/4
|
||||
var instanceTypeRe = regexp.MustCompile(`^([A-Za-z0-9][A-Za-z0-9/_-]*)\.c(\d+)\.m(\d+)(?:\.g(\d+))?$`)
|
||||
|
||||
func ParseInstanceType(instanceType string) (SInstanceType, error) {
|
||||
i := SInstanceType{}
|
||||
segs := strings.Split(instanceType, ".")
|
||||
if len(segs) < 3 {
|
||||
matches := instanceTypeRe.FindStringSubmatch(instanceType)
|
||||
if matches == nil {
|
||||
return i, fmt.Errorf("invalid instance type %s", instanceType)
|
||||
} else if len(segs) >= 4 {
|
||||
gpu, err := strconv.Atoi(strings.TrimLeft(segs[3], "g"))
|
||||
}
|
||||
|
||||
hostType := matches[1]
|
||||
cpu, err := strconv.Atoi(matches[2])
|
||||
if err != nil {
|
||||
return i, err
|
||||
}
|
||||
memGB, err := strconv.Atoi(matches[3])
|
||||
if err != nil {
|
||||
return i, err
|
||||
}
|
||||
|
||||
i.CPU = cpu
|
||||
i.MemoryMB = memGB * 1024
|
||||
if len(matches[4]) > 0 {
|
||||
gpu, err := strconv.Atoi(matches[4])
|
||||
if err != nil {
|
||||
return i, err
|
||||
}
|
||||
|
||||
i.GPU = gpu
|
||||
i.GpuType = hostType
|
||||
i.UHostType = "G"
|
||||
} else {
|
||||
i.UHostType = hostType
|
||||
}
|
||||
|
||||
cpu, err := strconv.Atoi(strings.TrimLeft(segs[1], "c"))
|
||||
if err != nil {
|
||||
return i, err
|
||||
}
|
||||
|
||||
mem, err := strconv.Atoi(strings.TrimLeft(segs[2], "m"))
|
||||
if err != nil {
|
||||
return i, err
|
||||
}
|
||||
|
||||
i.UHostType = segs[0]
|
||||
i.CPU = cpu
|
||||
i.MemoryMB = mem * 1024
|
||||
return i, nil
|
||||
}
|
||||
|
||||
func (self *SHost) _createVM(name, imgId string, sysDisk cloudprovider.SDiskInfo, cpu, memMB int, instanceType string,
|
||||
networkId, ipAddr, desc, passwd string,
|
||||
dataDisks []cloudprovider.SDiskInfo, secgroupIds []string, bc *billing.SBillingCycle) (string, error) {
|
||||
func (self *SHost) _createVM(opts *cloudprovider.SManagedVMCreateConfig) (string, error) {
|
||||
// 网络配置及安全组绑定
|
||||
net, _ := self.zone.region.getNetwork(networkId)
|
||||
if net == nil {
|
||||
return "", fmt.Errorf("invalid network ID %s", networkId)
|
||||
net, err := self.zone.region.getNetwork(opts.ExternalNetworkId)
|
||||
if err != nil {
|
||||
return "", errors.Wrapf(err, "getNetwork %s", opts.ExternalNetworkId)
|
||||
}
|
||||
|
||||
if net.wire == nil {
|
||||
log.Errorf("network's wire is empty")
|
||||
return "", fmt.Errorf("network's wire is empty")
|
||||
}
|
||||
|
||||
if net.wire.vpc == nil {
|
||||
log.Errorf("wire's vpc is empty")
|
||||
return "", fmt.Errorf("wire's vpc is empty")
|
||||
}
|
||||
|
||||
if len(passwd) == 0 {
|
||||
if len(opts.Password) == 0 {
|
||||
return "", fmt.Errorf("CreateVM password should not be emtpty")
|
||||
}
|
||||
|
||||
// 镜像及硬盘配置
|
||||
img, err := self.zone.region.GetImage(imgId)
|
||||
img, err := self.zone.region.GetImage(opts.ExternalImageId)
|
||||
if err != nil {
|
||||
log.Errorf("GetImage %s fail %s", imgId, err)
|
||||
return "", err
|
||||
return "", errors.Wrapf(err, "GetImage %s", opts.ExternalImageId)
|
||||
}
|
||||
|
||||
if img.GetStatus() != api.CACHED_IMAGE_STATUS_ACTIVE {
|
||||
log.Errorf("image %s status %s, expect %s", imgId, img.GetStatus(), api.CACHED_IMAGE_STATUS_ACTIVE)
|
||||
return "", fmt.Errorf("image not ready")
|
||||
return "", errors.Wrapf(cloudprovider.ErrInvalidStatus, "image %s status %s, expect %s", opts.ExternalImageId, img.GetStatus(), api.CACHED_IMAGE_STATUS_ACTIVE)
|
||||
}
|
||||
|
||||
disks := make([]SDisk, len(dataDisks)+1)
|
||||
disks := make([]SDisk, len(opts.DataDisks)+1)
|
||||
disks[0].SizeGB = int(img.ImageSizeGB)
|
||||
if sysDisk.SizeGB > 0 && sysDisk.SizeGB > int(img.ImageSizeGB) {
|
||||
disks[0].SizeGB = sysDisk.SizeGB
|
||||
if opts.SysDisk.SizeGB > 0 && opts.SysDisk.SizeGB > int(img.ImageSizeGB) {
|
||||
disks[0].SizeGB = opts.SysDisk.SizeGB
|
||||
}
|
||||
disks[0].DiskType = sysDisk.StorageType
|
||||
disks[0].DiskType = opts.SysDisk.StorageType
|
||||
|
||||
for i, dataDisk := range dataDisks {
|
||||
for i, dataDisk := range opts.DataDisks {
|
||||
disks[i+1].SizeGB = dataDisk.SizeGB
|
||||
disks[i+1].DiskType = dataDisk.StorageType
|
||||
}
|
||||
@@ -272,18 +265,18 @@ func (self *SHost) _createVM(name, imgId string, sysDisk cloudprovider.SDiskInfo
|
||||
// https://docs.ucloud.cn/api/uhost-api/uhost_type
|
||||
// https://docs.ucloud.cn/compute/uhost/introduction/uhost/type
|
||||
var vmId string
|
||||
i, err := ParseInstanceType(instanceType)
|
||||
i, err := ParseInstanceType(opts.InstanceType)
|
||||
if err != nil {
|
||||
if cpu <= 0 || memMB <= 0 {
|
||||
if opts.Cpu <= 0 || opts.MemoryMB <= 0 {
|
||||
return "", err
|
||||
} else {
|
||||
i.UHostType = "N2"
|
||||
i.CPU = cpu
|
||||
i.MemoryMB = memMB
|
||||
i.UHostType = "O"
|
||||
i.CPU = opts.Cpu
|
||||
i.MemoryMB = opts.MemoryMB
|
||||
}
|
||||
}
|
||||
|
||||
vmId, err = self.zone.region.CreateInstance(name, imgId, i.UHostType, passwd, net.wire.vpc.GetId(), networkId, secgroupIds, self.zone.ZoneId, desc, ipAddr, i.CPU, i.MemoryMB, i.GPU, disks, bc)
|
||||
vmId, err = self.zone.region.CreateInstance(opts.Name, opts.ExternalImageId, i.UHostType, opts.Password, net.wire.vpc.GetId(), opts.ExternalNetworkId, opts.ExternalSecgroupIds, self.zone.ZoneId, opts.Description, opts.IpAddr, i.CPU, i.MemoryMB, i.GPU, i.GpuType, disks, opts.BillingCycle)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Failed to create: %v", err)
|
||||
}
|
||||
@@ -295,14 +288,14 @@ func (self *SHost) _createVM(name, imgId string, sysDisk cloudprovider.SDiskInfo
|
||||
// https://docs.ucloud.cn/api/uhost-api/specification
|
||||
// 支持8-30位字符, 不能包含[A-Z],[a-z],[0-9]和[()`~!@#$%^&*-+=_|{}[]:;'<>,.?/]之外的非法字符
|
||||
func (self *SRegion) CreateInstance(name, imageId, hostType, password, vpcId, SubnetId string, securityGroupId []string,
|
||||
zoneId, desc, ipAddr string, cpu, memMB, gpu int, disks []SDisk, bc *billing.SBillingCycle) (string, error) {
|
||||
zoneId, desc, ipAddr string, cpu, memMB, gpu int, gpuType string, disks []SDisk, bc *billing.SBillingCycle) (string, error) {
|
||||
params := NewUcloudParams()
|
||||
params.Set("Zone", zoneId)
|
||||
params.Set("ImageId", imageId)
|
||||
params.Set("Password", base64.StdEncoding.EncodeToString([]byte(password)))
|
||||
params.Set("LoginMode", "Password")
|
||||
params.Set("Name", name)
|
||||
params.Set("UHostType", hostType)
|
||||
params.Set("MachineType", hostType)
|
||||
params.Set("CPU", cpu)
|
||||
params.Set("Memory", memMB)
|
||||
params.Set("VPCId", vpcId)
|
||||
@@ -312,6 +305,9 @@ func (self *SRegion) CreateInstance(name, imageId, hostType, password, vpcId, Su
|
||||
}
|
||||
if gpu > 0 {
|
||||
params.Set("GPU", gpu)
|
||||
if len(gpuType) > 0 {
|
||||
params.Set("GpuType", gpuType)
|
||||
}
|
||||
}
|
||||
|
||||
if bc != nil && bc.GetMonths() >= 1 && bc.GetMonths() < 10 {
|
||||
@@ -347,7 +343,7 @@ func (self *SRegion) CreateInstance(name, imageId, hostType, password, vpcId, Su
|
||||
ret := Ret{}
|
||||
err := self.DoAction("CreateUHostInstance", params, &ret)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "", errors.Wrapf(err, "CreateUHostInstance")
|
||||
}
|
||||
|
||||
if len(ret.UHostIds) == 1 {
|
||||
|
||||
+34
-54
@@ -55,6 +55,8 @@ type SInstance struct {
|
||||
State string `json:"State"`
|
||||
NetworkState string `json:"NetworkState"`
|
||||
HostType string `json:"HostType"`
|
||||
MachineType string `json:"MachineType"`
|
||||
GpuType string `json:"GpuType"`
|
||||
StorageType string `json:"StorageType"`
|
||||
TotalDiskSpace int `json:"TotalDiskSpace"`
|
||||
DiskSet []DiskSet `json:"DiskSet"`
|
||||
@@ -175,7 +177,7 @@ func (self *SInstance) GetStatus() string {
|
||||
}
|
||||
|
||||
func (self *SInstance) Refresh() error {
|
||||
new, err := self.host.zone.region.GetInstanceByID(self.GetId())
|
||||
new, err := self.host.zone.region.GetInstance(self.GetId())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -235,22 +237,17 @@ func (self *SInstance) GetLocalDisk(diskId, storageType string, sizeGB int, isBo
|
||||
|
||||
func (self *SInstance) GetIDisks() ([]cloudprovider.ICloudDisk, error) {
|
||||
localDisks := make([]SDisk, 0)
|
||||
diskIds := make([]string, 0)
|
||||
for _, disk := range self.DiskSet {
|
||||
if utils.IsInStringArray(disk.DiskType, []string{api.STORAGE_UCLOUD_LOCAL_NORMAL, api.STORAGE_UCLOUD_LOCAL_SSD}) {
|
||||
localDisks = append(localDisks, self.GetLocalDisk(disk.DiskID, disk.DiskType, disk.Size, disk.IsBoot))
|
||||
} else {
|
||||
diskIds = append(diskIds, disk.DiskID)
|
||||
}
|
||||
}
|
||||
|
||||
disks := []SDisk{}
|
||||
var err error
|
||||
if len(diskIds) > 0 {
|
||||
disks, err = self.host.zone.region.GetDisks("", "", diskIds)
|
||||
for _, disk := range self.DiskSet {
|
||||
if utils.IsInStringArray(disk.DiskType, api.UCLOUD_LOCAL_STORAGES) {
|
||||
localDisks = append(localDisks, self.GetLocalDisk(disk.DiskID, disk.DiskType, disk.Size, disk.IsBoot))
|
||||
continue
|
||||
}
|
||||
disk, err := self.host.zone.region.GetDisk(disk.DiskID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
disks = append(disks, *disk)
|
||||
}
|
||||
|
||||
disks = append(disks, localDisks...)
|
||||
@@ -302,12 +299,12 @@ func (self *SInstance) GetINics() ([]cloudprovider.ICloudNic, error) {
|
||||
func (self *SInstance) GetIEIP() (cloudprovider.ICloudEIP, error) {
|
||||
for _, ip := range self.IPSet {
|
||||
if len(ip.IPId) > 0 {
|
||||
eip, err := self.host.zone.region.GetEipById(ip.IPId)
|
||||
eip, err := self.host.zone.region.GetEip(ip.IPId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.Wrapf(err, "GetEip %s", ip.IPId)
|
||||
}
|
||||
|
||||
return &eip, nil
|
||||
return eip, nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -374,13 +371,22 @@ func (self *SInstance) GetMachine() string {
|
||||
return "pc"
|
||||
}
|
||||
|
||||
func (self *SInstance) GetInstanceType() string {
|
||||
// C1.c8.m24
|
||||
if strings.HasPrefix(self.HostType, "G") {
|
||||
return fmt.Sprintf("%s.c%d.m%d.g%d", self.HostType, self.CPU, self.MemoryMB/1014, self.GPU)
|
||||
} else {
|
||||
return fmt.Sprintf("%s.c%d.m%d", self.HostType, self.CPU, self.MemoryMB/1014)
|
||||
func (self *SInstance) instanceTypeHostPrefix() string {
|
||||
if self.GPU > 0 && len(self.GpuType) > 0 {
|
||||
return self.GpuType
|
||||
}
|
||||
if len(self.UHostType) > 0 {
|
||||
return self.UHostType
|
||||
}
|
||||
if len(self.MachineType) > 0 {
|
||||
return self.MachineType
|
||||
}
|
||||
return self.HostType
|
||||
}
|
||||
|
||||
func (self *SInstance) GetInstanceType() string {
|
||||
memGB := self.MemoryMB / 1024
|
||||
return formatInstanceSpec(self.instanceTypeHostPrefix(), self.CPU, memGB, self.GPU)
|
||||
}
|
||||
|
||||
// https://docs.ucloud.cn/api/unet-api/grant_firewall
|
||||
@@ -437,34 +443,7 @@ func (self *SInstance) UpdateUserData(userData string) error {
|
||||
}
|
||||
|
||||
// https://docs.ucloud.cn/api/uhost-api/reinstall_uhost_instance
|
||||
// 1.请确认在重新安装之前,该实例已被关闭;
|
||||
// 2.请确认该实例未挂载UDisk;
|
||||
// todo:// 3.将原系统重装为不同类型的系统时(Linux->Windows),不可选择保留数据盘;
|
||||
// 4.重装不同版本的系统时(CentOS6->CentOS7),若选择保留数据盘,请注意数据盘的文件系统格式;
|
||||
// 5.若主机CPU低于2核,不可重装为Windows系统。
|
||||
func (self *SInstance) RebuildRoot(ctx context.Context, desc *cloudprovider.SManagedVMRebuildRootConfig) (string, error) {
|
||||
if len(desc.PublicKey) > 0 {
|
||||
return "", fmt.Errorf("DeployVM not support assign ssh keypair")
|
||||
}
|
||||
|
||||
if self.GetStatus() != api.VM_READY {
|
||||
return "", fmt.Errorf("DeployVM instance status %s , expected %s.", self.GetStatus(), api.VM_READY)
|
||||
}
|
||||
|
||||
if len(self.DiskSet) > 1 {
|
||||
for _, disk := range self.DiskSet {
|
||||
if disk.Type == "Data" {
|
||||
err := self.host.zone.region.DetachDisk(self.host.zone.GetId(), self.GetId(), disk.DiskID)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("RebuildRoot detach disk %s", err)
|
||||
}
|
||||
|
||||
defer self.host.zone.region.AttachDisk(self.host.zone.GetId(), self.GetId(), disk.DiskID)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
err := self.host.zone.region.RebuildRoot(self.GetId(), desc.ImageId, desc.Password)
|
||||
if err != nil {
|
||||
return "", err
|
||||
@@ -475,12 +454,12 @@ func (self *SInstance) RebuildRoot(ctx context.Context, desc *cloudprovider.SMan
|
||||
return "", errors.Wrap(err, "RebuildRoot")
|
||||
}
|
||||
|
||||
disks, err := self.GetIDisks()
|
||||
if len(disks) > 0 {
|
||||
return disks[0].GetId(), nil
|
||||
} else {
|
||||
return "", fmt.Errorf("RebuildRoot %s", err)
|
||||
for _, disk := range self.DiskSet {
|
||||
if disk.Type == "SystemDisk" {
|
||||
return disk.DiskID, nil
|
||||
}
|
||||
}
|
||||
return "", errors.Wrapf(cloudprovider.ErrNotFound, "SystemDisk not found")
|
||||
}
|
||||
|
||||
func (self *SInstance) DeployVM(ctx context.Context, opts *cloudprovider.SInstanceDeployOptions) error {
|
||||
@@ -614,6 +593,7 @@ func (self *SRegion) DeleteVM(instanceId string) error {
|
||||
params := NewUcloudParams()
|
||||
params.Set("UHostId", instanceId)
|
||||
params.Set("Destroy", 1) // 跳过回收站,直接删除
|
||||
params.Set("ReleaseUDisk", true)
|
||||
|
||||
return self.DoAction("TerminateUHostInstance", params, nil)
|
||||
}
|
||||
|
||||
+1
-5
@@ -326,11 +326,7 @@ func (self *SRegion) GetZoneStorageTypes(zoneId string) ([]string, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
storageTypes := collectStorageTypesFromInstanceTypes(types, zoneId)
|
||||
if len(storageTypes) == 0 {
|
||||
return nil, fmt.Errorf("no storage types found for zone %s", zoneId)
|
||||
}
|
||||
return storageTypes, nil
|
||||
return collectStorageTypesFromInstanceTypes(types, zoneId), nil
|
||||
}
|
||||
|
||||
// GetAvailableInstanceTypes 获取地域/可用区下可售机型信息。
|
||||
|
||||
+10
-14
@@ -19,6 +19,7 @@ import (
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/netutils"
|
||||
"yunion.io/x/pkg/util/rbacscope"
|
||||
|
||||
@@ -142,9 +143,6 @@ func (self *SRegion) GetNetwork(networkId string) (*SNetwork, error) {
|
||||
}
|
||||
|
||||
func (self *SRegion) getNetwork(networkId string) (*SNetwork, error) {
|
||||
if len(networkId) == 0 {
|
||||
return nil, fmt.Errorf("getNetwork network id should not be empty")
|
||||
}
|
||||
networks := make([]SNetwork, 0)
|
||||
|
||||
params := NewUcloudParams()
|
||||
@@ -154,19 +152,17 @@ func (self *SRegion) getNetwork(networkId string) (*SNetwork, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(networks) == 1 {
|
||||
network := networks[0]
|
||||
vpc, err := self.GetVpc(network.VpcId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
for i := range networks {
|
||||
if networks[i].SubnetID == networkId {
|
||||
vpc, err := self.GetVpc(networks[i].VpcId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
networks[i].wire = &SWire{vpc: vpc}
|
||||
return &networks[i], nil
|
||||
}
|
||||
network.wire = &SWire{vpc: vpc}
|
||||
return &network, nil
|
||||
} else if len(networks) == 0 {
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
} else {
|
||||
return nil, fmt.Errorf("getNetwork %s %d found", networkId, len(networks))
|
||||
}
|
||||
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "getNetwork %s", networkId)
|
||||
}
|
||||
|
||||
// https://docs.ucloud.cn/api/vpc2.0-api/delete_subnet
|
||||
|
||||
+22
-22
@@ -71,11 +71,11 @@ func (self *SRegion) GetGeographicInfo() cloudprovider.SGeographicInfo {
|
||||
}
|
||||
|
||||
func (self *SRegion) GetIVMById(id string) (cloudprovider.ICloudVM, error) {
|
||||
instance, err := self.GetInstanceByID(id)
|
||||
instance, err := self.GetInstance(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &instance, nil
|
||||
return instance, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) GetIDiskById(id string) (cloudprovider.ICloudDisk, error) {
|
||||
@@ -144,29 +144,30 @@ func (self *SRegion) GetIZoneById(id string) (cloudprovider.ICloudZone, error) {
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
}
|
||||
|
||||
func (self *SRegion) GetEipById(eipId string) (SEip, error) {
|
||||
func (self *SRegion) GetEip(eipId string) (*SEip, error) {
|
||||
params := NewUcloudParams()
|
||||
params.Set("EIPIds.0", eipId)
|
||||
eips := make([]SEip, 0)
|
||||
err := self.DoListAll("DescribeEIP", params, &eips)
|
||||
if err != nil {
|
||||
return SEip{}, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(eips) == 1 {
|
||||
eip := eips[0]
|
||||
eip.region = self
|
||||
return eip, nil
|
||||
} else if len(eips) == 0 {
|
||||
return SEip{}, cloudprovider.ErrNotFound
|
||||
} else {
|
||||
return SEip{}, fmt.Errorf("GetEipById %d eip found", len(eips))
|
||||
for i := range eips {
|
||||
if eips[i].EIPID == eipId {
|
||||
eips[i].region = self
|
||||
return &eips[i], nil
|
||||
}
|
||||
}
|
||||
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "GetEip %s", eipId)
|
||||
}
|
||||
|
||||
func (self *SRegion) GetIEipById(id string) (cloudprovider.ICloudEIP, error) {
|
||||
eip, err := self.GetEipById(id)
|
||||
return &eip, err
|
||||
eip, err := self.GetEip(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return eip, nil
|
||||
}
|
||||
|
||||
// https://docs.ucloud.cn/api/unet-api/delete_firewall
|
||||
@@ -387,22 +388,21 @@ func (self *SRegion) GetZones() ([]SZone, error) {
|
||||
}
|
||||
|
||||
// https://docs.ucloud.cn/api/uhost-api/describe_uhost_instance
|
||||
func (self *SRegion) GetInstanceByID(instanceId string) (SInstance, error) {
|
||||
func (self *SRegion) GetInstance(instanceId string) (*SInstance, error) {
|
||||
params := NewUcloudParams()
|
||||
params.Set("UHostIds.0", instanceId)
|
||||
instances := make([]SInstance, 0)
|
||||
err := self.DoAction("DescribeUHostInstance", params, &instances)
|
||||
if err != nil {
|
||||
return SInstance{}, err
|
||||
return nil, errors.Wrapf(err, "DescribeUHostInstance")
|
||||
}
|
||||
|
||||
if len(instances) == 1 {
|
||||
return instances[0], nil
|
||||
} else if len(instances) == 0 {
|
||||
return SInstance{}, cloudprovider.ErrNotFound
|
||||
} else {
|
||||
return SInstance{}, fmt.Errorf("GetInstanceByID %s %d found.", instanceId, len(instances))
|
||||
for i := range instances {
|
||||
if instances[i].UHostID == instanceId {
|
||||
return &instances[i], nil
|
||||
}
|
||||
}
|
||||
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "GetInstance %s", instanceId)
|
||||
}
|
||||
|
||||
func (self *SRegion) GetClient() *SUcloudClient {
|
||||
|
||||
+22
-25
@@ -23,6 +23,7 @@ import (
|
||||
api "yunion.io/x/cloudmux/pkg/apis/compute"
|
||||
"yunion.io/x/cloudmux/pkg/cloudprovider"
|
||||
"yunion.io/x/cloudmux/pkg/multicloud"
|
||||
"yunion.io/x/pkg/utils"
|
||||
)
|
||||
|
||||
type SStorage struct {
|
||||
@@ -65,30 +66,18 @@ func (self *SStorage) GetIZone() cloudprovider.ICloudZone {
|
||||
}
|
||||
|
||||
func (self *SStorage) GetIDisks() ([]cloudprovider.ICloudDisk, error) {
|
||||
disks, err := self.zone.region.GetDisks(self.zone.GetId(), "", nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
filtedDisks := make([]SDisk, 0)
|
||||
for _, disk := range disks {
|
||||
// ssd 盘
|
||||
if self.storageType == api.STORAGE_UCLOUD_CLOUD_SSD && strings.Contains(disk.DiskType, "SSD") {
|
||||
filtedDisks = append(filtedDisks, disk)
|
||||
ret := []cloudprovider.ICloudDisk{}
|
||||
for _, isBoot := range []string{"True", "False"} {
|
||||
disks, err := self.zone.region.GetDisks(self.zone.GetId(), self.storageType, isBoot, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 普通盘
|
||||
if self.storageType == api.STORAGE_UCLOUD_CLOUD_NORMAL && !strings.Contains(disk.DiskType, "SSD") {
|
||||
filtedDisks = append(filtedDisks, disk)
|
||||
for _, disk := range disks {
|
||||
disk.storage = self
|
||||
ret = append(ret, &disk)
|
||||
}
|
||||
}
|
||||
|
||||
idisks := make([]cloudprovider.ICloudDisk, len(filtedDisks))
|
||||
for i := 0; i < len(filtedDisks); i += 1 {
|
||||
filtedDisks[i].storage = self
|
||||
idisks[i] = &filtedDisks[i]
|
||||
}
|
||||
return idisks, nil
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SStorage) GetStorageType() string {
|
||||
@@ -124,6 +113,10 @@ func (self *SStorage) CreateIDisk(opts *cloudprovider.DiskCreateConfig) (cloudpr
|
||||
switch self.storageType {
|
||||
case api.STORAGE_UCLOUD_CLOUD_SSD:
|
||||
diskType = "SSDDataDisk"
|
||||
case api.STORAGE_UCLOUD_CLOUD_ESSD:
|
||||
diskType = "ESSDDataDisk"
|
||||
case api.STORAGE_UCLOUD_CLOUD_RSSD:
|
||||
diskType = "RSSDDataDisk"
|
||||
}
|
||||
diskId, err := self.zone.region.CreateDisk(self.zone.GetId(), diskType, opts)
|
||||
if err != nil {
|
||||
@@ -140,12 +133,12 @@ func (self *SStorage) CreateIDisk(opts *cloudprovider.DiskCreateConfig) (cloudpr
|
||||
}
|
||||
|
||||
func (self *SStorage) GetIDiskById(idStr string) (cloudprovider.ICloudDisk, error) {
|
||||
if disk, err := self.zone.region.GetDisk(idStr); err != nil {
|
||||
disk, err := self.zone.region.GetDisk(idStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
disk.storage = self
|
||||
return disk, nil
|
||||
}
|
||||
disk.storage = self
|
||||
return disk, nil
|
||||
}
|
||||
|
||||
func (self *SStorage) GetMountPoint() string {
|
||||
@@ -155,3 +148,7 @@ func (self *SStorage) GetMountPoint() string {
|
||||
func (self *SStorage) IsSysDiskStore() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (self *SStorage) DisableSync() bool {
|
||||
return utils.IsInStringArray(self.storageType, api.UCLOUD_LOCAL_STORAGES)
|
||||
}
|
||||
|
||||
+12
-10
@@ -20,6 +20,7 @@ import (
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
)
|
||||
|
||||
var responseMetaKeys = map[string]bool{
|
||||
@@ -99,24 +100,21 @@ func detectArrayResultKey(resp jsonutils.JSONObject) string {
|
||||
return candidates[0]
|
||||
}
|
||||
|
||||
func unmarshalResult(resp jsonutils.JSONObject, respErr error, result interface{}) error {
|
||||
if respErr != nil {
|
||||
return respErr
|
||||
}
|
||||
|
||||
func unmarshalResult(resp jsonutils.JSONObject, result interface{}) error {
|
||||
if result == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var err error
|
||||
resultKey := detectResultKey(resp, result)
|
||||
if len(resultKey) > 0 {
|
||||
respErr = resp.Unmarshal(result, resultKey)
|
||||
err = resp.Unmarshal(result, resultKey)
|
||||
} else {
|
||||
respErr = resp.Unmarshal(result)
|
||||
err = resp.Unmarshal(result)
|
||||
}
|
||||
|
||||
if respErr != nil {
|
||||
log.Errorf("unmarshal json error %s", respErr)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "unmarshalResult")
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -154,7 +152,11 @@ func doListPart(client *SUcloudClient, action string, params SParams, result int
|
||||
func DoAction(client *SUcloudClient, action string, params SParams, result interface{}) error {
|
||||
params.SetAction(action)
|
||||
resp, err := jsonRequest(client, params)
|
||||
return unmarshalResult(resp, err, result)
|
||||
if err != nil {
|
||||
log.Debugf("DoAction %s %s error %s", action, params.PrettyString(), err)
|
||||
return err
|
||||
}
|
||||
return unmarshalResult(resp, result)
|
||||
}
|
||||
|
||||
// 遍历所有结果
|
||||
|
||||
+6
@@ -18,6 +18,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/utils"
|
||||
|
||||
api "yunion.io/x/cloudmux/pkg/apis/compute"
|
||||
"yunion.io/x/cloudmux/pkg/cloudprovider"
|
||||
@@ -52,6 +53,11 @@ func (self *SZone) fetchStorages() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, storageType := range api.UCLOUD_LOCAL_STORAGES {
|
||||
if !utils.IsInStringArray(storageType, storageTypes) {
|
||||
storageTypes = append(storageTypes, storageType)
|
||||
}
|
||||
}
|
||||
self.storageTypes = storageTypes
|
||||
self.istorages = make([]cloudprovider.ICloudStorage, len(self.storageTypes))
|
||||
for i, sc := range self.storageTypes {
|
||||
|
||||
Reference in New Issue
Block a user