wires.go 65 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018
  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. "database/sql"
  18. "fmt"
  19. "yunion.io/x/cloudmux/pkg/cloudprovider"
  20. "yunion.io/x/jsonutils"
  21. "yunion.io/x/log"
  22. "yunion.io/x/pkg/errors"
  23. "yunion.io/x/pkg/gotypes"
  24. "yunion.io/x/pkg/tristate"
  25. "yunion.io/x/pkg/util/compare"
  26. "yunion.io/x/pkg/util/netutils"
  27. "yunion.io/x/pkg/util/rbacscope"
  28. "yunion.io/x/pkg/util/sets"
  29. "yunion.io/x/pkg/utils"
  30. "yunion.io/x/sqlchemy"
  31. "yunion.io/x/onecloud/pkg/apis"
  32. api "yunion.io/x/onecloud/pkg/apis/compute"
  33. identityapi "yunion.io/x/onecloud/pkg/apis/identity"
  34. "yunion.io/x/onecloud/pkg/cloudcommon/db"
  35. "yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
  36. "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
  37. "yunion.io/x/onecloud/pkg/cloudcommon/validators"
  38. "yunion.io/x/onecloud/pkg/httperrors"
  39. "yunion.io/x/onecloud/pkg/mcclient"
  40. "yunion.io/x/onecloud/pkg/mcclient/auth"
  41. "yunion.io/x/onecloud/pkg/util/logclient"
  42. "yunion.io/x/onecloud/pkg/util/rbacutils"
  43. "yunion.io/x/onecloud/pkg/util/stringutils2"
  44. )
  45. type SWireManager struct {
  46. db.SStatusInfrasResourceBaseManager
  47. db.SExternalizedResourceBaseManager
  48. SManagedResourceBaseManager
  49. SVpcResourceBaseManager
  50. SZoneResourceBaseManager
  51. }
  52. var WireManager *SWireManager
  53. func init() {
  54. WireManager = &SWireManager{
  55. SStatusInfrasResourceBaseManager: db.NewStatusInfrasResourceBaseManager(
  56. SWire{},
  57. "wires_tbl",
  58. "wire",
  59. "wires",
  60. ),
  61. }
  62. WireManager.SetVirtualObject(WireManager)
  63. }
  64. type SWire struct {
  65. db.SStatusInfrasResourceBase
  66. db.SExternalizedResourceBase
  67. SManagedResourceBase
  68. SVpcResourceBase `wdith:"36" charset:"ascii" nullable:"false" list:"domain" create:"domain_required" update:""`
  69. SZoneResourceBase `width:"36" charset:"ascii" nullable:"true" list:"domain" create:"domain_required" update:""`
  70. // 带宽大小, 单位Mbps
  71. // example: 1000
  72. Bandwidth int `list:"domain" update:"domain" nullable:"false" create:"domain_required" json:"bandwidth"`
  73. // MTU
  74. // example: 1500
  75. Mtu int `list:"domain" update:"domain" nullable:"false" create:"domain_optional" default:"1500" json:"mtu"`
  76. // swagger:ignore
  77. ScheduleRank int `list:"domain" update:"domain" json:"schedule_rank"`
  78. // 可用区Id
  79. // ZoneId string `width:"36" charset:"ascii" nullable:"true" list:"domain" create:"domain_required"`
  80. // VPC Id
  81. // VpcId string `wdith:"36" charset:"ascii" nullable:"false" list:"domain" create:"domain_required"`
  82. }
  83. func (manager *SWireManager) GetContextManagers() [][]db.IModelManager {
  84. return [][]db.IModelManager{
  85. {ZoneManager},
  86. {VpcManager},
  87. }
  88. }
  89. func (manager *SWireManager) ValidateCreateData(
  90. ctx context.Context,
  91. userCred mcclient.TokenCredential,
  92. ownerId mcclient.IIdentityProvider,
  93. query jsonutils.JSONObject,
  94. input api.WireCreateInput,
  95. ) (api.WireCreateInput, error) {
  96. var err error
  97. if input.Bandwidth < 0 {
  98. return input, httperrors.NewOutOfRangeError("bandwidth must be greater than 0")
  99. }
  100. if input.Mtu < 0 || input.Mtu > 1000000 {
  101. return input, httperrors.NewOutOfRangeError("mtu must be range of 0~1000000")
  102. }
  103. if input.VpcId == "" {
  104. input.VpcId = api.DEFAULT_VPC_ID
  105. }
  106. _vpc, err := validators.ValidateModel(ctx, userCred, VpcManager, &input.VpcId)
  107. if err != nil {
  108. return input, err
  109. }
  110. vpc := _vpc.(*SVpc)
  111. if len(vpc.ManagerId) > 0 {
  112. return input, httperrors.NewNotSupportedError("Currently only onpremise classic VPC supports creating wire")
  113. }
  114. if len(input.ZoneId) == 0 {
  115. return input, httperrors.NewMissingParameterError("zone")
  116. }
  117. _, input.ZoneResourceInput, err = ValidateZoneResourceInput(ctx, userCred, input.ZoneResourceInput)
  118. if err != nil {
  119. return input, errors.Wrap(err, "ValidateZoneResourceInput")
  120. }
  121. input.StatusInfrasResourceBaseCreateInput, err = manager.SStatusInfrasResourceBaseManager.ValidateCreateData(ctx, userCred, ownerId, query, input.StatusInfrasResourceBaseCreateInput)
  122. if err != nil {
  123. return input, err
  124. }
  125. return input, nil
  126. }
  127. func (wire *SWire) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.WireUpdateInput) (api.WireUpdateInput, error) {
  128. data := jsonutils.Marshal(input).(*jsonutils.JSONDict)
  129. keysV := []validators.IValidator{
  130. validators.NewNonNegativeValidator("bandwidth"),
  131. validators.NewRangeValidator("mtu", 1, 1000000).Optional(true),
  132. }
  133. for _, v := range keysV {
  134. v.Optional(true)
  135. if err := v.Validate(ctx, data); err != nil {
  136. return input, err
  137. }
  138. }
  139. var err error
  140. input.InfrasResourceBaseUpdateInput, err = wire.SInfrasResourceBase.ValidateUpdateData(ctx, userCred, query, input.InfrasResourceBaseUpdateInput)
  141. if err != nil {
  142. return input, errors.Wrap(err, "SInfrasResourceBase.ValidateUpdateData")
  143. }
  144. return input, nil
  145. }
  146. func (wire *SWire) ValidateDeleteCondition(ctx context.Context, info *api.WireDetails) error {
  147. if wire.Id == api.DEFAULT_HOST_LOCAL_WIRE_ID {
  148. return httperrors.NewProtectedResourceError("not allow to delete default host local wire")
  149. }
  150. if gotypes.IsNil(info) {
  151. info = &api.WireDetails{}
  152. usage, err := WireManager.TotalResourceCount([]string{wire.Id})
  153. if err != nil {
  154. return err
  155. }
  156. info.WireUsage, _ = usage[wire.Id]
  157. }
  158. if info.HostCount > 0 {
  159. return httperrors.NewNotEmptyError("wire contains hosts")
  160. }
  161. if info.Networks > 0 {
  162. return httperrors.NewNotEmptyError("wire contains networks")
  163. }
  164. return wire.SInfrasResourceBase.ValidateDeleteCondition(ctx, nil)
  165. }
  166. func (manager *SWireManager) getWireExternalIdForClassicNetwork(provider string, vpcId string, zoneId string) string {
  167. if !utils.IsInStringArray(provider, api.REGIONAL_NETWORK_PROVIDERS) {
  168. return fmt.Sprintf("%s-%s", vpcId, zoneId)
  169. }
  170. return vpcId
  171. }
  172. func (manager *SWireManager) GetOrCreateWireForClassicNetwork(ctx context.Context, vpc *SVpc, zone *SZone) (*SWire, error) {
  173. cloudprovider := vpc.GetCloudprovider()
  174. if cloudprovider == nil {
  175. return nil, fmt.Errorf("failed to found cloudprovider for vpc %s(%s)", vpc.Id, vpc.Id)
  176. }
  177. externalId := manager.getWireExternalIdForClassicNetwork(cloudprovider.Provider, vpc.Id, zone.Id)
  178. name := fmt.Sprintf("emulate for vpc %s classic network", vpc.Id)
  179. zoneId := zone.Id
  180. if utils.IsInStringArray(cloudprovider.Provider, api.REGIONAL_NETWORK_PROVIDERS) { //reginal network
  181. zoneId = ""
  182. } else {
  183. name = fmt.Sprintf("emulate for zone %s vpc %s classic network", zone.Name, vpc.Id)
  184. }
  185. _wire, err := db.FetchByExternalIdAndManagerId(manager, externalId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
  186. q = q.Equals("manager_id", vpc.ManagerId)
  187. return q
  188. })
  189. if err == nil {
  190. return _wire.(*SWire), nil
  191. }
  192. if errors.Cause(err) != sql.ErrNoRows {
  193. return nil, errors.Wrap(err, "db.FetchByExternalIdAndManagerId")
  194. }
  195. wire := &SWire{}
  196. wire.VpcId = vpc.Id
  197. wire.ZoneId = zoneId
  198. wire.SetModelManager(manager, wire)
  199. wire.ExternalId = externalId
  200. wire.IsEmulated = true
  201. wire.Name = name
  202. wire.ManagerId = vpc.ManagerId
  203. err = manager.TableSpec().Insert(ctx, wire)
  204. if err != nil {
  205. return nil, errors.Wrap(err, "Insert wire for classic network")
  206. }
  207. return wire, nil
  208. }
  209. func (wire *SWire) HostCount() (int, error) {
  210. q := NetInterfaceManager.Query().Equals("wire_id", wire.Id).GroupBy("baremetal_id")
  211. return q.CountWithError()
  212. }
  213. func (swire *SWire) GetHosts() ([]SHost, error) {
  214. sq := NetInterfaceManager.Query("baremetal_id").Equals("wire_id", swire.Id)
  215. q := HostManager.Query().In("id", sq)
  216. hosts := []SHost{}
  217. err := db.FetchModelObjects(HostManager, q, &hosts)
  218. if err != nil {
  219. return nil, errors.Wrapf(err, "db.FetchModelObjects")
  220. }
  221. return hosts, nil
  222. }
  223. func (wire *SWire) NetworkCount() (int, error) {
  224. q := NetworkManager.Query().Equals("wire_id", wire.Id)
  225. return q.CountWithError()
  226. }
  227. func (wire *SWire) GetVpcId() string {
  228. if len(wire.VpcId) == 0 {
  229. return "default"
  230. } else {
  231. return wire.VpcId
  232. }
  233. }
  234. func (manager *SWireManager) getWiresByVpcAndZone(vpc *SVpc, zone *SZone) ([]SWire, error) {
  235. return manager.getWiresByVpcZoneAndManager(vpc, zone, nil)
  236. }
  237. func (manager *SWireManager) getWiresByVpcZoneAndManager(vpc *SVpc, zone *SZone, provider *SCloudprovider) ([]SWire, error) {
  238. wires := make([]SWire, 0)
  239. q := manager.Query()
  240. if vpc != nil {
  241. q = q.Equals("vpc_id", vpc.Id)
  242. }
  243. if zone != nil {
  244. q = q.Equals("zone_id", zone.Id)
  245. }
  246. if provider != nil {
  247. q = q.Equals("manager_id", provider.Id)
  248. }
  249. err := db.FetchModelObjects(manager, q, &wires)
  250. if err != nil {
  251. return nil, err
  252. }
  253. return wires, nil
  254. }
  255. func (manager *SWireManager) SyncWires(
  256. ctx context.Context,
  257. userCred mcclient.TokenCredential,
  258. vpc *SVpc,
  259. wires []cloudprovider.ICloudWire,
  260. provider *SCloudprovider,
  261. xor bool,
  262. zone *SZone,
  263. ) ([]SWire, []cloudprovider.ICloudWire, compare.SyncResult) {
  264. lockman.LockRawObject(ctx, manager.Keyword(), vpc.Id)
  265. defer lockman.ReleaseRawObject(ctx, manager.Keyword(), vpc.Id)
  266. localWires := make([]SWire, 0)
  267. remoteWires := make([]cloudprovider.ICloudWire, 0)
  268. syncResult := compare.SyncResult{}
  269. dbWires, err := manager.getWiresByVpcZoneAndManager(vpc, zone, provider)
  270. if err != nil {
  271. syncResult.Error(err)
  272. return nil, nil, syncResult
  273. }
  274. for i := range dbWires {
  275. if taskman.TaskManager.IsInTask(&dbWires[i]) {
  276. syncResult.Error(fmt.Errorf("object in task"))
  277. return nil, nil, syncResult
  278. }
  279. }
  280. removed := make([]SWire, 0)
  281. commondb := make([]SWire, 0)
  282. commonext := make([]cloudprovider.ICloudWire, 0)
  283. added := make([]cloudprovider.ICloudWire, 0)
  284. err = compare.CompareSets(dbWires, wires, &removed, &commondb, &commonext, &added)
  285. if err != nil {
  286. syncResult.Error(err)
  287. return nil, nil, syncResult
  288. }
  289. for i := 0; i < len(removed); i += 1 {
  290. err = removed[i].syncRemoveCloudWire(ctx, userCred)
  291. if err != nil { // cannot delete
  292. syncResult.DeleteError(err)
  293. } else {
  294. syncResult.Delete()
  295. }
  296. }
  297. for i := 0; i < len(commondb); i += 1 {
  298. if !xor {
  299. err = commondb[i].syncWithCloudWire(ctx, userCred, commonext[i], vpc, provider, zone)
  300. if err != nil {
  301. syncResult.UpdateError(err)
  302. }
  303. syncResult.Update()
  304. }
  305. localWires = append(localWires, commondb[i])
  306. remoteWires = append(remoteWires, commonext[i])
  307. }
  308. for i := 0; i < len(added); i += 1 {
  309. wire, err := manager.newFromCloudWire(ctx, userCred, added[i], vpc, provider, zone)
  310. if err != nil {
  311. syncResult.AddError(err)
  312. continue
  313. }
  314. localWires = append(localWires, *wire)
  315. remoteWires = append(remoteWires, added[i])
  316. syncResult.Add()
  317. }
  318. return localWires, remoteWires, syncResult
  319. }
  320. func (swire *SWire) syncRemoveCloudWire(ctx context.Context, userCred mcclient.TokenCredential) error {
  321. lockman.LockObject(ctx, swire)
  322. defer lockman.ReleaseObject(ctx, swire)
  323. vpc, _ := swire.GetVpc()
  324. cloudprovider := vpc.GetCloudprovider()
  325. if cloudprovider == nil || swire.ExternalId == WireManager.getWireExternalIdForClassicNetwork(cloudprovider.Provider, swire.VpcId, swire.ZoneId) {
  326. return nil
  327. }
  328. err := swire.ValidateDeleteCondition(ctx, nil)
  329. if err != nil { // cannot delete
  330. err = swire.markNetworkUnknown(ctx, userCred)
  331. } else {
  332. err = swire.Delete(ctx, userCred)
  333. }
  334. return err
  335. }
  336. func (swire *SWire) syncWithCloudWire(ctx context.Context, userCred mcclient.TokenCredential, extWire cloudprovider.ICloudWire, vpc *SVpc, provider *SCloudprovider, zone *SZone) error {
  337. diff, err := db.UpdateWithLock(ctx, swire, func() error {
  338. // swire.Name = extWire.GetName()
  339. swire.Bandwidth = extWire.GetBandwidth() // 10G
  340. swire.IsEmulated = extWire.IsEmulated()
  341. swire.Status = extWire.GetStatus()
  342. if len(swire.Description) == 0 {
  343. swire.Description = extWire.GetDescription()
  344. }
  345. swire.ManagerId = provider.Id
  346. if zone != nil {
  347. swire.ZoneId = zone.Id
  348. } else {
  349. vpc, _ := swire.GetVpc()
  350. if vpc != nil {
  351. region, err := vpc.GetRegion()
  352. if err != nil {
  353. return errors.Wrapf(err, "vpc.GetRegion")
  354. }
  355. if utils.IsInStringArray(region.Provider, api.REGIONAL_NETWORK_PROVIDERS) {
  356. swire.ZoneId = ""
  357. }
  358. }
  359. }
  360. if swire.IsEmulated {
  361. swire.DomainId = vpc.DomainId
  362. // swire.IsPublic = vpc.IsPublic
  363. // swire.PublicScope = vpc.PublicScope
  364. // swire.PublicSrc = vpc.PublicSrc
  365. }
  366. return nil
  367. })
  368. if err != nil {
  369. log.Errorf("syncWithCloudWire error %s", err)
  370. }
  371. if provider != nil && !swire.IsEmulated {
  372. SyncCloudDomain(userCred, swire, provider.GetOwnerId())
  373. swire.SyncShareState(ctx, userCred, provider.getAccountShareInfo())
  374. } else if swire.IsEmulated {
  375. swire.SaveSharedInfo(apis.TOwnerSource(vpc.PublicSrc), ctx, userCred, vpc.GetSharedInfo())
  376. }
  377. syncMetadata(ctx, userCred, swire, extWire, false)
  378. db.OpsLog.LogSyncUpdate(swire, diff, userCred)
  379. return err
  380. }
  381. func (swire *SWire) markNetworkUnknown(ctx context.Context, userCred mcclient.TokenCredential) error {
  382. nets, err := swire.getNetworks(ctx, nil, nil, rbacscope.ScopeNone)
  383. if err != nil {
  384. return err
  385. }
  386. for i := 0; i < len(nets); i += 1 {
  387. nets[i].SetStatus(ctx, userCred, api.NETWORK_STATUS_UNKNOWN, "wire sync to remove")
  388. }
  389. return nil
  390. }
  391. func (manager *SWireManager) newFromCloudWire(ctx context.Context, userCred mcclient.TokenCredential, extWire cloudprovider.ICloudWire, vpc *SVpc, provider *SCloudprovider, zone *SZone) (*SWire, error) {
  392. wire := SWire{}
  393. wire.SetModelManager(manager, &wire)
  394. wire.ExternalId = extWire.GetGlobalId()
  395. wire.Bandwidth = extWire.GetBandwidth()
  396. wire.Status = extWire.GetStatus()
  397. wire.Description = extWire.GetDescription()
  398. wire.VpcId = vpc.Id
  399. wire.ManagerId = provider.Id
  400. var err error
  401. wire.ZoneId, err = func() (string, error) {
  402. if zone != nil {
  403. return zone.Id, nil
  404. }
  405. izone := extWire.GetIZone()
  406. if gotypes.IsNil(izone) {
  407. return "", nil
  408. }
  409. zone, err := vpc.getZoneByExternalId(izone.GetGlobalId())
  410. if err != nil {
  411. return "", errors.Wrapf(err, "getZoneByExternalId")
  412. }
  413. return zone.Id, nil
  414. }()
  415. if err != nil {
  416. return nil, errors.Wrapf(err, "get zone id")
  417. }
  418. wire.IsEmulated = extWire.IsEmulated()
  419. wire.DomainId = vpc.DomainId
  420. wire.IsPublic = vpc.IsPublic
  421. wire.PublicScope = vpc.PublicScope
  422. wire.PublicSrc = vpc.PublicSrc
  423. err = func() error {
  424. lockman.LockRawObject(ctx, manager.Keyword(), "name")
  425. defer lockman.ReleaseRawObject(ctx, manager.Keyword(), "name")
  426. newName, err := db.GenerateName(ctx, manager, userCred, extWire.GetName())
  427. if err != nil {
  428. return err
  429. }
  430. wire.Name = newName
  431. return manager.TableSpec().Insert(ctx, &wire)
  432. }()
  433. if err != nil {
  434. return nil, errors.Wrapf(err, "Insert")
  435. }
  436. if provider != nil && !wire.IsEmulated {
  437. SyncCloudDomain(userCred, &wire, provider.GetOwnerId())
  438. wire.SyncShareState(ctx, userCred, provider.getAccountShareInfo())
  439. }
  440. syncMetadata(ctx, userCred, &wire, extWire, false)
  441. db.OpsLog.LogEvent(&wire, db.ACT_CREATE, wire.GetShortDesc(ctx), userCred)
  442. return &wire, nil
  443. }
  444. func filterByScopeOwnerId(q *sqlchemy.SQuery, scope rbacscope.TRbacScope, ownerId mcclient.IIdentityProvider, domainResource bool) *sqlchemy.SQuery {
  445. switch scope {
  446. case rbacscope.ScopeSystem:
  447. case rbacscope.ScopeDomain:
  448. q = q.Equals("domain_id", ownerId.GetProjectDomainId())
  449. case rbacscope.ScopeProject:
  450. if domainResource {
  451. q = q.Equals("domain_id", ownerId.GetProjectId())
  452. } else {
  453. q = q.Equals("tenant_id", ownerId.GetProjectId())
  454. }
  455. }
  456. return q
  457. }
  458. func fixVmwareProvider(providers []string) (bool, []string) {
  459. findVmware := false
  460. findOnecloud := false
  461. newp := make([]string, 0)
  462. for _, p := range providers {
  463. if p == api.CLOUD_PROVIDER_VMWARE {
  464. findVmware = true
  465. } else {
  466. if p == api.CLOUD_PROVIDER_ONECLOUD {
  467. findOnecloud = true
  468. }
  469. newp = append(newp, p)
  470. }
  471. }
  472. if findVmware && !findOnecloud {
  473. newp = append(newp, api.CLOUD_PROVIDER_ONECLOUD)
  474. }
  475. return findVmware, newp
  476. }
  477. func (manager *SWireManager) totalCountQ(
  478. ctx context.Context,
  479. rangeObjs []db.IStandaloneModel,
  480. hostTypes []string, hostProviders, hostBrands []string,
  481. providers []string, brands []string, cloudEnv string,
  482. scope rbacscope.TRbacScope,
  483. ownerId mcclient.IIdentityProvider,
  484. policyResult rbacutils.SPolicyResult,
  485. ) *sqlchemy.SQuery {
  486. guestsQ := GuestManager.Query()
  487. guestsQ = filterByScopeOwnerId(guestsQ, scope, ownerId, false)
  488. guestsQ = db.ObjectIdQueryWithPolicyResult(ctx, guestsQ, GuestManager, policyResult)
  489. guests := guestsQ.SubQuery()
  490. // hosts no filter, for guest networks
  491. hostsQ := HostManager.Query()
  492. if len(hostTypes) > 0 {
  493. hostsQ = hostsQ.In("host_type", hostTypes)
  494. }
  495. if len(hostProviders) > 0 || len(hostBrands) > 0 || len(cloudEnv) > 0 {
  496. hostsQ = CloudProviderFilter(hostsQ, hostsQ.Field("manager_id"), providers, brands, cloudEnv)
  497. }
  498. if len(rangeObjs) > 0 {
  499. hostsQ = RangeObjectsFilter(hostsQ, rangeObjs, nil, hostsQ.Field("zone_id"), hostsQ.Field("manager_id"), hostsQ.Field("id"), nil)
  500. }
  501. hosts := hostsQ.SubQuery()
  502. // hosts filter by owner, for host networks
  503. hostsQ2 := HostManager.Query()
  504. hostsQ2 = db.ObjectIdQueryWithPolicyResult(ctx, hostsQ2, HostManager, policyResult)
  505. hostsQ2 = filterByScopeOwnerId(hostsQ2, scope, ownerId, true)
  506. if len(hostTypes) > 0 {
  507. hostsQ2 = hostsQ2.In("host_type", hostTypes)
  508. }
  509. if len(hostProviders) > 0 || len(hostBrands) > 0 || len(cloudEnv) > 0 {
  510. hostsQ2 = CloudProviderFilter(hostsQ2, hostsQ2.Field("manager_id"), providers, brands, cloudEnv)
  511. }
  512. if len(rangeObjs) > 0 {
  513. hostsQ2 = RangeObjectsFilter(hostsQ2, rangeObjs, nil, hostsQ2.Field("zone_id"), hostsQ2.Field("manager_id"), hostsQ2.Field("id"), nil)
  514. }
  515. hosts2 := hostsQ2.SubQuery()
  516. groupsQ := GroupManager.Query()
  517. groupsQ = db.ObjectIdQueryWithPolicyResult(ctx, groupsQ, GroupManager, policyResult)
  518. groupsQ = filterByScopeOwnerId(groupsQ, scope, ownerId, false)
  519. groups := groupsQ.SubQuery()
  520. lbsQ := LoadbalancerManager.Query()
  521. lbsQ = db.ObjectIdQueryWithPolicyResult(ctx, lbsQ, LoadbalancerManager, policyResult)
  522. lbsQ = filterByScopeOwnerId(lbsQ, scope, ownerId, false)
  523. if len(providers) > 0 || len(brands) > 0 || len(cloudEnv) > 0 {
  524. lbsQ = CloudProviderFilter(lbsQ, lbsQ.Field("manager_id"), providers, brands, cloudEnv)
  525. }
  526. if len(rangeObjs) > 0 {
  527. lbsQ = RangeObjectsFilter(lbsQ, rangeObjs, lbsQ.Field("cloudregion_id"), lbsQ.Field("zone_id"), lbsQ.Field("manager_id"), nil, nil)
  528. }
  529. lbs := lbsQ.SubQuery()
  530. dbsQ := DBInstanceManager.Query()
  531. dbsQ = db.ObjectIdQueryWithPolicyResult(ctx, dbsQ, DBInstanceManager, policyResult)
  532. dbsQ = filterByScopeOwnerId(dbsQ, scope, ownerId, false)
  533. if len(providers) > 0 || len(brands) > 0 || len(cloudEnv) > 0 {
  534. dbsQ = CloudProviderFilter(dbsQ, dbsQ.Field("manager_id"), providers, brands, cloudEnv)
  535. }
  536. if len(rangeObjs) > 0 {
  537. dbsQ = RangeObjectsFilter(dbsQ, rangeObjs, dbsQ.Field("cloudregion_id"), dbsQ.Field("zone1"), dbsQ.Field("manager_id"), nil, nil)
  538. }
  539. dbs := dbsQ.SubQuery()
  540. var (
  541. gNicSQ *sqlchemy.SSubQuery
  542. gNicSQ4 *sqlchemy.SSubQuery
  543. gNicSQ6 *sqlchemy.SSubQuery
  544. hNicSQ *sqlchemy.SSubQuery
  545. grpNicSQ *sqlchemy.SSubQuery
  546. lbNicSQ *sqlchemy.SSubQuery
  547. eipNicSQ *sqlchemy.SSubQuery
  548. netifNicSQ *sqlchemy.SSubQuery
  549. dbNicSQ *sqlchemy.SSubQuery
  550. )
  551. {
  552. gNics := GuestnetworkManager.Query().SubQuery()
  553. gNicQ := gNics.Query(
  554. gNics.Field("network_id"),
  555. sqlchemy.COUNT("gnic_count"),
  556. sqlchemy.SUM("pending_deleted_gnic_count", guests.Field("pending_deleted")),
  557. )
  558. gNicQ = gNicQ.Join(guests, sqlchemy.Equals(guests.Field("id"), gNics.Field("guest_id")))
  559. gNicQ = gNicQ.Join(hosts, sqlchemy.Equals(guests.Field("host_id"), hosts.Field("id")))
  560. gNicQ = gNicQ.Filter(sqlchemy.IsTrue(hosts.Field("enabled")))
  561. gNicSQ = gNicQ.GroupBy(gNics.Field("network_id")).SubQuery()
  562. }
  563. {
  564. gNics := GuestnetworkManager.Query().IsNotEmpty("ip_addr").SubQuery()
  565. gNicQ := gNics.Query(
  566. gNics.Field("network_id"),
  567. sqlchemy.COUNT("gnic_count4"),
  568. )
  569. gNicQ = gNicQ.Join(guests, sqlchemy.Equals(guests.Field("id"), gNics.Field("guest_id")))
  570. gNicQ = gNicQ.Join(hosts, sqlchemy.Equals(guests.Field("host_id"), hosts.Field("id")))
  571. gNicQ = gNicQ.Filter(sqlchemy.IsTrue(hosts.Field("enabled")))
  572. gNicSQ4 = gNicQ.GroupBy(gNics.Field("network_id")).SubQuery()
  573. }
  574. {
  575. gNics := GuestnetworkManager.Query().IsNotEmpty("ip6_addr").SubQuery()
  576. gNicQ := gNics.Query(
  577. gNics.Field("network_id"),
  578. sqlchemy.COUNT("gnic_count6"),
  579. )
  580. gNicQ = gNicQ.Join(guests, sqlchemy.Equals(guests.Field("id"), gNics.Field("guest_id")))
  581. gNicQ = gNicQ.Join(hosts, sqlchemy.Equals(guests.Field("host_id"), hosts.Field("id")))
  582. gNicQ = gNicQ.Filter(sqlchemy.IsTrue(hosts.Field("enabled")))
  583. gNicSQ6 = gNicQ.GroupBy(gNics.Field("network_id")).SubQuery()
  584. }
  585. {
  586. hNics := HostnetworkManager.Query().SubQuery()
  587. hNicQ := hNics.Query(
  588. hNics.Field("network_id"),
  589. sqlchemy.COUNT("hnic_count"),
  590. )
  591. hNicQ = hNicQ.Join(hosts2, sqlchemy.Equals(hNics.Field("baremetal_id"), hosts2.Field("id")))
  592. hNicQ = hNicQ.Filter(sqlchemy.IsTrue(hosts2.Field("enabled")))
  593. hNicSQ = hNicQ.GroupBy(hNics.Field("network_id")).SubQuery()
  594. }
  595. {
  596. groupNics := GroupnetworkManager.Query().SubQuery()
  597. grpNicQ := groupNics.Query(
  598. groupNics.Field("network_id"),
  599. sqlchemy.COUNT("grpnic_count"),
  600. )
  601. grpNicQ = grpNicQ.Join(groups, sqlchemy.Equals(groups.Field("id"), groupNics.Field("group_id")))
  602. grpNicSQ = grpNicQ.GroupBy(groupNics.Field("network_id")).SubQuery()
  603. }
  604. {
  605. lbNics := LoadbalancernetworkManager.Query().SubQuery()
  606. lbNicQ := lbNics.Query(
  607. lbNics.Field("network_id"),
  608. sqlchemy.COUNT("lbnic_count"),
  609. )
  610. lbNicQ = lbNicQ.Join(lbs, sqlchemy.Equals(lbs.Field("id"), lbNics.Field("loadbalancer_id")))
  611. lbNicQ = lbNicQ.Filter(sqlchemy.IsFalse(lbs.Field("pending_deleted")))
  612. lbNicSQ = lbNicQ.GroupBy(lbNics.Field("network_id")).SubQuery()
  613. }
  614. {
  615. eipNicsQ := ElasticipManager.Query().IsNotEmpty("network_id")
  616. eipNicsQ = db.ObjectIdQueryWithPolicyResult(ctx, eipNicsQ, ElasticipManager, policyResult)
  617. eipNics := filterByScopeOwnerId(eipNicsQ, scope, ownerId, false).SubQuery()
  618. eipNicQ := eipNics.Query(
  619. eipNics.Field("network_id"),
  620. sqlchemy.COUNT("eipnic_count"),
  621. )
  622. if len(providers) > 0 || len(brands) > 0 || len(cloudEnv) > 0 {
  623. eipNicQ = CloudProviderFilter(eipNicQ, eipNicQ.Field("manager_id"), providers, brands, cloudEnv)
  624. }
  625. if len(rangeObjs) > 0 {
  626. eipNicQ = RangeObjectsFilter(eipNicQ, rangeObjs, eipNicQ.Field("cloudregion_id"), nil, eipNicQ.Field("manager_id"), nil, nil)
  627. }
  628. eipNicSQ = eipNicQ.GroupBy(eipNics.Field("network_id")).SubQuery()
  629. }
  630. {
  631. netifsQ := NetworkInterfaceManager.Query()
  632. netifsQ = db.ObjectIdQueryWithPolicyResult(ctx, netifsQ, NetworkInterfaceManager, policyResult)
  633. netifsQ = filterByScopeOwnerId(netifsQ, scope, ownerId, true)
  634. if len(providers) > 0 || len(brands) > 0 || len(cloudEnv) > 0 {
  635. netifsQ = CloudProviderFilter(netifsQ, netifsQ.Field("manager_id"), providers, brands, cloudEnv)
  636. }
  637. if len(rangeObjs) > 0 {
  638. netifsQ = RangeObjectsFilter(netifsQ, rangeObjs, netifsQ.Field("cloudregion_id"), nil, netifsQ.Field("manager_id"), nil, nil)
  639. }
  640. netifs := netifsQ.SubQuery()
  641. netifNics := NetworkinterfacenetworkManager.Query().SubQuery()
  642. netifNicQ := netifNics.Query(
  643. netifNics.Field("network_id"),
  644. sqlchemy.COUNT("netifnic_count"),
  645. )
  646. netifNicQ = netifNicQ.Join(netifs, sqlchemy.Equals(netifNics.Field("networkinterface_id"), netifs.Field("id")))
  647. netifNicSQ = netifNicQ.GroupBy(netifNics.Field("network_id")).SubQuery()
  648. }
  649. {
  650. dbNics := DBInstanceNetworkManager.Query().SubQuery()
  651. dbNicQ := dbNics.Query(
  652. dbNics.Field("network_id"),
  653. sqlchemy.COUNT("dbnic_count"),
  654. )
  655. dbNicQ = dbNicQ.Join(dbs, sqlchemy.Equals(dbs.Field("id"), dbNics.Field("dbinstance_id")))
  656. dbNicQ = dbNicQ.Filter(sqlchemy.IsFalse(dbs.Field("pending_deleted")))
  657. dbNicSQ = dbNicQ.GroupBy(dbNics.Field("network_id")).SubQuery()
  658. }
  659. networks := NetworkManager.Query().SubQuery()
  660. netQ := networks.Query(
  661. sqlchemy.SUM("guest_nic_count", gNicSQ.Field("gnic_count")),
  662. sqlchemy.SUM("pending_deleted_guest_nic_count", gNicSQ.Field("pending_deleted_gnic_count")),
  663. sqlchemy.SUM("host_nic_count", hNicSQ.Field("hnic_count")),
  664. sqlchemy.SUM("guest_nic_count4", gNicSQ4.Field("gnic_count4")),
  665. sqlchemy.SUM("guest_nic_count6", gNicSQ6.Field("gnic_count6")),
  666. sqlchemy.SUM("group_nic_count", grpNicSQ.Field("grpnic_count")),
  667. sqlchemy.SUM("lb_nic_count", lbNicSQ.Field("lbnic_count")),
  668. sqlchemy.SUM("eip_nic_count", eipNicSQ.Field("eipnic_count")),
  669. sqlchemy.SUM("netif_nic_count", netifNicSQ.Field("netifnic_count")),
  670. sqlchemy.SUM("db_nic_count", dbNicSQ.Field("dbnic_count")),
  671. )
  672. netQ = netQ.LeftJoin(gNicSQ, sqlchemy.Equals(gNicSQ.Field("network_id"), networks.Field("id")))
  673. netQ = netQ.LeftJoin(gNicSQ4, sqlchemy.Equals(gNicSQ4.Field("network_id"), networks.Field("id")))
  674. netQ = netQ.LeftJoin(gNicSQ6, sqlchemy.Equals(gNicSQ6.Field("network_id"), networks.Field("id")))
  675. netQ = netQ.LeftJoin(hNicSQ, sqlchemy.Equals(hNicSQ.Field("network_id"), networks.Field("id")))
  676. netQ = netQ.LeftJoin(grpNicSQ, sqlchemy.Equals(grpNicSQ.Field("network_id"), networks.Field("id")))
  677. netQ = netQ.LeftJoin(lbNicSQ, sqlchemy.Equals(lbNicSQ.Field("network_id"), networks.Field("id")))
  678. netQ = netQ.LeftJoin(eipNicSQ, sqlchemy.Equals(eipNicSQ.Field("network_id"), networks.Field("id")))
  679. netQ = netQ.LeftJoin(netifNicSQ, sqlchemy.Equals(netifNicSQ.Field("network_id"), networks.Field("id")))
  680. netQ = netQ.LeftJoin(dbNicSQ, sqlchemy.Equals(dbNicSQ.Field("network_id"), networks.Field("id")))
  681. return netQ
  682. }
  683. func (manager *SWireManager) totalCountQ2(
  684. ctx context.Context,
  685. rangeObjs []db.IStandaloneModel,
  686. hostTypes []string,
  687. providers []string, brands []string, cloudEnv string,
  688. scope rbacscope.TRbacScope,
  689. ownerId mcclient.IIdentityProvider,
  690. policyResult rbacutils.SPolicyResult,
  691. ) *sqlchemy.SQuery {
  692. var revSQ *sqlchemy.SSubQuery
  693. var revSQ6 *sqlchemy.SSubQuery
  694. {
  695. revIps := filterExpiredReservedIp4s(ReservedipManager.Query()).SubQuery()
  696. revQ := revIps.Query(
  697. revIps.Field("network_id"),
  698. sqlchemy.COUNT("rnic_count"),
  699. )
  700. revSQ = revQ.GroupBy(revIps.Field("network_id")).SubQuery()
  701. }
  702. {
  703. revIps := filterExpiredReservedIp6s(ReservedipManager.Query()).SubQuery()
  704. revQ := revIps.Query(
  705. revIps.Field("network_id"),
  706. sqlchemy.COUNT("rnic_count6"),
  707. )
  708. revSQ6 = revQ.GroupBy(revIps.Field("network_id")).SubQuery()
  709. }
  710. ownerNetQ1 := NetworkManager.Query()
  711. ownerNetQ1 = db.ObjectIdQueryWithPolicyResult(ctx, ownerNetQ1, NetworkManager, policyResult)
  712. ownerNetworks := filterByScopeOwnerId(ownerNetQ1, scope, ownerId, false).SubQuery()
  713. ownerNetQ := ownerNetworks.Query(
  714. ownerNetworks.Field("wire_id"),
  715. sqlchemy.COUNT("id").Label("net_count"),
  716. sqlchemy.SUM("rev_count", revSQ.Field("rnic_count")),
  717. sqlchemy.SUM("rev_count6", revSQ6.Field("rnic_count6")),
  718. )
  719. ownerNetQ = ownerNetQ.LeftJoin(revSQ, sqlchemy.Equals(revSQ.Field("network_id"), ownerNetworks.Field("id")))
  720. ownerNetQ = ownerNetQ.LeftJoin(revSQ6, sqlchemy.Equals(revSQ6.Field("network_id"), ownerNetworks.Field("id")))
  721. ownerNetQ = ownerNetQ.GroupBy(ownerNetworks.Field("wire_id"))
  722. ownerNetSQ := ownerNetQ.SubQuery()
  723. wires := WireManager.Query().SubQuery()
  724. q := wires.Query(
  725. sqlchemy.SUM("net_count", ownerNetSQ.Field("net_count")),
  726. sqlchemy.SUM("reserved_count", ownerNetSQ.Field("rev_count")),
  727. sqlchemy.SUM("reserved_count6", ownerNetSQ.Field("rev_count6")),
  728. )
  729. q = q.LeftJoin(ownerNetSQ, sqlchemy.Equals(wires.Field("id"), ownerNetSQ.Field("wire_id")))
  730. return filterWiresCountQuery(q, hostTypes, providers, brands, cloudEnv, rangeObjs)
  731. }
  732. func (manager *SWireManager) totalCountQ3(
  733. ctx context.Context,
  734. rangeObjs []db.IStandaloneModel,
  735. hostTypes []string,
  736. providers []string, brands []string, cloudEnv string,
  737. scope rbacscope.TRbacScope,
  738. ownerId mcclient.IIdentityProvider,
  739. policyResult rbacutils.SPolicyResult,
  740. ) *sqlchemy.SQuery {
  741. wiresQ := WireManager.Query()
  742. wiresQ = db.ObjectIdQueryWithPolicyResult(ctx, wiresQ, WireManager, policyResult)
  743. wires := filterByScopeOwnerId(WireManager.Query(), scope, ownerId, true).SubQuery()
  744. q := wires.Query(
  745. sqlchemy.COUNT("id").Label("wires_count"),
  746. sqlchemy.SUM("emulated_wires_count", wires.Field("is_emulated")),
  747. )
  748. return filterWiresCountQuery(q, hostTypes, providers, brands, cloudEnv, rangeObjs)
  749. }
  750. func filterWiresCountQuery(q *sqlchemy.SQuery, hostTypes, providers, brands []string, cloudEnv string, rangeObjs []db.IStandaloneModel) *sqlchemy.SQuery {
  751. if len(hostTypes) > 0 {
  752. hostwires := NetInterfaceManager.Query().SubQuery()
  753. hosts := HostManager.Query().SubQuery()
  754. hostWireQ := hostwires.Query(hostwires.Field("wire_id"))
  755. hostWireQ = hostWireQ.Join(hosts, sqlchemy.Equals(hostWireQ.Field("baremetal_id"), hosts.Field("id")))
  756. hostWireQ = hostWireQ.Filter(sqlchemy.In(hosts.Field("host_type"), hostTypes))
  757. hostWireQ = hostWireQ.GroupBy(hostwires.Field("wire_id"))
  758. hostWireSQ := hostWireQ.SubQuery()
  759. q = q.Join(hostWireSQ, sqlchemy.Equals(hostWireSQ.Field("wire_id"), q.Field("id")))
  760. }
  761. if len(rangeObjs) > 0 || len(providers) > 0 || len(brands) > 0 || len(cloudEnv) > 0 {
  762. vpcs := VpcManager.Query().SubQuery()
  763. q = q.Join(vpcs, sqlchemy.Equals(q.Field("vpc_id"), vpcs.Field("id")))
  764. q = CloudProviderFilter(q, q.Field("manager_id"), providers, brands, cloudEnv)
  765. q = RangeObjectsFilter(q, rangeObjs, vpcs.Field("cloudregion_id"), q.Field("zone_id"), q.Field("manager_id"), nil, nil)
  766. }
  767. return q
  768. }
  769. type WiresCountStat struct {
  770. WiresCount int
  771. EmulatedWiresCount int
  772. NetCount int
  773. GuestNicCount int
  774. GuestNicCount4 int
  775. GuestNicCount6 int
  776. HostNicCount int
  777. ReservedCount int
  778. ReservedCount6 int
  779. GroupNicCount int
  780. LbNicCount int
  781. EipNicCount int
  782. NetifNicCount int
  783. DbNicCount int
  784. PendingDeletedGuestNicCount int
  785. }
  786. func (wstat WiresCountStat) NicCount() int {
  787. return wstat.GuestNicCount + wstat.HostNicCount + wstat.ReservedCount + wstat.GroupNicCount + wstat.LbNicCount + wstat.NetifNicCount + wstat.EipNicCount + wstat.DbNicCount
  788. }
  789. func (manager *SWireManager) TotalCount(
  790. ctx context.Context,
  791. rangeObjs []db.IStandaloneModel,
  792. hostTypes []string,
  793. providers []string, brands []string, cloudEnv string,
  794. scope rbacscope.TRbacScope,
  795. ownerId mcclient.IIdentityProvider,
  796. policyResult rbacutils.SPolicyResult,
  797. ) WiresCountStat {
  798. vmwareP, hostProviders := fixVmwareProvider(providers)
  799. vmwareB, hostBrands := fixVmwareProvider(brands)
  800. if vmwareP || vmwareB {
  801. if !utils.IsInStringArray(api.HOST_TYPE_ESXI, hostTypes) {
  802. hostTypes = append(hostTypes, api.HOST_TYPE_ESXI)
  803. }
  804. } else {
  805. if utils.IsInStringArray(api.HOST_TYPE_ESXI, hostTypes) {
  806. providers = append(providers, api.CLOUD_PROVIDER_VMWARE)
  807. brands = append(brands, api.CLOUD_PROVIDER_VMWARE)
  808. }
  809. }
  810. if len(hostTypes) > 0 {
  811. for _, p := range providers {
  812. if hs, ok := api.CLOUD_PROVIDER_HOST_TYPE_MAP[p]; ok {
  813. hostTypes = append(hostTypes, hs...)
  814. }
  815. }
  816. for _, p := range brands {
  817. if hs, ok := api.CLOUD_PROVIDER_HOST_TYPE_MAP[p]; ok {
  818. hostTypes = append(hostTypes, hs...)
  819. }
  820. }
  821. }
  822. log.Debugf("providers: %#v hostProviders: %#v brands: %#v hostBrands: %#v hostTypes: %#v", providers, hostProviders, brands, hostBrands, hostTypes)
  823. stat := WiresCountStat{}
  824. err := manager.totalCountQ(
  825. ctx,
  826. rangeObjs,
  827. hostTypes, hostProviders, hostBrands,
  828. providers, brands, cloudEnv,
  829. scope, ownerId,
  830. policyResult,
  831. ).First(&stat)
  832. if err != nil {
  833. log.Errorf("Wire total count: %v", err)
  834. }
  835. err = manager.totalCountQ2(
  836. ctx,
  837. rangeObjs,
  838. hostTypes,
  839. providers, brands, cloudEnv,
  840. scope, ownerId,
  841. policyResult,
  842. ).First(&stat)
  843. if err != nil {
  844. log.Errorf("Wire total count 2: %v", err)
  845. }
  846. err = manager.totalCountQ3(
  847. ctx,
  848. rangeObjs,
  849. hostTypes,
  850. providers, brands, cloudEnv,
  851. scope, ownerId,
  852. policyResult,
  853. ).First(&stat)
  854. if err != nil {
  855. log.Errorf("Wire total count 2: %v", err)
  856. }
  857. return stat
  858. }
  859. func (swire *SWire) getNetworkQuery(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, scope rbacscope.TRbacScope) *sqlchemy.SQuery {
  860. additionalNicIds := NetworkAdditionalWireManager.networkIdQuery(swire.Id)
  861. q := NetworkManager.Query()
  862. q = q.Filter(sqlchemy.OR(
  863. sqlchemy.Equals(q.Field("wire_id"), swire.Id),
  864. sqlchemy.In(q.Field("id"), additionalNicIds.SubQuery()),
  865. ))
  866. if ownerId != nil {
  867. q = NetworkManager.FilterByOwner(ctx, q, NetworkManager, userCred, ownerId, scope)
  868. }
  869. return q
  870. }
  871. func (swire *SWire) GetNetworks(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, scope rbacscope.TRbacScope) ([]SNetwork, error) {
  872. return swire.getNetworks(ctx, userCred, ownerId, scope)
  873. }
  874. func (swire *SWire) getNetworks(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, scope rbacscope.TRbacScope) ([]SNetwork, error) {
  875. q := swire.getNetworkQuery(ctx, userCred, ownerId, scope)
  876. nets := make([]SNetwork, 0)
  877. err := db.FetchModelObjects(NetworkManager, q, &nets)
  878. if err != nil {
  879. return nil, err
  880. }
  881. return nets, nil
  882. }
  883. func (swire *SWire) getGatewayNetworkQuery(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, scope rbacscope.TRbacScope) *sqlchemy.SQuery {
  884. q := swire.getNetworkQuery(ctx, userCred, ownerId, scope)
  885. q = q.Filter(sqlchemy.OR(
  886. sqlchemy.AND(sqlchemy.IsNotNull(q.Field("guest_gateway")), sqlchemy.IsNotEmpty(q.Field("guest_gateway"))),
  887. sqlchemy.AND(sqlchemy.IsNotNull(q.Field("guest_gateway6")), sqlchemy.IsNotEmpty(q.Field("guest_gateway6"))),
  888. ))
  889. q = q.Equals("status", api.NETWORK_STATUS_AVAILABLE)
  890. return q
  891. }
  892. func (swire *SWire) getAutoAllocNetworks(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, scope rbacscope.TRbacScope) ([]SNetwork, error) {
  893. q := swire.getGatewayNetworkQuery(ctx, userCred, ownerId, scope)
  894. q = q.IsTrue("is_auto_alloc")
  895. nets := make([]SNetwork, 0)
  896. err := db.FetchModelObjects(NetworkManager, q, &nets)
  897. if err != nil {
  898. return nil, err
  899. }
  900. return nets, nil
  901. }
  902. func (swire *SWire) getPublicNetworks(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, scope rbacscope.TRbacScope) ([]SNetwork, error) {
  903. q := swire.getGatewayNetworkQuery(ctx, userCred, ownerId, scope)
  904. q = q.IsTrue("is_public")
  905. nets := make([]SNetwork, 0)
  906. err := db.FetchModelObjects(NetworkManager, q, &nets)
  907. if err != nil {
  908. return nil, err
  909. }
  910. return nets, nil
  911. }
  912. func (swire *SWire) getPrivateNetworks(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, scope rbacscope.TRbacScope) ([]SNetwork, error) {
  913. q := swire.getGatewayNetworkQuery(ctx, userCred, ownerId, scope)
  914. q = q.IsFalse("is_public")
  915. nets := make([]SNetwork, 0)
  916. err := db.FetchModelObjects(NetworkManager, q, &nets)
  917. if err != nil {
  918. return nil, err
  919. }
  920. return nets, nil
  921. }
  922. func (swire *SWire) GetCandidatePrivateNetwork(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, scope rbacscope.TRbacScope, isExit bool, serverTypes []api.TNetworkType) (*SNetwork, error) {
  923. nets, err := swire.getPrivateNetworks(ctx, userCred, ownerId, scope)
  924. if err != nil {
  925. return nil, err
  926. }
  927. return ChooseCandidateNetworks(nets, isExit, serverTypes), nil
  928. }
  929. func (swire *SWire) GetCandidateAutoAllocNetwork(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, scope rbacscope.TRbacScope, isExit bool, serverTypes []api.TNetworkType) (*SNetwork, error) {
  930. nets, err := swire.getAutoAllocNetworks(ctx, userCred, ownerId, scope)
  931. if err != nil {
  932. return nil, errors.Wrapf(err, "getAutoAllocNetworks with scope %s", scope)
  933. }
  934. return ChooseCandidateNetworks(nets, isExit, serverTypes), nil
  935. }
  936. func (swire *SWire) GetCandidateNetworkForIp(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, scope rbacscope.TRbacScope, ipAddr string) (*SNetwork, error) {
  937. ip, err := netutils.NewIPV4Addr(ipAddr)
  938. if err != nil {
  939. return nil, errors.Wrapf(err, "netutils.NewIPV4Addr: %s", ipAddr)
  940. }
  941. netPrivates, err := swire.getPrivateNetworks(ctx, userCred, ownerId, scope)
  942. if err != nil {
  943. return nil, errors.Wrapf(err, "swire.getPrivateNetworks %s", swire.GetId())
  944. }
  945. for _, net := range netPrivates {
  946. if net.IsAddressInRange(ip) {
  947. return &net, nil
  948. }
  949. }
  950. netPublics, err := swire.getPublicNetworks(ctx, userCred, ownerId, scope)
  951. if err != nil {
  952. return nil, errors.Wrapf(err, "swire.getPublicNetworks %s", swire.GetId())
  953. }
  954. for _, net := range netPublics {
  955. if net.IsAddressInRange(ip) {
  956. return &net, nil
  957. }
  958. }
  959. return nil, nil
  960. }
  961. func (swire *SWire) GetCandidateNetworkForIp6(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, scope rbacscope.TRbacScope, ip6Addr string) (*SNetwork, error) {
  962. ip6, err := netutils.NewIPV6Addr(ip6Addr)
  963. if err != nil {
  964. return nil, errors.Wrapf(err, "netutils.NewIPV6Addr: %s", ip6Addr)
  965. }
  966. netPrivates, err := swire.getPrivateNetworks(ctx, userCred, ownerId, scope)
  967. if err != nil {
  968. return nil, errors.Wrapf(err, "swire.getPrivateNetworks %s", swire.GetId())
  969. }
  970. for _, net := range netPrivates {
  971. if net.IsAddress6InRange(ip6) {
  972. return &net, nil
  973. }
  974. }
  975. netPublics, err := swire.getPublicNetworks(ctx, userCred, ownerId, scope)
  976. if err != nil {
  977. return nil, errors.Wrapf(err, "swire.getPublicNetworks %s", swire.GetId())
  978. }
  979. for _, net := range netPublics {
  980. if net.IsAddress6InRange(ip6) {
  981. return &net, nil
  982. }
  983. }
  984. return nil, nil
  985. }
  986. func ChooseNetworkByAddressCount(nets []*SNetwork) (*SNetwork, *SNetwork) {
  987. return chooseNetworkByAddressCount(nets)
  988. }
  989. func chooseNetworkByAddressCount(nets []*SNetwork) (*SNetwork, *SNetwork) {
  990. minCnt := 65535
  991. maxCnt := 0
  992. var minSel *SNetwork
  993. var maxSel *SNetwork
  994. for _, net := range nets {
  995. cnt, err := net.getFreeAddressCount()
  996. if err != nil || cnt <= 0 {
  997. continue
  998. }
  999. if minSel == nil || minCnt > cnt {
  1000. minSel = net
  1001. minCnt = cnt
  1002. }
  1003. if maxSel == nil || maxCnt < cnt {
  1004. maxSel = net
  1005. maxCnt = cnt
  1006. }
  1007. }
  1008. return minSel, maxSel
  1009. }
  1010. func ChooseCandidateNetworks(nets []SNetwork, isExit bool, serverTypes []api.TNetworkType) *SNetwork {
  1011. matchingNets := make([]*SNetwork, 0)
  1012. notMatchingNets := make([]*SNetwork, 0)
  1013. for _, s := range serverTypes {
  1014. net := chooseCandidateNetworksByNetworkType(nets, isExit, s)
  1015. if net != nil {
  1016. if api.IsInNetworkTypes(net.ServerType, serverTypes) {
  1017. matchingNets = append(matchingNets, net)
  1018. } else {
  1019. notMatchingNets = append(notMatchingNets, net)
  1020. }
  1021. }
  1022. }
  1023. if len(matchingNets) >= 1 {
  1024. return matchingNets[0]
  1025. }
  1026. if len(notMatchingNets) >= 1 {
  1027. return notMatchingNets[0]
  1028. }
  1029. return nil
  1030. }
  1031. func chooseCandidateNetworksByNetworkType(nets []SNetwork, isExit bool, serverType api.TNetworkType) *SNetwork {
  1032. matchingNets := make([]*SNetwork, 0)
  1033. notMatchingNets := make([]*SNetwork, 0)
  1034. for i := 0; i < len(nets); i++ {
  1035. net := nets[i]
  1036. if isExit != net.IsExitNetwork() {
  1037. continue
  1038. }
  1039. if serverType == net.ServerType || (len(net.ServerType) == 0 && serverType == api.NETWORK_TYPE_GUEST) {
  1040. matchingNets = append(matchingNets, &net)
  1041. } else {
  1042. notMatchingNets = append(notMatchingNets, &net)
  1043. }
  1044. }
  1045. minSel, maxSel := chooseNetworkByAddressCount(matchingNets)
  1046. if (isExit && minSel == nil) || (!isExit && maxSel == nil) {
  1047. minSel, maxSel = chooseNetworkByAddressCount(notMatchingNets)
  1048. }
  1049. if isExit {
  1050. return minSel
  1051. } else {
  1052. return maxSel
  1053. }
  1054. }
  1055. func (manager *SWireManager) InitializeData() error {
  1056. {
  1057. err := manager.initHostLocalWire()
  1058. if err != nil {
  1059. return errors.Wrap(err, "initHostLocalWire")
  1060. }
  1061. }
  1062. {
  1063. err := manager.initVpcId()
  1064. if err != nil {
  1065. return errors.Wrap(err, "initVpcId")
  1066. }
  1067. }
  1068. {
  1069. err := manager.initManagerId()
  1070. if err != nil {
  1071. return errors.Wrap(err, "initManagerId")
  1072. }
  1073. }
  1074. {
  1075. err := manager.cleanNoVpcWires()
  1076. if err != nil {
  1077. return errors.Wrap(err, "cleanNoVpcWires")
  1078. }
  1079. }
  1080. return nil
  1081. }
  1082. func (manager *SWireManager) initVpcId() error {
  1083. wires, err := manager.FetchWires(func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
  1084. q = q.Filter(sqlchemy.OR(
  1085. sqlchemy.IsEmpty(q.Field("vpc_id")),
  1086. sqlchemy.IsEmpty(q.Field("status")),
  1087. sqlchemy.Equals(q.Field("status"), "init"),
  1088. sqlchemy.Equals(q.Field("status"), api.WIRE_STATUS_READY_DEPRECATED),
  1089. ))
  1090. return q
  1091. })
  1092. if err != nil {
  1093. return errors.Wrap(err, "FetchWires")
  1094. }
  1095. for i := range wires {
  1096. w := wires[i]
  1097. _, err := db.Update(&w, func() error {
  1098. if len(w.VpcId) == 0 {
  1099. w.VpcId = api.DEFAULT_VPC_ID
  1100. }
  1101. if len(w.Status) == 0 || w.Status == "init" || w.Status == api.WIRE_STATUS_READY_DEPRECATED {
  1102. w.Status = api.WIRE_STATUS_AVAILABLE
  1103. }
  1104. return nil
  1105. })
  1106. if err != nil {
  1107. return errors.Wrap(err, "Update")
  1108. }
  1109. }
  1110. return nil
  1111. }
  1112. func (manager *SWireManager) initManagerId() error {
  1113. wires, err := manager.FetchWires(func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
  1114. vpcs := VpcManager.Query().SubQuery()
  1115. q = q.Join(vpcs, sqlchemy.Equals(q.Field("vpc_id"), vpcs.Field("id")))
  1116. q = q.Filter(sqlchemy.OR(
  1117. sqlchemy.IsNull(q.Field("manager_id")),
  1118. sqlchemy.NotEquals(q.Field("manager_id"), vpcs.Field("manager_id")),
  1119. ))
  1120. q = q.IsNullOrEmpty("manager_id")
  1121. return q
  1122. })
  1123. if err != nil {
  1124. return errors.Wrap(err, "FetchWires")
  1125. }
  1126. for i := range wires {
  1127. w := wires[i]
  1128. vpc, err := w.GetVpc()
  1129. if err != nil {
  1130. return errors.Wrap(err, "GetVpc")
  1131. }
  1132. _, err = db.Update(&w, func() error {
  1133. w.ManagerId = vpc.ManagerId
  1134. return nil
  1135. })
  1136. if err != nil {
  1137. return errors.Wrap(err, "Update")
  1138. }
  1139. }
  1140. return nil
  1141. }
  1142. func (manager *SWireManager) cleanNoVpcWires() error {
  1143. wires, err := manager.FetchWires(func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
  1144. // find wires whose VPC was deleted
  1145. deletedVpcs := VpcManager.RawQuery("id").IsTrue("deleted").SubQuery()
  1146. q = q.Join(deletedVpcs, sqlchemy.Equals(q.Field("vpc_id"), deletedVpcs.Field("id")))
  1147. return q
  1148. })
  1149. if err != nil {
  1150. return errors.Wrap(err, "FetchWires")
  1151. }
  1152. for i := range wires {
  1153. err := wires[i].Delete(context.Background(), auth.AdminCredential())
  1154. if err != nil {
  1155. return errors.Wrapf(err, "Delete wire %s", wires[i].Id)
  1156. }
  1157. }
  1158. return nil
  1159. }
  1160. func (manager *SWireManager) FetchWires(filter func(q *sqlchemy.SQuery) *sqlchemy.SQuery) ([]SWire, error) {
  1161. wires := make([]SWire, 0)
  1162. q := manager.Query()
  1163. q = filter(q)
  1164. err := db.FetchModelObjects(manager, q, &wires)
  1165. if err != nil {
  1166. return nil, errors.Wrap(err, "FetchModelObjects")
  1167. }
  1168. return wires, nil
  1169. }
  1170. func (wire *SWire) isOneCloudVpcWire() bool {
  1171. return IsOneCloudVpcResource(wire)
  1172. }
  1173. func (wire *SWire) getEnabledHosts() []SHost {
  1174. hosts := make([]SHost, 0)
  1175. hostQuery := HostManager.Query().SubQuery()
  1176. hostNetifQuery := NetInterfaceManager.Query().SubQuery()
  1177. q := hostQuery.Query()
  1178. q = q.Join(hostNetifQuery, sqlchemy.Equals(hostQuery.Field("id"), hostNetifQuery.Field("baremetal_id")))
  1179. q = q.Filter(sqlchemy.IsTrue(hostQuery.Field("enabled")))
  1180. q = q.Filter(sqlchemy.Equals(hostQuery.Field("host_status"), api.HOST_ONLINE))
  1181. if wire.isOneCloudVpcWire() {
  1182. q = q.Filter(sqlchemy.NOT(sqlchemy.IsNullOrEmpty(hostQuery.Field("ovn_version"))))
  1183. } else {
  1184. q = q.Filter(sqlchemy.Equals(hostNetifQuery.Field("wire_id"), wire.Id))
  1185. }
  1186. err := db.FetchModelObjects(HostManager, q, &hosts)
  1187. if err != nil {
  1188. log.Errorf("getEnabledHosts fail %s", err)
  1189. return nil
  1190. }
  1191. return hosts
  1192. }
  1193. func (wire *SWire) clearHostSchedDescCache() error {
  1194. hosts := wire.getEnabledHosts()
  1195. if hosts != nil {
  1196. for i := 0; i < len(hosts); i += 1 {
  1197. host := hosts[i]
  1198. if err := host.ClearSchedDescCache(); err != nil {
  1199. return errors.Wrapf(err, "wire %s clear host %s sched cache", wire.GetName(), host.GetName())
  1200. }
  1201. }
  1202. }
  1203. return nil
  1204. }
  1205. func (swire *SWire) GetIWire(ctx context.Context) (cloudprovider.ICloudWire, error) {
  1206. vpc, err := swire.GetVpc()
  1207. if err != nil {
  1208. return nil, errors.Wrapf(err, "GetVpc")
  1209. }
  1210. ivpc, err := vpc.GetIVpc(ctx)
  1211. if err != nil {
  1212. return nil, err
  1213. }
  1214. return ivpc.GetIWireById(swire.GetExternalId())
  1215. }
  1216. func (manager *SWireManager) FetchWireById(wireId string) *SWire {
  1217. wireObj, err := manager.FetchById(wireId)
  1218. if err != nil {
  1219. log.Errorf("FetchWireById fail %s", err)
  1220. return nil
  1221. }
  1222. return wireObj.(*SWire)
  1223. }
  1224. func (manager *SWireManager) FetchWireByExternalId(managerId, extId string) (*SWire, error) {
  1225. wires, err := manager.FetchWires(func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
  1226. q = q.Equals("manager_id", managerId).Equals("external_id", extId)
  1227. return q
  1228. })
  1229. if err != nil {
  1230. return nil, errors.Wrap(err, "FetchWires")
  1231. }
  1232. switch len(wires) {
  1233. case 0:
  1234. return nil, errors.Wrap(sql.ErrNoRows, "not found")
  1235. case 1:
  1236. return &wires[0], nil
  1237. default:
  1238. return nil, errors.Wrapf(httperrors.ErrDuplicateId, "duplicate wires externalId %s", extId)
  1239. }
  1240. }
  1241. func (manager *SWireManager) GetOnPremiseWireOfIp(ipAddr string) (*SWire, error) {
  1242. net, err := NetworkManager.GetOnPremiseNetworkOfIP(ipAddr, "", tristate.None)
  1243. if err != nil {
  1244. return nil, err
  1245. }
  1246. wire, _ := net.GetWire()
  1247. if wire != nil {
  1248. return wire, nil
  1249. } else {
  1250. return nil, fmt.Errorf("Wire not found")
  1251. }
  1252. }
  1253. func (manager *SWireManager) GetOnPremiseWireOfIp6(ip6Addr string) (*SWire, error) {
  1254. net, err := NetworkManager.GetOnPremiseNetworkOfIP6(ip6Addr, "", tristate.None)
  1255. if err != nil {
  1256. return nil, err
  1257. }
  1258. wire, _ := net.GetWire()
  1259. if wire != nil {
  1260. return wire, nil
  1261. } else {
  1262. return nil, fmt.Errorf("Wire not found")
  1263. }
  1264. }
  1265. func (w *SWire) PerformMergeNetwork(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.WireMergeNetworkInput) (jsonutils.JSONObject, error) {
  1266. return nil, w.StartMergeNetwork(ctx, userCred, "")
  1267. }
  1268. func (sm *SWireManager) FetchByIdsOrNames(idOrNames []string) ([]SWire, error) {
  1269. if len(idOrNames) == 0 {
  1270. return nil, nil
  1271. }
  1272. q := sm.Query()
  1273. if len(idOrNames) == 1 {
  1274. q.Filter(sqlchemy.OR(sqlchemy.Equals(q.Field("id"), idOrNames[0]), sqlchemy.Equals(q.Field("name"), idOrNames[0])))
  1275. } else {
  1276. q.Filter(sqlchemy.OR(sqlchemy.In(q.Field("id"), stringutils2.RemoveUtf8Strings(idOrNames)), sqlchemy.In(q.Field("name"), idOrNames)))
  1277. }
  1278. ret := make([]SWire, 0, len(idOrNames))
  1279. err := db.FetchModelObjects(sm, q, &ret)
  1280. if err != nil {
  1281. return nil, err
  1282. }
  1283. return ret, nil
  1284. }
  1285. func (w *SWire) PerformMergeFrom(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.WireMergeFromInput) (ret jsonutils.JSONObject, err error) {
  1286. if len(input.Sources) == 0 {
  1287. return nil, httperrors.NewMissingParameterError("sources")
  1288. }
  1289. defer func() {
  1290. if err != nil {
  1291. logclient.AddActionLogWithContext(ctx, w, logclient.ACT_MERGE, err.Error(), userCred, false)
  1292. }
  1293. }()
  1294. wires, err := WireManager.FetchByIdsOrNames(input.Sources)
  1295. if err != nil {
  1296. return
  1297. }
  1298. wireIdOrNameSet := sets.NewString(input.Sources...)
  1299. for i := range wires {
  1300. id, name := wires[i].GetId(), wires[i].GetName()
  1301. if wireIdOrNameSet.Has(id) {
  1302. wireIdOrNameSet.Delete(id)
  1303. continue
  1304. }
  1305. if wireIdOrNameSet.Has(name) {
  1306. wireIdOrNameSet.Delete(name)
  1307. }
  1308. }
  1309. if wireIdOrNameSet.Len() > 0 {
  1310. return nil, httperrors.NewInputParameterError("invalid wire id or name %v", wireIdOrNameSet.UnsortedList())
  1311. }
  1312. lockman.LockClass(ctx, WireManager, db.GetLockClassKey(WireManager, userCred))
  1313. defer lockman.ReleaseClass(ctx, WireManager, db.GetLockClassKey(WireManager, userCred))
  1314. for _, tw := range wires {
  1315. err = WireManager.handleWireIdChange(ctx, &wireIdChangeArgs{
  1316. oldWire: &tw,
  1317. newWire: w,
  1318. })
  1319. if err != nil {
  1320. return nil, errors.Wrapf(err, "unable to merge wire %s to %s", tw.GetId(), w.GetId())
  1321. }
  1322. if err = tw.Delete(ctx, userCred); err != nil {
  1323. return nil, err
  1324. }
  1325. }
  1326. logclient.AddActionLogWithContext(ctx, w, logclient.ACT_MERGE_FROM, "", userCred, true)
  1327. if input.MergeNetwork {
  1328. err = w.StartMergeNetwork(ctx, userCred, "")
  1329. if err != nil {
  1330. return nil, errors.Wrap(err, "unableto StartMergeNetwork")
  1331. }
  1332. }
  1333. return
  1334. }
  1335. func (w *SWire) PerformMergeTo(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.WireMergeInput) (ret jsonutils.JSONObject, err error) {
  1336. if len(input.Target) == 0 {
  1337. return nil, httperrors.NewMissingParameterError("target")
  1338. }
  1339. defer func() {
  1340. if err != nil {
  1341. logclient.AddActionLogWithContext(ctx, w, logclient.ACT_MERGE, err.Error(), userCred, false)
  1342. }
  1343. }()
  1344. iw, err := WireManager.FetchByIdOrName(ctx, userCred, input.Target)
  1345. if err == sql.ErrNoRows {
  1346. err = httperrors.NewNotFoundError("Wire %q", input.Target)
  1347. return
  1348. }
  1349. if err != nil {
  1350. return
  1351. }
  1352. tw := iw.(*SWire)
  1353. lockman.LockClass(ctx, WireManager, db.GetLockClassKey(WireManager, userCred))
  1354. defer lockman.ReleaseClass(ctx, WireManager, db.GetLockClassKey(WireManager, userCred))
  1355. err = WireManager.handleWireIdChange(ctx, &wireIdChangeArgs{
  1356. oldWire: w,
  1357. newWire: tw,
  1358. })
  1359. if err != nil {
  1360. return
  1361. }
  1362. logclient.AddActionLogWithContext(ctx, w, logclient.ACT_MERGE, "", userCred, true)
  1363. if err = w.Delete(ctx, userCred); err != nil {
  1364. return nil, err
  1365. }
  1366. if input.MergeNetwork {
  1367. err = tw.StartMergeNetwork(ctx, userCred, "")
  1368. if err != nil {
  1369. return nil, errors.Wrap(err, "unableto StartMergeNetwork")
  1370. }
  1371. }
  1372. return
  1373. }
  1374. func (w *SWire) StartMergeNetwork(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
  1375. task, err := taskman.TaskManager.NewTask(ctx, "NetworksUnderWireMergeTask", w, userCred, nil, parentTaskId, "", nil)
  1376. if err != nil {
  1377. return err
  1378. }
  1379. task.ScheduleRun(nil)
  1380. return nil
  1381. }
  1382. func (wm *SWireManager) handleWireIdChange(ctx context.Context, args *wireIdChangeArgs) error {
  1383. handlers := []wireIdChangeHandler{
  1384. // HostwireManager,
  1385. NetworkManager,
  1386. LoadbalancerClusterManager,
  1387. NetInterfaceManager,
  1388. }
  1389. errs := []error{}
  1390. for _, h := range handlers {
  1391. if err := h.handleWireIdChange(ctx, args); err != nil {
  1392. errs = append(errs, err)
  1393. }
  1394. }
  1395. if len(errs) > 0 {
  1396. err := errors.NewAggregate(errs)
  1397. return httperrors.NewGeneralError(err)
  1398. }
  1399. return nil
  1400. }
  1401. func (wire *SWire) PerformSetClassMetadata(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input apis.PerformSetClassMetadataInput) (jsonutils.JSONObject, error) {
  1402. vpc, err := wire.GetVpc()
  1403. if err != nil {
  1404. return nil, errors.Wrapf(err, "unable to get vpc of wire %s", wire.GetId())
  1405. }
  1406. if vpc.GetId() != api.DEFAULT_VPC_ID {
  1407. ok, err := db.IsInSameClass(ctx, vpc, db.ClassMetadataOwner(input))
  1408. if err != nil {
  1409. return nil, errors.Wrapf(err, "unable to check if vpc and wire are in same class")
  1410. }
  1411. if !ok {
  1412. return nil, httperrors.NewForbiddenError("the vpc %s and this wire have different class metadata", vpc.GetName())
  1413. }
  1414. }
  1415. return wire.SStatusInfrasResourceBase.PerformSetClassMetadata(ctx, userCred, query, input)
  1416. }
  1417. // 二层网络列表
  1418. func (manager *SWireManager) ListItemFilter(
  1419. ctx context.Context,
  1420. q *sqlchemy.SQuery,
  1421. userCred mcclient.TokenCredential,
  1422. query api.WireListInput,
  1423. ) (*sqlchemy.SQuery, error) {
  1424. var err error
  1425. {
  1426. managedFilter := query.ManagedResourceListInput
  1427. query.ManagedResourceListInput = api.ManagedResourceListInput{}
  1428. q, err = manager.SVpcResourceBaseManager.ListItemFilter(ctx, q, userCred, query.VpcFilterListInput)
  1429. if err != nil {
  1430. return nil, errors.Wrap(err, "SVpcResourceBaseManager.ListItemFilter")
  1431. }
  1432. q, err = manager.SManagedResourceBaseManager.ListItemFilter(ctx, q, userCred, managedFilter)
  1433. if err != nil {
  1434. return nil, errors.Wrap(err, "SManagedResourceBaseManager.ListItemFilter")
  1435. }
  1436. query.ManagedResourceListInput = managedFilter
  1437. }
  1438. q, err = manager.SExternalizedResourceBaseManager.ListItemFilter(ctx, q, userCred, query.ExternalizedResourceBaseListInput)
  1439. if err != nil {
  1440. return nil, errors.Wrap(err, "SExternalizedResourceBaseManager.ListItemFilter")
  1441. }
  1442. zoneQuery := api.ZonalFilterListInput{
  1443. ZonalFilterListBase: query.ZonalFilterListBase,
  1444. }
  1445. q, err = manager.SZoneResourceBaseManager.ListItemFilter(ctx, q, userCred, zoneQuery)
  1446. if err != nil {
  1447. return nil, errors.Wrap(err, "SZoneResourceBaseManager.ListItemFilter")
  1448. }
  1449. q, err = manager.SStatusInfrasResourceBaseManager.ListItemFilter(ctx, q, userCred, query.StatusInfrasResourceBaseListInput)
  1450. if err != nil {
  1451. return nil, errors.Wrap(err, "SStatusInfrasResourceBaseManager.ListItemFilter")
  1452. }
  1453. hostStr := query.HostId
  1454. if len(hostStr) > 0 {
  1455. hostObj, err := HostManager.FetchByIdOrName(ctx, userCred, hostStr)
  1456. if err != nil {
  1457. return nil, httperrors.NewResourceNotFoundError2(HostManager.Keyword(), hostStr)
  1458. }
  1459. sq := NetInterfaceManager.Query("wire_id").Equals("baremetal_id", hostObj.GetId())
  1460. q = q.Filter(sqlchemy.In(q.Field("id"), sq.SubQuery()))
  1461. }
  1462. if len(query.HostType) > 0 {
  1463. hs := HostManager.Query("id").Equals("host_type", query.HostType).SubQuery()
  1464. sq := NetInterfaceManager.Query("wire_id")
  1465. sq = sq.Join(hs, sqlchemy.Equals(sq.Field("baremetal_id"), hs.Field("id")))
  1466. q = q.Filter(sqlchemy.In(q.Field("id"), sq.SubQuery()))
  1467. }
  1468. if query.Bandwidth != nil {
  1469. q = q.Equals("bandwidth", *query.Bandwidth)
  1470. }
  1471. return q, nil
  1472. }
  1473. func (manager *SWireManager) OrderByExtraFields(
  1474. ctx context.Context,
  1475. q *sqlchemy.SQuery,
  1476. userCred mcclient.TokenCredential,
  1477. query api.WireListInput,
  1478. ) (*sqlchemy.SQuery, error) {
  1479. var err error
  1480. q, err = manager.SStatusInfrasResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.StatusInfrasResourceBaseListInput)
  1481. if err != nil {
  1482. return nil, errors.Wrap(err, "SInfrasResourceBaseManager.OrderByExtraFields")
  1483. }
  1484. q, err = manager.SVpcResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.VpcFilterListInput)
  1485. if err != nil {
  1486. return nil, errors.Wrap(err, "SVpcResourceBaseManager.OrderByExtraFields")
  1487. }
  1488. zoneQuery := api.ZonalFilterListInput{
  1489. ZonalFilterListBase: query.ZonalFilterListBase,
  1490. }
  1491. q, err = manager.SZoneResourceBaseManager.OrderByExtraFields(ctx, q, userCred, zoneQuery)
  1492. if err != nil {
  1493. return nil, errors.Wrap(err, "SZoneResourceBaseManager.OrderByExtraFields")
  1494. }
  1495. if db.NeedOrderQuery([]string{query.OrderByNetworkCount}) {
  1496. networkQ := NetworkManager.Query()
  1497. networkQ = networkQ.AppendField(networkQ.Field("wire_id"), sqlchemy.COUNT("network_count"))
  1498. networkQ = networkQ.GroupBy(networkQ.Field("wire_id"))
  1499. networkSQ := networkQ.SubQuery()
  1500. q = q.LeftJoin(networkSQ, sqlchemy.Equals(networkSQ.Field("wire_id"), q.Field("id")))
  1501. q = q.AppendField(q.QueryFields()...)
  1502. q = q.AppendField(networkSQ.Field("network_count"))
  1503. q = db.OrderByFields(q, []string{query.OrderByNetworkCount}, []sqlchemy.IQueryField{q.Field("network_count")})
  1504. }
  1505. return q, nil
  1506. }
  1507. func (manager *SWireManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
  1508. var err error
  1509. q, err = manager.SStatusInfrasResourceBaseManager.QueryDistinctExtraField(q, field)
  1510. if err == nil {
  1511. return q, nil
  1512. }
  1513. q, err = manager.SVpcResourceBaseManager.QueryDistinctExtraField(q, field)
  1514. if err == nil {
  1515. return q, nil
  1516. }
  1517. q, err = manager.SZoneResourceBaseManager.QueryDistinctExtraField(q, field)
  1518. if err == nil {
  1519. return q, nil
  1520. }
  1521. return q, httperrors.ErrNotFound
  1522. }
  1523. func (manager *SWireManager) QueryDistinctExtraFields(q *sqlchemy.SQuery, resource string, fields []string) (*sqlchemy.SQuery, error) {
  1524. var err error
  1525. q, err = manager.SVpcResourceBaseManager.QueryDistinctExtraFields(q, resource, fields)
  1526. if err == nil {
  1527. return q, nil
  1528. }
  1529. return q, httperrors.ErrNotFound
  1530. }
  1531. type SWireUsageCount struct {
  1532. Id string
  1533. api.WireUsage
  1534. }
  1535. func wmquery(manager db.IModelManager, uniqField, field string, wireIds []string, filter func(*sqlchemy.SQuery) *sqlchemy.SQuery) *sqlchemy.SSubQuery {
  1536. q := manager.Query("wire_id", uniqField)
  1537. if filter != nil {
  1538. q = filter(q)
  1539. }
  1540. sq := q.Distinct().SubQuery()
  1541. return sq.Query(
  1542. sq.Field("wire_id"),
  1543. sqlchemy.COUNT(field),
  1544. ).In("wire_id", wireIds).GroupBy(sq.Field("wire_id")).SubQuery()
  1545. }
  1546. func (manager *SWireManager) TotalResourceCount(wireIds []string) (map[string]api.WireUsage, error) {
  1547. // network
  1548. networkSQ := wmquery(NetworkManager, "id", "network_cnt", wireIds, nil)
  1549. hostSQ := wmquery(NetInterfaceManager, "baremetal_id", "host_cnt", wireIds, nil)
  1550. wires := manager.Query().SubQuery()
  1551. wireQ := wires.Query(
  1552. sqlchemy.SUM("networks", networkSQ.Field("network_cnt")),
  1553. sqlchemy.SUM("host_count", hostSQ.Field("host_cnt")),
  1554. )
  1555. wireQ.AppendField(wireQ.Field("id"))
  1556. wireQ = wireQ.LeftJoin(networkSQ, sqlchemy.Equals(wireQ.Field("id"), networkSQ.Field("wire_id")))
  1557. wireQ = wireQ.LeftJoin(hostSQ, sqlchemy.Equals(wireQ.Field("id"), hostSQ.Field("wire_id")))
  1558. wireQ = wireQ.Filter(sqlchemy.In(wireQ.Field("id"), wireIds)).GroupBy(wireQ.Field("id"))
  1559. wireCount := []SWireUsageCount{}
  1560. err := wireQ.All(&wireCount)
  1561. if err != nil {
  1562. return nil, errors.Wrapf(err, "wireQ.All")
  1563. }
  1564. result := map[string]api.WireUsage{}
  1565. for i := range wireCount {
  1566. result[wireCount[i].Id] = wireCount[i].WireUsage
  1567. }
  1568. return result, nil
  1569. }
  1570. func (manager *SWireManager) FetchCustomizeColumns(
  1571. ctx context.Context,
  1572. userCred mcclient.TokenCredential,
  1573. query jsonutils.JSONObject,
  1574. objs []interface{},
  1575. fields stringutils2.SSortedStrings,
  1576. isList bool,
  1577. ) []api.WireDetails {
  1578. rows := make([]api.WireDetails, len(objs))
  1579. stdRows := manager.SStatusInfrasResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
  1580. vpcRows := manager.SVpcResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
  1581. zoneRows := manager.SZoneResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
  1582. managerList := make([]interface{}, len(rows))
  1583. wireIds := make([]string, len(objs))
  1584. for i := range rows {
  1585. rows[i] = api.WireDetails{
  1586. StatusInfrasResourceBaseDetails: stdRows[i],
  1587. VpcResourceInfo: vpcRows[i],
  1588. ZoneResourceInfoBase: zoneRows[i].ZoneResourceInfoBase,
  1589. }
  1590. wire := objs[i].(*SWire)
  1591. wireIds[i] = wire.Id
  1592. managerList[i] = &SManagedResourceBase{wire.ManagerId}
  1593. }
  1594. managerRows := manager.SManagedResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, managerList, fields, isList)
  1595. usage, err := manager.TotalResourceCount(wireIds)
  1596. if err != nil {
  1597. log.Errorf("TotalResourceCount error: %v", err)
  1598. return rows
  1599. }
  1600. for i := range rows {
  1601. rows[i].WireUsage = usage[wireIds[i]]
  1602. rows[i].ManagedResourceInfo = managerRows[i]
  1603. }
  1604. return rows
  1605. }
  1606. func (man *SWireManager) removeWiresByVpc(ctx context.Context, userCred mcclient.TokenCredential, vpc *SVpc) error {
  1607. wires, err := man.FetchWires(func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
  1608. q = q.Equals("vpc_id", vpc.Id)
  1609. return q
  1610. })
  1611. if err != nil {
  1612. return errors.Wrap(err, "FetchWires")
  1613. }
  1614. var errs []error
  1615. for i := range wires {
  1616. wire := &wires[i]
  1617. if err := wire.Delete(ctx, userCred); err != nil {
  1618. errs = append(errs, err)
  1619. }
  1620. }
  1621. return errors.NewAggregate(errs)
  1622. }
  1623. /*func (swire *SWire) IsManaged() bool {
  1624. vpc, _ := swire.GetVpc()
  1625. if vpc == nil {
  1626. return false
  1627. }
  1628. return vpc.IsManaged()
  1629. }*/
  1630. func (model *SWire) CustomizeCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
  1631. vpc, _ := model.GetVpc()
  1632. if !data.Contains("public_scope") {
  1633. if !model.IsManaged() && db.IsAdminAllowPerform(ctx, userCred, model, "public") && ownerId.GetProjectDomainId() == userCred.GetProjectDomainId() && vpc != nil && vpc.IsPublic && vpc.PublicScope == string(rbacscope.ScopeSystem) {
  1634. model.SetShare(rbacscope.ScopeSystem)
  1635. } else {
  1636. model.SetShare(rbacscope.ScopeNone)
  1637. }
  1638. data.(*jsonutils.JSONDict).Set("public_scope", jsonutils.NewString(model.PublicScope))
  1639. }
  1640. model.Status = api.WIRE_STATUS_AVAILABLE
  1641. model.ManagerId = vpc.ManagerId
  1642. return model.SInfrasResourceBase.CustomizeCreate(ctx, userCred, ownerId, query, data)
  1643. }
  1644. func (model *SWire) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) {
  1645. model.SStatusInfrasResourceBase.PostCreate(ctx, userCred, ownerId, query, data)
  1646. vpc, err := model.GetVpc()
  1647. if err != nil {
  1648. log.Errorf("unable to getvpc of wire %s: %s", model.GetId(), vpc.GetId())
  1649. }
  1650. err = db.InheritFromTo(ctx, userCred, vpc, model)
  1651. if err != nil {
  1652. log.Errorf("unable to inhert vpc to model %s: %s", model.GetId(), err.Error())
  1653. }
  1654. }
  1655. func (wire *SWire) GetChangeOwnerCandidateDomainIds() []string {
  1656. candidates := [][]string{}
  1657. vpc, _ := wire.GetVpc()
  1658. if vpc != nil {
  1659. candidates = append(candidates,
  1660. vpc.GetChangeOwnerCandidateDomainIds(),
  1661. db.ISharableChangeOwnerCandidateDomainIds(vpc))
  1662. }
  1663. return db.ISharableMergeChangeOwnerCandidateDomainIds(wire, candidates...)
  1664. }
  1665. func (wire *SWire) GetChangeOwnerRequiredDomainIds() []string {
  1666. ctx := context.Background()
  1667. requires := stringutils2.SSortedStrings{}
  1668. networks, _ := wire.getNetworks(ctx, nil, nil, rbacscope.ScopeNone)
  1669. for i := range networks {
  1670. requires = stringutils2.Append(requires, networks[i].DomainId)
  1671. }
  1672. return requires
  1673. }
  1674. func (wire *SWire) GetRequiredSharedDomainIds() []string {
  1675. ctx := context.Background()
  1676. networks, _ := wire.getNetworks(ctx, nil, nil, rbacscope.ScopeNone)
  1677. if len(networks) == 0 {
  1678. return wire.SInfrasResourceBase.GetRequiredSharedDomainIds()
  1679. }
  1680. requires := make([][]string, len(networks))
  1681. for i := range networks {
  1682. requires[i] = db.ISharableChangeOwnerCandidateDomainIds(&networks[i])
  1683. }
  1684. return db.ISharableMergeShareRequireDomainIds(requires...)
  1685. }
  1686. func (manager *SWireManager) ListItemExportKeys(ctx context.Context,
  1687. q *sqlchemy.SQuery,
  1688. userCred mcclient.TokenCredential,
  1689. keys stringutils2.SSortedStrings,
  1690. ) (*sqlchemy.SQuery, error) {
  1691. var err error
  1692. q, err = manager.SStatusInfrasResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
  1693. if err != nil {
  1694. return nil, errors.Wrap(err, "SStatusInfrasResourceBaseManager.ListItemExportKeys")
  1695. }
  1696. if keys.ContainsAny(manager.SZoneResourceBaseManager.GetExportKeys()...) {
  1697. q, err = manager.SZoneResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
  1698. if err != nil {
  1699. return nil, errors.Wrap(err, "SZoneResourceBaseManager.ListItemExportKeys")
  1700. }
  1701. }
  1702. if keys.ContainsAny(manager.SVpcResourceBaseManager.GetExportKeys()...) {
  1703. q, err = manager.SVpcResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
  1704. if err != nil {
  1705. return nil, errors.Wrap(err, "SVpcResourceBaseManager.ListItemExportKeys")
  1706. }
  1707. }
  1708. return q, nil
  1709. }
  1710. func (swire *SWire) GetDetailsTopology(ctx context.Context, userCred mcclient.TokenCredential, input *api.WireTopologyInput) (*api.WireTopologyOutput, error) {
  1711. ret := &api.WireTopologyOutput{
  1712. Name: swire.Name,
  1713. Status: swire.Status,
  1714. Bandwidth: swire.Bandwidth,
  1715. Networks: []api.NetworkTopologyOutput{},
  1716. Hosts: []api.HostTopologyOutput{},
  1717. }
  1718. if len(swire.ZoneId) > 0 {
  1719. zone, _ := swire.GetZone()
  1720. if zone != nil {
  1721. ret.Zone = zone.Name
  1722. }
  1723. }
  1724. hosts, err := swire.GetHosts()
  1725. if err != nil {
  1726. return nil, errors.Wrapf(err, "GetHosts for wire %s", swire.Id)
  1727. }
  1728. for i := range hosts {
  1729. hns := hosts[i].GetBaremetalnetworks()
  1730. hss := hosts[i]._getAttachedStorages(tristate.None, tristate.None, nil)
  1731. host := api.HostTopologyOutput{
  1732. Name: hosts[i].Name,
  1733. Id: hosts[i].Id,
  1734. Status: hosts[i].Status,
  1735. HostStatus: hosts[i].HostStatus,
  1736. HostType: hosts[i].HostType,
  1737. Networks: []api.HostnetworkTopologyOutput{},
  1738. Schedtags: GetSchedtagsDetailsToResourceV2(&hosts[i], ctx),
  1739. }
  1740. for j := range hns {
  1741. host.Networks = append(host.Networks, api.HostnetworkTopologyOutput{
  1742. IpAddr: hns[j].IpAddr,
  1743. Ip6Addr: hns[j].Ip6Addr,
  1744. MacAddr: hns[j].MacAddr,
  1745. })
  1746. }
  1747. for j := range hss {
  1748. host.Storages = append(host.Storages, api.StorageShortDesc{
  1749. Name: hss[j].Name,
  1750. Id: hss[j].Id,
  1751. Status: hss[j].Status,
  1752. Enabled: hss[j].Enabled.Bool(),
  1753. StorageType: hss[j].StorageType,
  1754. CapacityMb: hss[j].Capacity,
  1755. })
  1756. }
  1757. ret.Hosts = append(ret.Hosts, host)
  1758. }
  1759. networks, err := swire.GetNetworks(ctx, nil, nil, rbacscope.ScopeSystem)
  1760. if err != nil {
  1761. return nil, errors.Wrapf(err, "GetNetworks")
  1762. }
  1763. for j := range networks {
  1764. network := api.NetworkTopologyOutput{
  1765. Name: networks[j].Name,
  1766. Status: networks[j].Status,
  1767. GuestIpStart: networks[j].GuestIpStart,
  1768. GuestIpEnd: networks[j].GuestIpEnd,
  1769. GuestIpMask: networks[j].GuestIpMask,
  1770. ServerType: networks[j].ServerType,
  1771. VlanId: networks[j].VlanId,
  1772. // Address: []api.SNetworkUsedAddress{},
  1773. }
  1774. network.GetNetworkAddressesOutput, err = networks[j].fetchAddressDetails(ctx, userCred, userCred, rbacscope.ScopeSystem)
  1775. if err != nil {
  1776. return nil, errors.Wrapf(err, "fetchAddressDetails")
  1777. }
  1778. ret.Networks = append(ret.Networks, network)
  1779. }
  1780. return ret, nil
  1781. }
  1782. func (wire *SWire) GetCloudproviderId() string {
  1783. return wire.SManagedResourceBase.GetCloudproviderId()
  1784. }
  1785. func (wire *SWire) GetCloudprovider() *SCloudprovider {
  1786. return wire.SManagedResourceBase.GetCloudprovider()
  1787. }
  1788. func (wire *SWire) GetProviderName() string {
  1789. return wire.SManagedResourceBase.GetProviderName()
  1790. }
  1791. func (wire *SWire) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
  1792. if err := NetworkAdditionalWireManager.DeleteWire(ctx, wire.Id); err != nil {
  1793. return errors.Wrap(err, "NetworkAdditionalWireManager.DeleteWire")
  1794. }
  1795. return wire.SStatusInfrasResourceBase.Delete(ctx, userCred)
  1796. }
  1797. func (manager *SWireManager) initHostLocalWire() error {
  1798. if _, err := manager.FetchById(api.DEFAULT_HOST_LOCAL_WIRE_ID); err != nil {
  1799. if err == sql.ErrNoRows {
  1800. defWire := SWire{}
  1801. defWire.SetModelManager(WireManager, &defWire)
  1802. defWire.Id = api.DEFAULT_HOST_LOCAL_WIRE_ID
  1803. defWire.Name = api.DEFAULT_HOST_LOCAL_WIRE_NAME
  1804. defWire.VpcId = api.DEFAULT_VPC_ID
  1805. defWire.ZoneId = "" // host local wire is not associated with a zone
  1806. defWire.ManagerId = "" // host local wire is not associated with a manager
  1807. defWire.IsEmulated = false
  1808. defWire.ExternalId = "" // host local wire is not associated with an external id
  1809. defWire.IsPublic = true
  1810. defWire.PublicScope = string(rbacscope.ScopeSystem)
  1811. defWire.Status = api.WIRE_STATUS_AVAILABLE
  1812. defWire.Description = "Host local wire"
  1813. defWire.Bandwidth = 10000
  1814. defWire.Mtu = 1500
  1815. defWire.ScheduleRank = 0
  1816. defWire.DomainId = identityapi.DEFAULT_DOMAIN_ID
  1817. err = manager.TableSpec().Insert(context.TODO(), &defWire)
  1818. if err != nil {
  1819. log.Errorf("Insert default host local wire fail: %s", err)
  1820. }
  1821. return err
  1822. } else {
  1823. return err
  1824. }
  1825. }
  1826. return nil
  1827. }