hostnetworks.go 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package models
  15. import (
  16. "context"
  17. "yunion.io/x/jsonutils"
  18. "yunion.io/x/log"
  19. "yunion.io/x/pkg/errors"
  20. "yunion.io/x/sqlchemy"
  21. api "yunion.io/x/onecloud/pkg/apis/compute"
  22. "yunion.io/x/onecloud/pkg/cloudcommon/db"
  23. "yunion.io/x/onecloud/pkg/mcclient"
  24. "yunion.io/x/onecloud/pkg/util/stringutils2"
  25. )
  26. // +onecloud:swagger-gen-ignore
  27. type SHostnetworkManager struct {
  28. SHostJointsManager
  29. SNetworkResourceBaseManager
  30. }
  31. var HostnetworkManager *SHostnetworkManager
  32. func init() {
  33. db.InitManager(func() {
  34. HostnetworkManager = &SHostnetworkManager{
  35. SHostJointsManager: NewHostJointsManager(
  36. "baremetal_id",
  37. SHostnetwork{},
  38. "baremetalnetworks_tbl",
  39. "baremetalnetwork",
  40. "baremetalnetworks",
  41. NetworkManager,
  42. ),
  43. }
  44. HostnetworkManager.SetVirtualObject(HostnetworkManager)
  45. })
  46. }
  47. // +onecloud:model-api-gen
  48. type SHostnetwork struct {
  49. SHostJointsBase
  50. // 宿主机ID
  51. BaremetalId string `width:"36" charset:"ascii" nullable:"false" list:"domain"`
  52. // 网络ID
  53. NetworkId string `width:"36" charset:"ascii" nullable:"false" list:"domain"`
  54. // IP地址
  55. IpAddr string `width:"16" charset:"ascii" list:"domain"`
  56. // IPv6地址
  57. Ip6Addr string `width:"64" charset:"ascii" list:"domain"`
  58. // MAC地址
  59. MacAddr string `width:"18" charset:"ascii" list:"domain"`
  60. // VLAN
  61. VlanId int `nullable:"false" default:"1" list:"domain"`
  62. }
  63. func (manager *SHostnetworkManager) GetMasterFieldName() string {
  64. return manager.getHostIdFieldName()
  65. }
  66. func (manager *SHostnetworkManager) GetSlaveFieldName() string {
  67. return "network_id"
  68. }
  69. func (manager *SHostnetworkManager) FetchCustomizeColumns(
  70. ctx context.Context,
  71. userCred mcclient.TokenCredential,
  72. query jsonutils.JSONObject,
  73. objs []interface{},
  74. fields stringutils2.SSortedStrings,
  75. isList bool,
  76. ) []api.HostnetworkDetails {
  77. rows := make([]api.HostnetworkDetails, len(objs))
  78. hostRows := manager.SHostJointsManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
  79. hostIds := make([]string, len(rows))
  80. netIds := make([]string, len(rows))
  81. macIds := make([]string, len(rows))
  82. vlanIds := make([]int, len(rows))
  83. for i := range rows {
  84. rows[i] = api.HostnetworkDetails{
  85. HostJointResourceDetails: hostRows[i],
  86. }
  87. hostIds[i] = objs[i].(*SHostnetwork).BaremetalId
  88. netIds[i] = objs[i].(*SHostnetwork).NetworkId
  89. macIds[i] = objs[i].(*SHostnetwork).MacAddr
  90. vlanIds[i] = objs[i].(*SHostnetwork).VlanId
  91. }
  92. hostIdMaps, err := db.FetchIdNameMap2(HostManager, hostIds)
  93. if err != nil {
  94. log.Errorf("FetchIdNameMap2 hostIds fail %s", err)
  95. return rows
  96. }
  97. netWireMaps, err := manager.fetchNetWireMap(netIds)
  98. if err != nil {
  99. log.Errorf("fetchNetWireMap netIds fail %s", err)
  100. return rows
  101. }
  102. for i := range rows {
  103. if name, ok := hostIdMaps[hostIds[i]]; ok {
  104. rows[i].Host = name
  105. }
  106. if nw, ok := netWireMaps[netIds[i]]; ok {
  107. rows[i].Network = nw.Name
  108. rows[i].Wire = nw.WireName
  109. rows[i].WireId = nw.WireId
  110. }
  111. netif, _ := NetInterfaceManager.FetchByMacVlan(macIds[i], vlanIds[i])
  112. if netif != nil {
  113. rows[i].NicType = netif.NicType
  114. }
  115. }
  116. return rows
  117. }
  118. type sNetWire struct {
  119. Id string
  120. Name string
  121. WireId string
  122. WireName string
  123. }
  124. func (manager *SHostnetworkManager) fetchNetWireMap(netIds []string) (map[string]*sNetWire, error) {
  125. if len(netIds) == 0 {
  126. return map[string]*sNetWire{}, nil
  127. }
  128. q := NetworkManager.Query("id", "name", "wire_id")
  129. if len(netIds) == 1 {
  130. q = q.Equals("id", netIds[0])
  131. } else {
  132. q = q.In("id", netIds)
  133. }
  134. wireSubq := WireManager.Query("id", "name").SubQuery()
  135. q = q.Join(wireSubq, sqlchemy.Equals(q.Field("wire_id"), wireSubq.Field("id")))
  136. q = q.AppendField(wireSubq.Field("name", "wire_name"))
  137. nws := make([]sNetWire, 0, len(netIds))
  138. err := q.All(&nws)
  139. if err != nil {
  140. return nil, err
  141. }
  142. ret := make(map[string]*sNetWire, len(netIds))
  143. for i := range nws {
  144. ret[nws[i].Id] = &nws[i]
  145. }
  146. return ret, nil
  147. }
  148. func (bn *SHostnetwork) GetHost() *SHost {
  149. master, _ := HostManager.FetchById(bn.BaremetalId)
  150. if master != nil {
  151. return master.(*SHost)
  152. }
  153. return nil
  154. }
  155. func (bn *SHostnetwork) GetNetwork() *SNetwork {
  156. slave, _ := NetworkManager.FetchById(bn.NetworkId)
  157. if slave != nil {
  158. return slave.(*SNetwork)
  159. }
  160. return nil
  161. }
  162. func (bn *SHostnetwork) GetNetInterface() (*SNetInterface, error) {
  163. return NetInterfaceManager.FetchByMacVlan(bn.MacAddr, bn.VlanId)
  164. }
  165. func (bn *SHostnetwork) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
  166. return db.DeleteModel(ctx, userCred, bn)
  167. }
  168. func (bn *SHostnetwork) Detach(ctx context.Context, userCred mcclient.TokenCredential) error {
  169. return db.DetachJoint(ctx, userCred, bn)
  170. }
  171. func (man *SHostnetworkManager) QueryByAddress(addr string) *sqlchemy.SQuery {
  172. q := HostnetworkManager.Query()
  173. return q.Filter(sqlchemy.Equals(q.Field("ip_addr"), addr))
  174. }
  175. func (man *SHostnetworkManager) GetHostNetworkByAddress(addr string) *SHostnetwork {
  176. network := SHostnetwork{}
  177. err := man.QueryByAddress(addr).First(&network)
  178. if err == nil {
  179. return &network
  180. }
  181. return nil
  182. }
  183. func (man *SHostnetworkManager) GetNetworkByAddress(addr string) *SNetwork {
  184. net := man.GetHostNetworkByAddress(addr)
  185. if net == nil {
  186. return nil
  187. }
  188. return net.GetNetwork()
  189. }
  190. func (man *SHostnetworkManager) GetHostByAddress(addr string) *SHost {
  191. networks := man.TableSpec().Instance()
  192. hosts := HostManager.Query()
  193. q := hosts.Join(networks, sqlchemy.AND(
  194. sqlchemy.IsFalse(networks.Field("deleted")),
  195. sqlchemy.Equals(networks.Field("ip_addr"), addr),
  196. sqlchemy.Equals(networks.Field("baremetal_id"), hosts.Field("id")),
  197. ))
  198. host := &SHost{}
  199. host.SetModelManager(HostManager, host)
  200. err := q.First(host)
  201. if err == nil {
  202. return host
  203. }
  204. return nil
  205. }
  206. func (manager *SHostnetworkManager) ListItemFilter(
  207. ctx context.Context,
  208. q *sqlchemy.SQuery,
  209. userCred mcclient.TokenCredential,
  210. query api.HostnetworkListInput,
  211. ) (*sqlchemy.SQuery, error) {
  212. var err error
  213. q, err = manager.SHostJointsManager.ListItemFilter(ctx, q, userCred, query.HostJointsListInput)
  214. if err != nil {
  215. return nil, errors.Wrap(err, "SHostResourceBaseManager.ListItemFilter")
  216. }
  217. q, err = manager.SNetworkResourceBaseManager.ListItemFilter(ctx, q, userCred, query.NetworkFilterListInput)
  218. if err != nil {
  219. return nil, errors.Wrap(err, "SNetworkResourceBaseManager.ListItemFilter")
  220. }
  221. if len(query.IpAddr) > 0 {
  222. q = q.In("ip_addr", query.IpAddr)
  223. }
  224. if len(query.MacAddr) > 0 {
  225. q = q.In("mac_addr", query.MacAddr)
  226. }
  227. return q, nil
  228. }
  229. func (manager *SHostnetworkManager) OrderByExtraFields(
  230. ctx context.Context,
  231. q *sqlchemy.SQuery,
  232. userCred mcclient.TokenCredential,
  233. query api.HostnetworkListInput,
  234. ) (*sqlchemy.SQuery, error) {
  235. var err error
  236. q, err = manager.SHostJointsManager.OrderByExtraFields(ctx, q, userCred, query.HostJointsListInput)
  237. if err != nil {
  238. return nil, errors.Wrap(err, "SHostResourceBaseManager.OrderByExtraFields")
  239. }
  240. q, err = manager.SNetworkResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.NetworkFilterListInput)
  241. if err != nil {
  242. return nil, errors.Wrap(err, "SNetworkResourceBaseManager.OrderByExtraFields")
  243. }
  244. return q, nil
  245. }
  246. func (manager *SHostnetworkManager) ListItemExportKeys(ctx context.Context,
  247. q *sqlchemy.SQuery,
  248. userCred mcclient.TokenCredential,
  249. keys stringutils2.SSortedStrings,
  250. ) (*sqlchemy.SQuery, error) {
  251. var err error
  252. q, err = manager.SHostJointsManager.ListItemExportKeys(ctx, q, userCred, keys)
  253. if err != nil {
  254. return nil, errors.Wrap(err, "SHostJointsManager.ListItemExportKeys")
  255. }
  256. if keys.ContainsAny(manager.SNetworkResourceBaseManager.GetExportKeys()...) {
  257. q, err = manager.SNetworkResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
  258. if err != nil {
  259. return nil, errors.Wrap(err, "SNetworkResourceBaseManager.ListItemExportKeys")
  260. }
  261. }
  262. return q, nil
  263. }
  264. func (manager *SHostnetworkManager) fetchHostnetworks(filter func(q *sqlchemy.SQuery) *sqlchemy.SQuery) ([]SHostnetwork, error) {
  265. q := manager.Query()
  266. q = filter(q)
  267. ret := make([]SHostnetwork, 0)
  268. err := db.FetchModelObjects(manager, q, &ret)
  269. if err != nil {
  270. return nil, errors.Wrap(err, "FetchModelObjects")
  271. }
  272. return ret, nil
  273. }
  274. func (manager *SHostnetworkManager) fetchHostnetworksByNetwork(netId string) ([]SHostnetwork, error) {
  275. return manager.fetchHostnetworks(func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
  276. q = q.Equals("network_id", netId)
  277. return q
  278. })
  279. }