nodes.go 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982
  1. package logic
  2. import (
  3. "context"
  4. "encoding/json"
  5. "errors"
  6. "fmt"
  7. "maps"
  8. "net"
  9. "slices"
  10. "sort"
  11. "sync"
  12. "time"
  13. validator "github.com/go-playground/validator/v10"
  14. "github.com/google/uuid"
  15. "github.com/gravitl/netmaker/database"
  16. "github.com/gravitl/netmaker/logger"
  17. "github.com/gravitl/netmaker/logic/acls"
  18. "github.com/gravitl/netmaker/logic/acls/nodeacls"
  19. "github.com/gravitl/netmaker/models"
  20. "github.com/gravitl/netmaker/servercfg"
  21. "github.com/gravitl/netmaker/validation"
  22. "github.com/seancfoley/ipaddress-go/ipaddr"
  23. "golang.org/x/exp/slog"
  24. )
  25. var (
  26. nodeCacheMutex = &sync.RWMutex{}
  27. nodeNetworkCacheMutex = &sync.RWMutex{}
  28. nodesCacheMap = make(map[string]models.Node)
  29. nodesNetworkCacheMap = make(map[string]map[string]models.Node)
  30. IPv4Network = "0.0.0.0/0"
  31. IPv6Network = "::/0"
  32. )
  33. func getNodeFromCache(nodeID string) (node models.Node, ok bool) {
  34. nodeCacheMutex.RLock()
  35. node, ok = nodesCacheMap[nodeID]
  36. if node.Mutex == nil {
  37. node.Mutex = &sync.Mutex{}
  38. }
  39. nodeCacheMutex.RUnlock()
  40. return
  41. }
  42. func getNodesFromCache() (nodes []models.Node) {
  43. nodeCacheMutex.RLock()
  44. for _, node := range nodesCacheMap {
  45. if node.Mutex == nil {
  46. node.Mutex = &sync.Mutex{}
  47. }
  48. nodes = append(nodes, node)
  49. }
  50. nodeCacheMutex.RUnlock()
  51. return
  52. }
  53. func deleteNodeFromCache(nodeID string) {
  54. nodeCacheMutex.Lock()
  55. delete(nodesCacheMap, nodeID)
  56. nodeCacheMutex.Unlock()
  57. }
  58. func deleteNodeFromNetworkCache(nodeID string, network string) {
  59. nodeNetworkCacheMutex.Lock()
  60. delete(nodesNetworkCacheMap[network], nodeID)
  61. nodeNetworkCacheMutex.Unlock()
  62. }
  63. func storeNodeInNetworkCache(node models.Node, network string) {
  64. nodeNetworkCacheMutex.Lock()
  65. if nodesNetworkCacheMap[network] == nil {
  66. nodesNetworkCacheMap[network] = make(map[string]models.Node)
  67. }
  68. nodesNetworkCacheMap[network][node.ID.String()] = node
  69. nodeNetworkCacheMutex.Unlock()
  70. }
  71. func storeNodeInCache(node models.Node) {
  72. nodeCacheMutex.Lock()
  73. nodesCacheMap[node.ID.String()] = node
  74. nodeCacheMutex.Unlock()
  75. }
  76. func loadNodesIntoNetworkCache(nMap map[string]models.Node) {
  77. nodeNetworkCacheMutex.Lock()
  78. for _, v := range nMap {
  79. network := v.Network
  80. if nodesNetworkCacheMap[network] == nil {
  81. nodesNetworkCacheMap[network] = make(map[string]models.Node)
  82. }
  83. nodesNetworkCacheMap[network][v.ID.String()] = v
  84. }
  85. nodeNetworkCacheMutex.Unlock()
  86. }
  87. func loadNodesIntoCache(nMap map[string]models.Node) {
  88. nodeCacheMutex.Lock()
  89. nodesCacheMap = nMap
  90. nodeCacheMutex.Unlock()
  91. }
  92. func ClearNodeCache() {
  93. nodeCacheMutex.Lock()
  94. nodesCacheMap = make(map[string]models.Node)
  95. nodesNetworkCacheMap = make(map[string]map[string]models.Node)
  96. nodeCacheMutex.Unlock()
  97. }
  98. const (
  99. // RELAY_NODE_ERR - error to return if relay node is unfound
  100. RELAY_NODE_ERR = "could not find relay for node"
  101. // NodePurgeTime time to wait for node to response to a NODE_DELETE actions
  102. NodePurgeTime = time.Second * 10
  103. // NodePurgeCheckTime is how often to check nodes for Pending Delete
  104. NodePurgeCheckTime = time.Second * 30
  105. )
  106. // GetNetworkNodes - gets the nodes of a network
  107. func GetNetworkNodes(network string) ([]models.Node, error) {
  108. if networkNodes, ok := nodesNetworkCacheMap[network]; ok {
  109. nodeNetworkCacheMutex.Lock()
  110. defer nodeNetworkCacheMutex.Unlock()
  111. return slices.Collect(maps.Values(networkNodes)), nil
  112. }
  113. allnodes, err := GetAllNodes()
  114. if err != nil {
  115. return []models.Node{}, err
  116. }
  117. return GetNetworkNodesMemory(allnodes, network), nil
  118. }
  119. // GetHostNodes - fetches all nodes part of the host
  120. func GetHostNodes(host *models.Host) []models.Node {
  121. nodes := []models.Node{}
  122. for _, nodeID := range host.Nodes {
  123. node, err := GetNodeByID(nodeID)
  124. if err == nil {
  125. nodes = append(nodes, node)
  126. }
  127. }
  128. return nodes
  129. }
  130. // GetNetworkNodesMemory - gets all nodes belonging to a network from list in memory
  131. func GetNetworkNodesMemory(allNodes []models.Node, network string) []models.Node {
  132. if networkNodes, ok := nodesNetworkCacheMap[network]; ok {
  133. nodeNetworkCacheMutex.Lock()
  134. defer nodeNetworkCacheMutex.Unlock()
  135. return slices.Collect(maps.Values(networkNodes))
  136. }
  137. var nodes = make([]models.Node, 0, len(allNodes))
  138. for i := range allNodes {
  139. node := allNodes[i]
  140. if node.Network == network {
  141. nodes = append(nodes, node)
  142. }
  143. }
  144. return nodes
  145. }
  146. // UpdateNodeCheckin - updates the checkin time of a node
  147. func UpdateNodeCheckin(node *models.Node) error {
  148. node.SetLastCheckIn()
  149. data, err := json.Marshal(node)
  150. if err != nil {
  151. return err
  152. }
  153. node.EgressDetails = models.EgressDetails{}
  154. err = database.Insert(node.ID.String(), string(data), database.NODES_TABLE_NAME)
  155. if err != nil {
  156. return err
  157. }
  158. if servercfg.CacheEnabled() {
  159. storeNodeInCache(*node)
  160. storeNodeInNetworkCache(*node, node.Network)
  161. }
  162. return nil
  163. }
  164. // UpsertNode - updates node in the DB
  165. func UpsertNode(newNode *models.Node) error {
  166. newNode.SetLastModified()
  167. data, err := json.Marshal(newNode)
  168. if err != nil {
  169. return err
  170. }
  171. newNode.EgressDetails = models.EgressDetails{}
  172. err = database.Insert(newNode.ID.String(), string(data), database.NODES_TABLE_NAME)
  173. if err != nil {
  174. return err
  175. }
  176. if servercfg.CacheEnabled() {
  177. storeNodeInCache(*newNode)
  178. storeNodeInNetworkCache(*newNode, newNode.Network)
  179. }
  180. return nil
  181. }
  182. // UpdateNode - takes a node and updates another node with it's values
  183. func UpdateNode(currentNode *models.Node, newNode *models.Node) error {
  184. if newNode.Address.IP.String() != currentNode.Address.IP.String() {
  185. if network, err := GetParentNetwork(newNode.Network); err == nil {
  186. if !IsAddressInCIDR(newNode.Address.IP, network.AddressRange) {
  187. return fmt.Errorf("invalid address provided; out of network range for node %s", newNode.ID)
  188. }
  189. }
  190. }
  191. nodeACLDelta := currentNode.DefaultACL != newNode.DefaultACL
  192. newNode.Fill(currentNode, servercfg.IsPro)
  193. // check for un-settable server values
  194. if err := ValidateNode(newNode, true); err != nil {
  195. return err
  196. }
  197. if newNode.ID == currentNode.ID {
  198. if nodeACLDelta {
  199. if err := UpdateProNodeACLs(newNode); err != nil {
  200. logger.Log(1, "failed to apply node level ACLs during creation of node", newNode.ID.String(), "-", err.Error())
  201. return err
  202. }
  203. }
  204. newNode.EgressDetails = models.EgressDetails{}
  205. newNode.SetLastModified()
  206. if data, err := json.Marshal(newNode); err != nil {
  207. return err
  208. } else {
  209. err = database.Insert(newNode.ID.String(), string(data), database.NODES_TABLE_NAME)
  210. if err != nil {
  211. return err
  212. }
  213. if servercfg.CacheEnabled() {
  214. storeNodeInCache(*newNode)
  215. storeNodeInNetworkCache(*newNode, newNode.Network)
  216. if _, ok := allocatedIpMap[newNode.Network]; ok {
  217. if newNode.Address.IP != nil && !newNode.Address.IP.Equal(currentNode.Address.IP) {
  218. AddIpToAllocatedIpMap(newNode.Network, newNode.Address.IP)
  219. RemoveIpFromAllocatedIpMap(currentNode.Network, currentNode.Address.IP.String())
  220. }
  221. if newNode.Address6.IP != nil && !newNode.Address6.IP.Equal(currentNode.Address6.IP) {
  222. AddIpToAllocatedIpMap(newNode.Network, newNode.Address6.IP)
  223. RemoveIpFromAllocatedIpMap(currentNode.Network, currentNode.Address6.IP.String())
  224. }
  225. }
  226. }
  227. return nil
  228. }
  229. }
  230. return fmt.Errorf("failed to update node %s, cannot change ID", currentNode.ID.String())
  231. }
  232. // DeleteNode - marks node for deletion (and adds to zombie list) if called by UI or deletes node if called by node
  233. func DeleteNode(node *models.Node, purge bool) error {
  234. alreadyDeleted := node.PendingDelete || node.Action == models.NODE_DELETE
  235. node.Action = models.NODE_DELETE
  236. //delete ext clients if node is ingress gw
  237. if node.IsIngressGateway {
  238. if err := DeleteGatewayExtClients(node.ID.String(), node.Network); err != nil {
  239. slog.Error("failed to delete ext clients", "nodeid", node.ID.String(), "error", err.Error())
  240. }
  241. }
  242. if node.IsRelayed {
  243. // cleanup node from relayednodes on relay node
  244. relayNode, err := GetNodeByID(node.RelayedBy)
  245. if err == nil {
  246. relayedNodes := []string{}
  247. for _, relayedNodeID := range relayNode.RelayedNodes {
  248. if relayedNodeID == node.ID.String() {
  249. continue
  250. }
  251. relayedNodes = append(relayedNodes, relayedNodeID)
  252. }
  253. relayNode.RelayedNodes = relayedNodes
  254. UpsertNode(&relayNode)
  255. }
  256. }
  257. if node.FailedOverBy != uuid.Nil {
  258. ResetFailedOverPeer(node)
  259. }
  260. if node.IsRelay {
  261. // unset all the relayed nodes
  262. SetRelayedNodes(false, node.ID.String(), node.RelayedNodes)
  263. }
  264. if node.EgressDetails.InternetGwID != "" {
  265. inetNode, err := GetNodeByID(node.EgressDetails.InternetGwID)
  266. if err == nil {
  267. clientNodeIDs := []string{}
  268. for _, inetNodeClientID := range inetNode.EgressDetails.InetNodeReq.InetNodeClientIDs {
  269. if inetNodeClientID == node.ID.String() {
  270. continue
  271. }
  272. clientNodeIDs = append(clientNodeIDs, inetNodeClientID)
  273. }
  274. inetNode.EgressDetails.InetNodeReq.InetNodeClientIDs = clientNodeIDs
  275. UpsertNode(&inetNode)
  276. }
  277. }
  278. if node.EgressDetails.IsInternetGateway {
  279. UnsetInternetGw(node)
  280. }
  281. if !purge && !alreadyDeleted {
  282. newnode := *node
  283. newnode.PendingDelete = true
  284. if err := UpdateNode(node, &newnode); err != nil {
  285. return err
  286. }
  287. newZombie <- node.ID
  288. return nil
  289. }
  290. if alreadyDeleted {
  291. logger.Log(1, "forcibly deleting node", node.ID.String())
  292. }
  293. host, err := GetHost(node.HostID.String())
  294. if err != nil {
  295. logger.Log(1, "no host found for node", node.ID.String(), "deleting..")
  296. if delErr := DeleteNodeByID(node); delErr != nil {
  297. logger.Log(0, "failed to delete node", node.ID.String(), delErr.Error())
  298. }
  299. return err
  300. }
  301. if err := DissasociateNodeFromHost(node, host); err != nil {
  302. return err
  303. }
  304. go RemoveNodeFromAclPolicy(*node)
  305. go RemoveNodeFromEgress(*node)
  306. return nil
  307. }
  308. // GetNodeByHostRef - gets the node by host id and network
  309. func GetNodeByHostRef(hostid, network string) (node models.Node, err error) {
  310. nodes, err := GetNetworkNodes(network)
  311. if err != nil {
  312. return models.Node{}, err
  313. }
  314. for _, node := range nodes {
  315. if node.HostID.String() == hostid && node.Network == network {
  316. return node, nil
  317. }
  318. }
  319. return models.Node{}, errors.New("node not found")
  320. }
  321. // DeleteNodeByID - deletes a node from database
  322. func DeleteNodeByID(node *models.Node) error {
  323. var err error
  324. var key = node.ID.String()
  325. if err = database.DeleteRecord(database.NODES_TABLE_NAME, key); err != nil {
  326. if !database.IsEmptyRecord(err) {
  327. return err
  328. }
  329. }
  330. if servercfg.CacheEnabled() {
  331. deleteNodeFromCache(node.ID.String())
  332. deleteNodeFromNetworkCache(node.ID.String(), node.Network)
  333. }
  334. if servercfg.IsDNSMode() {
  335. SetDNS()
  336. }
  337. _, err = nodeacls.RemoveNodeACL(nodeacls.NetworkID(node.Network), nodeacls.NodeID(node.ID.String()))
  338. if err != nil {
  339. // ignoring for now, could hit a nil pointer if delete called twice
  340. logger.Log(2, "attempted to remove node ACL for node", node.ID.String())
  341. }
  342. // removeZombie <- node.ID
  343. if err = DeleteMetrics(node.ID.String()); err != nil {
  344. logger.Log(1, "unable to remove metrics from DB for node", node.ID.String(), err.Error())
  345. }
  346. //recycle ip address
  347. if servercfg.CacheEnabled() {
  348. if node.Address.IP != nil {
  349. RemoveIpFromAllocatedIpMap(node.Network, node.Address.IP.String())
  350. }
  351. if node.Address6.IP != nil {
  352. RemoveIpFromAllocatedIpMap(node.Network, node.Address6.IP.String())
  353. }
  354. }
  355. return nil
  356. }
  357. // IsNodeIDUnique - checks if node id is unique
  358. func IsNodeIDUnique(node *models.Node) (bool, error) {
  359. _, err := database.FetchRecord(database.NODES_TABLE_NAME, node.ID.String())
  360. return database.IsEmptyRecord(err), err
  361. }
  362. // ValidateNode - validates node values
  363. func ValidateNode(node *models.Node, isUpdate bool) error {
  364. v := validator.New()
  365. _ = v.RegisterValidation("id_unique", func(fl validator.FieldLevel) bool {
  366. if isUpdate {
  367. return true
  368. }
  369. isFieldUnique, _ := IsNodeIDUnique(node)
  370. return isFieldUnique
  371. })
  372. _ = v.RegisterValidation("network_exists", func(fl validator.FieldLevel) bool {
  373. _, err := GetNetworkByNode(node)
  374. return err == nil
  375. })
  376. _ = v.RegisterValidation("checkyesornoorunset", func(f1 validator.FieldLevel) bool {
  377. return validation.CheckYesOrNoOrUnset(f1)
  378. })
  379. err := v.Struct(node)
  380. return err
  381. }
  382. // GetAllNodes - returns all nodes in the DB
  383. func GetAllNodes() ([]models.Node, error) {
  384. var nodes []models.Node
  385. if servercfg.CacheEnabled() {
  386. nodes = getNodesFromCache()
  387. if len(nodes) != 0 {
  388. return nodes, nil
  389. }
  390. }
  391. nodesMap := make(map[string]models.Node)
  392. if servercfg.CacheEnabled() {
  393. defer loadNodesIntoCache(nodesMap)
  394. defer loadNodesIntoNetworkCache(nodesMap)
  395. }
  396. collection, err := database.FetchRecords(database.NODES_TABLE_NAME)
  397. if err != nil {
  398. if database.IsEmptyRecord(err) {
  399. return []models.Node{}, nil
  400. }
  401. return []models.Node{}, err
  402. }
  403. for _, value := range collection {
  404. var node models.Node
  405. // ignore legacy nodes in database
  406. if err := json.Unmarshal([]byte(value), &node); err != nil {
  407. logger.Log(3, "legacy node detected: ", err.Error())
  408. continue
  409. }
  410. // add node to our array
  411. nodes = append(nodes, node)
  412. if node.Mutex == nil {
  413. node.Mutex = &sync.Mutex{}
  414. }
  415. nodesMap[node.ID.String()] = node
  416. }
  417. return nodes, nil
  418. }
  419. func AddStaticNodestoList(nodes []models.Node) []models.Node {
  420. netMap := make(map[string]struct{})
  421. for _, node := range nodes {
  422. if _, ok := netMap[node.Network]; ok {
  423. continue
  424. }
  425. if node.IsIngressGateway {
  426. nodes = append(nodes, GetStaticNodesByNetwork(models.NetworkID(node.Network), false)...)
  427. netMap[node.Network] = struct{}{}
  428. }
  429. }
  430. return nodes
  431. }
  432. func AddStatusToNodes(nodes []models.Node, statusCall bool) (nodesWithStatus []models.Node) {
  433. aclDefaultPolicyStatusMap := make(map[string]bool)
  434. for _, node := range nodes {
  435. if _, ok := aclDefaultPolicyStatusMap[node.Network]; !ok {
  436. // check default policy if all allowed return true
  437. defaultPolicy, _ := GetDefaultPolicy(models.NetworkID(node.Network), models.DevicePolicy)
  438. aclDefaultPolicyStatusMap[node.Network] = defaultPolicy.Enabled
  439. }
  440. if statusCall {
  441. GetNodeStatus(&node, aclDefaultPolicyStatusMap[node.Network])
  442. } else {
  443. GetNodeCheckInStatus(&node, true)
  444. }
  445. nodesWithStatus = append(nodesWithStatus, node)
  446. }
  447. return
  448. }
  449. // GetNetworkByNode - gets the network model from a node
  450. func GetNetworkByNode(node *models.Node) (models.Network, error) {
  451. var network = models.Network{}
  452. networkData, err := database.FetchRecord(database.NETWORKS_TABLE_NAME, node.Network)
  453. if err != nil {
  454. return network, err
  455. }
  456. if err = json.Unmarshal([]byte(networkData), &network); err != nil {
  457. return models.Network{}, err
  458. }
  459. return network, nil
  460. }
  461. // SetNodeDefaults - sets the defaults of a node to avoid empty fields
  462. func SetNodeDefaults(node *models.Node, resetConnected bool) {
  463. parentNetwork, _ := GetNetworkByNode(node)
  464. _, cidr, err := net.ParseCIDR(parentNetwork.AddressRange)
  465. if err == nil {
  466. node.NetworkRange = *cidr
  467. }
  468. _, cidr, err = net.ParseCIDR(parentNetwork.AddressRange6)
  469. if err == nil {
  470. node.NetworkRange6 = *cidr
  471. }
  472. if node.DefaultACL == "" {
  473. node.DefaultACL = parentNetwork.DefaultACL
  474. }
  475. if node.FailOverPeers == nil {
  476. node.FailOverPeers = make(map[string]struct{})
  477. }
  478. node.SetLastModified()
  479. //node.SetLastCheckIn()
  480. if resetConnected {
  481. node.SetDefaultConnected()
  482. }
  483. node.SetExpirationDateTime()
  484. if node.Tags == nil {
  485. node.Tags = make(map[models.TagID]struct{})
  486. }
  487. }
  488. // GetRecordKey - get record key
  489. // depricated
  490. func GetRecordKey(id string, network string) (string, error) {
  491. if id == "" || network == "" {
  492. return "", errors.New("unable to get record key")
  493. }
  494. return id + "###" + network, nil
  495. }
  496. func GetNodeByID(uuid string) (models.Node, error) {
  497. if servercfg.CacheEnabled() {
  498. if node, ok := getNodeFromCache(uuid); ok {
  499. return node, nil
  500. }
  501. }
  502. var record, err = database.FetchRecord(database.NODES_TABLE_NAME, uuid)
  503. if err != nil {
  504. return models.Node{}, err
  505. }
  506. var node models.Node
  507. if err = json.Unmarshal([]byte(record), &node); err != nil {
  508. return models.Node{}, err
  509. }
  510. if servercfg.CacheEnabled() {
  511. storeNodeInCache(node)
  512. storeNodeInNetworkCache(node, node.Network)
  513. }
  514. return node, nil
  515. }
  516. // GetDeletedNodeByID - get a deleted node
  517. func GetDeletedNodeByID(uuid string) (models.Node, error) {
  518. var node models.Node
  519. record, err := database.FetchRecord(database.DELETED_NODES_TABLE_NAME, uuid)
  520. if err != nil {
  521. return models.Node{}, err
  522. }
  523. if err = json.Unmarshal([]byte(record), &node); err != nil {
  524. return models.Node{}, err
  525. }
  526. SetNodeDefaults(&node, true)
  527. return node, nil
  528. }
  529. // FindRelay - returns the node that is the relay for a relayed node
  530. func FindRelay(node *models.Node) *models.Node {
  531. relay, err := GetNodeByID(node.RelayedBy)
  532. if err != nil {
  533. logger.Log(0, "FindRelay: "+err.Error())
  534. return nil
  535. }
  536. return &relay
  537. }
  538. // GetAllNodesAPI - get all nodes for api usage
  539. func GetAllNodesAPI(nodes []models.Node) []models.ApiNode {
  540. apiNodes := []models.ApiNode{}
  541. for i := range nodes {
  542. newApiNode := nodes[i].ConvertToAPINode()
  543. apiNodes = append(apiNodes, *newApiNode)
  544. }
  545. return apiNodes[:]
  546. }
  547. // GetNodesStatusAPI - gets nodes status
  548. func GetNodesStatusAPI(nodes []models.Node) map[string]models.ApiNodeStatus {
  549. apiStatusNodesMap := make(map[string]models.ApiNodeStatus)
  550. for i := range nodes {
  551. newApiNode := nodes[i].ConvertToStatusNode()
  552. apiStatusNodesMap[newApiNode.ID] = *newApiNode
  553. }
  554. return apiStatusNodesMap
  555. }
  556. // DeleteExpiredNodes - goroutine which deletes nodes which are expired
  557. func DeleteExpiredNodes(ctx context.Context, peerUpdate chan *models.Node) {
  558. // Delete Expired Nodes Every Hour
  559. ticker := time.NewTicker(time.Hour)
  560. for {
  561. select {
  562. case <-ctx.Done():
  563. ticker.Stop()
  564. return
  565. case <-ticker.C:
  566. allnodes, err := GetAllNodes()
  567. if err != nil {
  568. slog.Error("failed to retrieve all nodes", "error", err.Error())
  569. return
  570. }
  571. for _, node := range allnodes {
  572. node := node
  573. if time.Now().After(node.ExpirationDateTime) {
  574. peerUpdate <- &node
  575. slog.Info("deleting expired node", "nodeid", node.ID.String())
  576. }
  577. }
  578. }
  579. }
  580. }
  581. // createNode - creates a node in database
  582. func createNode(node *models.Node) error {
  583. // lock because we need unique IPs and having it concurrent makes parallel calls result in same "unique" IPs
  584. addressLock.Lock()
  585. defer addressLock.Unlock()
  586. host, err := GetHost(node.HostID.String())
  587. if err != nil {
  588. return err
  589. }
  590. SetNodeDefaults(node, true)
  591. defaultACLVal := acls.Allowed
  592. parentNetwork, err := GetNetwork(node.Network)
  593. if err == nil {
  594. if parentNetwork.DefaultACL != "yes" {
  595. defaultACLVal = acls.NotAllowed
  596. }
  597. }
  598. if node.DefaultACL == "" {
  599. node.DefaultACL = "unset"
  600. }
  601. if node.Address.IP == nil {
  602. if parentNetwork.IsIPv4 == "yes" {
  603. if node.Address.IP, err = UniqueAddress(node.Network, false); err != nil {
  604. return err
  605. }
  606. _, cidr, err := net.ParseCIDR(parentNetwork.AddressRange)
  607. if err != nil {
  608. return err
  609. }
  610. node.Address.Mask = net.CIDRMask(cidr.Mask.Size())
  611. }
  612. } else if !IsIPUnique(node.Network, node.Address.String(), database.NODES_TABLE_NAME, false) {
  613. return fmt.Errorf("invalid address: ipv4 " + node.Address.String() + " is not unique")
  614. }
  615. if node.Address6.IP == nil {
  616. if parentNetwork.IsIPv6 == "yes" {
  617. if node.Address6.IP, err = UniqueAddress6(node.Network, false); err != nil {
  618. return err
  619. }
  620. _, cidr, err := net.ParseCIDR(parentNetwork.AddressRange6)
  621. if err != nil {
  622. return err
  623. }
  624. node.Address6.Mask = net.CIDRMask(cidr.Mask.Size())
  625. }
  626. } else if !IsIPUnique(node.Network, node.Address6.String(), database.NODES_TABLE_NAME, true) {
  627. return fmt.Errorf("invalid address: ipv6 " + node.Address6.String() + " is not unique")
  628. }
  629. node.ID = uuid.New()
  630. //Create a JWT for the node
  631. tokenString, _ := CreateJWT(node.ID.String(), host.MacAddress.String(), node.Network)
  632. if tokenString == "" {
  633. //logic.ReturnErrorResponse(w, r, errorResponse)
  634. return err
  635. }
  636. err = ValidateNode(node, false)
  637. if err != nil {
  638. return err
  639. }
  640. CheckZombies(node)
  641. node.SetLastCheckIn()
  642. nodebytes, err := json.Marshal(&node)
  643. if err != nil {
  644. return err
  645. }
  646. err = database.Insert(node.ID.String(), string(nodebytes), database.NODES_TABLE_NAME)
  647. if err != nil {
  648. return err
  649. }
  650. if servercfg.CacheEnabled() {
  651. storeNodeInCache(*node)
  652. storeNodeInNetworkCache(*node, node.Network)
  653. if _, ok := allocatedIpMap[node.Network]; ok {
  654. if node.Address.IP != nil {
  655. AddIpToAllocatedIpMap(node.Network, node.Address.IP)
  656. }
  657. if node.Address6.IP != nil {
  658. AddIpToAllocatedIpMap(node.Network, node.Address6.IP)
  659. }
  660. }
  661. }
  662. _, err = nodeacls.CreateNodeACL(nodeacls.NetworkID(node.Network), nodeacls.NodeID(node.ID.String()), defaultACLVal)
  663. if err != nil {
  664. logger.Log(1, "failed to create node ACL for node,", node.ID.String(), "err:", err.Error())
  665. return err
  666. }
  667. if err = UpdateProNodeACLs(node); err != nil {
  668. logger.Log(1, "failed to apply node level ACLs during creation of node", node.ID.String(), "-", err.Error())
  669. return err
  670. }
  671. if err = UpdateMetrics(node.ID.String(), &models.Metrics{Connectivity: make(map[string]models.Metric)}); err != nil {
  672. logger.Log(1, "failed to initialize metrics for node", node.ID.String(), err.Error())
  673. }
  674. SetNetworkNodesLastModified(node.Network)
  675. if servercfg.IsDNSMode() {
  676. err = SetDNS()
  677. }
  678. return err
  679. }
  680. // SortApiNodes - Sorts slice of ApiNodes by their ID alphabetically with numbers first
  681. func SortApiNodes(unsortedNodes []models.ApiNode) {
  682. sort.Slice(unsortedNodes, func(i, j int) bool {
  683. return unsortedNodes[i].ID < unsortedNodes[j].ID
  684. })
  685. }
  686. func ValidateParams(nodeid, netid string) (models.Node, error) {
  687. node, err := GetNodeByID(nodeid)
  688. if err != nil {
  689. slog.Error("error fetching node", "node", nodeid, "error", err.Error())
  690. return node, fmt.Errorf("error fetching node during parameter validation: %v", err)
  691. }
  692. if node.Network != netid {
  693. slog.Error("network url param does not match node id", "url nodeid", netid, "node", node.Network)
  694. return node, fmt.Errorf("network url param does not match node network")
  695. }
  696. return node, nil
  697. }
  698. func ValidateNodeIp(currentNode *models.Node, newNode *models.ApiNode) error {
  699. if currentNode.Address.IP != nil && currentNode.Address.String() != newNode.Address {
  700. if !IsIPUnique(newNode.Network, newNode.Address, database.NODES_TABLE_NAME, false) ||
  701. !IsIPUnique(newNode.Network, newNode.Address, database.EXT_CLIENT_TABLE_NAME, false) {
  702. return errors.New("ip specified is already allocated: " + newNode.Address)
  703. }
  704. }
  705. if currentNode.Address6.IP != nil && currentNode.Address6.String() != newNode.Address6 {
  706. if !IsIPUnique(newNode.Network, newNode.Address6, database.NODES_TABLE_NAME, false) ||
  707. !IsIPUnique(newNode.Network, newNode.Address6, database.EXT_CLIENT_TABLE_NAME, false) {
  708. return errors.New("ip specified is already allocated: " + newNode.Address6)
  709. }
  710. }
  711. return nil
  712. }
  713. func ValidateEgressRange(netID string, ranges []string) error {
  714. network, err := GetNetworkSettings(netID)
  715. if err != nil {
  716. slog.Error("error getting network with netid", "error", netID, err.Error)
  717. return errors.New("error getting network with netid: " + netID + " " + err.Error())
  718. }
  719. ipv4Net := network.AddressRange
  720. ipv6Net := network.AddressRange6
  721. for _, v := range ranges {
  722. if ipv4Net != "" {
  723. if ContainsCIDR(ipv4Net, v) {
  724. slog.Error("egress range should not be the same as or contained in the netmaker network address", "error", v, ipv4Net)
  725. return errors.New("egress range should not be the same as or contained in the netmaker network address" + v + " " + ipv4Net)
  726. }
  727. }
  728. if ipv6Net != "" {
  729. if ContainsCIDR(ipv6Net, v) {
  730. slog.Error("egress range should not be the same as or contained in the netmaker network address", "error", v, ipv6Net)
  731. return errors.New("egress range should not be the same as or contained in the netmaker network address" + v + " " + ipv6Net)
  732. }
  733. }
  734. }
  735. return nil
  736. }
  737. func ContainsCIDR(net1, net2 string) bool {
  738. one, two := ipaddr.NewIPAddressString(net1),
  739. ipaddr.NewIPAddressString(net2)
  740. return one.Contains(two) || two.Contains(one)
  741. }
  742. // GetAllFailOvers - gets all the nodes that are failovers
  743. func GetAllFailOvers() ([]models.Node, error) {
  744. nodes, err := GetAllNodes()
  745. if err != nil {
  746. return nil, err
  747. }
  748. igs := make([]models.Node, 0)
  749. for _, node := range nodes {
  750. if node.IsFailOver {
  751. igs = append(igs, node)
  752. }
  753. }
  754. return igs, nil
  755. }
  756. func ValidateInetGwReq(inetNode models.Node, req models.InetNodeReq, update bool) error {
  757. inetHost, err := GetHost(inetNode.HostID.String())
  758. if err != nil {
  759. return err
  760. }
  761. if inetHost.FirewallInUse == models.FIREWALL_NONE {
  762. return errors.New("iptables or nftables needs to be installed")
  763. }
  764. if inetNode.EgressDetails.InternetGwID != "" {
  765. return fmt.Errorf("node %s is using a internet gateway already", inetHost.Name)
  766. }
  767. if inetNode.IsRelayed {
  768. return fmt.Errorf("node %s is being relayed", inetHost.Name)
  769. }
  770. for _, clientNodeID := range req.InetNodeClientIDs {
  771. clientNode, err := GetNodeByID(clientNodeID)
  772. if err != nil {
  773. return err
  774. }
  775. if clientNode.IsFailOver {
  776. return errors.New("failover node cannot be set to use internet gateway")
  777. }
  778. clientHost, err := GetHost(clientNode.HostID.String())
  779. if err != nil {
  780. return err
  781. }
  782. if clientHost.IsDefault {
  783. return errors.New("default host cannot be set to use internet gateway")
  784. }
  785. if clientHost.OS != models.OS_Types.Linux && clientHost.OS != models.OS_Types.Windows {
  786. return errors.New("can only attach linux or windows machine to a internet gateway")
  787. }
  788. if clientNode.EgressDetails.IsInternetGateway {
  789. return fmt.Errorf("node %s acting as internet gateway cannot use another internet gateway", clientHost.Name)
  790. }
  791. if update {
  792. if clientNode.EgressDetails.InternetGwID != "" && clientNode.EgressDetails.InternetGwID != inetNode.ID.String() {
  793. return fmt.Errorf("node %s is already using a internet gateway", clientHost.Name)
  794. }
  795. } else {
  796. if clientNode.EgressDetails.InternetGwID != "" {
  797. return fmt.Errorf("node %s is already using a internet gateway", clientHost.Name)
  798. }
  799. }
  800. if clientNode.FailedOverBy != uuid.Nil {
  801. ResetFailedOverPeer(&clientNode)
  802. }
  803. if clientNode.IsRelayed && clientNode.RelayedBy != inetNode.ID.String() {
  804. return fmt.Errorf("node %s is being relayed", clientHost.Name)
  805. }
  806. for _, nodeID := range clientHost.Nodes {
  807. node, err := GetNodeByID(nodeID)
  808. if err != nil {
  809. continue
  810. }
  811. if node.EgressDetails.InternetGwID != "" && node.EgressDetails.InternetGwID != inetNode.ID.String() {
  812. return errors.New("nodes on same host cannot use different internet gateway")
  813. }
  814. }
  815. }
  816. return nil
  817. }
  818. // SetInternetGw - sets the node as internet gw based on flag bool
  819. func SetInternetGw(node *models.Node, req models.InetNodeReq) {
  820. node.EgressDetails.IsInternetGateway = true
  821. node.EgressDetails.InetNodeReq = req
  822. for _, clientNodeID := range req.InetNodeClientIDs {
  823. clientNode, err := GetNodeByID(clientNodeID)
  824. if err != nil {
  825. continue
  826. }
  827. clientNode.EgressDetails.InternetGwID = node.ID.String()
  828. UpsertNode(&clientNode)
  829. }
  830. }
  831. func UnsetInternetGw(node *models.Node) {
  832. nodes, err := GetNetworkNodes(node.Network)
  833. if err != nil {
  834. slog.Error("failed to get network nodes", "network", node.Network, "error", err)
  835. return
  836. }
  837. for _, clientNode := range nodes {
  838. if node.ID.String() == clientNode.EgressDetails.InternetGwID {
  839. clientNode.EgressDetails.InternetGwID = ""
  840. UpsertNode(&clientNode)
  841. }
  842. }
  843. node.EgressDetails.IsInternetGateway = false
  844. node.EgressDetails.InetNodeReq = models.InetNodeReq{}
  845. }
  846. func SetDefaultGwForRelayedUpdate(relayed, relay models.Node, peerUpdate models.HostPeerUpdate) models.HostPeerUpdate {
  847. if relay.EgressDetails.InternetGwID != "" {
  848. relayedHost, err := GetHost(relayed.HostID.String())
  849. if err != nil {
  850. return peerUpdate
  851. }
  852. peerUpdate.ChangeDefaultGw = true
  853. peerUpdate.DefaultGwIp = relay.Address.IP
  854. if peerUpdate.DefaultGwIp == nil || relayedHost.EndpointIP == nil {
  855. peerUpdate.DefaultGwIp = relay.Address6.IP
  856. }
  857. }
  858. return peerUpdate
  859. }
  860. func SetDefaultGw(node models.Node, peerUpdate models.HostPeerUpdate) models.HostPeerUpdate {
  861. if node.EgressDetails.InternetGwID != "" {
  862. inetNode, err := GetNodeByID(node.EgressDetails.InternetGwID)
  863. if err != nil {
  864. return peerUpdate
  865. }
  866. host, err := GetHost(node.HostID.String())
  867. if err != nil {
  868. return peerUpdate
  869. }
  870. peerUpdate.ChangeDefaultGw = true
  871. peerUpdate.DefaultGwIp = inetNode.Address.IP
  872. if peerUpdate.DefaultGwIp == nil || host.EndpointIP == nil {
  873. peerUpdate.DefaultGwIp = inetNode.Address6.IP
  874. }
  875. }
  876. return peerUpdate
  877. }
  878. // GetAllowedIpForInetNodeClient - get inet cidr for node using a inet gw
  879. func GetAllowedIpForInetNodeClient(node, peer *models.Node) []net.IPNet {
  880. var allowedips = []net.IPNet{}
  881. if peer.Address.IP != nil {
  882. _, ipnet, _ := net.ParseCIDR(IPv4Network)
  883. allowedips = append(allowedips, *ipnet)
  884. }
  885. if peer.Address6.IP != nil {
  886. _, ipnet, _ := net.ParseCIDR(IPv6Network)
  887. allowedips = append(allowedips, *ipnet)
  888. }
  889. return allowedips
  890. }