nodes.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. package logic
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "sort"
  7. "time"
  8. "github.com/go-playground/validator/v10"
  9. "github.com/gravitl/netmaker/database"
  10. "github.com/gravitl/netmaker/logger"
  11. "github.com/gravitl/netmaker/models"
  12. "github.com/gravitl/netmaker/validation"
  13. )
  14. // GetNetworkNodes - gets the nodes of a network
  15. func GetNetworkNodes(network string) ([]models.Node, error) {
  16. var nodes = []models.Node{}
  17. collection, err := database.FetchRecords(database.NODES_TABLE_NAME)
  18. if err != nil {
  19. if database.IsEmptyRecord(err) {
  20. return []models.Node{}, nil
  21. }
  22. return nodes, err
  23. }
  24. for _, value := range collection {
  25. var node models.Node
  26. err := json.Unmarshal([]byte(value), &node)
  27. if err != nil {
  28. continue
  29. }
  30. if node.Network == network {
  31. nodes = append(nodes, node)
  32. }
  33. }
  34. return nodes, nil
  35. }
  36. // GetSortedNetworkServerNodes - gets nodes of a network, except sorted by update time
  37. func GetSortedNetworkServerNodes(network string) ([]models.Node, error) {
  38. var nodes []models.Node
  39. collection, err := database.FetchRecords(database.NODES_TABLE_NAME)
  40. if err != nil {
  41. if database.IsEmptyRecord(err) {
  42. return []models.Node{}, nil
  43. }
  44. return nodes, err
  45. }
  46. for _, value := range collection {
  47. var node models.Node
  48. err := json.Unmarshal([]byte(value), &node)
  49. if err != nil {
  50. continue
  51. }
  52. if node.Network == network && node.IsServer == "yes" {
  53. nodes = append(nodes, node)
  54. }
  55. }
  56. sort.Sort(models.NodesArray(nodes))
  57. return nodes, nil
  58. }
  59. // UncordonNode - approves a node to join a network
  60. func UncordonNode(nodeid string) (models.Node, error) {
  61. node, err := GetNodeByID(nodeid)
  62. if err != nil {
  63. return models.Node{}, err
  64. }
  65. node.SetLastModified()
  66. node.IsPending = "no"
  67. node.PullChanges = "yes"
  68. data, err := json.Marshal(&node)
  69. if err != nil {
  70. return node, err
  71. }
  72. err = database.Insert(node.ID, string(data), database.NODES_TABLE_NAME)
  73. return node, err
  74. }
  75. // GetPeers - gets the peers of a given node
  76. func GetPeers(node *models.Node) ([]models.Node, error) {
  77. if IsLeader(node) {
  78. SetNetworkServerPeers(node)
  79. }
  80. excludeIsRelayed := node.IsRelay != "yes"
  81. var relayedNode string
  82. if node.IsRelayed == "yes" {
  83. relayedNode = node.Address
  84. }
  85. peers, err := GetPeersList(node.Network, excludeIsRelayed, relayedNode)
  86. if err != nil {
  87. return nil, err
  88. }
  89. return peers, nil
  90. }
  91. // IsLeader - determines if a given server node is a leader
  92. func IsLeader(node *models.Node) bool {
  93. nodes, err := GetSortedNetworkServerNodes(node.Network)
  94. if err != nil {
  95. logger.Log(0, "ERROR: COULD NOT RETRIEVE SERVER NODES. THIS WILL BREAK HOLE PUNCHING.")
  96. return false
  97. }
  98. for _, n := range nodes {
  99. if n.LastModified > time.Now().Add(-1*time.Minute).Unix() {
  100. return n.Address == node.Address
  101. }
  102. }
  103. return len(nodes) <= 1 || nodes[1].Address == node.Address
  104. }
  105. // == DB related functions ==
  106. // UpdateNode - takes a node and updates another node with it's values
  107. func UpdateNode(currentNode *models.Node, newNode *models.Node) error {
  108. newNode.Fill(currentNode)
  109. if err := ValidateNode(newNode, true); err != nil {
  110. return err
  111. }
  112. if newNode.ID == currentNode.ID {
  113. newNode.SetLastModified()
  114. if data, err := json.Marshal(newNode); err != nil {
  115. return err
  116. } else {
  117. return database.Insert(newNode.ID, string(data), database.NODES_TABLE_NAME)
  118. }
  119. }
  120. return fmt.Errorf("failed to update node " + newNode.MacAddress + ", cannot change macaddress.")
  121. }
  122. // IsNodeIDUnique - checks if node id is unique
  123. func IsNodeIDUnique(node *models.Node) (bool, error) {
  124. _, err := database.FetchRecord(database.NODES_TABLE_NAME, node.ID)
  125. return database.IsEmptyRecord(err), err
  126. }
  127. // ValidateNode - validates node values
  128. func ValidateNode(node *models.Node, isUpdate bool) error {
  129. v := validator.New()
  130. _ = v.RegisterValidation("macaddress_unique", func(fl validator.FieldLevel) bool {
  131. if isUpdate {
  132. return true
  133. }
  134. isFieldUnique, _ := IsNodeIDUnique(node)
  135. return isFieldUnique
  136. })
  137. _ = v.RegisterValidation("network_exists", func(fl validator.FieldLevel) bool {
  138. _, err := GetNetworkByNode(node)
  139. return err == nil
  140. })
  141. _ = v.RegisterValidation("in_charset", func(fl validator.FieldLevel) bool {
  142. isgood := node.NameInNodeCharSet()
  143. return isgood
  144. })
  145. _ = v.RegisterValidation("checkyesorno", func(fl validator.FieldLevel) bool {
  146. return validation.CheckYesOrNo(fl)
  147. })
  148. err := v.Struct(node)
  149. return err
  150. }
  151. // GetAllNodes - returns all nodes in the DB
  152. func GetAllNodes() ([]models.Node, error) {
  153. var nodes []models.Node
  154. collection, err := database.FetchRecords(database.NODES_TABLE_NAME)
  155. if err != nil {
  156. if database.IsEmptyRecord(err) {
  157. return []models.Node{}, nil
  158. }
  159. return []models.Node{}, err
  160. }
  161. for _, value := range collection {
  162. var node models.Node
  163. if err := json.Unmarshal([]byte(value), &node); err != nil {
  164. return []models.Node{}, err
  165. }
  166. // add node to our array
  167. nodes = append(nodes, node)
  168. }
  169. return nodes, nil
  170. }
  171. // CheckIsServer - check if a node is the server node
  172. func CheckIsServer(node *models.Node) bool {
  173. nodeData, err := database.FetchRecords(database.NODES_TABLE_NAME)
  174. if err != nil && !database.IsEmptyRecord(err) {
  175. return false
  176. }
  177. for _, value := range nodeData {
  178. var tmpNode models.Node
  179. if err := json.Unmarshal([]byte(value), &tmpNode); err != nil {
  180. continue
  181. }
  182. if tmpNode.Network == node.Network && tmpNode.MacAddress != node.MacAddress {
  183. return false
  184. }
  185. }
  186. return true
  187. }
  188. // GetNetworkByNode - gets the network model from a node
  189. func GetNetworkByNode(node *models.Node) (models.Network, error) {
  190. var network = models.Network{}
  191. networkData, err := database.FetchRecord(database.NETWORKS_TABLE_NAME, node.Network)
  192. if err != nil {
  193. return network, err
  194. }
  195. if err = json.Unmarshal([]byte(networkData), &network); err != nil {
  196. return models.Network{}, err
  197. }
  198. return network, nil
  199. }
  200. // SetNodeDefaults - sets the defaults of a node to avoid empty fields
  201. func SetNodeDefaults(node *models.Node) {
  202. //TODO: Maybe I should make Network a part of the node struct. Then we can just query the Network object for stuff.
  203. parentNetwork, _ := GetNetworkByNode(node)
  204. node.ExpirationDateTime = time.Now().Unix() + models.TEN_YEARS_IN_SECONDS
  205. if node.ListenPort == 0 {
  206. node.ListenPort = parentNetwork.DefaultListenPort
  207. }
  208. if node.SaveConfig == "" {
  209. if parentNetwork.DefaultSaveConfig != "" {
  210. node.SaveConfig = parentNetwork.DefaultSaveConfig
  211. } else {
  212. node.SaveConfig = "yes"
  213. }
  214. }
  215. if node.Interface == "" {
  216. node.Interface = parentNetwork.DefaultInterface
  217. }
  218. if node.PersistentKeepalive == 0 {
  219. node.PersistentKeepalive = parentNetwork.DefaultKeepalive
  220. }
  221. if node.PostUp == "" {
  222. postup := parentNetwork.DefaultPostUp
  223. node.PostUp = postup
  224. }
  225. if node.PostDown == "" {
  226. postdown := parentNetwork.DefaultPostDown
  227. node.PostDown = postdown
  228. }
  229. if node.IsStatic == "" {
  230. node.IsStatic = "no"
  231. }
  232. if node.UDPHolePunch == "" {
  233. node.UDPHolePunch = parentNetwork.DefaultUDPHolePunch
  234. if node.UDPHolePunch == "" {
  235. node.UDPHolePunch = "yes"
  236. }
  237. }
  238. // == Parent Network settings ==
  239. if node.IsDualStack == "" {
  240. node.IsDualStack = parentNetwork.IsDualStack
  241. }
  242. if node.MTU == 0 {
  243. node.MTU = parentNetwork.DefaultMTU
  244. }
  245. // == node defaults if not set by parent ==
  246. node.SetIPForwardingDefault()
  247. node.SetDNSOnDefault()
  248. node.SetIsLocalDefault()
  249. node.SetIsDualStackDefault()
  250. node.SetLastModified()
  251. node.SetDefaultName()
  252. node.SetLastCheckIn()
  253. node.SetLastPeerUpdate()
  254. node.SetRoamingDefault()
  255. node.SetPullChangesDefault()
  256. node.SetDefaultAction()
  257. node.SetIsServerDefault()
  258. node.SetIsStaticDefault()
  259. node.SetDefaultEgressGateway()
  260. node.SetDefaultIngressGateway()
  261. node.SetDefaulIsPending()
  262. node.SetDefaultMTU()
  263. node.SetDefaultIsRelayed()
  264. node.SetDefaultIsRelay()
  265. node.KeyUpdateTimeStamp = time.Now().Unix()
  266. }
  267. // GetRecordKey - get record key
  268. // depricated
  269. func GetRecordKey(id string, network string) (string, error) {
  270. if id == "" || network == "" {
  271. return "", errors.New("unable to get record key")
  272. }
  273. return id + "###" + network, nil
  274. }
  275. // GetNodeByMacAddress - gets a node by mac address
  276. func GetNodeByMacAddress(network string, macaddress string) (models.Node, error) {
  277. var node models.Node
  278. key, err := GetRecordKey(macaddress, network)
  279. if err != nil {
  280. return node, err
  281. }
  282. record, err := database.FetchRecord(database.NODES_TABLE_NAME, key)
  283. if err != nil {
  284. return models.Node{}, err
  285. }
  286. if err = json.Unmarshal([]byte(record), &node); err != nil {
  287. return models.Node{}, err
  288. }
  289. SetNodeDefaults(&node)
  290. return node, nil
  291. }
  292. // GetDeletedNodeByMacAddress - get a deleted node
  293. func GetDeletedNodeByMacAddress(network string, macaddress string) (models.Node, error) {
  294. var node models.Node
  295. key, err := GetRecordKey(macaddress, network)
  296. if err != nil {
  297. return node, err
  298. }
  299. record, err := database.FetchRecord(database.DELETED_NODES_TABLE_NAME, key)
  300. if err != nil {
  301. return models.Node{}, err
  302. }
  303. if err = json.Unmarshal([]byte(record), &node); err != nil {
  304. return models.Node{}, err
  305. }
  306. SetNodeDefaults(&node)
  307. return node, nil
  308. }
  309. // GetNodeRelay - gets the relay node of a given network
  310. func GetNodeRelay(network string, relayedNodeAddr string) (models.Node, error) {
  311. collection, err := database.FetchRecords(database.NODES_TABLE_NAME)
  312. var relay models.Node
  313. if err != nil {
  314. if database.IsEmptyRecord(err) {
  315. return relay, nil
  316. }
  317. logger.Log(2, err.Error())
  318. return relay, err
  319. }
  320. for _, value := range collection {
  321. err := json.Unmarshal([]byte(value), &relay)
  322. if err != nil {
  323. logger.Log(2, err.Error())
  324. continue
  325. }
  326. if relay.IsRelay == "yes" {
  327. for _, addr := range relay.RelayAddrs {
  328. if addr == relayedNodeAddr {
  329. return relay, nil
  330. }
  331. }
  332. }
  333. }
  334. return relay, errors.New("could not find relay for node " + relayedNodeAddr)
  335. }
  336. // GetNodeByIDorMacAddress - gets the node, if a mac address exists, but not id, then it should delete it and recreate in DB with new ID
  337. func GetNodeByIDorMacAddress(uuid string, macaddress string, network string) (models.Node, error) {
  338. var node models.Node
  339. var err error
  340. node, err = GetNodeByID(uuid)
  341. if err != nil && macaddress != "" && network != "" {
  342. node, err = GetNodeByMacAddress(network, macaddress)
  343. if err != nil {
  344. return models.Node{}, err
  345. }
  346. err = DeleteNodeByMacAddress(&node, true) // remove node
  347. if err != nil {
  348. return models.Node{}, err
  349. }
  350. err = CreateNode(&node)
  351. if err != nil {
  352. return models.Node{}, err
  353. }
  354. logger.Log(2, "rewriting legacy node data; node now has id,", node.ID)
  355. node.PullChanges = "yes"
  356. }
  357. return node, err
  358. }
  359. // GetNodeByID - get node by uuid, should have been set by create
  360. func GetNodeByID(uuid string) (models.Node, error) {
  361. var record, err = database.FetchRecord(database.NODES_TABLE_NAME, uuid)
  362. if err != nil {
  363. return models.Node{}, err
  364. }
  365. var node models.Node
  366. if err = json.Unmarshal([]byte(record), &node); err != nil {
  367. return models.Node{}, err
  368. }
  369. return node, nil
  370. }
  371. // GetDeletedNodeByID - get a deleted node
  372. func GetDeletedNodeByID(uuid string) (models.Node, error) {
  373. var node models.Node
  374. record, err := database.FetchRecord(database.DELETED_NODES_TABLE_NAME, uuid)
  375. if err != nil {
  376. return models.Node{}, err
  377. }
  378. if err = json.Unmarshal([]byte(record), &node); err != nil {
  379. return models.Node{}, err
  380. }
  381. SetNodeDefaults(&node)
  382. return node, nil
  383. }