mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-24 16:03:43 +08:00
fix: 支持同步经典网络ip地址
This commit is contained in:
@@ -49,6 +49,7 @@ const (
|
||||
// STORAGE_CLOUD_SSD ="cloud_ssd"
|
||||
STORAGE_LOCAL_BASIC = "local_basic"
|
||||
STORAGE_LOCAL_SSD = "local_ssd"
|
||||
STORAGE_LOCAL_PRO = "local_pro"
|
||||
STORAGE_CLOUD_BASIC = "cloud_basic"
|
||||
STORAGE_CLOUD_PREMIUM = "cloud_premium"
|
||||
|
||||
|
||||
@@ -305,6 +305,7 @@ type ICloudVM interface {
|
||||
type ICloudNic interface {
|
||||
GetIP() string
|
||||
GetMAC() string
|
||||
InClassicNetwork() bool
|
||||
GetDriver() string
|
||||
GetINetwork() ICloudNetwork
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ func (self *SQcloudGuestDriver) ValidateResizeDisk(guest *models.SGuest, disk *m
|
||||
if disk.DiskType == api.DISK_TYPE_SYS {
|
||||
return fmt.Errorf("Cannot resize system disk")
|
||||
}
|
||||
if utils.IsInStringArray(storage.StorageType, []string{api.STORAGE_LOCAL_BASIC, api.STORAGE_LOCAL_SSD}) {
|
||||
if utils.IsInStringArray(storage.StorageType, []string{api.STORAGE_LOCAL_BASIC, api.STORAGE_LOCAL_SSD, api.STORAGE_LOCAL_PRO}) {
|
||||
return fmt.Errorf("Cannot resize %s disk", storage.StorageType)
|
||||
}
|
||||
if disk.DiskSize/1024%10 > 0 {
|
||||
@@ -135,6 +135,8 @@ func (self *SQcloudGuestDriver) ValidateCreateData(ctx context.Context, userCred
|
||||
if sysDisk.SizeMb > 1024*1024 {
|
||||
return nil, fmt.Errorf("The %s system disk size must be less than 1024GB", sysDisk.Backend)
|
||||
}
|
||||
case api.STORAGE_LOCAL_PRO:
|
||||
return nil, fmt.Errorf("storage %s can not be system disk", sysDisk.Backend)
|
||||
}
|
||||
|
||||
for i := 1; i < len(input.Disks); i++ {
|
||||
@@ -152,6 +154,8 @@ func (self *SQcloudGuestDriver) ValidateCreateData(ctx context.Context, userCred
|
||||
if disk.SizeMb < 100*1024 || disk.SizeMb > 16000*1024 {
|
||||
return nil, httperrors.NewInputParameterError("The %s disk size must be in the range of 100GB ~ 16000GB", disk.Backend)
|
||||
}
|
||||
case api.STORAGE_LOCAL_PRO:
|
||||
return nil, httperrors.NewInputParameterError("storage %s can not be data disk")
|
||||
}
|
||||
if disk.SizeMb/1024%10 > 0 {
|
||||
return nil, httperrors.NewInputParameterError("Data disk size must be an integer multiple of 10G")
|
||||
@@ -171,7 +175,7 @@ func (self *SQcloudGuestDriver) ValidateChangeConfig(ctx context.Context, userCr
|
||||
return httperrors.NewResourceNotFoundError("failed to found storage for disk %s(%s)", disk.Name, disk.Id)
|
||||
}
|
||||
// 腾讯云系统盘为本地存储,不支持调整配置
|
||||
if utils.IsInStringArray(storage.StorageType, []string{api.STORAGE_LOCAL_BASIC, api.STORAGE_LOCAL_SSD}) {
|
||||
if utils.IsInStringArray(storage.StorageType, []string{api.STORAGE_LOCAL_BASIC, api.STORAGE_LOCAL_SSD, api.STORAGE_LOCAL_PRO}) {
|
||||
return httperrors.NewUnsupportOperationError("The system disk is locally stored and does not support changing configuration")
|
||||
}
|
||||
}
|
||||
@@ -190,7 +194,7 @@ func (self *SQcloudGuestDriver) ValidateChangeConfig(ctx context.Context, userCr
|
||||
if newDisk.SizeMb < 100*1024 || newDisk.SizeMb > 16000*1024 {
|
||||
return httperrors.NewInputParameterError("The %s disk size must be in the range of 100GB ~ 16000GB", newDisk.Backend)
|
||||
}
|
||||
case api.STORAGE_LOCAL_BASIC, api.STORAGE_LOCAL_SSD:
|
||||
case api.STORAGE_LOCAL_BASIC, api.STORAGE_LOCAL_SSD, api.STORAGE_LOCAL_PRO:
|
||||
return httperrors.NewUnsupportOperationError("Not support create local storage disks")
|
||||
case "": //这里Backend为空有可能会导致创建出来还是local storage,依然会出错,需要用户显式指定
|
||||
return httperrors.NewInputParameterError("Please input new disk backend type")
|
||||
|
||||
@@ -2623,6 +2623,18 @@ type sAddGuestnic struct {
|
||||
func getCloudNicNetwork(vnic cloudprovider.ICloudNic, host *SHost, ipList []string, index int) (*SNetwork, error) {
|
||||
vnet := vnic.GetINetwork()
|
||||
if vnet == nil {
|
||||
if vnic.InClassicNetwork() {
|
||||
vpc, err := VpcManager.NewVpcForClassicNetwork(host)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "NewVpcForClassicNetwork")
|
||||
}
|
||||
zone := host.GetZone()
|
||||
wire, err := WireManager.NewWireForClassicNetwork(vpc, zone)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "NewWireForClassicNetwork")
|
||||
}
|
||||
return NetworkManager.NewClassicNetwork(wire)
|
||||
}
|
||||
ip := vnic.GetIP()
|
||||
if len(ip) == 0 {
|
||||
if index < len(ipList) {
|
||||
|
||||
@@ -275,6 +275,39 @@ func (self *SNetwork) GetNetworkInterfacesCount() (int, error) {
|
||||
return NetworkInterfaceManager.Query().In("id", sq).CountWithError()
|
||||
}
|
||||
|
||||
func (manager *SNetworkManager) NewClassicNetwork(wire *SWire) (*SNetwork, error) {
|
||||
_network, err := db.FetchByExternalId(manager, wire.Id)
|
||||
if err == nil {
|
||||
return _network.(*SNetwork), nil
|
||||
}
|
||||
if errors.Cause(err) != sql.ErrNoRows {
|
||||
return nil, errors.Wrap(err, "db.FetchByExternalId")
|
||||
}
|
||||
network := SNetwork{
|
||||
GuestIpStart: "0.0.0.0",
|
||||
GuestIpEnd: "255.255.255.255",
|
||||
GuestIpMask: 0,
|
||||
GuestGateway: "0.0.0.0",
|
||||
WireId: wire.Id,
|
||||
ServerType: api.NETWORK_TYPE_GUEST,
|
||||
}
|
||||
network.SetModelManager(manager, &network)
|
||||
network.Name = fmt.Sprintf("emulate network for classic network with wire %s", wire.Id)
|
||||
network.ExternalId = wire.Id
|
||||
network.IsEmulated = true
|
||||
network.IsPublic = true
|
||||
network.PublicScope = "system"
|
||||
admin := auth.AdminCredential()
|
||||
network.DomainId = admin.GetProjectDomainId()
|
||||
network.ProjectId = admin.GetProjectId()
|
||||
network.Status = api.NETWORK_STATUS_UNAVAILABLE
|
||||
err = manager.TableSpec().Insert(&network)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Insert classic network")
|
||||
}
|
||||
return &network, nil
|
||||
}
|
||||
|
||||
func (self *SNetwork) GetUsedAddresses() map[string]bool {
|
||||
used := make(map[string]bool)
|
||||
|
||||
@@ -588,6 +621,10 @@ func (self *SNetwork) syncRemoveCloudNetwork(ctx context.Context, userCred mccli
|
||||
lockman.LockObject(ctx, self)
|
||||
defer lockman.ReleaseObject(ctx, self)
|
||||
|
||||
if self.ExternalId == self.WireId {
|
||||
return nil
|
||||
}
|
||||
|
||||
err := self.ValidateDeleteCondition(ctx)
|
||||
if err != nil { // cannot delete
|
||||
err = self.SetStatus(userCred, api.NETWORK_STATUS_UNKNOWN, "Sync to remove")
|
||||
|
||||
@@ -176,6 +176,39 @@ func (self *SVpc) GetWires() []SWire {
|
||||
return wires
|
||||
}
|
||||
|
||||
func (manager *SVpcManager) getVpcExternalIdForClassicNetwork(regionId, cloudproviderId string) string {
|
||||
return fmt.Sprintf("%s-%s", regionId, cloudproviderId)
|
||||
}
|
||||
|
||||
func (manager *SVpcManager) NewVpcForClassicNetwork(host *SHost) (*SVpc, error) {
|
||||
region := host.GetRegion()
|
||||
cloudprovider := host.GetCloudprovider()
|
||||
externalId := manager.getVpcExternalIdForClassicNetwork(region.Id, cloudprovider.Id)
|
||||
_vpc, err := db.FetchByExternalId(manager, externalId)
|
||||
if err == nil {
|
||||
return _vpc.(*SVpc), nil
|
||||
}
|
||||
if errors.Cause(err) != sql.ErrNoRows {
|
||||
return nil, errors.Wrap(err, "db.FetchByExternalId")
|
||||
}
|
||||
vpc := &SVpc{
|
||||
IsDefault: false,
|
||||
CloudregionId: region.Id,
|
||||
}
|
||||
vpc.SetModelManager(manager, vpc)
|
||||
vpc.Name = fmt.Sprintf("emulated vpc for %s %s classic network", region.Name, cloudprovider.Name)
|
||||
vpc.IsEmulated = true
|
||||
vpc.Enabled = false
|
||||
vpc.Status = api.VPC_STATUS_UNAVAILABLE
|
||||
vpc.ExternalId = externalId
|
||||
vpc.ManagerId = host.ManagerId
|
||||
err = manager.TableSpec().Insert(vpc)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Insert vpc for classic network")
|
||||
}
|
||||
return vpc, nil
|
||||
}
|
||||
|
||||
func (self *SVpc) getNetworkQuery() *sqlchemy.SQuery {
|
||||
q := NetworkManager.Query()
|
||||
wireQ := self.getWireQuery().SubQuery()
|
||||
@@ -383,6 +416,10 @@ func (self *SVpc) syncRemoveCloudVpc(ctx context.Context, userCred mcclient.Toke
|
||||
lockman.LockObject(ctx, self)
|
||||
defer lockman.ReleaseObject(ctx, self)
|
||||
|
||||
if VpcManager.getVpcExternalIdForClassicNetwork(self.CloudregionId, self.ManagerId) == self.ExternalId { //为经典网络虚拟的vpc
|
||||
return nil
|
||||
}
|
||||
|
||||
err := self.ValidateDeleteCondition(ctx)
|
||||
if err != nil { // cannot delete
|
||||
self.markAllNetworksUnknown(userCred)
|
||||
|
||||
@@ -25,6 +25,7 @@ import (
|
||||
"yunion.io/x/pkg/tristate"
|
||||
"yunion.io/x/pkg/util/compare"
|
||||
"yunion.io/x/pkg/util/netutils"
|
||||
"yunion.io/x/pkg/utils"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
@@ -171,6 +172,48 @@ func (wire *SWire) ValidateDeleteCondition(ctx context.Context) error {
|
||||
return wire.SStandaloneResourceBase.ValidateDeleteCondition(ctx)
|
||||
}
|
||||
|
||||
func (manager *SWireManager) getWireExternalIdForClassicNetwork(provider string, vpcId string, zoneId string) string {
|
||||
if !utils.IsInStringArray(provider, api.REGIONAL_NETWORK_PROVIDERS) {
|
||||
return fmt.Sprintf("%s-%s", vpcId, zoneId)
|
||||
}
|
||||
return vpcId
|
||||
}
|
||||
|
||||
func (manager *SWireManager) NewWireForClassicNetwork(vpc *SVpc, zone *SZone) (*SWire, error) {
|
||||
cloudprovider := vpc.GetCloudprovider()
|
||||
if cloudprovider == nil {
|
||||
return nil, fmt.Errorf("failed to found cloudprovider for vpc %s(%s)", vpc.Id, vpc.Id)
|
||||
}
|
||||
externalId := manager.getWireExternalIdForClassicNetwork(cloudprovider.Provider, vpc.Id, zone.Id)
|
||||
name := fmt.Sprintf("emulate for vpc %s classic network", vpc.Id)
|
||||
zoneId := zone.Id
|
||||
if utils.IsInStringArray(cloudprovider.Provider, api.REGIONAL_NETWORK_PROVIDERS) { //reginal network
|
||||
zoneId = ""
|
||||
} else {
|
||||
name = fmt.Sprintf("emulate for zone %s vpc %s classic network", zone.Name, vpc.Id)
|
||||
}
|
||||
_wire, err := db.FetchByExternalId(manager, externalId)
|
||||
if err == nil {
|
||||
return _wire.(*SWire), nil
|
||||
}
|
||||
if errors.Cause(err) != sql.ErrNoRows {
|
||||
return nil, errors.Wrap(err, "db.FetchByExternalId")
|
||||
}
|
||||
wire := &SWire{
|
||||
VpcId: vpc.Id,
|
||||
ZoneId: zoneId,
|
||||
}
|
||||
wire.SetModelManager(manager, wire)
|
||||
wire.ExternalId = externalId
|
||||
wire.IsEmulated = true
|
||||
wire.Name = name
|
||||
err = manager.TableSpec().Insert(wire)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Insert wire for classic network")
|
||||
}
|
||||
return wire, nil
|
||||
}
|
||||
|
||||
func (wire *SWire) getHostwireQuery() *sqlchemy.SQuery {
|
||||
return HostwireManager.Query().Equals("wire_id", wire.Id)
|
||||
}
|
||||
@@ -289,6 +332,12 @@ func (self *SWire) syncRemoveCloudWire(ctx context.Context, userCred mcclient.To
|
||||
lockman.LockObject(ctx, self)
|
||||
defer lockman.ReleaseObject(ctx, self)
|
||||
|
||||
vpc := self.getVpc()
|
||||
cloudprovider := vpc.GetCloudprovider()
|
||||
if self.ExternalId == WireManager.getWireExternalIdForClassicNetwork(cloudprovider.Provider, self.VpcId, self.ZoneId) {
|
||||
return nil
|
||||
}
|
||||
|
||||
err := self.ValidateDeleteCondition(ctx)
|
||||
if err != nil { // cannot delete
|
||||
err = self.markNetworkUnknown(userCred)
|
||||
|
||||
@@ -34,6 +34,10 @@ func (self *SInstanceNic) GetMAC() string {
|
||||
return ip.ToMac("00:16:")
|
||||
}
|
||||
|
||||
func (self *SInstanceNic) InClassicNetwork() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SInstanceNic) GetDriver() string {
|
||||
return "virtio"
|
||||
}
|
||||
|
||||
@@ -34,6 +34,10 @@ func (self *SInstanceNic) GetMAC() string {
|
||||
return ip.ToMac("00:16:")
|
||||
}
|
||||
|
||||
func (self *SInstanceNic) InClassicNetwork() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SInstanceNic) GetDriver() string {
|
||||
return "virtio"
|
||||
}
|
||||
|
||||
@@ -48,6 +48,10 @@ func (self *SClassicInstanceNic) GetDriver() string {
|
||||
return "virtio"
|
||||
}
|
||||
|
||||
func (self *SClassicInstanceNic) InClassicNetwork() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (self *SClassicInstanceNic) GetINetwork() cloudprovider.ICloudNetwork {
|
||||
wires, err := self.instance.host.GetIWires()
|
||||
if err != nil {
|
||||
|
||||
@@ -54,7 +54,7 @@ func (self *SClassicNetwork) IsEmulated() bool {
|
||||
}
|
||||
|
||||
func (self *SClassicNetwork) GetStatus() string {
|
||||
return "available"
|
||||
return api.NETWORK_STATUS_UNAVAILABLE
|
||||
}
|
||||
|
||||
func (self *SClassicNetwork) Delete() error {
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/multicloud"
|
||||
)
|
||||
@@ -200,10 +201,7 @@ func (self *SClassicVpc) GetRegion() cloudprovider.ICloudRegion {
|
||||
}
|
||||
|
||||
func (self *SClassicVpc) GetStatus() string {
|
||||
if strings.ToLower(self.Properties.Status) == "created" {
|
||||
return "available"
|
||||
}
|
||||
return "disabled"
|
||||
return api.VPC_STATUS_UNAVAILABLE
|
||||
}
|
||||
|
||||
func (self *SClassicVpc) Refresh() error {
|
||||
|
||||
@@ -91,6 +91,10 @@ func (self *SInstanceNic) GetDriver() string {
|
||||
return "virtio"
|
||||
}
|
||||
|
||||
func (self *SInstanceNic) InClassicNetwork() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SInstanceNic) updateSecurityGroup(secgroupId string) error {
|
||||
region := self.instance.host.zone.region
|
||||
self.Properties.NetworkSecurityGroup = nil
|
||||
|
||||
@@ -54,6 +54,10 @@ func (self *SInstanceNic) GetDriver() string {
|
||||
return "virtio"
|
||||
}
|
||||
|
||||
func (self *SInstanceNic) InClassicNetwork() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SInstanceNic) GetINetwork() cloudprovider.ICloudNetwork {
|
||||
network, err := self.instance.host.zone.region.GetNetwork(self.NetID)
|
||||
if err != nil {
|
||||
|
||||
@@ -54,6 +54,10 @@ func (nic *SVirtualNIC) GetMAC() string {
|
||||
return netutils.FormatMacAddr(nic.getVirtualEthernetCard().MacAddress)
|
||||
}
|
||||
|
||||
func (nic *SVirtualNIC) InClassicNetwork() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (nic *SVirtualNIC) GetINetwork() cloudprovider.ICloudNetwork {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -46,6 +46,10 @@ func (nic *SNetworkInterface) GetDriver() string {
|
||||
return "virtio"
|
||||
}
|
||||
|
||||
func (nic *SNetworkInterface) InClassicNetwork() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (nic *SNetworkInterface) GetINetwork() cloudprovider.ICloudNetwork {
|
||||
network, err := nic.instance.host.zone.region.GetNetwork(nic.Subnetwork)
|
||||
if err != nil {
|
||||
|
||||
@@ -74,6 +74,10 @@ func (self *SInstanceNic) GetDriver() string {
|
||||
return "virtio"
|
||||
}
|
||||
|
||||
func (self *SInstanceNic) InClassicNetwork() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SInstanceNic) GetINetwork() cloudprovider.ICloudNetwork {
|
||||
instanceId := self.instance.GetId()
|
||||
subnets, err := self.instance.host.zone.region.getSubnetIdsByInstanceId(instanceId)
|
||||
|
||||
@@ -38,6 +38,10 @@ func (nic *SInstanceNic) GetDriver() string {
|
||||
return "virtio"
|
||||
}
|
||||
|
||||
func (nic *SInstanceNic) InClassicNetwork() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (nic *SInstanceNic) GetINetwork() cloudprovider.ICloudNetwork {
|
||||
ports, err := nic.instance.host.zone.region.GetPorts(nic.MacAddr)
|
||||
if err == nil {
|
||||
|
||||
@@ -216,7 +216,7 @@ func (self *SInstance) getVpc() (*SVpc, error) {
|
||||
func (self *SInstance) GetIDisks() ([]cloudprovider.ICloudDisk, error) {
|
||||
idisks := make([]cloudprovider.ICloudDisk, 0)
|
||||
|
||||
if utils.IsInStringArray(self.SystemDisk.DiskType, []string{"LOCAL_BASIC", "LOCAL_SSD"}) {
|
||||
if utils.IsInStringArray(self.SystemDisk.DiskType, self.host.zone.localstorages) {
|
||||
storage := SLocalStorage{zone: self.host.zone, storageType: self.SystemDisk.DiskType}
|
||||
disk := SLocalDisk{
|
||||
storage: &storage,
|
||||
@@ -229,7 +229,7 @@ func (self *SInstance) GetIDisks() ([]cloudprovider.ICloudDisk, error) {
|
||||
}
|
||||
|
||||
for i := 0; i < len(self.DataDisks); i++ {
|
||||
if utils.IsInStringArray(self.DataDisks[i].DiskType, []string{"LOCAL_BASIC", "LOCAL_SSD"}) {
|
||||
if utils.IsInStringArray(self.DataDisks[i].DiskType, self.host.zone.localstorages) {
|
||||
storage := SLocalStorage{zone: self.host.zone, storageType: self.DataDisks[i].DiskType}
|
||||
disk := SLocalDisk{
|
||||
storage: &storage,
|
||||
@@ -270,12 +270,16 @@ func (self *SInstance) GetIDisks() ([]cloudprovider.ICloudDisk, error) {
|
||||
|
||||
func (self *SInstance) GetINics() ([]cloudprovider.ICloudNic, error) {
|
||||
nics := make([]cloudprovider.ICloudNic, 0)
|
||||
classic := false
|
||||
if len(self.VirtualPrivateCloud.VpcId) == 0 {
|
||||
classic = true
|
||||
}
|
||||
for _, ip := range self.VirtualPrivateCloud.PrivateIpAddresses {
|
||||
nic := SInstanceNic{instance: self, ipAddr: ip}
|
||||
nics = append(nics, &nic)
|
||||
}
|
||||
for _, ip := range self.PrivateIpAddresses {
|
||||
nic := SInstanceNic{instance: self, ipAddr: ip}
|
||||
nic := SInstanceNic{instance: self, ipAddr: ip, classic: classic}
|
||||
nics = append(nics, &nic)
|
||||
}
|
||||
return nics, nil
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
type SInstanceNic struct {
|
||||
instance *SInstance
|
||||
ipAddr string
|
||||
classic bool
|
||||
}
|
||||
|
||||
func (self *SInstanceNic) GetIP() string {
|
||||
@@ -38,6 +39,10 @@ func (self *SInstanceNic) GetDriver() string {
|
||||
return "virtio"
|
||||
}
|
||||
|
||||
func (self *SInstanceNic) InClassicNetwork() bool {
|
||||
return self.classic
|
||||
}
|
||||
|
||||
func (self *SInstanceNic) GetINetwork() cloudprovider.ICloudNetwork {
|
||||
networkId := self.instance.VirtualPrivateCloud.SubnetId
|
||||
wires, err := self.instance.host.GetIWires()
|
||||
|
||||
@@ -14,7 +14,11 @@
|
||||
|
||||
package qcloud
|
||||
|
||||
import "yunion.io/x/log"
|
||||
import (
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/utils"
|
||||
)
|
||||
|
||||
// "time"
|
||||
|
||||
@@ -54,3 +58,73 @@ func (self *SRegion) GetInstanceTypes() ([]SInstanceType, error) {
|
||||
func (self *SInstanceType) memoryMB() int {
|
||||
return int(self.Memory * 1024)
|
||||
}
|
||||
|
||||
type SLocalDiskType struct {
|
||||
Type string
|
||||
PartitionType string
|
||||
MinSize int
|
||||
MaxSize int
|
||||
}
|
||||
|
||||
type SStorageBlockAttr struct {
|
||||
Type string
|
||||
MinSize int
|
||||
MaxSize int
|
||||
}
|
||||
|
||||
type SExternal struct {
|
||||
ReleaseAddress string
|
||||
UnsupportNetworks []string
|
||||
StorageBlockAttr SStorageBlockAttr
|
||||
}
|
||||
|
||||
type SZoneInstanceType struct {
|
||||
Zone string
|
||||
InstanceType string
|
||||
InstanceChargeType string
|
||||
NetworkCard int
|
||||
Externals SExternal
|
||||
Cpu int
|
||||
Memory int
|
||||
InstanceFamily string
|
||||
TypeName string
|
||||
LocalDiskTypeList []SLocalDiskType
|
||||
Status string
|
||||
}
|
||||
|
||||
func (self *SRegion) GetZoneInstanceTypes(zoneId string) ([]SZoneInstanceType, error) {
|
||||
params := map[string]string{}
|
||||
params["Region"] = self.Region
|
||||
params["Filters.0.Name"] = "zone"
|
||||
params["Filters.0.Values.0"] = zoneId
|
||||
body, err := self.cvmRequest("DescribeZoneInstanceConfigInfos", params, true)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "DescribeZoneInstanceConfigInfos")
|
||||
}
|
||||
instanceTypes := []SZoneInstanceType{}
|
||||
err = body.Unmarshal(&instanceTypes, "InstanceTypeQuotaSet")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "body.Unmarshal")
|
||||
}
|
||||
return instanceTypes, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) GetZoneLocalStorages(zoneId string) ([]string, error) {
|
||||
instanceTypes, err := self.GetZoneInstanceTypes(zoneId)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetZoneInstanceTypes")
|
||||
}
|
||||
storages := []string{}
|
||||
for _, instanceType := range instanceTypes {
|
||||
storage := instanceType.Externals.StorageBlockAttr.Type
|
||||
if len(storage) > 0 && !utils.IsInStringArray(storage, storages) {
|
||||
storages = append(storages, storage)
|
||||
}
|
||||
for _, localstorage := range instanceType.LocalDiskTypeList {
|
||||
if len(localstorage.Type) > 0 && !utils.IsInStringArray(localstorage.Type, storages) {
|
||||
storages = append(storages, localstorage.Type)
|
||||
}
|
||||
}
|
||||
}
|
||||
return storages, nil
|
||||
}
|
||||
|
||||
@@ -32,4 +32,18 @@ func init() {
|
||||
printList(zones, len(zones), args.Offset, args.Limit, []string{})
|
||||
return nil
|
||||
})
|
||||
|
||||
type ZoneInstanceTypeListOptions struct {
|
||||
ZONE string
|
||||
}
|
||||
|
||||
shellutils.R(&ZoneInstanceTypeListOptions{}, "zone-instance-type-list", "List zone instance type", func(cli *qcloud.SRegion, args *ZoneInstanceTypeListOptions) error {
|
||||
instanceTypes, err := cli.GetZoneInstanceTypes(args.ZONE)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printList(instanceTypes, 0, 0, 0, []string{})
|
||||
return nil
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
@@ -47,6 +47,8 @@ type SZone struct {
|
||||
|
||||
instanceTypes []string
|
||||
refreshTime time.Time
|
||||
localstorages []string
|
||||
cloudstorages []string
|
||||
|
||||
Zone string
|
||||
ZoneName string
|
||||
@@ -139,22 +141,27 @@ func (self *SZone) fetchStorages() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
storageTypes := []string{}
|
||||
self.cloudstorages = []string{}
|
||||
for _, diskConfig := range diskConfigSet {
|
||||
if !utils.IsInStringArray(strings.ToUpper(diskConfig.DiskType), storageTypes) {
|
||||
storageTypes = append(storageTypes, strings.ToUpper(diskConfig.DiskType))
|
||||
if !utils.IsInStringArray(strings.ToUpper(diskConfig.DiskType), self.cloudstorages) {
|
||||
self.cloudstorages = append(self.cloudstorages, strings.ToUpper(diskConfig.DiskType))
|
||||
storage := SStorage{zone: self, storageType: diskConfig.DiskType, available: diskConfig.Available}
|
||||
self.istorages = append(self.istorages, &storage)
|
||||
}
|
||||
}
|
||||
for _, storageType := range []string{"CLOUD_PREMIUM", "CLOUD_SSD", "CLOUD_BASIC"} {
|
||||
if !utils.IsInStringArray(storageType, storageTypes) {
|
||||
if !utils.IsInStringArray(storageType, self.cloudstorages) {
|
||||
self.cloudstorages = append(self.cloudstorages, storageType)
|
||||
storage := SStorage{zone: self, storageType: storageType, available: false}
|
||||
self.istorages = append(self.istorages, &storage)
|
||||
}
|
||||
}
|
||||
for _, localstorageType := range []string{"LOCAL_BASIC", "LOCAL_SSD"} {
|
||||
storage := SLocalStorage{zone: self, storageType: localstorageType, available: self.region.GetId() == "ap-hongkong"} //仅有香港本地存储可用
|
||||
self.localstorages, err = self.region.GetZoneLocalStorages(self.Zone)
|
||||
if err != nil {
|
||||
log.Errorf("falied to fetch local storage for zone %s", self.Zone)
|
||||
}
|
||||
for _, localstorageType := range self.localstorages {
|
||||
storage := SLocalStorage{zone: self, storageType: localstorageType, available: true}
|
||||
self.istorages = append(self.istorages, &storage)
|
||||
}
|
||||
return nil
|
||||
@@ -168,14 +175,14 @@ func (self *SZone) GetIStorages() ([]cloudprovider.ICloudStorage, error) {
|
||||
}
|
||||
|
||||
func (self *SZone) getLocalStorageByCategory(category string) (*SLocalStorage, error) {
|
||||
if utils.IsInStringArray(strings.ToLower(category), []string{"local_basic", "local_ssd"}) {
|
||||
if utils.IsInStringArray(strings.ToUpper(category), self.localstorages) {
|
||||
return &SLocalStorage{zone: self, storageType: strings.ToUpper(category)}, nil
|
||||
}
|
||||
return nil, fmt.Errorf("No such storage %s", category)
|
||||
}
|
||||
|
||||
func (self *SZone) validateStorageType(category string) error {
|
||||
if utils.IsInStringArray(strings.ToLower(category), []string{"local_basic", "local_ssd", "cloud_basic", "cloud_ssd", "cloud_premium"}) {
|
||||
if utils.IsInStringArray(strings.ToUpper(category), self.localstorages) || utils.IsInStringArray(strings.ToUpper(category), self.cloudstorages) {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("No such storage %s", category)
|
||||
@@ -187,7 +194,7 @@ func (self *SZone) getStorageByCategory(category string) (*SStorage, error) {
|
||||
return nil, err
|
||||
}
|
||||
for i := 0; i < len(storages); i++ {
|
||||
if utils.IsInStringArray(storages[i].GetStorageType(), []string{"local_basic", "local_ssd"}) {
|
||||
if utils.IsInStringArray(storages[i].GetStorageType(), self.localstorages) {
|
||||
continue
|
||||
//return &SStorage{zone: self, storageType: strings.ToUpper(storages[i].GetStorageType())}, nil
|
||||
}
|
||||
|
||||
@@ -38,6 +38,10 @@ func (self *SInstanceNic) GetDriver() string {
|
||||
return "virtio"
|
||||
}
|
||||
|
||||
func (self *SInstanceNic) InClassicNetwork() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SInstanceNic) GetINetwork() cloudprovider.ICloudNetwork {
|
||||
for _, ip := range self.instance.IPSet {
|
||||
if ip.IP == self.ipAddr {
|
||||
|
||||
@@ -49,6 +49,10 @@ func (nic *SInstanceNic) GetDriver() string {
|
||||
return "virtio"
|
||||
}
|
||||
|
||||
func (nic *SInstanceNic) InClassicNetwork() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (nic *SInstanceNic) GetINetwork() cloudprovider.ICloudNetwork {
|
||||
networks, err := nic.instance.host.zone.region.GetNetworks(nic.instance.host.zone.UUID, "", nic.L3NetworkUUID, "")
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user