nodes.go 8.9 KB

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