relays.go 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. package logic
  2. import (
  3. "errors"
  4. "fmt"
  5. "net"
  6. "github.com/gravitl/netmaker/logger"
  7. "github.com/gravitl/netmaker/logic"
  8. "github.com/gravitl/netmaker/logic/acls/nodeacls"
  9. "github.com/gravitl/netmaker/models"
  10. "github.com/gravitl/netmaker/mq"
  11. "github.com/gravitl/netmaker/servercfg"
  12. "golang.org/x/exp/slog"
  13. )
  14. // CreateRelay - creates a relay
  15. func CreateRelay(relay models.RelayRequest) ([]models.Node, models.Node, error) {
  16. var returnnodes []models.Node
  17. node, err := logic.GetNodeByID(relay.NodeID)
  18. if err != nil {
  19. return returnnodes, models.Node{}, err
  20. }
  21. host, err := logic.GetHost(node.HostID.String())
  22. if err != nil {
  23. return returnnodes, models.Node{}, err
  24. }
  25. if host.OS != "linux" {
  26. return returnnodes, models.Node{}, fmt.Errorf("only linux machines can be relay nodes")
  27. }
  28. err = ValidateRelay(relay)
  29. if err != nil {
  30. return returnnodes, models.Node{}, err
  31. }
  32. node.IsRelay = true
  33. node.RelayedNodes = relay.RelayedNodes
  34. node.SetLastModified()
  35. err = logic.UpsertNode(&node)
  36. if err != nil {
  37. return returnnodes, node, err
  38. }
  39. returnnodes = SetRelayedNodes(true, relay.NodeID, relay.RelayedNodes)
  40. return returnnodes, node, nil
  41. }
  42. // SetRelayedNodes- sets and saves node as relayed
  43. func SetRelayedNodes(setRelayed bool, relay string, relayed []string) []models.Node {
  44. var returnnodes []models.Node
  45. for _, id := range relayed {
  46. node, err := logic.GetNodeByID(id)
  47. if err != nil {
  48. logger.Log(0, "setRelayedNodes.GetNodebyID", err.Error())
  49. continue
  50. }
  51. node.IsRelayed = setRelayed
  52. if node.IsRelayed {
  53. node.RelayedBy = relay
  54. } else {
  55. node.RelayedBy = ""
  56. }
  57. node.SetLastModified()
  58. if err := logic.UpsertNode(&node); err != nil {
  59. logger.Log(0, "setRelayedNodes.Insert", err.Error())
  60. continue
  61. }
  62. returnnodes = append(returnnodes, node)
  63. }
  64. return returnnodes
  65. }
  66. //func GetRelayedNodes(relayNode *models.Node) (models.Node, error) {
  67. // var returnnodes []models.Node
  68. // networkNodes, err := GetNetworkNodes(relayNode.Network)
  69. // if err != nil {
  70. // return returnnodes, err
  71. // }
  72. // for _, node := range networkNodes {
  73. // for _, addr := range relayNode.RelayAddrs {
  74. // if addr == node.Address.IP.String() || addr == node.Address6.IP.String() {
  75. // returnnodes = append(returnnodes, node)
  76. // }
  77. // }
  78. // }
  79. // return returnnodes, nil
  80. //}
  81. // ValidateRelay - checks if relay is valid
  82. func ValidateRelay(relay models.RelayRequest) error {
  83. var err error
  84. //isIp := functions.IsIpCIDR(gateway.RangeString)
  85. empty := len(relay.RelayedNodes) == 0
  86. if empty {
  87. return errors.New("IP Ranges Cannot Be Empty")
  88. }
  89. node, err := logic.GetNodeByID(relay.NodeID)
  90. if err != nil {
  91. return err
  92. }
  93. if node.IsRelay {
  94. return errors.New("node is already acting as a relay")
  95. }
  96. for _, relayedNodeID := range relay.RelayedNodes {
  97. relayedNode, err := logic.GetNodeByID(relayedNodeID)
  98. if err != nil {
  99. return err
  100. }
  101. if relayedNode.IsIngressGateway {
  102. return errors.New("cannot relay an ingress gateway (" + relayedNodeID + ")")
  103. }
  104. }
  105. return err
  106. }
  107. // UpdateRelayNodes - updates relay nodes
  108. func updateRelayNodes(relay string, oldNodes []string, newNodes []string) []models.Node {
  109. _ = SetRelayedNodes(false, relay, oldNodes)
  110. return SetRelayedNodes(true, relay, newNodes)
  111. }
  112. func RelayUpdates(currentNode, newNode *models.Node) bool {
  113. relayUpdates := false
  114. if servercfg.IsPro && newNode.IsRelay && len(newNode.RelayedNodes) > 0 {
  115. if len(newNode.RelayedNodes) != len(currentNode.RelayedNodes) {
  116. relayUpdates = true
  117. } else {
  118. for i, node := range newNode.RelayedNodes {
  119. if node != currentNode.RelayedNodes[i] {
  120. relayUpdates = true
  121. }
  122. }
  123. }
  124. }
  125. return relayUpdates
  126. }
  127. func UpdateRelayed(currentNode, newNode *models.Node) {
  128. updatenodes := updateRelayNodes(currentNode.ID.String(), currentNode.RelayedNodes, newNode.RelayedNodes)
  129. if len(updatenodes) > 0 {
  130. for _, relayedNode := range updatenodes {
  131. node := relayedNode
  132. go func() {
  133. if err := mq.NodeUpdate(&node); err != nil {
  134. slog.Error("error publishing node update to node", "node", node.ID, "error", err)
  135. }
  136. }()
  137. }
  138. }
  139. }
  140. // DeleteRelay - deletes a relay
  141. func DeleteRelay(network, nodeid string) ([]models.Node, models.Node, error) {
  142. var returnnodes []models.Node
  143. node, err := logic.GetNodeByID(nodeid)
  144. if err != nil {
  145. return returnnodes, models.Node{}, err
  146. }
  147. returnnodes = SetRelayedNodes(false, nodeid, node.RelayedNodes)
  148. node.IsRelay = false
  149. node.RelayedNodes = []string{}
  150. node.SetLastModified()
  151. if err = logic.UpsertNode(&node); err != nil {
  152. return returnnodes, models.Node{}, err
  153. }
  154. return returnnodes, node, nil
  155. }
  156. func RelayedAllowedIPs(peer, node *models.Node) []net.IPNet {
  157. var allowedIPs = []net.IPNet{}
  158. for _, relayedNodeID := range peer.RelayedNodes {
  159. if node.ID.String() == relayedNodeID {
  160. continue
  161. }
  162. relayedNode, err := logic.GetNodeByID(relayedNodeID)
  163. if err != nil {
  164. continue
  165. }
  166. allowed := getRelayedAddresses(relayedNodeID)
  167. if relayedNode.IsEgressGateway {
  168. allowed = append(allowed, logic.GetEgressIPs(&relayedNode)...)
  169. }
  170. allowedIPs = append(allowedIPs, allowed...)
  171. }
  172. return allowedIPs
  173. }
  174. // GetAllowedIpsForRelayed - returns the peerConfig for a node relayed by relay
  175. func GetAllowedIpsForRelayed(relayed, relay *models.Node) (allowedIPs []net.IPNet) {
  176. if relayed.RelayedBy != relay.ID.String() {
  177. logger.Log(0, "RelayedByRelay called with invalid parameters")
  178. return
  179. }
  180. peers, err := logic.GetNetworkNodes(relay.Network)
  181. if err != nil {
  182. logger.Log(0, "error getting network clients", err.Error())
  183. return
  184. }
  185. for _, peer := range peers {
  186. if peer.ID == relayed.ID || peer.ID == relay.ID {
  187. continue
  188. }
  189. if nodeacls.AreNodesAllowed(nodeacls.NetworkID(relayed.Network), nodeacls.NodeID(relayed.ID.String()), nodeacls.NodeID(peer.ID.String())) {
  190. allowedIPs = append(allowedIPs, logic.GetAllowedIPs(relayed, &peer, nil)...)
  191. }
  192. }
  193. return
  194. }
  195. func getRelayedAddresses(id string) []net.IPNet {
  196. addrs := []net.IPNet{}
  197. node, err := logic.GetNodeByID(id)
  198. if err != nil {
  199. logger.Log(0, "getRelayedAddresses: "+err.Error())
  200. return addrs
  201. }
  202. if node.Address.IP != nil {
  203. node.Address.Mask = net.CIDRMask(32, 32)
  204. addrs = append(addrs, node.Address)
  205. }
  206. if node.Address6.IP != nil {
  207. node.Address.Mask = net.CIDRMask(128, 128)
  208. addrs = append(addrs, node.Address6)
  209. }
  210. return addrs
  211. }