diff --git a/cmd/climc/shell/compute/wires.go b/cmd/climc/shell/compute/wires.go index 9f1eb3ed2c..e8686ea161 100644 --- a/cmd/climc/shell/compute/wires.go +++ b/cmd/climc/shell/compute/wires.go @@ -32,4 +32,5 @@ func init() { cmd.Perform("change-owner-candidate-domains", new(options.WireOptions)) cmd.PerformWithKeyword("merge", "merge-from", new(options.WireMergeOptions)) cmd.Perform("merge-network", new(options.WireOptions)) + cmd.Get("topology", &options.WireOptions{}) } diff --git a/pkg/apis/compute/network_const.go b/pkg/apis/compute/network_const.go index 1e90b76cd4..ab9afb817b 100644 --- a/pkg/apis/compute/network_const.go +++ b/pkg/apis/compute/network_const.go @@ -87,6 +87,7 @@ type SNetworkUsedAddress struct { MacAddr string Owner string OwnerId string + OwnerStatus string OwnerType string AssociateId string AssociateType string diff --git a/pkg/apis/compute/wire.go b/pkg/apis/compute/wire.go index c87fd79de4..16be7a1b1b 100644 --- a/pkg/apis/compute/wire.go +++ b/pkg/apis/compute/wire.go @@ -115,3 +115,6 @@ type WireMergeFromInput struct { type WireMergeNetworkInput struct { } + +type WireTopologyInput struct { +} diff --git a/pkg/compute/models/networks_used_addresses_query.go b/pkg/compute/models/networks_used_addresses_query.go index a06fd59717..6f5dc344cb 100644 --- a/pkg/compute/models/networks_used_addresses_query.go +++ b/pkg/compute/models/networks_used_addresses_query.go @@ -62,6 +62,7 @@ func (manager *SGuestnetworkManager) usedAddressQuery(args *usedAddressQueryArgs baseq.Field("mac_addr"), sqlchemy.NewStringField(GuestManager.KeywordPlural()).Label("owner_type"), ownerq.Field("id").Label("owner_id"), + ownerq.Field("status").Label("owner_status"), ownerq.Field("name").Label("owner"), sqlchemy.NewStringField("").Label("associate_id"), sqlchemy.NewStringField("").Label("associate_type"), @@ -93,6 +94,7 @@ func (manager *SHostnetworkManager) usedAddressQuery(args *usedAddressQueryArgs) baseq.Field("mac_addr"), sqlchemy.NewStringField(HostManager.KeywordPlural()).Label("owner_type"), ownerq.Field("id").Label("owner_id"), + ownerq.Field("status").Label("owner_status"), ownerq.Field("name").Label("owner"), sqlchemy.NewStringField("").Label("associate_id"), sqlchemy.NewStringField("").Label("associate_type"), @@ -123,6 +125,7 @@ func (manager *SReservedipManager) usedAddressQuery(args *usedAddressQueryArgs) sqlchemy.NewStringField("").Label("mac_addr"), sqlchemy.NewStringField(ReservedipManager.KeywordPlural()).Label("owner_type"), baseq.Field("id").Label("owner_id"), + baseq.Field("status").Label("owner_status"), baseq.Field("notes").Label("owner"), sqlchemy.NewStringField("").Label("associate_id"), sqlchemy.NewStringField("").Label("associate_type"), @@ -152,6 +155,7 @@ func (manager *SGroupnetworkManager) usedAddressQuery(args *usedAddressQueryArgs sqlchemy.NewStringField("").Label("mac_addr"), sqlchemy.NewStringField(GroupManager.KeywordPlural()).Label("owner_type"), ownerq.Field("id").Label("owner_id"), + ownerq.Field("status").Label("owner_status"), ownerq.Field("name").Label("owner"), sqlchemy.NewStringField("").Label("associate_id"), sqlchemy.NewStringField("").Label("associate_type"), @@ -183,6 +187,7 @@ func (manager *SLoadbalancernetworkManager) usedAddressQuery(args *usedAddressQu sqlchemy.NewStringField("").Label("mac_addr"), sqlchemy.NewStringField(LoadbalancerManager.KeywordPlural()).Label("owner_type"), ownerq.Field("id").Label("owner_id"), + ownerq.Field("status").Label("owner_status"), ownerq.Field("name").Label("owner"), sqlchemy.NewStringField("").Label("associate_id"), sqlchemy.NewStringField("").Label("associate_type"), @@ -214,6 +219,7 @@ func (manager *SElasticipManager) usedAddressQuery(args *usedAddressQueryArgs) * sqlchemy.NewStringField("").Label("mac_addr"), sqlchemy.NewStringField(ElasticipManager.KeywordPlural()).Label("owner_type"), ownerq.Field("id").Label("owner_id"), + ownerq.Field("status").Label("owner_status"), ownerq.Field("name").Label("owner"), ownerq.Field("associate_id"), ownerq.Field("associate_type"), @@ -245,6 +251,7 @@ func (manager *SNetworkinterfacenetworkManager) usedAddressQuery(args *usedAddre ownerq.Field("mac").Label("mac_addr"), sqlchemy.NewStringField(NetworkInterfaceManager.KeywordPlural()).Label("owner_type"), ownerq.Field("id").Label("owner_id"), + ownerq.Field("status").Label("owner_status"), ownerq.Field("name").Label("owner"), ownerq.Field("associate_id"), ownerq.Field("associate_type"), @@ -276,6 +283,7 @@ func (manager *SDBInstanceManager) usedAddressQuery(args *usedAddressQueryArgs) sqlchemy.NewStringField("").Label("mac_addr"), sqlchemy.NewStringField(DBInstanceManager.KeywordPlural()).Label("owner_type"), ownerq.Field("id").Label("owner_id"), + ownerq.Field("status").Label("owner_status"), ownerq.Field("name").Label("owner"), sqlchemy.NewStringField("").Label("associate_id"), sqlchemy.NewStringField("").Label("associate_type"), @@ -306,6 +314,7 @@ func (manager *SNetworkAddressManager) usedAddressQuery(args *usedAddressQueryAr sqlchemy.NewStringField("").Label("mac_addr"), sqlchemy.NewStringField(NetworkAddressManager.KeywordPlural()).Label("owner_type"), baseq.Field("id").Label("owner_id"), + sqlchemy.NewStringField("available").Label("owner_status"), baseq.Field("id").Label("owner"), baseq.Field("parent_id").Label("associate_id"), baseq.Field("parent_type").Label("associate_type"), diff --git a/pkg/compute/models/wires.go b/pkg/compute/models/wires.go index 7a806a42eb..e4fee3e701 100644 --- a/pkg/compute/models/wires.go +++ b/pkg/compute/models/wires.go @@ -18,6 +18,7 @@ import ( "context" "database/sql" "fmt" + "sort" "yunion.io/x/jsonutils" "yunion.io/x/log" @@ -1502,3 +1503,69 @@ func (manager *SWireManager) ListItemExportKeys(ctx context.Context, } return q, nil } + +func (self *SWire) GetDetailsTopology(ctx context.Context, userCred mcclient.TokenCredential, input *api.WireTopologyInput) (*api.WireTopologyOutput, error) { + ret := &api.WireTopologyOutput{ + Name: self.Name, + Status: self.Status, + Bandwidth: self.Bandwidth, + Networks: []api.NetworkTopologyOutput{}, + Hosts: []api.HostTopologyOutput{}, + } + if len(self.ZoneId) > 0 { + zone, _ := self.GetZone() + if zone != nil { + ret.Zone = zone.Name + } + } + hosts, err := self.GetHosts() + if err != nil { + return nil, errors.Wrapf(err, "GetHosts for wire %s", self.Id) + } + for i := range hosts { + hns := hosts[i].GetBaremetalnetworks() + host := api.HostTopologyOutput{ + Name: hosts[i].Name, + Status: hosts[i].Status, + HostStatus: hosts[i].HostStatus, + HostType: hosts[i].HostType, + Networks: []api.HostnetworkTopologyOutput{}, + } + for j := range hns { + host.Networks = append(host.Networks, api.HostnetworkTopologyOutput{ + IpAddr: hns[j].IpAddr, + MacAddr: hns[j].MacAddr, + }) + } + ret.Hosts = append(ret.Hosts, host) + } + networks, err := self.GetNetworks(nil, rbacutils.ScopeSystem) + if err != nil { + return nil, errors.Wrapf(err, "GetNetworks") + } + for j := range networks { + network := api.NetworkTopologyOutput{ + Name: networks[j].Name, + Status: networks[j].Status, + GuestIpStart: networks[j].GuestIpStart, + GuestIpEnd: networks[j].GuestIpEnd, + GuestIpMask: networks[j].GuestIpMask, + ServerType: networks[j].ServerType, + VlanId: networks[j].VlanId, + Address: []api.SNetworkUsedAddress{}, + } + + netAddrs := make([]api.SNetworkUsedAddress, 0) + + q := networks[j].getUsedAddressQuery(userCred, rbacutils.ScopeDomain, false) + err = q.All(&netAddrs) + if err != nil { + return nil, errors.Wrapf(err, "q.All") + } + + sort.Sort(SNetworkUsedAddressList(netAddrs)) + network.Address = netAddrs + ret.Networks = append(ret.Networks, network) + } + return ret, nil +}