mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-07-01 01:36:11 +08:00
ctyun bugfix
This commit is contained in:
@@ -49,7 +49,7 @@ func init() {
|
||||
type CloudregionCityListOptions struct {
|
||||
Manager string `help:"List objects belonging to the cloud provider"`
|
||||
Account string `help:"List objects belonging to the cloud account"`
|
||||
Provider string `help:"List objects from the provider" choices:"VMware|Aliyun|Qcloud|Azure|Aws|Huawei|Openstack|Ucloud|ZStack"`
|
||||
Provider string `help:"List objects from the provider" choices:"VMware|Aliyun|Qcloud|Azure|Aws|Huawei|Openstack|Ucloud|ZStack|Ctyun"`
|
||||
City string `help:"List regions in the specified city"`
|
||||
|
||||
PublicCloud *bool `help:"List objects belonging to public cloud" json:"public_cloud"`
|
||||
|
||||
@@ -38,7 +38,7 @@ func init() {
|
||||
Occupied bool `help:"show occupid host" json:"-"`
|
||||
Enabled bool `help:"Show enabled host only" json:"-"`
|
||||
Disabled bool `help:"Show disabled host only" json:"-"`
|
||||
HostType string `help:"Host type filter" choices:"baremetal|hypervisor|esxi|kubelet|hyperv|aliyun|azure|qcloud|aws|huawei|ucloud|google"`
|
||||
HostType string `help:"Host type filter" choices:"baremetal|hypervisor|esxi|kubelet|hyperv|aliyun|azure|qcloud|aws|huawei|ucloud|google|ctyun"`
|
||||
AnyMac string `help:"Mac matches one of the host's interface"`
|
||||
|
||||
IsBaremetal *bool `help:"filter host list by is_baremetal=true|false"`
|
||||
|
||||
@@ -22,9 +22,9 @@ import (
|
||||
)
|
||||
|
||||
type GeneralUsageOptions struct {
|
||||
HostType []string `help:"Host types" choices:"hypervisor|baremetal|esxi|xen|kubelet|hyperv|aliyun|azure|aws|huawei|qcloud|openstack|ucloud|zstack|google"`
|
||||
Provider []string `help:"Provider" choices:"OneCloud|VMware|Aliyun|Azure|Aws|Qcloud|Huawei|OpenStack|Ucloud|ZStack|Google"`
|
||||
Brand []string `help:"Brands" choices:"OneCloud|VMware|Aliyun|Azure|Aws|Qcloud|Huawei|OpenStack|Ucloud|ZStack|DStack|Google"`
|
||||
HostType []string `help:"Host types" choices:"hypervisor|baremetal|esxi|xen|kubelet|hyperv|aliyun|azure|aws|huawei|qcloud|openstack|ucloud|zstack|google|ctyun"`
|
||||
Provider []string `help:"Provider" choices:"OneCloud|VMware|Aliyun|Azure|Aws|Qcloud|Huawei|OpenStack|Ucloud|ZStack|Google|Ctyun"`
|
||||
Brand []string `help:"Brands" choices:"OneCloud|VMware|Aliyun|Azure|Aws|Qcloud|Huawei|OpenStack|Ucloud|ZStack|DStack|Google|Ctyun"`
|
||||
Project string `help:"show usage of specified project"`
|
||||
|
||||
ProjectDomain string `help:"show usage of specified domain"`
|
||||
|
||||
@@ -59,6 +59,7 @@ var (
|
||||
|
||||
REGIONAL_NETWORK_PROVIDERS = []string{
|
||||
CLOUD_PROVIDER_HUAWEI,
|
||||
CLOUD_PROVIDER_CTYUN,
|
||||
CLOUD_PROVIDER_UCLOUD,
|
||||
CLOUD_PROVIDER_GOOGLE,
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
"time"
|
||||
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
)
|
||||
|
||||
func WaitStatus(res ICloudResource, expect string, interval time.Duration, timeout time.Duration) error {
|
||||
@@ -66,7 +67,7 @@ func WaitDeleted(res ICloudResource, interval time.Duration, timeout time.Durati
|
||||
for time.Now().Sub(startTime) < timeout {
|
||||
err := res.Refresh()
|
||||
if err != nil {
|
||||
if err == ErrNotFound {
|
||||
if errors.Cause(err) == ErrNotFound {
|
||||
return nil
|
||||
} else {
|
||||
return err
|
||||
|
||||
@@ -165,7 +165,7 @@ func (self *SManagedVirtualizedGuestDriver) RequestDetachDisk(ctx context.Contex
|
||||
}
|
||||
|
||||
_, err = disk.GetIDisk()
|
||||
if err == cloudprovider.ErrNotFound {
|
||||
if errors.Cause(err) == cloudprovider.ErrNotFound {
|
||||
//忽略云上磁盘已经被删除错误
|
||||
return nil, nil
|
||||
}
|
||||
@@ -617,7 +617,7 @@ func (self *SManagedVirtualizedGuestDriver) RequestUndeployGuestOnHost(ctx conte
|
||||
ihost, err := host.GetIHost()
|
||||
if err != nil {
|
||||
//私有云宿主机有可能下线,会导致虚拟机无限删除失败
|
||||
if err == cloudprovider.ErrNotFound {
|
||||
if errors.Cause(err) == cloudprovider.ErrNotFound {
|
||||
return nil, nil
|
||||
}
|
||||
log.Errorf("host.GetIHost fail %s", err)
|
||||
|
||||
@@ -49,3 +49,7 @@ func (self *SCtyunRegionDriver) ValidateCreateLoadbalancerAclData(ctx context.Co
|
||||
func (self *SCtyunRegionDriver) ValidateCreateLoadbalancerCertificateData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
|
||||
return nil, httperrors.NewNotImplementedError("%s does not currently support creating loadbalancer certificate", self.GetProvider())
|
||||
}
|
||||
|
||||
func (self *SCtyunRegionDriver) IsSecurityGroupBelongVpc() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
@@ -50,7 +51,7 @@ func (self *EipDeallocateTask) OnInit(ctx context.Context, obj db.IStandaloneMod
|
||||
if len(eip.ExternalId) > 0 {
|
||||
expEip, err := eip.GetIEip()
|
||||
if err != nil {
|
||||
if err != cloudprovider.ErrNotFound && err != cloudprovider.ErrInvalidProvider {
|
||||
if errors.Cause(err) != cloudprovider.ErrNotFound && err != cloudprovider.ErrInvalidProvider {
|
||||
msg := fmt.Sprintf("fail to find iEIP for eip %s", err)
|
||||
self.taskFail(ctx, eip, msg)
|
||||
return
|
||||
|
||||
@@ -213,7 +213,7 @@ type BaseListOptions struct {
|
||||
|
||||
Manager string `help:"List objects belonging to the cloud provider" json:"manager,omitempty"`
|
||||
Account string `help:"List objects belonging to the cloud account" json:"account,omitempty"`
|
||||
Provider []string `help:"List objects from the provider" choices:"OneCloud|VMware|Aliyun|Qcloud|Azure|Aws|Huawei|OpenStack|Ucloud|ZStack" json:"provider,omitempty"`
|
||||
Provider []string `help:"List objects from the provider" choices:"OneCloud|VMware|Aliyun|Qcloud|Azure|Aws|Huawei|OpenStack|Ucloud|ZStack|Ctyun" json:"provider,omitempty"`
|
||||
Brand []string `help:"List objects belonging to a special brand"`
|
||||
CloudEnv string `help:"Cloud environment" choices:"public|private|onpremise|private_or_onpremise" json:"cloud_env,omitempty"`
|
||||
PublicCloud *bool `help:"List objects belonging to public cloud" json:"public_cloud"`
|
||||
|
||||
@@ -39,7 +39,7 @@ type ServerListOptions struct {
|
||||
Gpu *bool `help:"Show gpu servers"`
|
||||
Secgroup string `help:"Secgroup ID or Name"`
|
||||
AdminSecgroup string `help:"AdminSecgroup ID or Name"`
|
||||
Hypervisor string `help:"Show server of hypervisor" choices:"kvm|esxi|container|baremetal|aliyun|azure|aws|huawei|ucloud|zstack|openstack"`
|
||||
Hypervisor string `help:"Show server of hypervisor" choices:"kvm|esxi|container|baremetal|aliyun|azure|aws|huawei|ucloud|zstack|openstack|ctyun"`
|
||||
Region string `help:"Show servers in cloudregion"`
|
||||
WithEip *bool `help:"Show Servers with EIP"`
|
||||
WithoutEip *bool `help:"Show Servers without EIP"`
|
||||
@@ -129,7 +129,7 @@ type ServerConfigs struct {
|
||||
Host string `help:"Preferred host where virtual server should be created" json:"prefer_host"`
|
||||
BackupHost string `help:"Perfered host where virtual backup server should be created"`
|
||||
|
||||
Hypervisor string `help:"Hypervisor type" choices:"kvm|esxi|baremetal|container|aliyun|azure|qcloud|aws|huawei|openstack|ucloud|zstack|google"`
|
||||
Hypervisor string `help:"Hypervisor type" choices:"kvm|esxi|baremetal|container|aliyun|azure|qcloud|aws|huawei|openstack|ucloud|zstack|google|ctyun"`
|
||||
ResourceType string `help:"Resource type" choices:"shared|prepaid|dedicated"`
|
||||
Backup bool `help:"Create server with backup server"`
|
||||
|
||||
|
||||
@@ -204,7 +204,7 @@ func formRequest(client *SCtyunClient, method httputils.THttpMethod, apiName str
|
||||
_, jsonResp, err := httputils.ParseJSONResponse(resp, err, client.debug)
|
||||
if err == nil {
|
||||
if code, _ := jsonResp.Int("statusCode"); code != 800 {
|
||||
if strings.Contains(jsonResp.String(), "itemNotFound") {
|
||||
if strings.Contains(jsonResp.String(), "NotFound") {
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
}
|
||||
|
||||
|
||||
@@ -331,7 +331,7 @@ func (self *SRegion) GetDisks() ([]SDisk, error) {
|
||||
}
|
||||
|
||||
for i := range disks {
|
||||
izone, err := self.GetIZoneById(disks[i].AvailabilityZone)
|
||||
izone, err := self.GetIZoneById(getZoneGlobalId(self, disks[i].AvailabilityZone))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetDisk.GetIZoneById")
|
||||
}
|
||||
@@ -353,7 +353,7 @@ func (self *SRegion) GetDisk(diskId string) (*SDisk, error) {
|
||||
|
||||
resp, err := self.client.DoGet("/apiproxy/v3/ondemand/queryVolumes", params)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Region.GetDisks.DoGet")
|
||||
return nil, errors.Wrap(err, "Region.GetDisk.DoGet")
|
||||
}
|
||||
|
||||
disks := make([]SDisk, 0)
|
||||
@@ -365,7 +365,7 @@ func (self *SRegion) GetDisk(diskId string) (*SDisk, error) {
|
||||
if len(disks) == 0 {
|
||||
return nil, errors.Wrap(cloudprovider.ErrNotFound, "SRegion.GetDisk")
|
||||
} else if len(disks) == 1 {
|
||||
izone, err := self.GetIZoneById(disks[0].AvailabilityZone)
|
||||
izone, err := self.GetIZoneById(getZoneGlobalId(self, disks[0].AvailabilityZone))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetDisk.GetIZoneById")
|
||||
}
|
||||
|
||||
@@ -148,8 +148,30 @@ func (self *SEip) GetAssociationType() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// eip查询接口未返回 绑定的实例ID/网卡port id。导致不能正常找出关联的主机
|
||||
func (self *SEip) GetAssociationExternalId() string {
|
||||
return self.WorkOrderResourceID
|
||||
vms, err := self.region.GetVMs()
|
||||
if err != nil {
|
||||
log.Errorf("SEip.GetAssociationExternalId.GetVMs %s", err)
|
||||
return ""
|
||||
}
|
||||
|
||||
for i := range vms {
|
||||
vm := vms[i]
|
||||
nics, err := self.region.GetNics(vm.GetId())
|
||||
if err != nil {
|
||||
log.Errorf("SEip.GetAssociationExternalId.GetNics %s", err)
|
||||
return ""
|
||||
}
|
||||
|
||||
for _, nic := range nics {
|
||||
if nic.PortID == self.PortID {
|
||||
return vm.GetGlobalId()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
// http://ctyun-api-url/apiproxy/v3/queryNetworkDetail
|
||||
|
||||
@@ -188,7 +188,7 @@ func (self *SRegion) getVMs(vmId string) ([]SInstance, error) {
|
||||
}
|
||||
|
||||
for i := range ret {
|
||||
izone, err := self.GetIZoneById(ret[i].OSEXTAZAvailabilityZone)
|
||||
izone, err := self.GetIZoneById(getZoneGlobalId(self, ret[i].OSEXTAZAvailabilityZone))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.getVMs.GetIZoneById")
|
||||
}
|
||||
@@ -214,7 +214,7 @@ func (self *SRegion) GetVMById(vmId string) (*SInstance, error) {
|
||||
if len(vms) == 0 {
|
||||
return nil, errors.Wrap(cloudprovider.ErrNotFound, "SRegion.GetVMById")
|
||||
} else if len(vms) == 1 {
|
||||
izone, err := self.GetIZoneById(vms[0].OSEXTAZAvailabilityZone)
|
||||
izone, err := self.GetIZoneById(getZoneGlobalId(self, vms[0].OSEXTAZAvailabilityZone))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetVMById.GetIZoneById")
|
||||
}
|
||||
|
||||
@@ -151,6 +151,10 @@ func (self *SInstance) GetStatus() string {
|
||||
|
||||
func (self *SInstance) Refresh() error {
|
||||
new, err := self.host.zone.region.GetVMById(self.GetId())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
new.host = self.host
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -347,7 +351,7 @@ func (self *SInstance) GetSecurityGroupIds() ([]string, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if len(self.MasterOrderId) == 0 {
|
||||
if len(self.MasterOrderId) > 0 {
|
||||
return self.getSecurityGroupIdsByMasterOrderId(self.MasterOrderId)
|
||||
}
|
||||
|
||||
@@ -365,7 +369,7 @@ func (self *SInstance) GetSecurityGroupIds() ([]string, error) {
|
||||
for i := range secgroups {
|
||||
// todo: bugfix 如果安全组重名比较尴尬
|
||||
if utils.IsInStringArray(secgroups[i].Name, names) {
|
||||
ids = append(ids, secgroups[i].ID)
|
||||
ids = append(ids, secgroups[i].ResSecurityGroupID)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -592,6 +596,7 @@ func (self *SRegion) CreateInstance(zoneId, name, imageId, volumetype, flavorRef
|
||||
return nil
|
||||
}
|
||||
|
||||
// vm & nic job
|
||||
func (self *SRegion) GetJob(jobId string) (jsonutils.JSONObject, error) {
|
||||
params := map[string]string{
|
||||
"regionId": self.GetId(),
|
||||
@@ -604,10 +609,31 @@ func (self *SRegion) GetJob(jobId string) (jsonutils.JSONObject, error) {
|
||||
}
|
||||
|
||||
ret := jsonutils.NewDict()
|
||||
err = resp.Unmarshal(&ret)
|
||||
err = resp.Unmarshal(&ret, "returnObj")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetJob.Unmarshal")
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// 查询云硬盘备份JOB状态信息
|
||||
func (self *SRegion) GetVbsJob(jobId string) (jsonutils.JSONObject, error) {
|
||||
params := map[string]string{
|
||||
"regionId": self.GetId(),
|
||||
"jobId": jobId,
|
||||
}
|
||||
|
||||
resp, err := self.client.DoGet("/apiproxy/v3/ondemand/queryVbsJob", params)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetVbsJob.DoGet")
|
||||
}
|
||||
|
||||
ret := jsonutils.NewDict()
|
||||
err = resp.Unmarshal(&ret, "returnObj")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetVbsJob.Unmarshal")
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
@@ -177,7 +177,7 @@ func (self *SRegion) GetNetwroks(vpcId string) ([]SNetwork, error) {
|
||||
return networks, err
|
||||
}
|
||||
|
||||
func (self *SRegion) GetNetwork(subnetId string) (*SNetwork, error) {
|
||||
func (self *SRegion) getNetwork(subnetId string) (*SNetwork, error) {
|
||||
querys := map[string]string{
|
||||
"subnetId": subnetId,
|
||||
"regionId": self.GetId(),
|
||||
@@ -185,13 +185,22 @@ func (self *SRegion) GetNetwork(subnetId string) (*SNetwork, error) {
|
||||
|
||||
resp, err := self.client.DoGet("/apiproxy/v3/querySubnetDetail", querys)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetNetwork.DoGet")
|
||||
return nil, errors.Wrap(err, "SRegion.getNetwork.DoGet")
|
||||
}
|
||||
|
||||
network := &SNetwork{}
|
||||
err = resp.Unmarshal(network, "returnObj")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetNetwork.Unmarshal")
|
||||
return nil, errors.Wrap(err, "SRegion.getNetwork.Unmarshal")
|
||||
}
|
||||
|
||||
return network, nil
|
||||
}
|
||||
|
||||
func (self *SRegion) GetNetwork(subnetId string) (*SNetwork, error) {
|
||||
network, err := self.getNetwork(subnetId)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetNetwork.getNetwork")
|
||||
}
|
||||
|
||||
vpc, err := self.GetVpc(network.VpcID)
|
||||
|
||||
@@ -73,6 +73,8 @@ func (self *SRegion) fetchInfrastructure() error {
|
||||
zone := self.izones[j].(*SZone)
|
||||
zone.addWire(&wire)
|
||||
}
|
||||
|
||||
vpc.fetchNetworks()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -218,7 +220,16 @@ func (self *SRegion) GetIEips() ([]cloudprovider.ICloudEIP, error) {
|
||||
}
|
||||
|
||||
func (self *SRegion) GetIVpcById(id string) (cloudprovider.ICloudVpc, error) {
|
||||
return self.GetVpc(id)
|
||||
ivpcs, err := self.GetIVpcs()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for i := 0; i < len(ivpcs); i += 1 {
|
||||
if ivpcs[i].GetGlobalId() == id {
|
||||
return ivpcs[i], nil
|
||||
}
|
||||
}
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
}
|
||||
|
||||
func (self *SRegion) GetIZoneById(id string) (cloudprovider.ICloudZone, error) {
|
||||
@@ -417,6 +428,10 @@ func (self *SRegion) GetInstances(instanceId string) ([]SInstance, error) {
|
||||
"regionId": self.GetId(),
|
||||
}
|
||||
|
||||
if len(instanceId) > 0 {
|
||||
params["instanceId"] = instanceId
|
||||
}
|
||||
|
||||
resp, err := self.client.DoGet("/apiproxy/v3/ondemand/queryVMs", params)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SRegion.GetInstances.DoGet")
|
||||
|
||||
@@ -36,7 +36,7 @@ type SStorage struct {
|
||||
}
|
||||
|
||||
func (self *SStorage) GetId() string {
|
||||
return fmt.Sprintf("%s-%s-%s", self.zone.region.client.providerId, self.zone.GetId(), self.storageType)
|
||||
return fmt.Sprintf("%s-%s-%s", self.zone.region.client.providerId, self.zone.GetGlobalId(), self.storageType)
|
||||
}
|
||||
|
||||
func (self *SStorage) GetName() string {
|
||||
@@ -44,7 +44,7 @@ func (self *SStorage) GetName() string {
|
||||
}
|
||||
|
||||
func (self *SStorage) GetGlobalId() string {
|
||||
return fmt.Sprintf("%s-%s-%s", self.zone.region.client.providerId, self.zone.GetGlobalId(), self.storageType)
|
||||
return self.GetId()
|
||||
}
|
||||
|
||||
func (self *SStorage) GetStatus() string {
|
||||
|
||||
@@ -18,6 +18,8 @@ import (
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/netutils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
)
|
||||
@@ -94,6 +96,16 @@ func (self *SWire) GetINetworkById(netid string) (cloudprovider.ICloudNetwork, e
|
||||
return nil, cloudprovider.ErrNotFound
|
||||
}
|
||||
|
||||
func getDefaultGateWay(cidr string) (string, error) {
|
||||
pref, err := netutils.NewIPV4Prefix(cidr)
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "getDefaultGateWay.NewIPV4Prefix")
|
||||
}
|
||||
startIp := pref.Address.NetAddr(pref.MaskLen) // 0
|
||||
startIp = startIp.StepUp() // 1
|
||||
return startIp.String(), nil
|
||||
}
|
||||
|
||||
func (self *SWire) CreateINetwork(name string, cidr string, desc string) (cloudprovider.ICloudNetwork, error) {
|
||||
return nil, cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
package ctyun
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
@@ -35,6 +37,10 @@ type SZone struct {
|
||||
ZoneType string `json:"zoneType"`
|
||||
}
|
||||
|
||||
func getZoneGlobalId(region *SRegion, zoneId string) string {
|
||||
return fmt.Sprintf("%s/%s", region.GetGlobalId(), zoneId)
|
||||
}
|
||||
|
||||
func (self *SZone) addWire(wire *SWire) {
|
||||
if self.iwires == nil {
|
||||
self.iwires = make([]cloudprovider.ICloudWire, 0)
|
||||
@@ -51,7 +57,7 @@ func (self *SZone) GetName() string {
|
||||
}
|
||||
|
||||
func (self *SZone) GetGlobalId() string {
|
||||
return self.GetId()
|
||||
return getZoneGlobalId(self.region, self.GetId())
|
||||
}
|
||||
|
||||
func (self *SZone) GetStatus() string {
|
||||
|
||||
Reference in New Issue
Block a user