networks.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698
  1. package logic
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "net"
  7. "os/exec"
  8. "strings"
  9. "time"
  10. "github.com/go-playground/validator/v10"
  11. "github.com/gravitl/netmaker/database"
  12. "github.com/gravitl/netmaker/logger"
  13. "github.com/gravitl/netmaker/models"
  14. "github.com/gravitl/netmaker/netclient/ncutils"
  15. "github.com/gravitl/netmaker/validation"
  16. )
  17. // GetNetworks - returns all networks from database
  18. func GetNetworks() ([]models.Network, error) {
  19. var networks []models.Network
  20. collection, err := database.FetchRecords(database.NETWORKS_TABLE_NAME)
  21. if err != nil {
  22. return networks, err
  23. }
  24. for _, value := range collection {
  25. var network models.Network
  26. if err := json.Unmarshal([]byte(value), &network); err != nil {
  27. return networks, err
  28. }
  29. // add network our array
  30. networks = append(networks, network)
  31. }
  32. return networks, err
  33. }
  34. // DeleteNetwork - deletes a network
  35. func DeleteNetwork(network string) error {
  36. nodeCount, err := GetNetworkNonServerNodeCount(network)
  37. if nodeCount == 0 || database.IsEmptyRecord(err) {
  38. // delete server nodes first then db records
  39. servers, err := GetSortedNetworkServerNodes(network)
  40. if err == nil {
  41. for _, s := range servers {
  42. if err = DeleteNode(&s, true); err != nil {
  43. logger.Log(2, "could not removed server", s.Name, "before deleting network", network)
  44. } else {
  45. logger.Log(2, "removed server", s.Name, "before deleting network", network)
  46. }
  47. }
  48. } else {
  49. logger.Log(1, "could not remove servers before deleting network", network)
  50. }
  51. return database.DeleteRecord(database.NETWORKS_TABLE_NAME, network)
  52. }
  53. return errors.New("node check failed. All nodes must be deleted before deleting network")
  54. }
  55. // CreateNetwork - creates a network in database
  56. func CreateNetwork(network models.Network) error {
  57. network.SetDefaults()
  58. network.SetNodesLastModified()
  59. network.SetNetworkLastModified()
  60. network.KeyUpdateTimeStamp = time.Now().Unix()
  61. err := ValidateNetwork(&network, false)
  62. if err != nil {
  63. //returnErrorResponse(w, r, formatError(err, "badrequest"))
  64. return err
  65. }
  66. data, err := json.Marshal(&network)
  67. if err != nil {
  68. return err
  69. }
  70. if err = database.Insert(network.NetID, string(data), database.NETWORKS_TABLE_NAME); err != nil {
  71. return err
  72. }
  73. return err
  74. }
  75. // NetworkNodesUpdatePullChanges - tells nodes on network to pull
  76. func NetworkNodesUpdatePullChanges(networkName string) error {
  77. collections, err := database.FetchRecords(database.NODES_TABLE_NAME)
  78. if err != nil {
  79. if database.IsEmptyRecord(err) {
  80. return nil
  81. }
  82. return err
  83. }
  84. for _, value := range collections {
  85. var node models.Node
  86. err := json.Unmarshal([]byte(value), &node)
  87. if err != nil {
  88. fmt.Println("error in node address assignment!")
  89. return err
  90. }
  91. if node.Network == networkName {
  92. node.PullChanges = "yes"
  93. data, err := json.Marshal(&node)
  94. if err != nil {
  95. return err
  96. }
  97. node.SetID()
  98. database.Insert(node.ID, string(data), database.NODES_TABLE_NAME)
  99. }
  100. }
  101. return nil
  102. }
  103. // GetNetworkNonServerNodeCount - get number of network non server nodes
  104. func GetNetworkNonServerNodeCount(networkName string) (int, error) {
  105. collection, err := database.FetchRecords(database.NODES_TABLE_NAME)
  106. count := 0
  107. if err != nil && !database.IsEmptyRecord(err) {
  108. return count, err
  109. }
  110. for _, value := range collection {
  111. var node models.Node
  112. if err = json.Unmarshal([]byte(value), &node); err != nil {
  113. return count, err
  114. } else {
  115. if node.Network == networkName && node.IsServer != "yes" {
  116. count++
  117. }
  118. }
  119. }
  120. return count, nil
  121. }
  122. // GetParentNetwork - get parent network
  123. func GetParentNetwork(networkname string) (models.Network, error) {
  124. var network models.Network
  125. networkData, err := database.FetchRecord(database.NETWORKS_TABLE_NAME, networkname)
  126. if err != nil {
  127. return network, err
  128. }
  129. if err = json.Unmarshal([]byte(networkData), &network); err != nil {
  130. return models.Network{}, err
  131. }
  132. return network, nil
  133. }
  134. // GetParentNetwork - get parent network
  135. func GetNetworkSettings(networkname string) (models.Network, error) {
  136. var network models.Network
  137. networkData, err := database.FetchRecord(database.NETWORKS_TABLE_NAME, networkname)
  138. if err != nil {
  139. return network, err
  140. }
  141. if err = json.Unmarshal([]byte(networkData), &network); err != nil {
  142. return models.Network{}, err
  143. }
  144. network.AccessKeys = []models.AccessKey{}
  145. return network, nil
  146. }
  147. // UniqueAddress - see if address is unique
  148. func UniqueAddress(networkName string) (string, error) {
  149. var network models.Network
  150. network, err := GetParentNetwork(networkName)
  151. if err != nil {
  152. fmt.Println("UniqueAddress encountered an error")
  153. return "666", err
  154. }
  155. offset := true
  156. ip, ipnet, err := net.ParseCIDR(network.AddressRange)
  157. if err != nil {
  158. fmt.Println("UniqueAddress encountered an error")
  159. return "666", err
  160. }
  161. for ip := ip.Mask(ipnet.Mask); ipnet.Contains(ip); Inc(ip) {
  162. if offset {
  163. offset = false
  164. continue
  165. }
  166. if networkName == "comms" {
  167. if IsIPUnique(networkName, ip.String(), database.INT_CLIENTS_TABLE_NAME, false) {
  168. return ip.String(), err
  169. }
  170. } else {
  171. if IsIPUnique(networkName, ip.String(), database.NODES_TABLE_NAME, false) && IsIPUnique(networkName, ip.String(), database.EXT_CLIENT_TABLE_NAME, false) {
  172. return ip.String(), err
  173. }
  174. }
  175. }
  176. //TODO
  177. err1 := errors.New("ERROR: No unique addresses available. Check network subnet.")
  178. return "W1R3: NO UNIQUE ADDRESSES AVAILABLE", err1
  179. }
  180. // IsIPUnique - checks if an IP is unique
  181. func IsIPUnique(network string, ip string, tableName string, isIpv6 bool) bool {
  182. isunique := true
  183. collection, err := database.FetchRecords(tableName)
  184. if err != nil {
  185. return isunique
  186. }
  187. for _, value := range collection { // filter
  188. var node models.Node
  189. if err = json.Unmarshal([]byte(value), &node); err != nil {
  190. continue
  191. }
  192. if isIpv6 {
  193. if node.Address6 == ip && node.Network == network {
  194. return false
  195. }
  196. } else {
  197. if node.Address == ip && node.Network == network {
  198. return false
  199. }
  200. }
  201. }
  202. return isunique
  203. }
  204. // UniqueAddress6 - see if ipv6 address is unique
  205. func UniqueAddress6(networkName string) (string, error) {
  206. var network models.Network
  207. network, err := GetParentNetwork(networkName)
  208. if err != nil {
  209. fmt.Println("Network Not Found")
  210. return "", err
  211. }
  212. if network.IsDualStack == "no" {
  213. return "", nil
  214. }
  215. offset := true
  216. ip, ipnet, err := net.ParseCIDR(network.AddressRange6)
  217. if err != nil {
  218. fmt.Println("UniqueAddress6 encountered an error")
  219. return "666", err
  220. }
  221. for ip := ip.Mask(ipnet.Mask); ipnet.Contains(ip); Inc(ip) {
  222. if offset {
  223. offset = false
  224. continue
  225. }
  226. if IsIPUnique(networkName, ip.String(), database.NODES_TABLE_NAME, true) {
  227. return ip.String(), err
  228. }
  229. }
  230. //TODO
  231. err1 := errors.New("ERROR: No unique addresses available. Check network subnet.")
  232. return "W1R3: NO UNIQUE ADDRESSES AVAILABLE", err1
  233. }
  234. // GetLocalIP - gets the local ip
  235. func GetLocalIP(node models.Node) string {
  236. var local string
  237. ifaces, err := net.Interfaces()
  238. if err != nil {
  239. return local
  240. }
  241. _, localrange, err := net.ParseCIDR(node.LocalRange)
  242. if err != nil {
  243. return local
  244. }
  245. found := false
  246. for _, i := range ifaces {
  247. if i.Flags&net.FlagUp == 0 {
  248. continue // interface down
  249. }
  250. if i.Flags&net.FlagLoopback != 0 {
  251. continue // loopback interface
  252. }
  253. addrs, err := i.Addrs()
  254. if err != nil {
  255. return local
  256. }
  257. for _, addr := range addrs {
  258. var ip net.IP
  259. switch v := addr.(type) {
  260. case *net.IPNet:
  261. if !found {
  262. ip = v.IP
  263. local = ip.String()
  264. if node.IsLocal == "yes" {
  265. found = localrange.Contains(ip)
  266. } else {
  267. found = true
  268. }
  269. }
  270. case *net.IPAddr:
  271. if !found {
  272. ip = v.IP
  273. local = ip.String()
  274. if node.IsLocal == "yes" {
  275. found = localrange.Contains(ip)
  276. } else {
  277. found = true
  278. }
  279. }
  280. }
  281. }
  282. }
  283. return local
  284. }
  285. // UpdateNetworkLocalAddresses - updates network localaddresses
  286. func UpdateNetworkLocalAddresses(networkName string) error {
  287. collection, err := database.FetchRecords(database.NODES_TABLE_NAME)
  288. if err != nil {
  289. return err
  290. }
  291. for _, value := range collection {
  292. var node models.Node
  293. err := json.Unmarshal([]byte(value), &node)
  294. if err != nil {
  295. fmt.Println("error in node address assignment!")
  296. return err
  297. }
  298. if node.Network == networkName {
  299. ipaddr, iperr := UniqueAddress(networkName)
  300. if iperr != nil {
  301. fmt.Println("error in node address assignment!")
  302. return iperr
  303. }
  304. node.Address = ipaddr
  305. newNodeData, err := json.Marshal(&node)
  306. if err != nil {
  307. fmt.Println("error in node address assignment!")
  308. return err
  309. }
  310. node.SetID()
  311. database.Insert(node.ID, string(newNodeData), database.NODES_TABLE_NAME)
  312. }
  313. }
  314. return nil
  315. }
  316. // RemoveNetworkNodeIPv6Addresses - removes network node IPv6 addresses
  317. func RemoveNetworkNodeIPv6Addresses(networkName string) error {
  318. collections, err := database.FetchRecords(database.NODES_TABLE_NAME)
  319. if err != nil {
  320. return err
  321. }
  322. for _, value := range collections {
  323. var node models.Node
  324. err := json.Unmarshal([]byte(value), &node)
  325. if err != nil {
  326. fmt.Println("error in node address assignment!")
  327. return err
  328. }
  329. if node.Network == networkName {
  330. node.IsDualStack = "no"
  331. node.Address6 = ""
  332. node.PullChanges = "yes"
  333. data, err := json.Marshal(&node)
  334. if err != nil {
  335. return err
  336. }
  337. node.SetID()
  338. database.Insert(node.ID, string(data), database.NODES_TABLE_NAME)
  339. }
  340. }
  341. return nil
  342. }
  343. // UpdateNetworkNodeAddresses - updates network node addresses
  344. func UpdateNetworkNodeAddresses(networkName string) error {
  345. collections, err := database.FetchRecords(database.NODES_TABLE_NAME)
  346. if err != nil {
  347. return err
  348. }
  349. for _, value := range collections {
  350. var node models.Node
  351. err := json.Unmarshal([]byte(value), &node)
  352. if err != nil {
  353. fmt.Println("error in node address assignment!")
  354. return err
  355. }
  356. if node.Network == networkName {
  357. ipaddr, iperr := UniqueAddress(networkName)
  358. if iperr != nil {
  359. fmt.Println("error in node address assignment!")
  360. return iperr
  361. }
  362. node.Address = ipaddr
  363. node.PullChanges = "yes"
  364. data, err := json.Marshal(&node)
  365. if err != nil {
  366. return err
  367. }
  368. node.SetID()
  369. database.Insert(node.ID, string(data), database.NODES_TABLE_NAME)
  370. }
  371. }
  372. return nil
  373. }
  374. // IsNetworkDisplayNameUnique - checks if displayname is unique from other networks
  375. func IsNetworkDisplayNameUnique(network *models.Network) (bool, error) {
  376. isunique := true
  377. records, err := GetNetworks()
  378. if err != nil && !database.IsEmptyRecord(err) {
  379. return false, err
  380. }
  381. for i := 0; i < len(records); i++ {
  382. if network.NetID == records[i].DisplayName {
  383. isunique = false
  384. }
  385. }
  386. return isunique, nil
  387. }
  388. // IsNetworkNameUnique - checks to see if any other networks have the same name (id)
  389. func IsNetworkNameUnique(network *models.Network) (bool, error) {
  390. isunique := true
  391. dbs, err := GetNetworks()
  392. if err != nil && !database.IsEmptyRecord(err) {
  393. return false, err
  394. }
  395. for i := 0; i < len(dbs); i++ {
  396. if network.NetID == dbs[i].NetID {
  397. isunique = false
  398. }
  399. }
  400. return isunique, nil
  401. }
  402. // UpdateNetwork - updates a network with another network's fields
  403. func UpdateNetwork(currentNetwork *models.Network, newNetwork *models.Network) (bool, bool, error) {
  404. if err := ValidateNetwork(newNetwork, true); err != nil {
  405. return false, false, err
  406. }
  407. if newNetwork.NetID == currentNetwork.NetID {
  408. hasrangeupdate := newNetwork.AddressRange != currentNetwork.AddressRange
  409. localrangeupdate := newNetwork.LocalRange != currentNetwork.LocalRange
  410. data, err := json.Marshal(newNetwork)
  411. if err != nil {
  412. return false, false, err
  413. }
  414. newNetwork.SetNetworkLastModified()
  415. err = database.Insert(newNetwork.NetID, string(data), database.NETWORKS_TABLE_NAME)
  416. return hasrangeupdate, localrangeupdate, err
  417. }
  418. // copy values
  419. return false, false, errors.New("failed to update network " + newNetwork.NetID + ", cannot change netid.")
  420. }
  421. // Inc - increments an IP
  422. func Inc(ip net.IP) {
  423. for j := len(ip) - 1; j >= 0; j-- {
  424. ip[j]++
  425. if ip[j] > 0 {
  426. break
  427. }
  428. }
  429. }
  430. // GetNetwork - gets a network from database
  431. func GetNetwork(networkname string) (models.Network, error) {
  432. var network models.Network
  433. networkData, err := database.FetchRecord(database.NETWORKS_TABLE_NAME, networkname)
  434. if err != nil {
  435. return network, err
  436. }
  437. if err = json.Unmarshal([]byte(networkData), &network); err != nil {
  438. return models.Network{}, err
  439. }
  440. return network, nil
  441. }
  442. // Network.NetIDInNetworkCharSet - checks if a netid of a network uses valid characters
  443. func NetIDInNetworkCharSet(network *models.Network) bool {
  444. charset := "abcdefghijklmnopqrstuvwxyz1234567890-_."
  445. for _, char := range network.NetID {
  446. if !strings.Contains(charset, strings.ToLower(string(char))) {
  447. return false
  448. }
  449. }
  450. return true
  451. }
  452. // Network.Validate - validates fields of an network struct
  453. func ValidateNetwork(network *models.Network, isUpdate bool) error {
  454. v := validator.New()
  455. _ = v.RegisterValidation("netid_valid", func(fl validator.FieldLevel) bool {
  456. inCharSet := NetIDInNetworkCharSet(network)
  457. if isUpdate {
  458. return inCharSet
  459. }
  460. isFieldUnique, _ := IsNetworkNameUnique(network)
  461. return isFieldUnique && inCharSet
  462. })
  463. //
  464. _ = v.RegisterValidation("displayname_valid", func(fl validator.FieldLevel) bool {
  465. isFieldUnique, _ := IsNetworkDisplayNameUnique(network)
  466. inCharSet := network.DisplayNameInNetworkCharSet()
  467. if isUpdate {
  468. return inCharSet
  469. }
  470. return isFieldUnique && inCharSet
  471. })
  472. _ = v.RegisterValidation("checkyesorno", func(fl validator.FieldLevel) bool {
  473. return validation.CheckYesOrNo(fl)
  474. })
  475. err := v.Struct(network)
  476. if err != nil {
  477. for _, e := range err.(validator.ValidationErrors) {
  478. fmt.Println(e)
  479. }
  480. }
  481. return err
  482. }
  483. // ParseNetwork - parses a network into a model
  484. func ParseNetwork(value string) (models.Network, error) {
  485. var network models.Network
  486. err := json.Unmarshal([]byte(value), &network)
  487. return network, err
  488. }
  489. // ValidateNetworkUpdate - checks if network is valid to update
  490. func ValidateNetworkUpdate(network models.Network) error {
  491. v := validator.New()
  492. _ = v.RegisterValidation("netid_valid", func(fl validator.FieldLevel) bool {
  493. if fl.Field().String() == "" {
  494. return true
  495. }
  496. inCharSet := nameInNetworkCharSet(fl.Field().String())
  497. return inCharSet
  498. })
  499. err := v.Struct(network)
  500. if err != nil {
  501. for _, e := range err.(validator.ValidationErrors) {
  502. logger.Log(1, "validator", e.Error())
  503. }
  504. }
  505. return err
  506. }
  507. // KeyUpdate - updates keys on network
  508. func KeyUpdate(netname string) (models.Network, error) {
  509. err := networkNodesUpdateAction(netname, models.NODE_UPDATE_KEY)
  510. if err != nil {
  511. return models.Network{}, err
  512. }
  513. return models.Network{}, nil
  514. }
  515. // == Private ==
  516. func networkNodesUpdateAction(networkName string, action string) error {
  517. collections, err := database.FetchRecords(database.NODES_TABLE_NAME)
  518. if err != nil {
  519. if database.IsEmptyRecord(err) {
  520. return nil
  521. }
  522. return err
  523. }
  524. for _, value := range collections {
  525. var node models.Node
  526. err := json.Unmarshal([]byte(value), &node)
  527. if err != nil {
  528. fmt.Println("error in node address assignment!")
  529. return err
  530. }
  531. if action == models.NODE_UPDATE_KEY && node.IsStatic == "yes" {
  532. continue
  533. }
  534. if node.Network == networkName {
  535. node.Action = action
  536. data, err := json.Marshal(&node)
  537. if err != nil {
  538. return err
  539. }
  540. node.SetID()
  541. database.Insert(node.ID, string(data), database.NODES_TABLE_NAME)
  542. }
  543. }
  544. return nil
  545. }
  546. func nameInNetworkCharSet(name string) bool {
  547. charset := "abcdefghijklmnopqrstuvwxyz1234567890-_."
  548. for _, char := range name {
  549. if !strings.Contains(charset, strings.ToLower(string(char))) {
  550. return false
  551. }
  552. }
  553. return true
  554. }
  555. func deleteInterface(ifacename string, postdown string) error {
  556. var err error
  557. if !ncutils.IsKernel() {
  558. err = RemoveConf(ifacename, true)
  559. } else {
  560. ipExec, errN := exec.LookPath("ip")
  561. err = errN
  562. if err != nil {
  563. logger.Log(1, err.Error())
  564. }
  565. _, err = ncutils.RunCmd(ipExec+" link del "+ifacename, false)
  566. if postdown != "" {
  567. runcmds := strings.Split(postdown, "; ")
  568. err = ncutils.RunCmds(runcmds, false)
  569. }
  570. }
  571. return err
  572. }
  573. func isInterfacePresent(iface string, address string) (string, bool) {
  574. var interfaces []net.Interface
  575. var err error
  576. interfaces, err = net.Interfaces()
  577. if err != nil {
  578. logger.Log(0, "ERROR: could not read interfaces")
  579. return "", true
  580. }
  581. for _, currIface := range interfaces {
  582. var currAddrs []net.Addr
  583. currAddrs, err = currIface.Addrs()
  584. if err != nil || len(currAddrs) == 0 {
  585. continue
  586. }
  587. for _, addr := range currAddrs {
  588. if strings.Contains(addr.String(), address) && currIface.Name != iface {
  589. logger.Log(2, "found iface", addr.String(), currIface.Name)
  590. interfaces = nil
  591. currAddrs = nil
  592. return currIface.Name, false
  593. }
  594. }
  595. currAddrs = nil
  596. }
  597. interfaces = nil
  598. logger.Log(2, "failed to find iface", iface)
  599. return "", true
  600. }