guestnetworks.go 46 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600
  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. "regexp"
  20. "strings"
  21. "time"
  22. "yunion.io/x/jsonutils"
  23. "yunion.io/x/log"
  24. "yunion.io/x/pkg/errors"
  25. "yunion.io/x/pkg/gotypes"
  26. "yunion.io/x/pkg/util/netutils"
  27. randutil "yunion.io/x/pkg/util/rand"
  28. "yunion.io/x/pkg/util/rbacscope"
  29. "yunion.io/x/pkg/util/regutils"
  30. "yunion.io/x/sqlchemy"
  31. billing_api "yunion.io/x/onecloud/pkg/apis/billing"
  32. api "yunion.io/x/onecloud/pkg/apis/compute"
  33. "yunion.io/x/onecloud/pkg/cloudcommon/db"
  34. "yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
  35. "yunion.io/x/onecloud/pkg/compute/options"
  36. "yunion.io/x/onecloud/pkg/httperrors"
  37. "yunion.io/x/onecloud/pkg/mcclient"
  38. "yunion.io/x/onecloud/pkg/util/stringutils2"
  39. )
  40. const (
  41. MAX_IFNAME_SIZE = 13
  42. MAX_HINT_LEN = MAX_IFNAME_SIZE - 4 // 9
  43. HINT_BASE_LEN = 6 // 6
  44. HINT_RAND_LEN = MAX_HINT_LEN - HINT_BASE_LEN // 3
  45. MAX_GUESTNIC_TO_SAME_NETWORK = 2
  46. )
  47. // +onecloud:swagger-gen-ignore
  48. type SGuestnetworkManager struct {
  49. SGuestJointsManager
  50. SNetworkResourceBaseManager
  51. }
  52. var GuestnetworkManager *SGuestnetworkManager
  53. func init() {
  54. db.InitManager(func() {
  55. GuestnetworkManager = &SGuestnetworkManager{
  56. SGuestJointsManager: NewGuestJointsManager(
  57. SGuestnetwork{},
  58. "guestnetworks_tbl",
  59. "guestnetwork",
  60. "guestnetworks",
  61. NetworkManager,
  62. ),
  63. }
  64. GuestnetworkManager.SetVirtualObject(GuestnetworkManager)
  65. GuestnetworkManager.TableSpec().AddIndex(true, "ip_addr", "guest_id", "deleted")
  66. GuestnetworkManager.TableSpec().AddIndex(true, "ip6_addr", "guest_id", "deleted")
  67. GuestnetworkManager.TableSpec().AddIndex(false, "mac_addr", "deleted")
  68. })
  69. }
  70. // +onecloud:model-api-gen
  71. type SGuestnetwork struct {
  72. SGuestJointsBase
  73. NetworkId string `width:"36" charset:"ascii" nullable:"false" list:"user" `
  74. // MAC地址
  75. MacAddr string `width:"32" charset:"ascii" nullable:"false" list:"user" index:"true"`
  76. // IPv4地址
  77. IpAddr string `width:"16" charset:"ascii" nullable:"true" list:"user"`
  78. // IPv6地址
  79. Ip6Addr string `width:"64" charset:"ascii" nullable:"true" list:"user"`
  80. // 虚拟网卡驱动
  81. Driver string `width:"16" charset:"ascii" nullable:"true" list:"user" update:"user"`
  82. // 网卡队列数
  83. NumQueues int `nullable:"true" default:"1" list:"user" update:"user"`
  84. // 带宽限制,单位mbps
  85. BwLimit int `nullable:"false" default:"0" list:"user"`
  86. // 下行流量限制,单位 bytes
  87. RxTrafficLimit int64 `nullable:"false" default:"0" list:"user"`
  88. RxTrafficUsed int64 `nullable:"false" default:"0" list:"user"`
  89. // 上行流量限制,单位 bytes
  90. TxTrafficLimit int64 `nullable:"false" default:"0" list:"user"`
  91. TxTrafficUsed int64 `nullable:"false" default:"0" list:"user"`
  92. // 网卡序号
  93. Index int `nullable:"false" default:"0" list:"user" update:"user"`
  94. // 是否为虚拟接口(无IP)
  95. Virtual bool `default:"false" list:"user"`
  96. // 虚拟网卡设备名称
  97. Ifname string `width:"16" charset:"ascii" nullable:"true" list:"user" update:"user"`
  98. // bind配对网卡MAC地址
  99. TeamWith string `width:"32" charset:"ascii" nullable:"false" list:"user"`
  100. // IPv4映射地址,当子网属于私有云vpc的时候分配,用于访问外网
  101. MappedIpAddr string `width:"16" charset:"ascii" nullable:"true" list:"user"`
  102. // IPv6映射地址,当子网属于私有云vpc的时候分配,用于访问外网
  103. MappedIp6Addr string `width:"64" charset:"ascii" nullable:"true" list:"user"`
  104. // 网卡关联的Eip实例
  105. EipId string `width:"36" charset:"ascii" nullable:"true" list:"user"`
  106. // 是否为缺省路由
  107. IsDefault bool `default:"false" list:"user"`
  108. // 端口映射
  109. PortMappings api.GuestPortMappings `length:"long" list:"user" update:"user"`
  110. SBillingTypeBase `billing_type->default:"prepaid"`
  111. SBillingChargeTypeBase `charge_type->default:"bandwidth"`
  112. }
  113. func (gn SGuestnetwork) GetIP() string {
  114. return gn.IpAddr
  115. }
  116. func (gn SGuestnetwork) GetMAC() string {
  117. return gn.MacAddr
  118. }
  119. func (manager *SGuestnetworkManager) GetSlaveFieldName() string {
  120. return "network_id"
  121. }
  122. func (manager *SGuestnetworkManager) FetchCustomizeColumns(
  123. ctx context.Context,
  124. userCred mcclient.TokenCredential,
  125. query jsonutils.JSONObject,
  126. objs []interface{},
  127. fields stringutils2.SSortedStrings,
  128. isList bool,
  129. ) []api.GuestnetworkDetails {
  130. rows := make([]api.GuestnetworkDetails, len(objs))
  131. guestRows := manager.SGuestJointsManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
  132. netIds := make([]string, len(rows))
  133. eipIds := make([]string, len(rows))
  134. for i := range rows {
  135. rows[i] = api.GuestnetworkDetails{
  136. GuestJointResourceDetails: guestRows[i],
  137. }
  138. netIds[i] = objs[i].(*SGuestnetwork).NetworkId
  139. eipIds[i] = objs[i].(*SGuestnetwork).EipId
  140. ipnets, err := NetworkAddressManager.fetchAddressesByGuestnetworkId(objs[i].(*SGuestnetwork).RowId)
  141. if err != nil {
  142. log.Errorf("NetworkAddressManager.fetchAddressesByGuestnetworkId %s", err)
  143. } else if len(ipnets) > 0 {
  144. rows[i].NetworkAddresses = ipnets
  145. }
  146. }
  147. netMap := make(map[string]SNetwork)
  148. err := db.FetchModelObjectsByIds(NetworkManager, "id", netIds, netMap)
  149. if err != nil {
  150. log.Errorf("FetchIdNameMap2 fail %s", err)
  151. return rows
  152. }
  153. for i := range rows {
  154. if net, ok := netMap[netIds[i]]; ok {
  155. rows[i].Network = net.Name
  156. rows[i].WireId = net.WireId
  157. rows[i].GuestIpMask = net.GuestIpMask
  158. rows[i].GuestGateway = net.GuestGateway
  159. rows[i].GuestIp6Mask = net.GuestIp6Mask
  160. rows[i].GuestGateway6 = net.GuestGateway6
  161. }
  162. }
  163. eipIdMaps, err := db.FetchIdFieldMap2(ElasticipManager, "ip_addr", eipIds)
  164. if err != nil {
  165. log.Errorf("FetchIdFieldMap2 fail %s", err)
  166. return rows
  167. }
  168. for i := range rows {
  169. if ip, ok := eipIdMaps[eipIds[i]]; ok {
  170. rows[i].EipAddr = ip
  171. }
  172. }
  173. return rows
  174. }
  175. func (manager *SGuestnetworkManager) fetchByRowIds(
  176. ctx context.Context,
  177. userCred mcclient.TokenCredential,
  178. rowIds []int64,
  179. ) ([]SGuestnetwork, error) {
  180. var gns []SGuestnetwork
  181. q := manager.Query().In("row_id", rowIds)
  182. if err := db.FetchModelObjects(manager, q, &gns); err != nil {
  183. return nil, errors.Wrapf(err, "fetch guestnetworks by row_id list")
  184. }
  185. idmap := map[int64]int{}
  186. for i := range gns {
  187. idmap[gns[i].RowId] = i
  188. }
  189. ret := make([]SGuestnetwork, len(rowIds))
  190. for i, rowId := range rowIds {
  191. if j, ok := idmap[rowId]; ok {
  192. ret[i] = gns[j]
  193. } else {
  194. return nil, errors.Wrapf(errors.ErrNotFound, "guestnetwork row %d", rowId)
  195. }
  196. }
  197. return ret, nil
  198. }
  199. func (manager *SGuestnetworkManager) fetchByRowId(
  200. ctx context.Context,
  201. userCred mcclient.TokenCredential,
  202. rowId int64,
  203. ) (*SGuestnetwork, error) {
  204. gns, err := manager.fetchByRowIds(ctx, userCred, []int64{rowId})
  205. if err != nil {
  206. return nil, err
  207. }
  208. if len(gns) != 1 {
  209. return nil, errors.Errorf("row_id %d: got %d guesnetwork entries", rowId, len(gns))
  210. }
  211. return &gns[0], nil
  212. }
  213. func (manager *SGuestnetworkManager) GenerateMac(suggestion string) (string, error) {
  214. return generateMac(suggestion)
  215. }
  216. func (manager *SGuestnetworkManager) FilterByMac(mac string) *sqlchemy.SQuery {
  217. return manager.Query().Equals("mac_addr", mac)
  218. }
  219. type newGuestNetworkArgs struct {
  220. guest *SGuest
  221. network *SNetwork
  222. index int
  223. ipAddr string
  224. allocDir api.IPAllocationDirection
  225. tryReserved bool
  226. requireDesignatedIP bool
  227. useDesignatedIP bool
  228. ip6Addr string
  229. requireIPv6 bool
  230. strictIPv6 bool
  231. // 是否为缺省路由
  232. isDefault bool
  233. ifname string
  234. macAddr string
  235. bwLimit int
  236. nicDriver string
  237. numQueues int
  238. teamWithMac string
  239. rxTrafficLimit int64
  240. txTrafficLimit int64
  241. virtual bool
  242. portMappings api.GuestPortMappings
  243. billingType billing_api.TBillingType
  244. chargeType billing_api.TNetChargeType
  245. }
  246. func (manager *SGuestnetworkManager) newGuestNetwork(
  247. ctx context.Context,
  248. userCred mcclient.TokenCredential,
  249. args newGuestNetworkArgs,
  250. ) (*SGuestnetwork, error) {
  251. gn := SGuestnetwork{}
  252. gn.SetModelManager(GuestnetworkManager, &gn)
  253. var (
  254. guest = args.guest
  255. network = args.network
  256. index = args.index
  257. address = args.ipAddr
  258. mac = args.macAddr
  259. driver = args.nicDriver
  260. numQueues = args.numQueues
  261. bwLimit = args.bwLimit
  262. virtual = args.virtual
  263. reserved = args.tryReserved
  264. allocDir = args.allocDir
  265. requiredDesignatedIp = args.requireDesignatedIP
  266. reUseAddr = args.useDesignatedIP
  267. ifname = args.ifname
  268. teamWithMac = args.teamWithMac
  269. isDefault = args.isDefault
  270. address6 = args.ip6Addr
  271. requireIPv6 = args.requireIPv6
  272. strictIPv6 = args.strictIPv6
  273. )
  274. gn.GuestId = guest.Id
  275. gn.NetworkId = network.Id
  276. gn.Index = index
  277. gn.Virtual = virtual
  278. if len(driver) == 0 {
  279. driver = api.NETWORK_DRIVER_VIRTIO
  280. }
  281. gn.Driver = driver
  282. gn.NumQueues = numQueues
  283. gn.RxTrafficLimit = args.rxTrafficLimit
  284. gn.TxTrafficLimit = args.txTrafficLimit
  285. if bwLimit >= 0 {
  286. gn.BwLimit = bwLimit
  287. }
  288. gn.PortMappings = args.portMappings
  289. gn.BillingType = args.billingType
  290. gn.ChargeType = args.chargeType
  291. lockman.LockObject(ctx, network)
  292. defer lockman.ReleaseObject(ctx, network)
  293. vpc, _ := network.GetVpc()
  294. if vpc == nil {
  295. return nil, fmt.Errorf("cannot find vpc of network %s(%s)", network.Id, network.Name)
  296. }
  297. provider := vpc.GetProviderName()
  298. if !virtual && !strictIPv6 && network.IsSupportIPv4() {
  299. if len(address) > 0 && reUseAddr {
  300. ipAddr, err := netutils.NewIPV4Addr(address)
  301. if err != nil {
  302. return nil, errors.Wrapf(err, "Reuse invalid address %s", address)
  303. }
  304. if !network.IsAddressInRange(ipAddr) {
  305. return nil, errors.Wrapf(httperrors.ErrOutOfRange, "%s not in network address range", address)
  306. }
  307. // if reuse Ip address, no need to check address availability
  308. // assign it anyway
  309. gn.IpAddr = address
  310. } else {
  311. // 如果是不具备IPAM能力的平台(主要是OneCloud和VMware,也就是VPC为ONECLOUD的平台 provider == api.CLOUD_PROVIDER_ONECLOUD ),则需要分配IP地址
  312. // 如果是其他云平台(具体IPAM能力的平台),则
  313. // * 开启options.Options.EnablePreAllocateIpAddr,也就是把IPAM的任务交给平台的,则需要分配IP地址
  314. // * IP地址为空并且 !options.Options.EnablePreAllocateIpAddr 时,不需要分配IP,等创建后自动同步过来
  315. // * 否则,还是需要先分配了
  316. if provider == api.CLOUD_PROVIDER_ONECLOUD || options.Options.EnablePreAllocateIpAddr || (!options.Options.EnablePreAllocateIpAddr && len(address) > 0) {
  317. addrTable := network.GetUsedAddresses(ctx)
  318. recentAddrTable := manager.getRecentlyReleasedIPAddresses(network.Id, network.getAllocTimoutDuration())
  319. ipAddr, err := network.GetFreeIP(ctx, userCred, addrTable, recentAddrTable, address, allocDir, reserved, api.AddressTypeIPv4)
  320. if err != nil {
  321. return nil, errors.Wrap(err, "GetFreeIPv4")
  322. }
  323. if len(address) > 0 && ipAddr != address && requiredDesignatedIp {
  324. usedAddr, _ := network.GetUsedAddressDetails(ctx, address)
  325. return nil, errors.Wrapf(httperrors.ErrConflict, "candidate ip %s is occupied with %#v!", address, usedAddr)
  326. }
  327. gn.IpAddr = ipAddr
  328. }
  329. }
  330. }
  331. var err error
  332. if ipBindMac := NetworkIpMacManager.GetMacFromIp(network.Id, gn.IpAddr); ipBindMac != "" {
  333. gn.MacAddr = ipBindMac
  334. } else {
  335. gn.MacAddr, err = manager.GenerateMac(mac)
  336. if err != nil {
  337. return nil, err
  338. }
  339. }
  340. if len(gn.MacAddr) == 0 {
  341. log.Errorf("Mac address generate fails")
  342. return nil, fmt.Errorf("mac address generate fails")
  343. }
  344. // assign ipv6 address
  345. if !virtual {
  346. if len(address6) > 0 || (requireIPv6 || len(gn.IpAddr) == 0) {
  347. if provider == api.CLOUD_PROVIDER_ONECLOUD || options.Options.EnablePreAllocateIpAddr || (!options.Options.EnablePreAllocateIpAddr && len(address6) > 0) {
  348. addrTable := network.GetUsedAddresses6(ctx)
  349. recentAddrTable := manager.getRecentlyReleasedIPAddresses6(network.Id, network.getAllocTimoutDuration())
  350. derived := false
  351. if len(address6) == 0 {
  352. // try to derive ipv6 address from mac and ipv4 address
  353. deriveAddr6 := netutils.DeriveIPv6AddrFromIPv4AddrMac(gn.IpAddr, gn.MacAddr, network.GuestIp6Start, network.GuestIp6End, network.GuestIp6Mask)
  354. if !isIpUsed(deriveAddr6, addrTable, recentAddrTable) {
  355. address6 = deriveAddr6
  356. derived = true
  357. }
  358. }
  359. ip6Addr, err := network.GetFreeIP(ctx, userCred, addrTable, recentAddrTable, address6, allocDir, reserved, api.AddressTypeIPv6)
  360. if err != nil {
  361. return nil, errors.Wrap(err, "GetFreeIPv6")
  362. }
  363. if len(address6) > 0 && ip6Addr != address6 && !derived && requiredDesignatedIp {
  364. usedAddr, _ := network.GetUsedAddressDetails(ctx, address6)
  365. return nil, errors.Wrapf(httperrors.ErrConflict, "candidate v6 ip %s is occupied with %#v!", address6, usedAddr)
  366. }
  367. gn.Ip6Addr = ip6Addr
  368. }
  369. }
  370. }
  371. if vpc.Id != api.DEFAULT_VPC_ID && provider == api.CLOUD_PROVIDER_ONECLOUD && (len(gn.IpAddr) > 0 || len(gn.Ip6Addr) > 0) {
  372. var err error
  373. GuestnetworkManager.lockAllocMappedAddr(ctx)
  374. defer GuestnetworkManager.unlockAllocMappedAddr(ctx)
  375. gn.MappedIpAddr, err = GuestnetworkManager.allocMappedIpAddr(ctx)
  376. if err != nil {
  377. return nil, errors.Wrap(err, "GuestnetworkManager.allocMappedIpAddr")
  378. }
  379. gn.MappedIp6Addr = api.GenVpcMappedIP6(gn.MappedIpAddr)
  380. }
  381. ifname, err = gn.checkOrAllocateIfname(network, ifname)
  382. if err != nil {
  383. return nil, err
  384. }
  385. gn.Ifname = ifname
  386. gn.TeamWith = teamWithMac
  387. if isDefault && ((len(gn.IpAddr) > 0 && len(network.GuestGateway) > 0) || (len(gn.Ip6Addr) > 0 && len(network.GuestGateway6) > 0)) {
  388. gn.IsDefault = isDefault
  389. }
  390. if len(gn.Ip6Addr) > 0 && len(gn.IpAddr) == 0 {
  391. gn.NumQueues = 1
  392. }
  393. err = manager.TableSpec().Insert(ctx, &gn)
  394. if err != nil {
  395. return nil, err
  396. }
  397. return &gn, nil
  398. }
  399. func (gn *SGuestnetwork) generateIfname(network *SNetwork, virtual bool, randomized bool) string {
  400. // It may happen that external networks when synced can miss ifname hint
  401. network.ensureIfnameHint()
  402. pattern := regexp.MustCompile(`\W+`)
  403. nName := pattern.ReplaceAllString(network.IfnameHint, "")
  404. if len(nName) > MAX_IFNAME_SIZE-4 {
  405. nName = nName[:(MAX_IFNAME_SIZE - 4)]
  406. }
  407. if virtual {
  408. return fmt.Sprintf("%s-%s", nName, randutil.String(3))
  409. } else {
  410. ip, _ := netutils.NewIPV4Addr(gn.IpAddr)
  411. cliaddr := ip.CliAddr(network.GuestIpMask)
  412. return fmt.Sprintf("%s-%d", nName, uint32(cliaddr))
  413. }
  414. }
  415. func (man *SGuestnetworkManager) ifnameUsed(ifname string) bool {
  416. // inviable names are always used
  417. if ifname == "" {
  418. return true
  419. }
  420. if len(ifname) > MAX_IFNAME_SIZE {
  421. return true
  422. }
  423. isa := func(c byte) bool {
  424. return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
  425. }
  426. if !isa(ifname[0]) {
  427. return true
  428. }
  429. for i := range ifname[1:] {
  430. c := ifname[i]
  431. if isa(c) || c >= '0' || c <= '9' || c == '_' || c == '-' {
  432. continue
  433. }
  434. return true
  435. }
  436. count, err := GuestnetworkManager.Query().Equals("ifname", ifname).CountWithError()
  437. if err != nil {
  438. panic(errors.Wrap(err, "query if ifname is used"))
  439. }
  440. return count > 0
  441. }
  442. func (gn *SGuestnetwork) checkOrAllocateIfname(network *SNetwork, preferIfname string) (string, error) {
  443. man := GuestnetworkManager
  444. if !man.ifnameUsed(preferIfname) {
  445. return preferIfname, nil
  446. }
  447. ifname := gn.generateIfname(network, gn.Virtual, false)
  448. if !man.ifnameUsed(ifname) {
  449. return ifname, nil
  450. }
  451. if !gn.Virtual {
  452. ifname = gn.generateIfname(network, true, false)
  453. }
  454. found := false
  455. for i := 0; i < 5; i++ {
  456. if !man.ifnameUsed(ifname) {
  457. found = true
  458. break
  459. }
  460. ifname = gn.generateIfname(network, true, true)
  461. }
  462. if !found {
  463. return "", httperrors.NewConflictError("cannot allocate ifname")
  464. }
  465. return ifname, nil
  466. }
  467. func (gn *SGuestnetwork) GetGuest() *SGuest {
  468. guest, _ := GuestManager.FetchById(gn.GuestId)
  469. if guest != nil {
  470. return guest.(*SGuest)
  471. }
  472. return nil
  473. }
  474. func (gn *SGuestnetwork) GetNetwork() (*SNetwork, error) {
  475. net, err := NetworkManager.FetchById(gn.NetworkId)
  476. if err != nil {
  477. return nil, errors.Wrapf(err, "FetchById %s", gn.NetworkId)
  478. }
  479. return net.(*SNetwork), nil
  480. }
  481. func (gn *SGuestnetwork) GetTeamGuestnetwork() (*SGuestnetwork, error) {
  482. if len(gn.TeamWith) > 0 {
  483. return GuestnetworkManager.FetchByIdsAndIpMac(gn.GuestId, gn.NetworkId, "", gn.TeamWith)
  484. }
  485. return nil, nil
  486. }
  487. func (gn *SGuestnetwork) getJsonDescAtBaremetal(host *SHost) *api.GuestnetworkJsonDesc {
  488. net, _ := gn.GetNetwork()
  489. netif := guestGetHostNetifFromNetwork(host, net)
  490. if netif == nil {
  491. log.Errorf("fail to find a valid net interface on baremetal %s for network %s", host.String(), net.String())
  492. }
  493. return gn.getJsonDescHostwire(netif)
  494. }
  495. func guestGetHostNetifFromNetwork(host *SHost, network *SNetwork) *SNetInterface {
  496. netifs := host.getNetifsOnWire(network.WireId)
  497. var netif *SNetInterface
  498. for i := range netifs {
  499. if netifs[i].NicType != api.NIC_TYPE_IPMI {
  500. if netif == nil || netif.NicType != api.NIC_TYPE_ADMIN {
  501. netif = &netifs[i]
  502. }
  503. }
  504. }
  505. return netif
  506. }
  507. func (gn *SGuestnetwork) getJsonDescAtHost(ctx context.Context, host *SHost) *api.GuestnetworkJsonDesc {
  508. var (
  509. ret *api.GuestnetworkJsonDesc = nil
  510. network, _ = gn.GetNetwork()
  511. )
  512. if network.isOneCloudVpcNetwork() {
  513. // onecloud vpc nic
  514. ret = gn.getJsonDescOneCloudVpc(network)
  515. } else if network.WireId == api.DEFAULT_HOST_LOCAL_WIRE_ID {
  516. // host local nic
  517. ret = gn.getJsonDescHostLocal(network)
  518. } else {
  519. // classic nic
  520. netifs := host.getNetifsOnWire(network.WireId)
  521. var netif *SNetInterface
  522. for i := range netifs {
  523. if len(netifs[i].Bridge) > 0 {
  524. netif = &netifs[i]
  525. break
  526. }
  527. }
  528. if netif == nil && len(netifs) > 0 {
  529. log.Errorf("fail to find a bridged net_interface on host %s for network %s?????", host.String(), network.String())
  530. netif = &netifs[0]
  531. }
  532. ret = gn.getJsonDescHostwire(netif)
  533. }
  534. {
  535. ipnets, err := NetworkAddressManager.fetchAddressesByGuestnetworkId(gn.RowId)
  536. if err != nil {
  537. log.Errorln(err)
  538. }
  539. if len(ipnets) > 0 {
  540. ret.Networkaddresses = jsonutils.Marshal(ipnets)
  541. }
  542. }
  543. return ret
  544. }
  545. func (gn *SGuestnetwork) getJsonDescHostwire(netif *SNetInterface) *api.GuestnetworkJsonDesc {
  546. desc := gn.getJsonDesc()
  547. if netif != nil {
  548. desc.Bridge = netif.Bridge
  549. desc.WireId = netif.WireId
  550. desc.Interface = netif.Interface
  551. }
  552. return desc
  553. }
  554. func (gn *SGuestnetwork) getJsonDescOneCloudVpc(network *SNetwork) *api.GuestnetworkJsonDesc {
  555. if gn.MappedIpAddr == "" {
  556. var (
  557. err error
  558. addr string
  559. )
  560. addr, err = GuestnetworkManager.allocMappedIpAddr(context.TODO())
  561. if err != nil {
  562. log.Errorf("getJsonDescOneCloudVpc: row %d: alloc mapped ipaddr: %v", gn.RowId, err)
  563. } else {
  564. if _, err := db.Update(gn, func() error {
  565. gn.MappedIpAddr = addr
  566. gn.MappedIp6Addr = api.GenVpcMappedIP6(addr)
  567. return nil
  568. }); err != nil {
  569. log.Errorf("getJsonDescOneCloudVpc: row %d: db update mapped addr: %v", gn.RowId, err)
  570. gn.MappedIpAddr = ""
  571. gn.MappedIp6Addr = ""
  572. }
  573. }
  574. } else if gn.MappedIp6Addr == "" {
  575. if _, err := db.Update(gn, func() error {
  576. gn.MappedIp6Addr = api.GenVpcMappedIP6(gn.MappedIpAddr)
  577. return nil
  578. }); err != nil {
  579. log.Errorf("getJsonDescOneCloudVpc for v6: row %d: db update mapped addr6: %v", gn.RowId, err)
  580. gn.MappedIp6Addr = ""
  581. }
  582. }
  583. desc := gn.getJsonDesc()
  584. vpc, _ := network.GetVpc()
  585. desc.Vpc.Id = vpc.Id
  586. desc.Vpc.Provider = api.VPC_PROVIDER_OVN
  587. desc.Vpc.MappedIpAddr = gn.MappedIpAddr
  588. desc.Vpc.MappedIp6Addr = gn.MappedIp6Addr
  589. return desc
  590. }
  591. func (gn *SGuestnetwork) getJsonDescHostLocal(network *SNetwork) *api.GuestnetworkJsonDesc {
  592. desc := gn.getJsonDesc()
  593. desc.Bridge = api.HostLocalBridge
  594. desc.WireId = api.DEFAULT_HOST_LOCAL_WIRE_ID
  595. return desc
  596. }
  597. func (gn *SGuestnetwork) getJsonDesc() *api.GuestnetworkJsonDesc {
  598. net, _ := gn.GetNetwork()
  599. var wire *SWire
  600. if net != nil {
  601. wire, _ = net.GetWire()
  602. }
  603. desc := &api.GuestnetworkJsonDesc{
  604. GuestnetworkBaseDesc: api.GuestnetworkBaseDesc{
  605. Net: net.Name,
  606. NetId: gn.NetworkId,
  607. Mac: gn.MacAddr,
  608. Virtual: gn.Virtual,
  609. IsDefault: gn.IsDefault,
  610. PortMappings: gn.PortMappings,
  611. },
  612. }
  613. if gn.Virtual {
  614. if len(gn.TeamWith) > 0 {
  615. teamGN, _ := gn.GetTeamGuestnetwork()
  616. if teamGN != nil {
  617. desc.Ip = teamGN.IpAddr
  618. }
  619. } else {
  620. desc.Ip = net.GetNetAddr().String()
  621. }
  622. } else {
  623. desc.Ip = gn.IpAddr
  624. }
  625. desc.Gateway = net.GuestGateway
  626. desc.Dns = net.GetDNS("")
  627. desc.Domain = net.GetDomain()
  628. desc.Ntp = net.GetNTP()
  629. desc.Ip6 = gn.Ip6Addr
  630. desc.Masklen6 = net.GuestIp6Mask
  631. desc.Gateway6 = net.GuestGateway6
  632. routes := net.GetRoutes()
  633. if routes != nil && len(routes) > 0 {
  634. desc.Routes = jsonutils.Marshal(routes)
  635. }
  636. desc.Masklen = net.GuestIpMask
  637. desc.Driver = gn.Driver
  638. desc.NumQueues = gn.NumQueues
  639. desc.RxTrafficLimit = gn.RxTrafficLimit
  640. desc.TxTrafficLimit = gn.TxTrafficLimit
  641. desc.Vlan = net.VlanId
  642. desc.Bw = gn.getBandwidth(net, wire)
  643. desc.Mtu = gn.getMtu(net, wire)
  644. desc.Index = gn.Index
  645. desc.VirtualIps = gn.GetVirtualIPs()
  646. desc.ExternalId = net.ExternalId
  647. desc.TeamWith = gn.TeamWith
  648. desc.BillingType = gn.BillingType
  649. desc.ChargeType = gn.ChargeType
  650. guest := gn.getGuest()
  651. if ifname, ok := gn.OvsOffloadIfname(); ok {
  652. desc.Ifname = ifname
  653. } else {
  654. desc.Ifname = gn.Ifname
  655. }
  656. if guest.GetHypervisor() != api.HYPERVISOR_KVM {
  657. manual := true
  658. desc.Manual = &manual
  659. } else {
  660. if gn.Driver == api.NETWORK_DRIVER_VFIO {
  661. dev, _ := gn.GetIsolatedDevice()
  662. if dev != nil {
  663. if dev.OvsOffloadInterface == "" {
  664. manual := true
  665. desc.Manual = &manual
  666. }
  667. if dev.IsInfinibandNic {
  668. desc.NicType = api.NIC_TYPE_INFINIBAND
  669. }
  670. }
  671. }
  672. }
  673. if options.Options.NetworkAlwaysManualConfig {
  674. manual := true
  675. desc.Manual = &manual
  676. }
  677. return desc
  678. }
  679. func (gn *SGuestnetwork) getSecgroupDesc() *api.GuestnetworkSecgroupDesc {
  680. secgroupJson, _ := GuestnetworksecgroupManager.getNetworkSecgroupJson(gn.GuestId, gn.Index)
  681. if len(secgroupJson) == 0 {
  682. return nil
  683. }
  684. guest := gn.GetGuest()
  685. securityRules := guest.getNetworkSecurityGroupsRules(gn.Index)
  686. return &api.GuestnetworkSecgroupDesc{
  687. Secgroups: secgroupJson,
  688. SecurityRules: securityRules,
  689. Index: gn.Index,
  690. Mac: gn.MacAddr,
  691. }
  692. }
  693. func (gn *SGuestnetwork) IsSriovWithoutOffload() bool {
  694. if gn.Driver != api.NETWORK_DRIVER_VFIO {
  695. return false
  696. }
  697. if dev, _ := gn.GetIsolatedDevice(); dev != nil && dev.OvsOffloadInterface != "" {
  698. return false
  699. }
  700. return true
  701. }
  702. func (gn *SGuestnetwork) OvsOffloadIfname() (string, bool) {
  703. if gn.Driver != api.NETWORK_DRIVER_VFIO {
  704. return "", false
  705. }
  706. if dev, _ := gn.GetIsolatedDevice(); dev != nil && dev.OvsOffloadInterface != "" {
  707. return dev.OvsOffloadInterface, true
  708. }
  709. return "", false
  710. }
  711. func (gn *SGuestnetwork) UpdateNicTrafficUsed(ctx context.Context, guest *SGuest, matrics *api.SNicTrafficRecord, tm time.Time, isReset bool) error {
  712. if gn.BillingType == billing_api.BILLING_TYPE_POSTPAID && gn.ChargeType == billing_api.NET_CHARGE_TYPE_BY_TRAFFIC {
  713. err := GuestNetworkTrafficLogManager.logTraffic(ctx, guest, gn, matrics, tm, isReset)
  714. if err != nil {
  715. return errors.Wrap(err, "log traffic")
  716. }
  717. }
  718. _, err := db.Update(gn, func() error {
  719. gn.RxTrafficUsed = matrics.RxTraffic
  720. gn.TxTrafficUsed = matrics.TxTraffic
  721. return nil
  722. })
  723. return errors.Wrap(err, "update guestnetwork traffic used")
  724. }
  725. func (gn *SGuestnetwork) UpdateBillingMode(ctx context.Context, userCred mcclient.TokenCredential, input api.ServerNicTrafficLimit) error {
  726. billingChange := false
  727. if len(input.BillingType) > 0 && input.BillingType != gn.BillingType {
  728. billingChange = true
  729. }
  730. if len(input.ChargeType) > 0 && input.ChargeType != gn.ChargeType {
  731. billingChange = true
  732. }
  733. var oldDesc *jsonutils.JSONDict
  734. if billingChange {
  735. oldDesc = gn.GetShortDesc(ctx)
  736. }
  737. _, err := db.Update(gn, func() error {
  738. if input.RxTrafficLimit != nil {
  739. gn.RxTrafficLimit = *input.RxTrafficLimit
  740. }
  741. if input.TxTrafficLimit != nil {
  742. gn.TxTrafficLimit = *input.TxTrafficLimit
  743. }
  744. if len(input.BillingType) > 0 && input.BillingType != gn.BillingType {
  745. gn.BillingType = input.BillingType
  746. }
  747. if len(input.ChargeType) > 0 && input.ChargeType != gn.ChargeType {
  748. gn.ChargeType = input.ChargeType
  749. }
  750. return nil
  751. })
  752. if err != nil {
  753. return errors.Wrap(err, "update guestnetwork billing mode")
  754. }
  755. if billingChange {
  756. guest := gn.GetGuest()
  757. net, _ := gn.GetNetwork()
  758. db.OpsLog.LogDetachEvent(ctx, guest, net, userCred, oldDesc)
  759. db.OpsLog.LogAttachEvent(ctx, guest, net, userCred, gn.GetShortDesc(ctx))
  760. }
  761. return nil
  762. }
  763. func (gn *SGuestnetwork) UpdatePortMappings(pms api.GuestPortMappings) error {
  764. _, err := db.Update(gn, func() error {
  765. gn.PortMappings = pms
  766. return nil
  767. })
  768. return err
  769. }
  770. func (manager *SGuestnetworkManager) GetGuestByAddress(address string, projectId string) *SGuest {
  771. gnQ := manager.Query()
  772. ipField := "ip_addr"
  773. if regutils.MatchIP6Addr(address) {
  774. ipField = "ip6_addr"
  775. }
  776. gnQ = gnQ.Equals(ipField, address)
  777. gnSubQ := gnQ.SubQuery()
  778. q := GuestManager.Query("hostname", "tenant_id")
  779. if len(projectId) > 0 {
  780. q = q.Equals("tenant_id", projectId)
  781. }
  782. q = q.Join(gnSubQ, sqlchemy.Equals(gnSubQ.Field("guest_id"), q.Field("id")))
  783. guests := make([]SGuest, 0)
  784. err := q.All(&guests)
  785. if err != nil {
  786. log.Errorf("GetGuestByAddress %s fail %s", address, err)
  787. return nil
  788. }
  789. if len(guests) == 0 {
  790. return nil
  791. }
  792. return &guests[0]
  793. }
  794. func (gn *SGuestnetwork) GetDetailedString() string {
  795. network, err := gn.GetNetwork()
  796. if err != nil {
  797. return ""
  798. }
  799. naCount, _ := NetworkAddressManager.fetchAddressCountByGuestnetworkId(gn.RowId)
  800. parts := []string{
  801. gn.IpAddr, fmt.Sprintf("%d", network.GuestIpMask),
  802. }
  803. if len(gn.Ip6Addr) > 0 {
  804. parts = append(parts, gn.Ip6Addr, fmt.Sprintf("%d", network.GuestIp6Mask))
  805. }
  806. parts = append(parts,
  807. gn.MacAddr,
  808. fmt.Sprintf("%d", network.VlanId),
  809. network.Name,
  810. gn.Driver,
  811. fmt.Sprintf("%d", gn.getBandwidth(network, nil)),
  812. fmt.Sprintf("%d", naCount),
  813. )
  814. return fmt.Sprintf("eth%d:%s", gn.Index, strings.Join(parts, "/"))
  815. }
  816. func (gn *SGuestnetwork) ValidateUpdateData(
  817. ctx context.Context,
  818. userCred mcclient.TokenCredential,
  819. query jsonutils.JSONObject,
  820. input api.GuestnetworkUpdateInput,
  821. ) (api.GuestnetworkUpdateInput, error) {
  822. if input.Index != nil {
  823. index := *input.Index
  824. q := GuestnetworkManager.Query().SubQuery()
  825. count, err := q.Query().Filter(sqlchemy.Equals(q.Field("guest_id"), gn.GuestId)).
  826. Filter(sqlchemy.NotEquals(q.Field("network_id"), gn.NetworkId)).
  827. Filter(sqlchemy.Equals(q.Field("index"), index)).CountWithError()
  828. if err != nil {
  829. return input, httperrors.NewInternalServerError("checkout nic index uniqueness fail %s", err)
  830. }
  831. if count > 0 {
  832. return input, httperrors.NewDuplicateResourceError("NIC Index %d has been occupied", index)
  833. }
  834. }
  835. if input.IsDefault != nil && *input.IsDefault {
  836. if gn.Virtual || len(gn.TeamWith) > 0 {
  837. return input, errors.Wrap(httperrors.ErrInvalidStatus, "cannot set virtual/slave interface as default")
  838. }
  839. net, err := gn.GetNetwork()
  840. if err != nil {
  841. return input, errors.Wrapf(err, "GetNetwork")
  842. }
  843. if len(net.GuestGateway) == 0 && len(net.GuestGateway6) == 0 {
  844. return input, errors.Wrap(httperrors.ErrInvalidStatus, "network of default gateway has no gateway")
  845. }
  846. if (len(gn.IpAddr) == 0 || (len(gn.IpAddr) > 0 && len(net.GuestGateway) == 0)) && (len(gn.Ip6Addr) == 0 || (len(gn.Ip6Addr) > 0 && len(net.GuestGateway6) == 0)) {
  847. return input, errors.Wrap(httperrors.ErrInvalidStatus, "nic of default gateway has no ip")
  848. }
  849. }
  850. for _, pm := range input.PortMappings {
  851. if err := validatePortMapping(pm); err != nil {
  852. return input, err
  853. }
  854. }
  855. var err error
  856. input.GuestJointBaseUpdateInput, err = gn.SGuestJointsBase.ValidateUpdateData(ctx, userCred, query, input.GuestJointBaseUpdateInput)
  857. if err != nil {
  858. return input, errors.Wrap(err, "SGuestJointsBase.ValidateUpdateData")
  859. }
  860. return input, nil
  861. }
  862. func (gn *SGuestnetwork) PostUpdate(ctx context.Context, userCred mcclient.TokenCredential, query, data jsonutils.JSONObject) {
  863. gn.SGuestJointsBase.PostUpdate(ctx, userCred, query, data)
  864. input := api.GuestnetworkUpdateInput{}
  865. err := data.Unmarshal(&input)
  866. if err != nil {
  867. log.Errorf("GuestnetworkUpdateInput unmarshal fail %s", err)
  868. return
  869. }
  870. if input.IsDefault != nil && *input.IsDefault {
  871. // make this nic as default, unset others
  872. guest := gn.GetGuest()
  873. err := guest.setDefaultGateway(ctx, userCred, gn.MacAddr)
  874. if err != nil {
  875. log.Errorf("fail to setDefaultGateway: %s", err)
  876. }
  877. } else {
  878. // try fix default gateway
  879. guest := gn.GetGuest()
  880. err := guest.fixDefaultGateway(ctx, userCred)
  881. if err != nil {
  882. log.Errorf("fail to fixDefaultGateway %s", err)
  883. }
  884. }
  885. }
  886. func (manager *SGuestnetworkManager) DeleteGuestNics(ctx context.Context, userCred mcclient.TokenCredential, gns []SGuestnetwork, reserve bool) error {
  887. for i := range gns {
  888. gn := gns[i]
  889. if len(gn.EipId) > 0 {
  890. return errors.Wrapf(httperrors.ErrInvalidStatus, "eip associate with %s", gn.IpAddr)
  891. }
  892. guest := gn.GetGuest()
  893. dev, err := guest.GetIsolatedDeviceByNetworkIndex(gn.Index)
  894. if err != nil {
  895. return errors.Wrap(err, "GetIsolatedDeviceByNetworkIndex")
  896. }
  897. if dev != nil {
  898. err = guest.detachIsolateDevice(ctx, userCred, dev)
  899. if err != nil {
  900. return errors.Wrapf(err, "detachIsolateDevice %s", dev.GetName())
  901. }
  902. }
  903. net, _ := gn.GetNetwork()
  904. if !gotypes.IsNil(net) && (regutils.MatchIP4Addr(gn.IpAddr) || regutils.MatchIP6Addr(gn.Ip6Addr)) {
  905. net.updateDnsRecord(&gn, false)
  906. if regutils.MatchIP4Addr(gn.IpAddr) {
  907. // ??
  908. // netman.get_manager().netmap_remove_node(gn.ip_addr)
  909. }
  910. }
  911. err = gn.Delete(ctx, userCred)
  912. if err != nil {
  913. log.Errorf("guest network %s delete fail %s", gn.GetDetailedString(), err)
  914. return errors.Wrapf(err, "Delete %s", gn.GetDetailedString())
  915. }
  916. gn.LogDetachEvent(ctx, userCred, guest, net)
  917. if !gotypes.IsNil(net) {
  918. if reserve && regutils.MatchIP4Addr(gn.IpAddr) {
  919. ReservedipManager.ReserveIP(ctx, userCred, net, gn.IpAddr, "Delete to reserve", api.AddressTypeIPv4)
  920. }
  921. if reserve && regutils.MatchIP6Addr(gn.Ip6Addr) {
  922. ReservedipManager.ReserveIP(ctx, userCred, net, gn.Ip6Addr, "Delete to reserve", api.AddressTypeIPv6)
  923. }
  924. }
  925. }
  926. return nil
  927. }
  928. func (manager *SGuestnetworkManager) getGuestNicByIP(ip string, networkId string, addrType api.TAddressType) (*SGuestnetwork, error) {
  929. gn := SGuestnetwork{}
  930. q := manager.Query()
  931. field := "ip_addr"
  932. if addrType == api.AddressTypeIPv6 {
  933. field = "ip6_addr"
  934. }
  935. q = q.Equals(field, ip).Equals("network_id", networkId)
  936. err := q.First(&gn)
  937. if err != nil {
  938. if err != sql.ErrNoRows {
  939. log.Errorf("getGuestNicByIP fail %s", err)
  940. return nil, err
  941. }
  942. return nil, nil
  943. }
  944. gn.SetModelManager(manager, &gn)
  945. return &gn, nil
  946. }
  947. func (gn *SGuestnetwork) LogDetachEvent(ctx context.Context, userCred mcclient.TokenCredential, guest *SGuest, network *SNetwork) {
  948. if network == nil {
  949. netTmp, err := NetworkManager.FetchById(gn.NetworkId)
  950. if err != nil {
  951. return
  952. }
  953. network = netTmp.(*SNetwork)
  954. }
  955. db.OpsLog.LogDetachEvent(ctx, guest, network, userCred, gn.GetShortDesc(ctx))
  956. }
  957. func (gn *SGuestnetwork) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
  958. if err := NetworkAddressManager.deleteByGuestnetworkId(ctx, userCred, gn.RowId); err != nil {
  959. return errors.Wrap(err, "delete attached network addresses")
  960. }
  961. return db.DeleteModel(ctx, userCred, gn)
  962. }
  963. func (gn *SGuestnetwork) Detach(ctx context.Context, userCred mcclient.TokenCredential) error {
  964. return db.DetachJoint(ctx, userCred, gn)
  965. }
  966. func totalGuestNicCount(
  967. scope rbacscope.TRbacScope,
  968. ownerId mcclient.IIdentityProvider,
  969. rangeObjs []db.IStandaloneModel,
  970. includeSystem bool,
  971. providers []string,
  972. brands []string,
  973. cloudEnv string,
  974. ) GuestnicsCount {
  975. guests := GuestManager.Query().SubQuery()
  976. hosts := HostManager.Query().SubQuery()
  977. guestnics := GuestnetworkManager.Query().SubQuery()
  978. q := guestnics.Query()
  979. q = q.Join(guests, sqlchemy.Equals(guests.Field("id"), guestnics.Field("guest_id")))
  980. q = q.Join(hosts, sqlchemy.Equals(guests.Field("host_id"), hosts.Field("id")))
  981. q = q.Filter(sqlchemy.IsFalse(guests.Field("pending_deleted")))
  982. q = CloudProviderFilter(q, hosts.Field("manager_id"), providers, brands, cloudEnv)
  983. q = RangeObjectsFilter(q, rangeObjs, nil, hosts.Field("zone_id"), hosts.Field("manager_id"), hosts.Field("id"), nil)
  984. switch scope {
  985. case rbacscope.ScopeSystem:
  986. // do nothing
  987. case rbacscope.ScopeDomain:
  988. q = q.Filter(sqlchemy.Equals(guests.Field("domain_id"), ownerId.GetProjectDomainId()))
  989. case rbacscope.ScopeProject:
  990. q = q.Filter(sqlchemy.Equals(guests.Field("tenant_id"), ownerId.GetProjectId()))
  991. }
  992. if !includeSystem {
  993. q = q.Filter(sqlchemy.OR(sqlchemy.IsNull(guests.Field("is_system")),
  994. sqlchemy.IsFalse(guests.Field("is_system"))))
  995. }
  996. return calculateNics(q)
  997. }
  998. type GuestnicsCount struct {
  999. InternalNicCount int
  1000. InternalVirtualNicCount int
  1001. ExternalNicCount int
  1002. ExternalVirtualNicCount int
  1003. InternalBandwidth int
  1004. ExternalBandwidth int
  1005. }
  1006. func calculateNics(q *sqlchemy.SQuery) GuestnicsCount {
  1007. cnt := GuestnicsCount{}
  1008. gns := make([]SGuestnetwork, 0)
  1009. err := db.FetchModelObjects(GuestnetworkManager, q, &gns)
  1010. if err != nil {
  1011. log.Errorf("guestnics total count query error %s", err)
  1012. }
  1013. for _, gn := range gns {
  1014. if gn.IsExit(nil) {
  1015. if gn.Virtual {
  1016. cnt.ExternalVirtualNicCount += 1
  1017. } else {
  1018. cnt.ExternalNicCount += 1
  1019. }
  1020. cnt.ExternalBandwidth += gn.BwLimit
  1021. } else {
  1022. if gn.Virtual {
  1023. cnt.InternalVirtualNicCount += 1
  1024. } else {
  1025. cnt.InternalNicCount += 1
  1026. }
  1027. cnt.InternalBandwidth += gn.BwLimit
  1028. }
  1029. }
  1030. return cnt
  1031. }
  1032. func (gn *SGuestnetwork) IsExit(net *SNetwork) bool {
  1033. if gn.IpAddr != "" {
  1034. addr, err := netutils.NewIPV4Addr(gn.IpAddr)
  1035. if err == nil {
  1036. return netutils.IsExitAddress(addr)
  1037. }
  1038. }
  1039. if net == nil {
  1040. net, _ = gn.GetNetwork()
  1041. }
  1042. if net != nil {
  1043. return net.IsExitNetwork()
  1044. }
  1045. return false
  1046. }
  1047. func (gn *SGuestnetwork) getBandwidth(net *SNetwork, wire *SWire) int {
  1048. if gn.BwLimit == 0 {
  1049. return 0
  1050. }
  1051. if gn.BwLimit > 0 && gn.BwLimit <= api.MAX_BANDWIDTH {
  1052. return gn.BwLimit
  1053. } else {
  1054. if wire == nil {
  1055. if net == nil {
  1056. net, _ = gn.GetNetwork()
  1057. }
  1058. if net != nil {
  1059. wire, _ = net.GetWire()
  1060. }
  1061. }
  1062. if wire != nil {
  1063. return wire.Bandwidth
  1064. }
  1065. return options.Options.DefaultBandwidth
  1066. }
  1067. }
  1068. func (gn *SGuestnetwork) getMtu(net *SNetwork, wire *SWire) int16 {
  1069. return net.getMtu(wire)
  1070. }
  1071. func (gn *SGuestnetwork) IsAllocated() bool {
  1072. region, _ := gn.GetGuest().getRegion()
  1073. provider := region.Provider
  1074. if regutils.MatchMacAddr(gn.MacAddr) && (gn.Virtual || regutils.MatchIP4Addr(gn.IpAddr) || regutils.MatchIP6Addr(gn.Ip6Addr) || (provider != api.CLOUD_PROVIDER_ONECLOUD && !options.Options.EnablePreAllocateIpAddr)) {
  1075. return true
  1076. }
  1077. return false
  1078. }
  1079. /* func GetIPTenantIdPairs() {
  1080. from guests import Guests
  1081. from hosts import Hosts
  1082. from sqlalchemy.sql.expression import bindparam
  1083. q = Guestnics.query(Guestnics.ip_addr, Guestnics.mac_addr,
  1084. bindparam('tunnel_key', None), # XXX: tunnel_key for VPC
  1085. Guests.tenant_id, Guests.name,
  1086. bindparam('tunnel_ip', None), Hosts.access_ip) \
  1087. .join(Guests, and_(Guests.id==Guestnics.guest_id,
  1088. Guests.deleted==False)) \
  1089. .join(Hosts, and_(Hosts.id==Guests.host_id,
  1090. Hosts.deleted==False))
  1091. return q.all()
  1092. } */
  1093. func (gn *SGuestnetwork) GetVirtualIPs() []string {
  1094. ips := make([]string, 0)
  1095. guest := gn.GetGuest()
  1096. net, _ := gn.GetNetwork()
  1097. for _, guestgroup := range guest.GetGroups() {
  1098. group := guestgroup.GetGroup()
  1099. groupnets, err := group.GetNetworks()
  1100. if err != nil {
  1101. continue
  1102. }
  1103. for _, groupnetwork := range groupnets {
  1104. gnet := groupnetwork.GetNetwork()
  1105. if net != nil && gnet.WireId == net.WireId {
  1106. ips = append(ips, groupnetwork.IpAddr)
  1107. }
  1108. }
  1109. }
  1110. return ips
  1111. }
  1112. func (gn *SGuestnetwork) GetIsolatedDevice() (*SIsolatedDevice, error) {
  1113. dev := SIsolatedDevice{}
  1114. q := IsolatedDeviceManager.Query().Equals("guest_id", gn.GuestId).Equals("network_index", gn.Index)
  1115. if cnt, err := q.CountWithError(); err != nil {
  1116. return nil, err
  1117. } else if cnt == 0 {
  1118. return nil, nil
  1119. }
  1120. err := q.First(&dev)
  1121. if err != nil {
  1122. return nil, err
  1123. }
  1124. dev.SetModelManager(IsolatedDeviceManager, &dev)
  1125. return &dev, nil
  1126. }
  1127. func (manager *SGuestnetworkManager) getRecentlyReleasedIPAddresses(networkId string, recentDuration time.Duration) map[string]bool {
  1128. return manager.getRecentlyReleasedIPAddressesInternal(networkId, recentDuration, api.AddressTypeIPv4)
  1129. }
  1130. func (manager *SGuestnetworkManager) getRecentlyReleasedIPAddresses6(networkId string, recentDuration time.Duration) map[string]bool {
  1131. return manager.getRecentlyReleasedIPAddressesInternal(networkId, recentDuration, api.AddressTypeIPv6)
  1132. }
  1133. func (manager *SGuestnetworkManager) getRecentlyReleasedIPAddressesInternal(networkId string, recentDuration time.Duration, addrType api.TAddressType) map[string]bool {
  1134. if recentDuration == 0 {
  1135. return nil
  1136. }
  1137. field := "ip_addr"
  1138. if addrType == api.AddressTypeIPv6 {
  1139. field = "ip6_addr"
  1140. }
  1141. since := time.Now().UTC().Add(-recentDuration)
  1142. q := manager.RawQuery(field)
  1143. q = q.Equals("network_id", networkId).IsTrue("deleted")
  1144. q = q.IsNotEmpty(field)
  1145. q = q.GT("deleted_at", since).Distinct()
  1146. rows, err := q.Rows()
  1147. if err != nil {
  1148. log.Errorf("GetRecentlyReleasedIPAddresses fail %s", err)
  1149. return nil
  1150. }
  1151. defer rows.Close()
  1152. ret := make(map[string]bool)
  1153. for rows.Next() {
  1154. var ip string
  1155. err = rows.Scan(&ip)
  1156. if err != nil {
  1157. log.Errorf("scan error %s", err)
  1158. } else {
  1159. ret[ip] = true
  1160. }
  1161. }
  1162. return ret
  1163. }
  1164. func (manager *SGuestnetworkManager) FilterByParams(q *sqlchemy.SQuery, params jsonutils.JSONObject) *sqlchemy.SQuery {
  1165. macStr := jsonutils.GetAnyString(params, []string{"mac", "mac_addr"})
  1166. if len(macStr) > 0 {
  1167. q = q.Filter(sqlchemy.Equals(q.Field("mac_addr"), macStr))
  1168. }
  1169. ipStr := jsonutils.GetAnyString(params, []string{"ipaddr", "ip_addr", "ip"})
  1170. if len(ipStr) > 0 {
  1171. q = q.Filter(sqlchemy.Equals(q.Field("ip_addr"), ipStr))
  1172. }
  1173. ip6Str := jsonutils.GetAnyString(params, []string{"ip6addr", "ip6_addr", "ip6"})
  1174. if len(ip6Str) > 0 {
  1175. q = q.Filter(sqlchemy.Equals(q.Field("ip6_addr"), ip6Str))
  1176. }
  1177. return q
  1178. }
  1179. func (manager *SGuestnetworkManager) FetchByIdsAndIpMac(guestId string, netId string, ipAddr string, mac string) (*SGuestnetwork, error) {
  1180. query := jsonutils.NewDict()
  1181. if len(mac) > 0 {
  1182. query.Add(jsonutils.NewString(mac), "mac_addr")
  1183. }
  1184. if len(ipAddr) > 0 {
  1185. query.Add(jsonutils.NewString(ipAddr), "ip_addr")
  1186. }
  1187. ign, err := db.FetchJointByIds(manager, guestId, netId, query)
  1188. if err != nil {
  1189. return nil, err
  1190. }
  1191. return ign.(*SGuestnetwork), nil
  1192. }
  1193. func (manager *SGuestnetworkManager) FetchByGuestId(guestId string) ([]SGuestnetwork, error) {
  1194. return manager.fetchGuestNetworks(func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
  1195. q = q.Equals("guest_id", guestId).Asc(q.Field("index"))
  1196. return q
  1197. })
  1198. }
  1199. func (manager *SGuestnetworkManager) fetchGuestNetworks(filter func(q *sqlchemy.SQuery) *sqlchemy.SQuery) ([]SGuestnetwork, error) {
  1200. q := manager.Query()
  1201. q = filter(q)
  1202. var rets []SGuestnetwork
  1203. if err := db.FetchModelObjects(manager, q, &rets); err != nil {
  1204. return nil, errors.Wrap(err, "FetchModelObjects")
  1205. }
  1206. return rets, nil
  1207. }
  1208. func (manager *SGuestnetworkManager) FetchByGuestIdIndex(guestId string, index int8) (*SGuestnetwork, error) {
  1209. rets, err := manager.FetchByGuestId(guestId)
  1210. if err != nil {
  1211. return nil, errors.Wrap(err, "FetchByGuestId")
  1212. }
  1213. if index >= 0 && int(index) < len(rets) {
  1214. return &rets[index], nil
  1215. }
  1216. return nil, errors.ErrNotFound
  1217. }
  1218. func (gn *SGuestnetwork) GetShortDesc(ctx context.Context) *jsonutils.JSONDict {
  1219. var net *SNetwork
  1220. var wire *SWire
  1221. if net == nil {
  1222. net, _ = gn.GetNetwork()
  1223. }
  1224. if wire == nil {
  1225. if net != nil {
  1226. wire, _ = net.GetWire()
  1227. }
  1228. }
  1229. desc := api.GuestnetworkShortDesc{}
  1230. if net != nil {
  1231. desc.BgpType = net.BgpType
  1232. }
  1233. if wire != nil {
  1234. desc.VpcId = wire.VpcId
  1235. }
  1236. if len(gn.IpAddr) > 0 {
  1237. desc.IpAddr = gn.IpAddr
  1238. desc.IsExit = gn.IsExit(net)
  1239. if desc.IsExit {
  1240. desc.NicType = "exit"
  1241. } else {
  1242. desc.NicType = "internal"
  1243. }
  1244. } else {
  1245. desc.NicType = "unused"
  1246. }
  1247. if len(gn.Ip6Addr) > 0 {
  1248. desc.Ip6Addr = gn.Ip6Addr
  1249. }
  1250. desc.Mac = gn.MacAddr
  1251. if len(gn.TeamWith) > 0 {
  1252. desc.TeamWith = gn.TeamWith
  1253. }
  1254. desc.BwLimitMbps = gn.getBandwidth(net, wire)
  1255. desc.Ifname = gn.Ifname
  1256. desc.IsDefault = gn.IsDefault
  1257. desc.BillingType = gn.BillingType
  1258. desc.ChargeType = gn.ChargeType
  1259. desc.GuestId = gn.GuestId
  1260. desc.NetworkId = gn.NetworkId
  1261. desc.PortMappings = gn.PortMappings
  1262. desc.SubIps = gn.GetSubIps()
  1263. return jsonutils.Marshal(desc).(*jsonutils.JSONDict)
  1264. }
  1265. func (gn *SGuestnetwork) GetWire() (*SWire, error) {
  1266. net, err := gn.GetNetwork()
  1267. if err != nil {
  1268. return nil, errors.Wrap(err, "GetNetwork")
  1269. }
  1270. return net.GetWire()
  1271. }
  1272. func (gn *SGuestnetwork) GetVpc() (*SVpc, error) {
  1273. net, err := gn.GetNetwork()
  1274. if err != nil {
  1275. return nil, errors.Wrap(err, "GetNetwork")
  1276. }
  1277. return net.GetVpc()
  1278. }
  1279. func (gn *SGuestnetwork) ToNetworkConfig() *api.NetworkConfig {
  1280. net, err := gn.GetNetwork()
  1281. if err != nil {
  1282. return nil
  1283. }
  1284. wire, _ := net.GetWire()
  1285. ret := &api.NetworkConfig{
  1286. Index: int(gn.Index),
  1287. Network: net.Id,
  1288. Wire: wire.Id,
  1289. Mac: gn.MacAddr,
  1290. Address: gn.IpAddr,
  1291. Address6: gn.Ip6Addr,
  1292. Driver: gn.Driver,
  1293. BwLimit: gn.BwLimit,
  1294. Project: net.ProjectId,
  1295. Domain: net.DomainId,
  1296. Ifname: gn.Ifname,
  1297. NetType: net.ServerType,
  1298. Exit: net.IsExitNetwork(),
  1299. }
  1300. return ret
  1301. }
  1302. func (manager *SGuestnetworkManager) ListItemFilter(
  1303. ctx context.Context,
  1304. q *sqlchemy.SQuery,
  1305. userCred mcclient.TokenCredential,
  1306. query api.GuestnetworkListInput,
  1307. ) (*sqlchemy.SQuery, error) {
  1308. var err error
  1309. q, err = manager.SGuestJointsManager.ListItemFilter(ctx, q, userCred, query.GuestJointsListInput)
  1310. if err != nil {
  1311. return nil, errors.Wrap(err, "SGuestJointsManager.ListItemFilter")
  1312. }
  1313. q, err = manager.SNetworkResourceBaseManager.ListItemFilter(ctx, q, userCred, query.NetworkFilterListInput)
  1314. if err != nil {
  1315. return nil, errors.Wrap(err, "SNetworkResourceBaseManager.ListItemFilter")
  1316. }
  1317. if len(query.MacAddr) > 0 {
  1318. q = q.In("mac_addr", query.MacAddr)
  1319. }
  1320. if len(query.IpAddr) > 0 {
  1321. naSubQ := NetworkAddressManager.Query("parent_id").Equals("type", api.NetworkAddressTypeSubIP).Equals("parent_type", api.NetworkAddressParentTypeGuestnetwork).In("ip_addr", query.IpAddr).SubQuery()
  1322. q = q.Filter(sqlchemy.OR(
  1323. sqlchemy.In(q.Field("ip_addr"), query.IpAddr),
  1324. sqlchemy.In(q.Field("row_id"), naSubQ),
  1325. ))
  1326. }
  1327. if len(query.Ip6Addr) > 0 {
  1328. q = q.In("ip6_addr", query.Ip6Addr)
  1329. }
  1330. if len(query.Driver) > 0 {
  1331. q = q.In("driver", query.Driver)
  1332. }
  1333. if len(query.Ifname) > 0 {
  1334. q = q.In("ifname", query.Ifname)
  1335. }
  1336. if len(query.TeamWith) > 0 {
  1337. q = q.In("team_with", query.TeamWith)
  1338. }
  1339. return q, nil
  1340. }
  1341. func (manager *SGuestnetworkManager) OrderByExtraFields(
  1342. ctx context.Context,
  1343. q *sqlchemy.SQuery,
  1344. userCred mcclient.TokenCredential,
  1345. query api.GuestnetworkListInput,
  1346. ) (*sqlchemy.SQuery, error) {
  1347. var err error
  1348. q, err = manager.SGuestJointsManager.OrderByExtraFields(ctx, q, userCred, query.GuestJointsListInput)
  1349. if err != nil {
  1350. return nil, errors.Wrap(err, "SGuestJointsManager.OrderByExtraFields")
  1351. }
  1352. q, err = manager.SNetworkResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.NetworkFilterListInput)
  1353. if err != nil {
  1354. return nil, errors.Wrap(err, "SNetworkResourceBaseManager.OrderByExtraFields")
  1355. }
  1356. return q, nil
  1357. }
  1358. func (manager *SGuestnetworkManager) ListItemExportKeys(ctx context.Context,
  1359. q *sqlchemy.SQuery,
  1360. userCred mcclient.TokenCredential,
  1361. keys stringutils2.SSortedStrings,
  1362. ) (*sqlchemy.SQuery, error) {
  1363. var err error
  1364. q, err = manager.SGuestJointsManager.ListItemExportKeys(ctx, q, userCred, keys)
  1365. if err != nil {
  1366. return nil, errors.Wrap(err, "SGuestJointsManager.ListItemExportKeys")
  1367. }
  1368. if keys.ContainsAny(manager.SNetworkResourceBaseManager.GetExportKeys()...) {
  1369. q, err = manager.SNetworkResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
  1370. if err != nil {
  1371. return nil, errors.Wrap(err, "SNetworkResourceBaseManager.ListItemExportKeys")
  1372. }
  1373. }
  1374. return q, nil
  1375. }
  1376. func (manager *SGuestnetworkManager) InitializeData() error {
  1377. err := manager.initOvnMappedIps()
  1378. if err != nil {
  1379. return errors.Wrap(err, "initOvnMappedIps")
  1380. }
  1381. return nil
  1382. }
  1383. func (manager *SGuestnetworkManager) initOvnMappedIps() error {
  1384. q := manager.Query()
  1385. networksQ := NetworkManager.Query().SubQuery()
  1386. wiresQ := WireManager.Query().SubQuery()
  1387. vpcQ := VpcManager.Query().SubQuery()
  1388. regionQ := CloudregionManager.Query().SubQuery()
  1389. q = q.Join(networksQ, sqlchemy.Equals(q.Field("network_id"), networksQ.Field("id")))
  1390. q = q.Join(wiresQ, sqlchemy.Equals(networksQ.Field("wire_id"), wiresQ.Field("id")))
  1391. q = q.Join(vpcQ, sqlchemy.Equals(wiresQ.Field("vpc_id"), vpcQ.Field("id")))
  1392. q = q.Join(regionQ, sqlchemy.Equals(vpcQ.Field("cloudregion_id"), regionQ.Field("id")))
  1393. q = q.Filter(sqlchemy.Equals(regionQ.Field("provider"), api.CLOUD_PROVIDER_ONECLOUD))
  1394. q = q.Filter(sqlchemy.NotEquals(vpcQ.Field("id"), api.DEFAULT_VPC_ID))
  1395. q = q.Filter(sqlchemy.OR(
  1396. sqlchemy.IsEmpty(q.Field("mapped_ip_addr")),
  1397. sqlchemy.IsEmpty(q.Field("mapped_ip6_addr")),
  1398. ))
  1399. gns := make([]SGuestnetwork, 0)
  1400. err := db.FetchModelObjects(manager, q, &gns)
  1401. if err != nil {
  1402. return errors.Wrap(err, "FetchModelObjects")
  1403. }
  1404. for i := range gns {
  1405. gn := &gns[i]
  1406. var v4addr string
  1407. if gn.MappedIpAddr == "" {
  1408. addr, err := manager.allocMappedIpAddr(context.Background())
  1409. if err != nil {
  1410. return errors.Wrap(err, "allocMappedIpAddr")
  1411. }
  1412. v4addr = addr
  1413. } else {
  1414. v4addr = gn.MappedIpAddr
  1415. }
  1416. if _, err := db.Update(gn, func() error {
  1417. gn.MappedIpAddr = v4addr
  1418. gn.MappedIp6Addr = api.GenVpcMappedIP6(v4addr)
  1419. return nil
  1420. }); err != nil {
  1421. return errors.Wrap(err, "db.Update")
  1422. }
  1423. }
  1424. return nil
  1425. }
  1426. func (guest *SGuest) IsStrictIpv6() (bool, error) {
  1427. q := GuestnetworkManager.Query().Equals("guest_id", guest.Id)
  1428. q = q.IsNotEmpty("ip6_addr").IsNullOrEmpty("ip_addr").IsFalse("virtual")
  1429. cnt, err := q.CountWithError()
  1430. if err != nil {
  1431. return false, errors.Wrap(err, "CountWithError")
  1432. }
  1433. return cnt > 0, nil
  1434. }
  1435. func (gn *SGuestnetwork) GetSubIps() string {
  1436. subIPQ := NetworkAddressManager.fetchSubIpsQuery(api.NetworkAddressParentTypeGuestnetwork)
  1437. subIPQ = subIPQ.Equals("parent_id", gn.RowId)
  1438. result := struct {
  1439. SubIps string `json:"sub_ips"`
  1440. }{}
  1441. err := subIPQ.First(&result)
  1442. if err != nil {
  1443. log.Errorf("Guestnetwork %s/%s/%s GetSubIps fail %s", gn.GuestId, gn.NetworkId, gn.MacAddr, err)
  1444. return ""
  1445. }
  1446. return result.SubIps
  1447. }