diff --git a/cmd/climc/shell/hosts.go b/cmd/climc/shell/hosts.go index 5644f29465..54a1133c7e 100644 --- a/cmd/climc/shell/hosts.go +++ b/cmd/climc/shell/hosts.go @@ -26,6 +26,7 @@ func init() { AnyMac string `help:"Mac matches one of the host's interface"` Manager string `help:"Show regions belongs to the cloud provider"` + Usable bool `help:"List all zones that is usable"` options.BaseListOptions } @@ -68,6 +69,10 @@ func init() { params.Add(jsonutils.NewString(args.Manager), "manager") } + if args.Usable { + params.Add(jsonutils.JSONTrue, "usable") + } + if args.Empty { params.Add(jsonutils.JSONTrue, "is_empty") } else if args.Occupied { diff --git a/pkg/compute/models/hosts.go b/pkg/compute/models/hosts.go index 80c153b325..aa767108dd 100644 --- a/pkg/compute/models/hosts.go +++ b/pkg/compute/models/hosts.go @@ -149,7 +149,7 @@ func (manager *SHostManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQu q = q.Equals("access_mac", anyMac) } } - var scopeQuery *sqlchemy.SSubQuery + // var scopeQuery *sqlchemy.SSubQuery schedTagStr := jsonutils.GetAnyString(query, []string{"schedtag", "schedtag_id"}) if len(schedTagStr) > 0 { @@ -158,7 +158,8 @@ func (manager *SHostManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQu return nil, httperrors.NewResourceNotFoundError("Schedtag %s not found", schedTagStr) } hostschedtags := HostschedtagManager.Query().SubQuery() - scopeQuery = hostschedtags.Query(hostschedtags.Field("host_id")).Equals("schedtag_id", schedTag.GetId()).SubQuery() + scopeQuery := hostschedtags.Query(hostschedtags.Field("host_id")).Equals("schedtag_id", schedTag.GetId()).SubQuery() + q = q.In("id", scopeQuery) } wireStr := jsonutils.GetAnyString(query, []string{"wire", "wire_id"}) @@ -168,7 +169,8 @@ func (manager *SHostManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQu return nil, httperrors.NewResourceNotFoundError("Wire %s not found", wireStr) } hostwires := HostwireManager.Query().SubQuery() - scopeQuery = hostwires.Query(hostwires.Field("host_id")).Equals("wire_id", wire.GetId()).SubQuery() + scopeQuery := hostwires.Query(hostwires.Field("host_id")).Equals("wire_id", wire.GetId()).SubQuery() + q = q.In("id", scopeQuery) } storageStr := jsonutils.GetAnyString(query, []string{"storage", "storage_id"}) @@ -178,7 +180,8 @@ func (manager *SHostManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQu return nil, httperrors.NewResourceNotFoundError("Storage %s not found", storageStr) } hoststorages := HoststorageManager.Query().SubQuery() - scopeQuery = hoststorages.Query(hoststorages.Field("host_id")).Equals("storage_id", storage.GetId()).SubQuery() + scopeQuery := hoststorages.Query(hoststorages.Field("host_id")).Equals("storage_id", storage.GetId()).SubQuery() + q = q.In("id", scopeQuery) } zoneStr := jsonutils.GetAnyString(query, []string{"zone", "zone_id"}) @@ -202,9 +205,18 @@ func (manager *SHostManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQu q = q.Filter(sqlchemy.Equals(q.Field("manager_id"), provider.GetId())) } - if scopeQuery != nil { - q = q.In("id", scopeQuery) + usable := jsonutils.QueryBoolean(query, "usable", false) + if usable { + hostwires := HostwireManager.Query().SubQuery() + networks := NetworkManager.Query().SubQuery() + + hostQ := hostwires.Query(sqlchemy.DISTINCT("host_id", hostwires.Field("host_id"))) + hostQ = hostQ.Join(networks, sqlchemy.Equals(hostwires.Field("wire_id"), networks.Field("wire_id"))) + hostQ = hostQ.Filter(sqlchemy.Equals(networks.Field("status"), NETWORK_STATUS_AVAILABLE)) + + q = q.In("id", hostQ.SubQuery()) } + return q, nil } @@ -1632,6 +1644,7 @@ func (self *SHost) getMoreDetails(extra *jsonutils.JSONDict) *jsonutils.JSONDict memCommitRate = float64(usage.GuestVmemSize) * 1.0 / float64(totalMem) } extra.Add(jsonutils.NewFloat(memCommitRate), "mem_commit_rate") + extra = self.SManagedResourceBase.getExtraDetails(extra) return extra } diff --git a/pkg/compute/models/managedresource.go b/pkg/compute/models/managedresource.go index b6883e10a4..e44a9041e3 100644 --- a/pkg/compute/models/managedresource.go +++ b/pkg/compute/models/managedresource.go @@ -3,6 +3,7 @@ package models import ( "fmt" + "yunion.io/x/jsonutils" "yunion.io/x/onecloud/pkg/cloudprovider" ) @@ -28,3 +29,11 @@ func (self *SManagedResourceBase) GetDriver() (cloudprovider.ICloudProvider, err func (self *SManagedResourceBase) IsManaged() bool { return len(self.ManagerId) > 0 } + +func (self *SManagedResourceBase) getExtraDetails(extra *jsonutils.JSONDict) *jsonutils.JSONDict { + manager := self.GetCloudprovider() + if manager != nil { + extra.Add(jsonutils.NewString(manager.Name), "manager") + } + return extra +}