hostwires.go 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  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/httperrors"
  24. "yunion.io/x/onecloud/pkg/mcclient"
  25. "yunion.io/x/onecloud/pkg/util/stringutils2"
  26. )
  27. // +onecloud:swagger-gen-ignore
  28. type SHostwireManagerDeprecated struct {
  29. SHostJointsManager
  30. SWireResourceBaseManager
  31. }
  32. var HostwireManagerDeprecated *SHostwireManagerDeprecated
  33. func init() {
  34. db.InitManager(func() {
  35. HostwireManagerDeprecated = &SHostwireManagerDeprecated{
  36. SHostJointsManager: NewHostJointsManager(
  37. "host_id",
  38. SHostwireDeprecated{},
  39. "hostwires_tbl",
  40. "hostwire",
  41. "hostwires",
  42. WireManager,
  43. ),
  44. }
  45. HostwireManagerDeprecated.SetVirtualObject(HostwireManagerDeprecated)
  46. })
  47. }
  48. // +onecloud:model-api-gen
  49. type SHostwireDeprecated struct {
  50. SHostJointsBase
  51. Bridge string `width:"64" charset:"ascii" nullable:"false" list:"domain" update:"domain" create:"domain_required"`
  52. // 接口名称
  53. Interface string `width:"64" charset:"ascii" nullable:"false" list:"domain" update:"domain" create:"domain_required"`
  54. // 是否是主地址
  55. IsMaster bool `nullable:"true" default:"false" list:"domain" update:"domain" create:"domain_optional"`
  56. // MAC地址
  57. MacAddr string `width:"18" charset:"ascii" list:"domain" update:"domain" create:"domain_required"`
  58. // 宿主机Id
  59. HostId string `width:"128" charset:"ascii" nullable:"false" list:"domain" create:"domain_required"`
  60. // 二层网络Id
  61. WireId string `width:"128" charset:"ascii" nullable:"false" list:"domain" create:"domain_required"`
  62. }
  63. func (manager *SHostwireManagerDeprecated) GetMasterFieldName() string {
  64. return "host_id"
  65. }
  66. func (manager *SHostwireManagerDeprecated) GetSlaveFieldName() string {
  67. return "wire_id"
  68. }
  69. func (manager *SHostwireManagerDeprecated) 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.HostwireDetails {
  77. rows := make([]api.HostwireDetails, len(objs))
  78. hostRows := manager.SHostJointsManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
  79. wireIds := make([]string, len(rows))
  80. for i := range rows {
  81. rows[i] = api.HostwireDetails{
  82. HostJointResourceDetails: hostRows[i],
  83. }
  84. wireIds[i] = objs[i].(*SHostwireDeprecated).WireId
  85. }
  86. wires := make(map[string]SWire)
  87. err := db.FetchStandaloneObjectsByIds(WireManager, wireIds, &wires)
  88. if err != nil {
  89. log.Errorf("db.FetchStandaloneObjectsByIds fail %s", err)
  90. return rows
  91. }
  92. for i := range rows {
  93. if wire, ok := wires[wireIds[i]]; ok {
  94. rows[i].Wire = wire.Name
  95. rows[i].Bandwidth = wire.Bandwidth
  96. }
  97. }
  98. return rows
  99. }
  100. func (hw *SHostwireDeprecated) GetWire() *SWire {
  101. wire, _ := WireManager.FetchById(hw.WireId)
  102. if wire != nil {
  103. return wire.(*SWire)
  104. }
  105. return nil
  106. }
  107. func (hw *SHostwireDeprecated) GetHost() *SHost {
  108. host, _ := HostManager.FetchById(hw.HostId)
  109. if host != nil {
  110. return host.(*SHost)
  111. }
  112. return nil
  113. }
  114. func (self *SHostwireDeprecated) GetGuestnicsCount() (int, error) {
  115. guestnics := GuestnetworkManager.Query().SubQuery()
  116. guests := GuestManager.Query().SubQuery()
  117. nets := NetworkManager.Query().SubQuery()
  118. q := guestnics.Query()
  119. q = q.Join(guests, sqlchemy.AND(sqlchemy.IsFalse(guests.Field("deleted")),
  120. sqlchemy.Equals(guests.Field("id"), guestnics.Field("guest_id")),
  121. sqlchemy.Equals(guests.Field("host_id"), self.HostId)))
  122. q = q.Join(nets, sqlchemy.AND(sqlchemy.IsFalse(nets.Field("deleted")),
  123. sqlchemy.Equals(nets.Field("id"), guestnics.Field("network_id")),
  124. sqlchemy.Equals(nets.Field("wire_id"), self.WireId)))
  125. return q.CountWithError()
  126. }
  127. func (self *SHostwireDeprecated) ValidateDeleteCondition(ctx context.Context, info jsonutils.JSONObject) error {
  128. cnt, err := self.GetGuestnicsCount()
  129. if err != nil {
  130. return httperrors.NewInternalServerError("GetGuestnicsCount fail %s", err)
  131. }
  132. if cnt > 0 {
  133. // check if this is the last one
  134. // host := self.GetHost()
  135. // if len(host.getHostwiresOfId(self.WireId)) == 1 {
  136. // return httperrors.NewNotEmptyError("guest on the host are using networks on this wire")
  137. // }
  138. }
  139. return self.SHostJointsBase.ValidateDeleteCondition(ctx, nil)
  140. }
  141. func (self *SHostwireDeprecated) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
  142. return db.DeleteModel(ctx, userCred, self)
  143. }
  144. func (self *SHostwireDeprecated) PreDelete(ctx context.Context, userCred mcclient.TokenCredential) {
  145. host := self.GetHost()
  146. if host == nil {
  147. log.Errorf("no host found??")
  148. return
  149. }
  150. netif := host.GetNetInterface(self.MacAddr, 1)
  151. if netif == nil {
  152. log.Errorf("no netinterface for %s", self.MacAddr)
  153. return
  154. }
  155. err := host.DisableNetif(ctx, userCred, netif, false)
  156. if err != nil {
  157. log.Errorf("host.DisableNetif fail %s", err)
  158. return
  159. }
  160. err = netif.UnsetWire()
  161. if err != nil {
  162. log.Errorf("netif.UnsetWire fail %s", err)
  163. return
  164. }
  165. }
  166. func (self *SHostwireDeprecated) Detach(ctx context.Context, userCred mcclient.TokenCredential) error {
  167. return db.DetachJoint(ctx, userCred, self)
  168. }
  169. func (manager *SHostwireManagerDeprecated) FilterByParams(q *sqlchemy.SQuery, params jsonutils.JSONObject) *sqlchemy.SQuery {
  170. macStr := jsonutils.GetAnyString(params, []string{"mac", "mac_addr"})
  171. if len(macStr) > 0 {
  172. q = q.Filter(sqlchemy.Equals(q.Field("mac_addr"), macStr))
  173. }
  174. return q
  175. }
  176. func (manager *SHostwireManagerDeprecated) FetchByHostIdAndMac(hostId string, mac string) (*SHostwireDeprecated, error) {
  177. hw, err := db.NewModelObject(manager)
  178. if err != nil {
  179. return nil, err
  180. }
  181. q := manager.Query().Equals("host_id", hostId).Equals("mac_addr", mac)
  182. err = q.First(hw)
  183. if err != nil {
  184. return nil, err
  185. }
  186. return hw.(*SHostwireDeprecated), nil
  187. }
  188. func (manager *SHostwireManagerDeprecated) ListItemFilter(
  189. ctx context.Context,
  190. q *sqlchemy.SQuery,
  191. userCred mcclient.TokenCredential,
  192. query api.HostwireListInput,
  193. ) (*sqlchemy.SQuery, error) {
  194. var err error
  195. q, err = manager.SHostJointsManager.ListItemFilter(ctx, q, userCred, query.HostJointsListInput)
  196. if err != nil {
  197. return nil, errors.Wrap(err, "SHostResourceBaseManager.ListItemFilter")
  198. }
  199. q, err = manager.SWireResourceBaseManager.ListItemFilter(ctx, q, userCred, query.WireFilterListInput)
  200. if err != nil {
  201. return nil, errors.Wrap(err, "SWireResourceBaseManager.ListItemFilter")
  202. }
  203. if len(query.Bridge) > 0 {
  204. q = q.In("bridge", query.Bridge)
  205. }
  206. if len(query.Interface) > 0 {
  207. q = q.In("interface", query.Interface)
  208. }
  209. if query.IsMaster != nil {
  210. if *query.IsMaster {
  211. q = q.IsTrue("is_master")
  212. } else {
  213. q = q.IsFalse("is_master")
  214. }
  215. }
  216. if len(query.MacAddr) > 0 {
  217. q = q.In("mac_addr", query.MacAddr)
  218. }
  219. return q, nil
  220. }
  221. func (manager *SHostwireManagerDeprecated) OrderByExtraFields(
  222. ctx context.Context,
  223. q *sqlchemy.SQuery,
  224. userCred mcclient.TokenCredential,
  225. query api.HostwireListInput,
  226. ) (*sqlchemy.SQuery, error) {
  227. var err error
  228. q, err = manager.SHostJointsManager.OrderByExtraFields(ctx, q, userCred, query.HostJointsListInput)
  229. if err != nil {
  230. return nil, errors.Wrap(err, "SHostResourceBaseManager.OrderByExtraFields")
  231. }
  232. q, err = manager.SWireResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.WireFilterListInput)
  233. if err != nil {
  234. return nil, errors.Wrap(err, "SWireResourceBaseManager.OrderByExtraFields")
  235. }
  236. return q, nil
  237. }
  238. func (manager *SHostwireManagerDeprecated) ListItemExportKeys(ctx context.Context,
  239. q *sqlchemy.SQuery,
  240. userCred mcclient.TokenCredential,
  241. keys stringutils2.SSortedStrings,
  242. ) (*sqlchemy.SQuery, error) {
  243. var err error
  244. q, err = manager.SHostJointsManager.ListItemExportKeys(ctx, q, userCred, keys)
  245. if err != nil {
  246. return nil, errors.Wrap(err, "SHostJointsManager.ListItemExportKeys")
  247. }
  248. if keys.ContainsAny(manager.SWireResourceBaseManager.GetExportKeys()...) {
  249. q, err = manager.SWireResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
  250. if err != nil {
  251. return nil, errors.Wrap(err, "SWireResourceBaseManager.ListItemExportKeys")
  252. }
  253. }
  254. return q, nil
  255. }
  256. func (hw *SHostwireDeprecated) PostCreate(
  257. ctx context.Context,
  258. userCred mcclient.TokenCredential,
  259. ownerId mcclient.IIdentityProvider,
  260. query jsonutils.JSONObject,
  261. data jsonutils.JSONObject,
  262. ) {
  263. hw.SHostJointsBase.PostCreate(ctx, userCred, ownerId, query, data)
  264. hw.syncClassMetadata(ctx, userCred)
  265. }
  266. func (hw *SHostwireDeprecated) syncClassMetadata(ctx context.Context, userCred mcclient.TokenCredential) error {
  267. host := hw.GetHost()
  268. wire := hw.GetWire()
  269. err := db.InheritFromTo(ctx, userCred, wire, host)
  270. if err != nil {
  271. log.Errorf("Inherit class metadata from host to wire fail: %s", err)
  272. return errors.Wrap(err, "InheritFromTo")
  273. }
  274. return nil
  275. }