diff --git a/cmd/climc/shell/compute/storages.go b/cmd/climc/shell/compute/storages.go index c300e74147..37a8889ac3 100644 --- a/cmd/climc/shell/compute/storages.go +++ b/cmd/climc/shell/compute/storages.go @@ -68,6 +68,7 @@ func init() { RbdClientMountTimeout int64 `help:"ceph client_mount_timeout"` RbdKey string `help:"ceph rbd key"` Reserved string `help:"Reserved storage space"` + Capacity int `help:"Capacity for storage"` } R(&StorageUpdateOptions{}, "storage-update", "Update a storage", func(s *mcclient.ClientSession, args *StorageUpdateOptions) error { params, err := options.StructToParams(args) diff --git a/pkg/apis/compute/network_const.go b/pkg/apis/compute/network_const.go index 62c04b9f85..fe74d47a4c 100644 --- a/pkg/apis/compute/network_const.go +++ b/pkg/apis/compute/network_const.go @@ -62,6 +62,7 @@ var ( CLOUD_PROVIDER_CTYUN, CLOUD_PROVIDER_UCLOUD, CLOUD_PROVIDER_GOOGLE, + CLOUD_PROVIDER_OPENSTACK, } ) diff --git a/pkg/compute/models/wires.go b/pkg/compute/models/wires.go index 08679e8f7d..e1afdf72e2 100644 --- a/pkg/compute/models/wires.go +++ b/pkg/compute/models/wires.go @@ -22,6 +22,7 @@ import ( "yunion.io/x/jsonutils" "yunion.io/x/log" "yunion.io/x/pkg/errors" + "yunion.io/x/pkg/gotypes" "yunion.io/x/pkg/tristate" "yunion.io/x/pkg/util/compare" "yunion.io/x/pkg/util/netutils" @@ -361,6 +362,17 @@ func (self *SWire) syncWithCloudWire(ctx context.Context, userCred mcclient.Toke self.IsEmulated = extWire.IsEmulated() + vpc := self.GetVpc() + if vpc != nil { + region, err := vpc.GetRegion() + if err != nil { + return errors.Wrapf(err, "vpc.GetRegion") + } + if utils.IsInStringArray(region.Provider, api.REGIONAL_NETWORK_PROVIDERS) { + self.ZoneId = "" + } + } + if self.IsEmulated { self.DomainId = vpc.DomainId // self.IsPublic = vpc.IsPublic @@ -408,8 +420,15 @@ func (manager *SWireManager) newFromCloudWire(ctx context.Context, userCred mccl wire.ExternalId = extWire.GetGlobalId() wire.Bandwidth = extWire.GetBandwidth() wire.VpcId = vpc.Id - izone := extWire.GetIZone() - if izone != nil { + region, err := vpc.GetRegion() + if err != nil { + return nil, errors.Wrapf(err, "GetRegion for vpc %s(%s)", vpc.Name, vpc.Id) + } + if !utils.IsInStringArray(region.Provider, api.REGIONAL_NETWORK_PROVIDERS) { + izone := extWire.GetIZone() + if gotypes.IsNil(izone) { + return nil, fmt.Errorf("missing zone for wire %s(%s)", wire.Name, wire.ExternalId) + } zone, err := vpc.getZoneByExternalId(izone.GetGlobalId()) if err != nil { return nil, errors.Wrapf(err, "newFromCloudWire.getZoneByExternalId") diff --git a/pkg/multicloud/openstack/hypervisor.go b/pkg/multicloud/openstack/hypervisor.go index e9529a9ba4..b06ddad0f9 100644 --- a/pkg/multicloud/openstack/hypervisor.go +++ b/pkg/multicloud/openstack/hypervisor.go @@ -94,7 +94,19 @@ func (host *SHypervisor) GetGlobalId() string { } func (host *SHypervisor) GetIWires() ([]cloudprovider.ICloudWire, error) { - return host.zone.GetIWires() + vpcs, err := host.zone.region.GetIVpcs() + if err != nil { + return nil, errors.Wrapf(err, "GetIVpc") + } + ret := []cloudprovider.ICloudWire{} + for i := range vpcs { + iwires, err := vpcs[i].GetIWires() + if err != nil { + return nil, errors.Wrapf(err, "GetIWires") + } + ret = append(ret, iwires...) + } + return ret, nil } func (host *SHypervisor) GetIStorages() ([]cloudprovider.ICloudStorage, error) { diff --git a/pkg/multicloud/openstack/network.go b/pkg/multicloud/openstack/network.go index dcbd723e9e..d927da02a0 100644 --- a/pkg/multicloud/openstack/network.go +++ b/pkg/multicloud/openstack/network.go @@ -146,12 +146,12 @@ func (network *SNetwork) GetStatus() string { } func (network *SNetwork) Delete() error { - nw, err := network.wire.zone.region.GetNetwork(network.Id) + nw, err := network.wire.vpc.region.GetNetwork(network.Id) if err != nil { return errors.Wrapf(err, "GetNetwork(%s)", network.Id) } if len(nw.AllocationPools) <= 1 || len(network.AllocationPools) == 0 { - return network.wire.zone.region.DeleteNetwork(network.Id) + return network.wire.vpc.region.DeleteNetwork(network.Id) } pools := []AllocationPool{} for i := range nw.AllocationPools { @@ -167,7 +167,7 @@ func (network *SNetwork) Delete() error { }, } resource := fmt.Sprintf("/v2.0/subnets/%s", network.Id) - _, err = network.wire.zone.region.vpcUpdate(resource, jsonutils.Marshal(params)) + _, err = network.wire.vpc.region.vpcUpdate(resource, jsonutils.Marshal(params)) return err } @@ -309,7 +309,7 @@ func (region *SRegion) GetNetworks(vpcId string) ([]SNetwork, error) { } func (network *SNetwork) Refresh() error { - _network, err := network.wire.zone.region.GetNetwork(network.Id) + _network, err := network.wire.vpc.region.GetNetwork(network.Id) if err != nil { return err } diff --git a/pkg/multicloud/openstack/region.go b/pkg/multicloud/openstack/region.go index cac1692ff4..d28afe212b 100644 --- a/pkg/multicloud/openstack/region.go +++ b/pkg/multicloud/openstack/region.go @@ -36,8 +36,7 @@ type SRegion struct { Name string - zones []SZone - vpcs []SVpc + vpcs []SVpc storageCache *SStoragecache routers []SRouter @@ -239,23 +238,20 @@ func (region *SRegion) GetIZoneById(id string) (cloudprovider.ICloudZone, error) return nil, cloudprovider.ErrNotFound } -func (region *SRegion) fetchZones() error { - if len(region.zones) > 0 { - return nil - } - zones, err := region.GetZones() +func (region *SRegion) GetZones() ([]SZone, error) { + zones, err := region.getZones() if err != nil { - return errors.Wrap(err, "GetZones") + return nil, errors.Wrap(err, "getZones") } - region.zones = []SZone{} + ret := []SZone{} for i := 0; i < len(zones); i++ { if zones[i].ZoneName == "internal" { continue } zones[i].region = region - region.zones = append(region.zones, zones[i]) + ret = append(ret, zones[i]) } - return nil + return ret, nil } func (region *SRegion) fetchVpcs() error { @@ -392,15 +388,15 @@ func (region *SRegion) ProjectId() string { } func (region *SRegion) GetIZones() ([]cloudprovider.ICloudZone, error) { - err := region.fetchZones() + zones, err := region.GetZones() if err != nil { - return nil, err + return nil, errors.Wrapf(err, "GetZones") } - izones := []cloudprovider.ICloudZone{} - for i := range region.zones { - izones = append(izones, ®ion.zones[i]) + ret := []cloudprovider.ICloudZone{} + for i := range zones { + ret = append(ret, &zones[i]) } - return izones, nil + return ret, nil } func (region *SRegion) GetIVpcs() ([]cloudprovider.ICloudVpc, error) { diff --git a/pkg/multicloud/openstack/vpc.go b/pkg/multicloud/openstack/vpc.go index 755ac27fab..23b7e8397c 100644 --- a/pkg/multicloud/openstack/vpc.go +++ b/pkg/multicloud/openstack/vpc.go @@ -21,7 +21,6 @@ import ( "yunion.io/x/jsonutils" "yunion.io/x/pkg/errors" - "yunion.io/x/pkg/utils" api "yunion.io/x/onecloud/pkg/apis/compute" "yunion.io/x/onecloud/pkg/cloudprovider" @@ -186,19 +185,7 @@ func (vpc *SVpc) GetIWireById(wireId string) (cloudprovider.ICloudWire, error) { } func (vpc *SVpc) GetIWires() ([]cloudprovider.ICloudWire, error) { - err := vpc.region.fetchZones() - if err != nil { - return nil, errors.Wrap(err, "fetchZones") - } - iwire := []cloudprovider.ICloudWire{} - for i := range vpc.region.zones { - if !utils.IsInStringArray(vpc.region.zones[i].ZoneName, vpc.AvailabilityZones) { - continue - } - wire := &SWire{vpc: vpc, zone: &vpc.region.zones[i]} - iwire = append(iwire, wire) - } - return iwire, nil + return []cloudprovider.ICloudWire{&SWire{vpc: vpc}}, nil } func (vpc *SVpc) GetRegion() cloudprovider.ICloudRegion { diff --git a/pkg/multicloud/openstack/wire.go b/pkg/multicloud/openstack/wire.go index a3660af402..488ad80a9a 100644 --- a/pkg/multicloud/openstack/wire.go +++ b/pkg/multicloud/openstack/wire.go @@ -15,8 +15,6 @@ package openstack import ( - "fmt" - "yunion.io/x/pkg/errors" "yunion.io/x/onecloud/pkg/cloudprovider" @@ -25,12 +23,12 @@ import ( type SWire struct { multicloud.SResourceBase - zone *SZone - vpc *SVpc + + vpc *SVpc } func (wire *SWire) GetId() string { - return fmt.Sprintf("%s-%s", wire.vpc.GetId(), wire.zone.GetId()) + return wire.vpc.GetId() } func (wire *SWire) GetName() string { @@ -50,7 +48,7 @@ func (wire *SWire) Refresh() error { } func (wire *SWire) GetGlobalId() string { - return fmt.Sprintf("%s-%s", wire.vpc.GetGlobalId(), wire.zone.GetGlobalId()) + return wire.vpc.GetGlobalId() } func (wire *SWire) GetIVpc() cloudprovider.ICloudVpc { @@ -58,7 +56,7 @@ func (wire *SWire) GetIVpc() cloudprovider.ICloudVpc { } func (wire *SWire) GetIZone() cloudprovider.ICloudZone { - return wire.zone + return nil } func (wire *SWire) GetBandwidth() int { @@ -66,7 +64,7 @@ func (wire *SWire) GetBandwidth() int { } func (wire *SWire) CreateINetwork(opts *cloudprovider.SNetworkCreateOptions) (cloudprovider.ICloudNetwork, error) { - network, err := wire.zone.region.CreateNetwork(wire.vpc.Id, opts.ProjectId, opts.Name, opts.Cidr, opts.Desc) + network, err := wire.vpc.region.CreateNetwork(wire.vpc.Id, opts.ProjectId, opts.Name, opts.Cidr, opts.Desc) if err != nil { return nil, errors.Wrap(err, "CreateNetwork") } diff --git a/pkg/multicloud/openstack/zone.go b/pkg/multicloud/openstack/zone.go index 2a4a297310..4b804a3c1f 100644 --- a/pkg/multicloud/openstack/zone.go +++ b/pkg/multicloud/openstack/zone.go @@ -87,19 +87,6 @@ func (zone *SZone) GetIRegion() cloudprovider.ICloudRegion { return zone.region } -func (zone *SZone) GetIWires() ([]cloudprovider.ICloudWire, error) { - err := zone.region.fetchVpcs() - if err != nil { - return nil, errors.Wrap(err, "fetchVpcs") - } - iwires := []cloudprovider.ICloudWire{} - for i := range zone.region.vpcs { - wire := &SWire{zone: zone, vpc: &zone.region.vpcs[i]} - iwires = append(iwires, wire) - } - return iwires, nil -} - func (zone *SZone) getStorageByCategory(category, host string) (*SStorage, error) { storages, err := zone.region.GetStorageTypes() if err != nil { @@ -208,7 +195,7 @@ func (zone *SZone) GetIHostById(id string) (cloudprovider.ICloudHost, error) { return nil, cloudprovider.ErrNotFound } -func (region *SRegion) GetZones() ([]SZone, error) { +func (region *SRegion) getZones() ([]SZone, error) { zones := []SZone{} resp, err := region.ecsList("os-availability-zone/detail", nil) if err != nil {