From c03cd96d7870073c5ac6128911673ee31a6659b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B1=88=E8=BD=A9?= Date: Tue, 1 Sep 2026 16:05:51 +0800 Subject: [PATCH] fix(region): support filter cloudprovider by regions (#25461) --- pkg/apis/compute/cloudprovider.go | 2 +- pkg/compute/models/cloudproviders.go | 31 +++++++++++-------- .../options/compute/cloudproviders.go | 2 +- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/pkg/apis/compute/cloudprovider.go b/pkg/apis/compute/cloudprovider.go index 74f9966f5c..7376572cd6 100644 --- a/pkg/apis/compute/cloudprovider.go +++ b/pkg/apis/compute/cloudprovider.go @@ -249,7 +249,7 @@ type CloudproviderListInput struct { UsableResourceListInput - CloudregionResourceInput + CloudregionResourceListInput ZoneResourceInput diff --git a/pkg/compute/models/cloudproviders.go b/pkg/compute/models/cloudproviders.go index 320c6f54fd..ecbe736c41 100644 --- a/pkg/compute/models/cloudproviders.go +++ b/pkg/compute/models/cloudproviders.go @@ -1251,7 +1251,7 @@ func (manager *SCloudproviderManager) ListItemFilter( } var zone *SZone - var region *SCloudregion + regionIds := make([]string, 0) if len(query.ZoneId) > 0 { zoneObj, err := validators.ValidateModel(ctx, userCred, ZoneManager, &query.ZoneId) @@ -1259,10 +1259,11 @@ func (manager *SCloudproviderManager) ListItemFilter( return nil, err } zone = zoneObj.(*SZone) - region, err = zone.GetRegion() + region, err := zone.GetRegion() if err != nil { return nil, err } + regionIds = append(regionIds, region.Id) vpcs := VpcManager.Query("manager_id").Equals("cloudregion_id", region.Id).Distinct() if !utils.IsInStringArray(region.Provider, api.REGIONAL_NETWORK_PROVIDERS) { wires := WireManager.Query().Equals("zone_id", query.ZoneId).SubQuery() @@ -1276,17 +1277,21 @@ func (manager *SCloudproviderManager) ListItemFilter( ), ) } else if len(query.CloudregionId) > 0 { - regionObj, err := CloudregionManager.FetchByIdOrName(ctx, userCred, query.CloudregionId) - if err != nil { - if err == sql.ErrNoRows { - return nil, httperrors.NewResourceNotFoundError2("cloudregion", query.CloudregionId) + for _, regionId := range query.CloudregionId { + if len(regionId) == 0 { + continue } - return nil, httperrors.NewGeneralError(err) + regionObj, err := ValidateCloudregionId(ctx, userCred, regionId) + if err != nil { + return nil, errors.Wrapf(err, "ValidateCloudregionId %s", regionId) + } + regionIds = append(regionIds, regionObj.GetId()) + } + if len(regionIds) > 0 { + pr := CloudproviderRegionManager.Query().SubQuery() + sq := pr.Query(pr.Field("cloudprovider_id")).In("cloudregion_id", regionIds).Distinct() + q = q.In("id", sq) } - region = regionObj.(*SCloudregion) - pr := CloudproviderRegionManager.Query().SubQuery() - sq := pr.Query(pr.Field("cloudprovider_id")).Equals("cloudregion_id", region.Id).Distinct() - q = q.In("id", sq) } if query.Usable != nil && *query.Usable { @@ -1310,8 +1315,8 @@ func (manager *SCloudproviderManager) ListItemFilter( if zone != nil { zoneFilter := sqlchemy.OR(sqlchemy.Equals(wires.Field("zone_id"), zone.GetId()), sqlchemy.IsNullOrEmpty(wires.Field("zone_id"))) sq = sq.Filter(zoneFilter) - } else if region != nil { - sq = sq.Filter(sqlchemy.Equals(vpcs.Field("cloudregion_id"), region.GetId())) + } else if len(regionIds) > 0 { + sq = sq.Filter(sqlchemy.In(vpcs.Field("cloudregion_id"), regionIds)) } q = q.Filter(sqlchemy.In(q.Field("id"), sq.SubQuery())) diff --git a/pkg/mcclient/options/compute/cloudproviders.go b/pkg/mcclient/options/compute/cloudproviders.go index c75f0fc90d..1cb46f48a7 100644 --- a/pkg/mcclient/options/compute/cloudproviders.go +++ b/pkg/mcclient/options/compute/cloudproviders.go @@ -27,7 +27,7 @@ type CloudproviderListOptions struct { HasObjectStorage bool `help:"filter cloudproviders that has object storage" negative:"no-object-storage"` Capability []string `help:"capability filter" choices:"project|compute|network|loadbalancer|objectstore|rds|cache|event"` - Cloudregion string `help:"filter cloudproviders by cloudregion"` + Cloudregion []string `help:"filter cloudproviders by cloudregion id or name" json:"cloudregion_id"` ReadOnly *bool `help:"filter read only account" negative:"no-read-only"`