dbinstancenetworks.go 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  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. "fmt"
  18. "yunion.io/x/cloudmux/pkg/cloudprovider"
  19. "yunion.io/x/log"
  20. "yunion.io/x/pkg/errors"
  21. "yunion.io/x/pkg/util/compare"
  22. "yunion.io/x/pkg/util/netutils"
  23. "yunion.io/x/sqlchemy"
  24. api "yunion.io/x/onecloud/pkg/apis/compute"
  25. "yunion.io/x/onecloud/pkg/cloudcommon/db"
  26. "yunion.io/x/onecloud/pkg/mcclient"
  27. )
  28. // +onecloud:swagger-gen-ignore
  29. type SDBInstanceNetworkManager struct {
  30. SDBInstanceJointsManager
  31. SNetworkResourceBaseManager
  32. }
  33. var DBInstanceNetworkManager *SDBInstanceNetworkManager
  34. func init() {
  35. db.InitManager(func() {
  36. DBInstanceNetworkManager = &SDBInstanceNetworkManager{
  37. SDBInstanceJointsManager: NewDBInstanceJointsManager(
  38. SDBInstanceNetwork{},
  39. "dbinstancenetworks_tbl",
  40. "dbinstancenetwork",
  41. "dbinstancenetworks",
  42. NetworkManager,
  43. ),
  44. }
  45. DBInstanceNetworkManager.SetVirtualObject(DBInstanceNetworkManager)
  46. DBInstanceNetworkManager.TableSpec().AddIndex(true, "ip_addr", "dbinstance_id")
  47. })
  48. }
  49. // +onecloud:swagger-gen-ignore
  50. type SDBInstanceNetwork struct {
  51. SDBInstanceJointsBase
  52. NetworkId string `width:"36" charset:"ascii" nullable:"true" list:"user"`
  53. IpAddr string `width:"16" charset:"ascii" nullable:"false" list:"user"`
  54. }
  55. func (manager *SDBInstanceNetworkManager) GetSlaveFieldName() string {
  56. return "network_id"
  57. }
  58. func (self *SDBInstanceNetwork) Detach(ctx context.Context, userCred mcclient.TokenCredential) error {
  59. return db.DetachJoint(ctx, userCred, self)
  60. }
  61. // RDS网络列表
  62. func (manager *SDBInstanceNetworkManager) ListItemFilter(
  63. ctx context.Context,
  64. q *sqlchemy.SQuery,
  65. userCred mcclient.TokenCredential,
  66. query api.DBInstanceNetworkListInput,
  67. ) (*sqlchemy.SQuery, error) {
  68. var err error
  69. q, err = manager.SDBInstanceJointsManager.ListItemFilter(ctx, q, userCred, query.DBInstanceJoinListInput)
  70. if err != nil {
  71. return nil, errors.Wrap(err, "SDBInstanceJointsManager.ListItemFilter")
  72. }
  73. q, err = manager.SNetworkResourceBaseManager.ListItemFilter(ctx, q, userCred, query.NetworkFilterListInput)
  74. if err != nil {
  75. return nil, errors.Wrap(err, "SNetworkResourceBaseManager.ListItemFilter")
  76. }
  77. return q, nil
  78. }
  79. func (self *SDBInstanceNetwork) GetNetwork() (*SNetwork, error) {
  80. network, err := NetworkManager.FetchById(self.NetworkId)
  81. if err != nil {
  82. return nil, err
  83. }
  84. return network.(*SNetwork), nil
  85. }
  86. func (manager *SDBInstanceNetworkManager) newNetwork(ctx context.Context, userCred mcclient.TokenCredential, rdsId, networkId, ipAddr string) error {
  87. ds := &SDBInstanceNetwork{}
  88. ds.SetModelManager(DBInstanceNetworkManager, ds)
  89. ds.DBInstanceId = rdsId
  90. ds.NetworkId = networkId
  91. ds.IpAddr = ipAddr
  92. return manager.TableSpec().Insert(ctx, ds)
  93. }
  94. func (manager *SDBInstanceNetworkManager) SyncDBInstanceNetwork(ctx context.Context, userCred mcclient.TokenCredential, dbinstance *SDBInstance, exts []cloudprovider.SDBInstanceNetwork) compare.SyncResult {
  95. result := compare.SyncResult{}
  96. networks, err := dbinstance.GetDBNetworks()
  97. if err != nil {
  98. result.Error(err)
  99. return result
  100. }
  101. localMap := map[string]SDBInstanceNetwork{}
  102. for i := range networks {
  103. localMap[networks[i].NetworkId+networks[i].IpAddr] = networks[i]
  104. }
  105. remoteMap := map[string]bool{}
  106. for i := range exts {
  107. _network, err := db.FetchByExternalIdAndManagerId(NetworkManager, exts[i].NetworkId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
  108. wire := WireManager.Query().SubQuery()
  109. vpc := VpcManager.Query().SubQuery()
  110. return q.Join(wire, sqlchemy.Equals(wire.Field("id"), q.Field("wire_id"))).
  111. Join(vpc, sqlchemy.Equals(vpc.Field("id"), wire.Field("vpc_id"))).
  112. Filter(sqlchemy.Equals(vpc.Field("manager_id"), dbinstance.ManagerId))
  113. })
  114. if err != nil {
  115. result.Error(err)
  116. continue
  117. }
  118. network := _network.(*SNetwork)
  119. exts[i].NetworkId = network.GetId()
  120. remoteMap[exts[i].NetworkId+exts[i].IP] = true
  121. _, ok := localMap[exts[i].NetworkId+exts[i].IP]
  122. if !ok {
  123. ipAddr, err := netutils.NewIPV4Addr(exts[i].IP)
  124. if err != nil {
  125. result.AddError(errors.Wrapf(err, "invalid ip"))
  126. }
  127. if !network.IsAddressInRange(ipAddr) {
  128. result.AddError(fmt.Errorf("IP %s not in network %s(%s) address range", exts[i].IP, network.Name, network.Id))
  129. continue
  130. }
  131. err = manager.newNetwork(ctx, userCred, dbinstance.Id, exts[i].NetworkId, exts[i].IP)
  132. if err != nil {
  133. result.AddError(err)
  134. continue
  135. }
  136. result.Add()
  137. }
  138. }
  139. for i := range networks {
  140. _, ok := remoteMap[networks[i].NetworkId+networks[i].IpAddr]
  141. if ok {
  142. continue
  143. }
  144. err = networks[i].Detach(ctx, userCred)
  145. if err != nil {
  146. result.DeleteError(err)
  147. continue
  148. }
  149. result.Delete()
  150. }
  151. return result
  152. }
  153. func (manager *SDBInstanceNetworkManager) OrderByExtraFields(
  154. ctx context.Context,
  155. q *sqlchemy.SQuery,
  156. userCred mcclient.TokenCredential,
  157. query api.DBInstanceNetworkListInput,
  158. ) (*sqlchemy.SQuery, error) {
  159. var err error
  160. q, err = manager.SDBInstanceJointsManager.OrderByExtraFields(ctx, q, userCred, query.DBInstanceJoinListInput)
  161. if err != nil {
  162. return nil, errors.Wrap(err, "SDBInstanceJointsManager.OrderByExtraFields")
  163. }
  164. q, err = manager.SNetworkResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.NetworkFilterListInput)
  165. if err != nil {
  166. return nil, errors.Wrap(err, "SNetworkResourceBaseManager.OrderByExtraFields")
  167. }
  168. return q, nil
  169. }
  170. func (manager *SDBInstanceNetworkManager) InitializeData() error {
  171. sq := DBInstanceManager.Query("id")
  172. q := manager.Query().NotIn("dbinstance_id", sq.SubQuery())
  173. networks := []SDBInstanceNetwork{}
  174. err := db.FetchModelObjects(manager, q, &networks)
  175. if err != nil {
  176. return errors.Wrapf(err, "db.FetchModelObjects")
  177. }
  178. for i := range networks {
  179. _, err := db.Update(&networks[i], func() error {
  180. return networks[i].MarkDelete()
  181. })
  182. if err != nil {
  183. return errors.Wrapf(err, "db.Update.MarkDelete")
  184. }
  185. }
  186. log.Debugf("SDBInstanceNetworkManager cleaned %d dirty data.", len(networks))
  187. return nil
  188. }