networks_used_addresses_query.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  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. "time"
  18. "yunion.io/x/pkg/util/rbacscope"
  19. "yunion.io/x/sqlchemy"
  20. api "yunion.io/x/onecloud/pkg/apis/compute"
  21. "yunion.io/x/onecloud/pkg/mcclient"
  22. )
  23. type usedAddressQueryArgs struct {
  24. network *SNetwork
  25. userCred mcclient.TokenCredential
  26. owner mcclient.IIdentityProvider
  27. scope rbacscope.TRbacScope
  28. addrOnly bool
  29. addrType api.TAddressType
  30. }
  31. type usedAddressQueryProvider interface {
  32. KeywordPlural() string
  33. usedAddressQuery(ctx context.Context, args *usedAddressQueryArgs) *sqlchemy.SQuery
  34. }
  35. func getUsedAddressQueryProviders() []usedAddressQueryProvider {
  36. return []usedAddressQueryProvider{
  37. GuestnetworkManager,
  38. HostnetworkManager,
  39. ReservedipManager,
  40. GroupnetworkManager,
  41. LoadbalancernetworkManager,
  42. ElasticipManager,
  43. NetworkinterfacenetworkManager,
  44. DBInstanceManager,
  45. NetworkAddressManager,
  46. }
  47. }
  48. func getUsedAddress6QueryProviders() []usedAddressQueryProvider {
  49. return []usedAddressQueryProvider{
  50. GuestnetworkManager,
  51. ReservedipManager,
  52. }
  53. }
  54. func (manager *SGuestnetworkManager) usedAddressQuery(ctx context.Context, args *usedAddressQueryArgs) *sqlchemy.SQuery {
  55. var (
  56. baseq = GuestnetworkManager.Query().Equals("network_id", args.network.Id).SubQuery()
  57. retq *sqlchemy.SQuery
  58. )
  59. field := "ip_addr"
  60. if args.addrType == api.AddressTypeIPv6 {
  61. field = "ip6_addr"
  62. }
  63. if args.addrOnly {
  64. retq = baseq.Query(baseq.Field(field))
  65. } else {
  66. var fields []sqlchemy.IQueryField = []sqlchemy.IQueryField{
  67. baseq.Field(field),
  68. }
  69. ownerq := GuestManager.FilterByOwner(ctx, GuestManager.Query(), GuestManager, args.userCred, args.owner, args.scope).SubQuery()
  70. fields = append(fields,
  71. baseq.Field("mac_addr"),
  72. sqlchemy.NewStringField(GuestManager.KeywordPlural()).Label("owner_type"),
  73. ownerq.Field("id").Label("owner_id"),
  74. ownerq.Field("status").Label("owner_status"),
  75. ownerq.Field("name").Label("owner"),
  76. sqlchemy.NewStringField("").Label("associate_id"),
  77. sqlchemy.NewStringField("").Label("associate_type"),
  78. baseq.Field("created_at"),
  79. )
  80. retq = baseq.Query(fields...).LeftJoin(
  81. ownerq,
  82. sqlchemy.Equals(
  83. ownerq.Field("id"),
  84. baseq.Field("guest_id"),
  85. ),
  86. )
  87. }
  88. retq = retq.IsNotEmpty(field)
  89. return retq
  90. }
  91. func (manager *SHostnetworkManager) usedAddressQuery(ctx context.Context, args *usedAddressQueryArgs) *sqlchemy.SQuery {
  92. var (
  93. baseq = HostnetworkManager.Query().Equals("network_id", args.network.Id).SubQuery()
  94. retq *sqlchemy.SQuery
  95. )
  96. field := "ip_addr"
  97. if args.addrType == api.AddressTypeIPv6 {
  98. field = "ip6_addr"
  99. }
  100. if args.addrOnly {
  101. retq = baseq.Query(
  102. baseq.Field(field),
  103. )
  104. } else {
  105. ownerq := HostManager.FilterByOwner(ctx, HostManager.Query(), HostManager, args.userCred, args.owner, args.scope).SubQuery()
  106. retq = baseq.Query(
  107. baseq.Field(field),
  108. baseq.Field("mac_addr"),
  109. sqlchemy.NewStringField(HostManager.KeywordPlural()).Label("owner_type"),
  110. ownerq.Field("id").Label("owner_id"),
  111. ownerq.Field("status").Label("owner_status"),
  112. ownerq.Field("name").Label("owner"),
  113. sqlchemy.NewStringField("").Label("associate_id"),
  114. sqlchemy.NewStringField("").Label("associate_type"),
  115. baseq.Field("created_at"),
  116. ).LeftJoin(
  117. ownerq,
  118. sqlchemy.Equals(
  119. ownerq.Field("id"),
  120. baseq.Field("baremetal_id"),
  121. ),
  122. )
  123. }
  124. return retq
  125. }
  126. func (manager *SReservedipManager) usedAddressQuery(ctx context.Context, args *usedAddressQueryArgs) *sqlchemy.SQuery {
  127. var (
  128. baseq = ReservedipManager.Query().Equals("network_id", args.network.Id).SubQuery()
  129. retq *sqlchemy.SQuery
  130. )
  131. field := "ip_addr"
  132. if args.addrType == api.AddressTypeIPv6 {
  133. field = "ip6_addr"
  134. }
  135. if args.addrOnly {
  136. retq = baseq.Query(baseq.Field(field))
  137. } else {
  138. var fields []sqlchemy.IQueryField = []sqlchemy.IQueryField{
  139. baseq.Field(field),
  140. }
  141. fields = append(fields,
  142. sqlchemy.NewStringField("").Label("mac_addr"),
  143. sqlchemy.NewStringField(ReservedipManager.KeywordPlural()).Label("owner_type"),
  144. sqlchemy.CASTString(baseq.Field("id"), "owner_id"),
  145. baseq.Field("status").Label("owner_status"),
  146. baseq.Field("notes").Label("owner"),
  147. sqlchemy.NewStringField("").Label("associate_id"),
  148. sqlchemy.NewStringField("").Label("associate_type"),
  149. baseq.Field("created_at"),
  150. )
  151. retq = baseq.Query(fields...)
  152. }
  153. retq = retq.Filter(sqlchemy.OR(
  154. sqlchemy.IsNullOrEmpty(baseq.Field("expired_at")),
  155. sqlchemy.GT(baseq.Field("expired_at"), time.Now()),
  156. ))
  157. retq = retq.IsNotEmpty(field)
  158. return retq
  159. }
  160. func (manager *SGroupnetworkManager) usedAddressQuery(ctx context.Context, args *usedAddressQueryArgs) *sqlchemy.SQuery {
  161. var (
  162. baseq = GroupnetworkManager.Query().Equals("network_id", args.network.Id).SubQuery()
  163. retq *sqlchemy.SQuery
  164. )
  165. if args.addrOnly {
  166. var fields []sqlchemy.IQueryField
  167. if args.addrType == api.AddressTypeIPv6 {
  168. fields = append(fields, baseq.Field("ip6_addr"))
  169. } else {
  170. fields = append(fields, baseq.Field("ip_addr"))
  171. }
  172. retq = baseq.Query(fields...)
  173. } else {
  174. var fields []sqlchemy.IQueryField
  175. if args.addrType == api.AddressTypeIPv6 {
  176. fields = append(fields, baseq.Field("ip6_addr"))
  177. } else {
  178. fields = append(fields, baseq.Field("ip_addr"))
  179. }
  180. ownerq := GroupManager.FilterByOwner(ctx, GroupManager.Query(), GroupManager, args.userCred, args.owner, args.scope).SubQuery()
  181. fields = append(fields,
  182. sqlchemy.NewStringField("").Label("mac_addr"),
  183. sqlchemy.NewStringField(GroupManager.KeywordPlural()).Label("owner_type"),
  184. ownerq.Field("id").Label("owner_id"),
  185. ownerq.Field("status").Label("owner_status"),
  186. ownerq.Field("name").Label("owner"),
  187. sqlchemy.NewStringField("").Label("associate_id"),
  188. sqlchemy.NewStringField("").Label("associate_type"),
  189. baseq.Field("created_at"),
  190. )
  191. retq = baseq.Query(fields...).LeftJoin(
  192. ownerq,
  193. sqlchemy.Equals(
  194. ownerq.Field("id"),
  195. baseq.Field("group_id"),
  196. ),
  197. )
  198. }
  199. return retq
  200. }
  201. func (manager *SLoadbalancernetworkManager) usedAddressQuery(ctx context.Context, args *usedAddressQueryArgs) *sqlchemy.SQuery {
  202. var (
  203. baseq = LoadbalancernetworkManager.Query().Equals("network_id", args.network.Id).SubQuery()
  204. retq *sqlchemy.SQuery
  205. )
  206. if args.addrOnly {
  207. retq = baseq.Query(
  208. baseq.Field("ip_addr"),
  209. )
  210. } else {
  211. ownerq := LoadbalancerManager.FilterByOwner(ctx, LoadbalancerManager.Query(), LoadbalancerManager, args.userCred, args.owner, args.scope).SubQuery()
  212. retq = baseq.Query(
  213. baseq.Field("ip_addr"),
  214. sqlchemy.NewStringField("").Label("mac_addr"),
  215. sqlchemy.NewStringField(LoadbalancerManager.KeywordPlural()).Label("owner_type"),
  216. ownerq.Field("id").Label("owner_id"),
  217. ownerq.Field("status").Label("owner_status"),
  218. ownerq.Field("name").Label("owner"),
  219. sqlchemy.NewStringField("").Label("associate_id"),
  220. sqlchemy.NewStringField("").Label("associate_type"),
  221. baseq.Field("created_at"),
  222. ).LeftJoin(
  223. ownerq,
  224. sqlchemy.Equals(
  225. ownerq.Field("id"),
  226. baseq.Field("loadbalancer_id"),
  227. ),
  228. )
  229. }
  230. return retq
  231. }
  232. func (manager *SElasticipManager) usedAddressQuery(ctx context.Context, args *usedAddressQueryArgs) *sqlchemy.SQuery {
  233. var (
  234. baseq = ElasticipManager.Query().Equals("network_id", args.network.Id).SubQuery()
  235. retq *sqlchemy.SQuery
  236. )
  237. if args.addrOnly {
  238. retq = baseq.Query(
  239. baseq.Field("ip_addr"),
  240. )
  241. } else {
  242. ownerq := ElasticipManager.FilterByOwner(ctx, ElasticipManager.Query().Equals("network_id", args.network.Id), ElasticipManager, args.userCred, args.owner, args.scope).SubQuery()
  243. retq = baseq.Query(
  244. baseq.Field("ip_addr"),
  245. sqlchemy.NewStringField("").Label("mac_addr"),
  246. sqlchemy.NewStringField(ElasticipManager.KeywordPlural()).Label("owner_type"),
  247. ownerq.Field("id").Label("owner_id"),
  248. ownerq.Field("status").Label("owner_status"),
  249. ownerq.Field("name").Label("owner"),
  250. ownerq.Field("associate_id"),
  251. ownerq.Field("associate_type"),
  252. baseq.Field("created_at"),
  253. ).LeftJoin(
  254. ownerq,
  255. sqlchemy.Equals(
  256. baseq.Field("id"),
  257. ownerq.Field("id"),
  258. ),
  259. )
  260. }
  261. return retq
  262. }
  263. func (manager *SNetworkinterfacenetworkManager) usedAddressQuery(ctx context.Context, args *usedAddressQueryArgs) *sqlchemy.SQuery {
  264. var (
  265. baseq = NetworkinterfacenetworkManager.Query().Equals("network_id", args.network.Id).SubQuery()
  266. retq *sqlchemy.SQuery
  267. )
  268. if args.addrOnly {
  269. retq = baseq.Query(
  270. baseq.Field("ip_addr"),
  271. )
  272. } else {
  273. ownerq := NetworkInterfaceManager.FilterByOwner(ctx, NetworkInterfaceManager.Query(), NetworkInterfaceManager, args.userCred, args.owner, args.scope).SubQuery()
  274. retq = baseq.Query(
  275. baseq.Field("ip_addr"),
  276. ownerq.Field("mac").Label("mac_addr"),
  277. sqlchemy.NewStringField(NetworkInterfaceManager.KeywordPlural()).Label("owner_type"),
  278. ownerq.Field("id").Label("owner_id"),
  279. ownerq.Field("status").Label("owner_status"),
  280. ownerq.Field("name").Label("owner"),
  281. ownerq.Field("associate_id"),
  282. ownerq.Field("associate_type"),
  283. baseq.Field("created_at"),
  284. ).LeftJoin(
  285. ownerq,
  286. sqlchemy.Equals(
  287. baseq.Field("networkinterface_id"),
  288. ownerq.Field("id"),
  289. ),
  290. )
  291. }
  292. return retq
  293. }
  294. func (manager *SDBInstanceManager) usedAddressQuery(ctx context.Context, args *usedAddressQueryArgs) *sqlchemy.SQuery {
  295. var (
  296. baseq = DBInstanceNetworkManager.Query().Equals("network_id", args.network.Id).SubQuery()
  297. retq *sqlchemy.SQuery
  298. )
  299. if args.addrOnly {
  300. retq = baseq.Query(
  301. baseq.Field("ip_addr"),
  302. )
  303. } else {
  304. ownerq := DBInstanceManager.FilterByOwner(ctx, DBInstanceManager.Query(), DBInstanceManager, args.userCred, args.owner, args.scope).SubQuery()
  305. retq = baseq.Query(
  306. baseq.Field("ip_addr"),
  307. sqlchemy.NewStringField("").Label("mac_addr"),
  308. sqlchemy.NewStringField(DBInstanceManager.KeywordPlural()).Label("owner_type"),
  309. ownerq.Field("id").Label("owner_id"),
  310. ownerq.Field("status").Label("owner_status"),
  311. ownerq.Field("name").Label("owner"),
  312. sqlchemy.NewStringField("").Label("associate_id"),
  313. sqlchemy.NewStringField("").Label("associate_type"),
  314. baseq.Field("created_at"),
  315. ).LeftJoin(
  316. ownerq,
  317. sqlchemy.Equals(
  318. ownerq.Field("id"),
  319. baseq.Field("dbinstance_id"),
  320. ),
  321. )
  322. }
  323. return retq
  324. }
  325. func (manager *SNetworkAddressManager) usedAddressQuery(ctx context.Context, args *usedAddressQueryArgs) *sqlchemy.SQuery {
  326. var (
  327. retq *sqlchemy.SQuery
  328. )
  329. if args.addrOnly {
  330. baseq := NetworkAddressManager.Query().Equals("network_id", args.network.Id).SubQuery()
  331. retq = baseq.Query(
  332. baseq.Field("ip_addr"),
  333. )
  334. } else {
  335. baseq := NetworkAddressManager.Query().Equals("parent_type", api.NetworkAddressParentTypeGuestnetwork).Equals("network_id", args.network.Id).SubQuery()
  336. guestNetworks := GuestnetworkManager.Query().SubQuery()
  337. guests := GuestManager.Query().SubQuery()
  338. retq = baseq.Query(
  339. baseq.Field("ip_addr"),
  340. guestNetworks.Field("mac_addr").Label("mac_addr"),
  341. sqlchemy.NewStringField(NetworkAddressManager.KeywordPlural()).Label("owner_type"),
  342. baseq.Field("id").Label("owner_id"),
  343. sqlchemy.NewStringField("available").Label("owner_status"),
  344. guests.Field("name").Label("owner"),
  345. baseq.Field("parent_id").Label("associate_id"),
  346. baseq.Field("parent_type").Label("associate_type"),
  347. baseq.Field("created_at"),
  348. ).Join(guestNetworks, sqlchemy.Equals(guestNetworks.Field("row_id"), baseq.Field("parent_id"))).Join(guests, sqlchemy.Equals(guests.Field("id"), guestNetworks.Field("guest_id")))
  349. retq = NetworkAddressManager.FilterByOwner(ctx, retq, NetworkAddressManager, args.userCred, args.owner, args.scope)
  350. }
  351. return retq
  352. }