Merge pull request #747 from tb365/bugfix/tb-sku-provider-filter-fix

sku provider filter by zone
This commit is contained in:
yunion-ci-robot
2019-05-09 17:50:33 +08:00
committed by GitHub
2 changed files with 73 additions and 59 deletions
+30 -19
View File
@@ -481,21 +481,8 @@ func normalizeProvider(provider string) string {
return provider
}
func providerFilter(q *sqlchemy.SQuery, provider string, public_cloud bool) *sqlchemy.SQuery {
// 过滤出公有云provider状态健康的sku
if public_cloud {
providerTable := CloudproviderManager.Query().SubQuery()
providerRegionTable := CloudproviderRegionManager.Query().SubQuery()
subq := providerRegionTable.Query(sqlchemy.DISTINCT("cloudregion_id", providerRegionTable.Field("cloudregion_id")))
subq = subq.Join(providerTable, sqlchemy.Equals(providerRegionTable.Field("cloudprovider_id"), providerTable.Field("id")))
subq = subq.Filter(sqlchemy.IsTrue(providerTable.Field("enabled")))
subq = subq.Filter(sqlchemy.In(providerTable.Field("status"), api.CLOUD_PROVIDER_VALID_STATUS))
subq = subq.Filter(sqlchemy.Equals(providerTable.Field("health_status"), api.CLOUD_PROVIDER_HEALTH_NORMAL))
q = q.Filter(sqlchemy.In(q.Field("cloudregion_id"), subq.SubQuery()))
}
// 过滤出network usable的sku
func networkUsableRegionQueries(f sqlchemy.IQueryField) []sqlchemy.ICondition {
iconditions := make([]sqlchemy.ICondition, 0)
providers := CloudproviderManager.Query().SubQuery()
networks := NetworkManager.Query().SubQuery()
wires := WireManager.Query().SubQuery()
@@ -518,10 +505,34 @@ func providerFilter(q *sqlchemy.SQuery, provider string, public_cloud bool) *sql
sq2 = sq2.Filter(sqlchemy.IsNullOrEmpty(vpcs.Field("manager_id")))
sq2 = sq2.Filter(sqlchemy.Equals(vpcs.Field("status"), api.VPC_STATUS_AVAILABLE))
q = q.Filter(sqlchemy.OR(
sqlchemy.In(q.Field("cloudregion_id"), sq.SubQuery()),
sqlchemy.In(q.Field("cloudregion_id"), sq2.SubQuery()),
))
iconditions = append(iconditions, sqlchemy.In(f, sq.SubQuery()))
iconditions = append(iconditions, sqlchemy.In(f, sq2.SubQuery()))
return iconditions
}
func providerFilter(q *sqlchemy.SQuery, provider string, public_cloud bool) *sqlchemy.SQuery {
// 过滤出公有云provider状态健康的sku
if public_cloud {
providerTable := CloudproviderManager.Query().SubQuery()
providerRegionTable := CloudproviderRegionManager.Query().SubQuery()
subq := providerRegionTable.Query(sqlchemy.DISTINCT("cloudregion_id", providerRegionTable.Field("cloudregion_id")))
subq = subq.Join(providerTable, sqlchemy.Equals(providerRegionTable.Field("cloudprovider_id"), providerTable.Field("id")))
subq = subq.Filter(sqlchemy.IsTrue(providerTable.Field("enabled")))
subq = subq.Filter(sqlchemy.In(providerTable.Field("status"), api.CLOUD_PROVIDER_VALID_STATUS))
subq = subq.Filter(sqlchemy.Equals(providerTable.Field("health_status"), api.CLOUD_PROVIDER_HEALTH_NORMAL))
q = q.Filter(sqlchemy.In(q.Field("cloudregion_id"), subq.SubQuery()))
}
// 过滤出network usable的sku
if public_cloud {
iconditions := NetworkUsableZoneQueries(q.Field("zone_id"), true, true)
q = q.Filter(sqlchemy.OR(iconditions...))
} else {
// 私有云sku 只定义到region层级, zone id 为空.因此只能按region查询
iconditions := networkUsableRegionQueries(q.Field("cloudregion_id"))
q = q.Filter(sqlchemy.OR(iconditions...))
}
if provider == "all" {
// provider 参数为all时。表示查询所有instance type.
+43 -40
View File
@@ -415,7 +415,7 @@ func (manager *SZoneManager) InitializeData() error {
Query 1:
vpc.manager_id is not empty && wire.zone_id is not empty
*/
func (manager *SZoneManager) usableZoneQ1(providers, vpcs, wires, networks *sqlchemy.SSubQuery, usableNet, usableVpc bool) *sqlchemy.SSubQuery {
func usableZoneQ1(providers, vpcs, wires, networks *sqlchemy.SSubQuery, usableNet, usableVpc bool) *sqlchemy.SSubQuery {
// join tables
sq := wires.Query(sqlchemy.DISTINCT("zone_id", wires.Field("zone_id")))
if usableNet {
@@ -443,7 +443,7 @@ func (manager *SZoneManager) usableZoneQ1(providers, vpcs, wires, networks *sqlc
Query 2:
vpc.manager_id is empty && wire.zone_id is not empty
*/
func (manager *SZoneManager) usableZoneQ2(vpcs, wires, networks *sqlchemy.SSubQuery, usableNet, usableVpc bool) *sqlchemy.SSubQuery {
func usableZoneQ2(vpcs, wires, networks *sqlchemy.SSubQuery, usableNet, usableVpc bool) *sqlchemy.SSubQuery {
// join tables
sq := wires.Query(sqlchemy.DISTINCT("zone_id", wires.Field("zone_id")))
if usableNet {
@@ -470,7 +470,7 @@ vpc.manager_id is not empty && wire.zone_id is empty
2019.01.17 目前华为云子网在整个region 可用。wire中zone_id留空。
*/
func (manager *SZoneManager) usableZoneQ3(providers, vpcs, wires, networks, zones *sqlchemy.SSubQuery, usableNet, usableVpc bool) *sqlchemy.SSubQuery {
func usableZoneQ3(providers, vpcs, wires, networks, zones *sqlchemy.SSubQuery, usableNet, usableVpc bool) *sqlchemy.SSubQuery {
// join tables
sq := zones.Query(sqlchemy.DISTINCT("zone_id", zones.Field("id")))
sq = sq.Join(vpcs, sqlchemy.Equals(zones.Field("cloudregion_id"), vpcs.Field("cloudregion_id")))
@@ -501,7 +501,7 @@ vpc.manager_id is empty && wire.zone_id is empty
2019.01.17 目前华为云子网在整个region 可用。wire中zone_id留空。
*/
func (manager *SZoneManager) usableZoneQ4(vpcs, wires, networks, zones *sqlchemy.SSubQuery, usableNet, usableVpc bool) *sqlchemy.SSubQuery {
func usableZoneQ4(vpcs, wires, networks, zones *sqlchemy.SSubQuery, usableNet, usableVpc bool) *sqlchemy.SSubQuery {
// join tables
sq := zones.Query(sqlchemy.DISTINCT("zone_id", zones.Field("id")))
sq = sq.Join(vpcs, sqlchemy.Equals(zones.Field("cloudregion_id"), vpcs.Field("cloudregion_id")))
@@ -523,6 +523,41 @@ func (manager *SZoneManager) usableZoneQ4(vpcs, wires, networks, zones *sqlchemy
return sq.SubQuery()
}
func networkUsableZoneQueries(usableNet, usableVpc bool) []*sqlchemy.SSubQuery {
queries := make([]*sqlchemy.SSubQuery, 4)
queries[0] = usableZoneQ1(CloudproviderManager.Query().SubQuery(),
VpcManager.Query().SubQuery(),
WireManager.Query().SubQuery(),
NetworkManager.Query().SubQuery(),
usableNet, usableVpc)
queries[1] = usableZoneQ2(VpcManager.Query().SubQuery(),
WireManager.Query().SubQuery(),
NetworkManager.Query().SubQuery(),
usableNet, usableVpc)
queries[2] = usableZoneQ3(CloudproviderManager.Query().SubQuery(),
VpcManager.Query().SubQuery(),
WireManager.Query().SubQuery(),
NetworkManager.Query().SubQuery(),
ZoneManager.Query().SubQuery(),
usableNet, usableVpc)
queries[3] = usableZoneQ4(VpcManager.Query().SubQuery(),
WireManager.Query().SubQuery(),
NetworkManager.Query().SubQuery(),
ZoneManager.Query().SubQuery(),
usableNet, usableVpc)
return queries
}
func NetworkUsableZoneQueries(field sqlchemy.IQueryField, usableNet, usableVpc bool) []sqlchemy.ICondition {
queries := networkUsableZoneQueries(usableNet, usableVpc)
iconditions := make([]sqlchemy.ICondition, 0)
for i := range queries {
iconditions = append(iconditions, sqlchemy.In(field, queries[i]))
}
return iconditions
}
func (manager *SZoneManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*sqlchemy.SQuery, error) {
q, err := manager.SStatusStandaloneResourceBaseManager.ListItemFilter(ctx, q, userCred, query)
if err != nil {
@@ -567,42 +602,10 @@ func (manager *SZoneManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQu
if jsonutils.QueryBoolean(query, "usable", false) || jsonutils.QueryBoolean(query, "usable_vpc", false) {
usableNet := jsonutils.QueryBoolean(query, "usable", false)
usableVpc := jsonutils.QueryBoolean(query, "usable_vpc", false)
sq1 := manager.usableZoneQ1(
CloudproviderManager.Query().SubQuery(),
VpcManager.Query().SubQuery(),
WireManager.Query().SubQuery(),
NetworkManager.Query().SubQuery(),
usableNet, usableVpc)
sq2 := manager.usableZoneQ2(
VpcManager.Query().SubQuery(),
WireManager.Query().SubQuery(),
NetworkManager.Query().SubQuery(),
usableNet, usableVpc)
sq3 := manager.usableZoneQ3(
CloudproviderManager.Query().SubQuery(),
VpcManager.Query().SubQuery(),
WireManager.Query().SubQuery(),
NetworkManager.Query().SubQuery(),
ZoneManager.Query().SubQuery(),
usableNet, usableVpc)
sq4 := manager.usableZoneQ4(
VpcManager.Query().SubQuery(),
WireManager.Query().SubQuery(),
NetworkManager.Query().SubQuery(),
ZoneManager.Query().SubQuery(),
usableNet, usableVpc)
q = q.Filter(sqlchemy.OR(
sqlchemy.In(q.Field("id"), sq1),
sqlchemy.In(q.Field("id"), sq2),
sqlchemy.In(q.Field("id"), sq3),
sqlchemy.In(q.Field("id"), sq4),
))
usableVpc := jsonutils.QueryBoolean(query, "usable_vpc",
false)
iconditions := NetworkUsableZoneQueries(q.Field("id"), usableNet, usableVpc)
q = q.Filter(sqlchemy.OR(iconditions...))
q = q.Equals("status", api.ZONE_ENABLE)
}