node_grpc.go 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. package controller
  2. import (
  3. "context"
  4. "encoding/json"
  5. "errors"
  6. "strings"
  7. "time"
  8. nodepb "github.com/gravitl/netmaker/grpc"
  9. "github.com/gravitl/netmaker/logger"
  10. "github.com/gravitl/netmaker/logic"
  11. "github.com/gravitl/netmaker/models"
  12. "github.com/gravitl/netmaker/mq"
  13. "github.com/gravitl/netmaker/netclient/ncutils"
  14. "github.com/gravitl/netmaker/servercfg"
  15. )
  16. // NodeServiceServer - represents the service server for gRPC
  17. type NodeServiceServer struct {
  18. nodepb.UnimplementedNodeServiceServer
  19. }
  20. // NodeServiceServer.ReadNode - reads node and responds with gRPC
  21. func (s *NodeServiceServer) ReadNode(ctx context.Context, req *nodepb.Object) (*nodepb.Object, error) {
  22. var node, err = getNewOrLegacyNode(req.Data)
  23. if err != nil {
  24. return nil, err
  25. }
  26. node.NetworkSettings, err = logic.GetNetworkSettings(node.Network)
  27. if err != nil {
  28. return nil, err
  29. }
  30. node.SetLastCheckIn()
  31. // Cast to ReadNodeRes type
  32. nodeData, errN := json.Marshal(&node)
  33. if errN != nil {
  34. return nil, err
  35. }
  36. logic.UpdateNode(&node, &node)
  37. response := &nodepb.Object{
  38. Data: string(nodeData),
  39. Type: nodepb.NODE_TYPE,
  40. }
  41. return response, nil
  42. }
  43. // NodeServiceServer.CreateNode - creates a node and responds over gRPC
  44. func (s *NodeServiceServer) CreateNode(ctx context.Context, req *nodepb.Object) (*nodepb.Object, error) {
  45. var node = models.Node{}
  46. var err error
  47. data := req.GetData()
  48. if err := json.Unmarshal([]byte(data), &node); err != nil {
  49. return nil, err
  50. }
  51. validKey := logic.IsKeyValid(node.Network, node.AccessKey)
  52. node.NetworkSettings, err = logic.GetNetworkSettings(node.Network)
  53. if err != nil {
  54. return nil, err
  55. }
  56. if !validKey {
  57. if node.NetworkSettings.AllowManualSignUp == "yes" {
  58. node.IsPending = "yes"
  59. } else {
  60. return nil, errors.New("invalid key, and network does not allow no-key signups")
  61. }
  62. }
  63. getServerAddrs(&node)
  64. key, keyErr := logic.RetrievePublicTrafficKey()
  65. if keyErr != nil {
  66. logger.Log(0, "error retrieving key: ", keyErr.Error())
  67. return nil, keyErr
  68. }
  69. node.TrafficKeys = models.TrafficKeys{
  70. Mine: node.TrafficKeys.Mine,
  71. Server: key,
  72. }
  73. err = logic.CreateNode(&node)
  74. if err != nil {
  75. return nil, err
  76. }
  77. nodeData, errN := json.Marshal(&node)
  78. if errN != nil {
  79. return nil, err
  80. }
  81. response := &nodepb.Object{
  82. Data: string(nodeData),
  83. Type: nodepb.NODE_TYPE,
  84. }
  85. network, err := logic.GetParentNetwork(node.Network)
  86. if err != nil {
  87. return nil, err
  88. }
  89. network.NodesLastModified = time.Now().Unix()
  90. network.DefaultServerAddrs = node.NetworkSettings.DefaultServerAddrs
  91. if err := logic.SaveNetwork(&network); err != nil {
  92. return nil, err
  93. }
  94. err = runServerPeerUpdate(node.Network, isServer(&node), "node_grpc create")
  95. if err != nil {
  96. logger.Log(1, "internal error when setting peers after node,", node.ID, "was created (gRPC)")
  97. }
  98. logger.Log(0, "new node,", node.Name, ", added on network,"+node.Network)
  99. // notify other nodes on network of new peer
  100. go func() {
  101. if err := mq.PublishPeerUpdate(&node); err != nil {
  102. logger.Log(0, "failed to inform peers of new node ", err.Error())
  103. }
  104. }()
  105. return response, nil
  106. }
  107. // NodeServiceServer.UpdateNode updates a node and responds over gRPC
  108. func (s *NodeServiceServer) UpdateNode(ctx context.Context, req *nodepb.Object) (*nodepb.Object, error) {
  109. var newnode models.Node
  110. if err := json.Unmarshal([]byte(req.GetData()), &newnode); err != nil {
  111. return nil, err
  112. }
  113. node, err := logic.GetNodeByIDorMacAddress(newnode.ID, newnode.MacAddress, newnode.Network)
  114. if err != nil {
  115. return nil, err
  116. }
  117. if !servercfg.GetRce() {
  118. newnode.PostDown = node.PostDown
  119. newnode.PostUp = node.PostUp
  120. }
  121. var shouldPeersUpdate = ncutils.IfaceDelta(&node, &newnode)
  122. getServerAddrs(&node)
  123. err = logic.UpdateNode(&node, &newnode)
  124. if err != nil {
  125. return nil, err
  126. }
  127. newnode.NetworkSettings, err = logic.GetNetworkSettings(node.Network)
  128. if err != nil {
  129. return nil, err
  130. }
  131. nodeData, errN := json.Marshal(&newnode)
  132. if errN != nil {
  133. return nil, err
  134. }
  135. err = runServerPeerUpdate(newnode.Network, shouldPeersUpdate, "node_grpc update")
  136. if err != nil {
  137. logger.Log(1, "could not update peers on gRPC after node,", newnode.ID, "updated (gRPC), \nerror:", err.Error())
  138. }
  139. return &nodepb.Object{
  140. Data: string(nodeData),
  141. Type: nodepb.NODE_TYPE,
  142. }, nil
  143. }
  144. func getServerAddrs(node *models.Node) {
  145. var serverNodes = logic.GetServerNodes(node.Network)
  146. var serverAddrs = make([]models.ServerAddr, len(serverNodes))
  147. for i, server := range serverNodes {
  148. serverAddrs[i] = models.ServerAddr{
  149. IsLeader: logic.IsLeader(&server),
  150. Address: server.Address,
  151. }
  152. }
  153. // TODO consolidate functionality around files
  154. node.NetworkSettings.DefaultServerAddrs = serverAddrs
  155. }
  156. // NodeServiceServer.DeleteNode - deletes a node and responds over gRPC
  157. func (s *NodeServiceServer) DeleteNode(ctx context.Context, req *nodepb.Object) (*nodepb.Object, error) {
  158. var node, err = getNewOrLegacyNode(req.Data)
  159. if err != nil {
  160. return nil, err
  161. }
  162. err = logic.DeleteNodeByID(&node, true)
  163. if err != nil {
  164. return nil, err
  165. }
  166. err = runServerPeerUpdate(node.Network, false, "node_grpc delete")
  167. if err != nil {
  168. logger.Log(1, "internal error when setting peers after deleting node:", node.ID, "over gRPC")
  169. }
  170. // notify other nodes on network of deleted peer
  171. go func() {
  172. if err := mq.PublishPeerUpdate(&node); err != nil {
  173. logger.Log(0, "failed to inform peers of deleted node ", err.Error())
  174. }
  175. }()
  176. return &nodepb.Object{
  177. Data: "success",
  178. Type: nodepb.STRING_TYPE,
  179. }, nil
  180. }
  181. // NodeServiceServer.GetPeers - fetches peers over gRPC
  182. func (s *NodeServiceServer) GetPeers(ctx context.Context, req *nodepb.Object) (*nodepb.Object, error) {
  183. var node, err = getNewOrLegacyNode(req.Data)
  184. if err != nil {
  185. return nil, err
  186. }
  187. excludeIsRelayed := node.IsRelay != "yes"
  188. var relayedNode string
  189. if node.IsRelayed == "yes" {
  190. relayedNode = node.Address
  191. }
  192. peers, err := logic.GetPeersList(node.Network, excludeIsRelayed, relayedNode)
  193. if err != nil {
  194. return nil, err
  195. }
  196. peersData, err := json.Marshal(&peers)
  197. logger.Log(3, node.Address, "checked in successfully")
  198. return &nodepb.Object{
  199. Data: string(peersData),
  200. Type: nodepb.NODE_TYPE,
  201. }, err
  202. }
  203. // NodeServiceServer.GetExtPeers - returns ext peers for a gateway node
  204. func (s *NodeServiceServer) GetExtPeers(ctx context.Context, req *nodepb.Object) (*nodepb.Object, error) {
  205. var node, err = getNewOrLegacyNode(req.Data)
  206. if err != nil {
  207. return nil, err
  208. }
  209. peers, err := logic.GetExtPeersList(&node)
  210. if err != nil {
  211. return nil, err
  212. }
  213. var extPeers []models.Node
  214. for i := 0; i < len(peers); i++ {
  215. extPeers = append(extPeers, models.Node{
  216. Address: peers[i].Address,
  217. Address6: peers[i].Address6,
  218. Endpoint: peers[i].Endpoint,
  219. PublicKey: peers[i].PublicKey,
  220. PersistentKeepalive: peers[i].KeepAlive,
  221. ListenPort: peers[i].ListenPort,
  222. LocalAddress: peers[i].LocalAddress,
  223. })
  224. }
  225. extData, err := json.Marshal(&extPeers)
  226. if err != nil {
  227. return nil, err
  228. }
  229. return &nodepb.Object{
  230. Data: string(extData),
  231. Type: nodepb.EXT_PEER,
  232. }, nil
  233. }
  234. // == private methods ==
  235. func getNewOrLegacyNode(data string) (models.Node, error) {
  236. var reqNode, node models.Node
  237. var err error
  238. if err = json.Unmarshal([]byte(data), &reqNode); err != nil {
  239. oldID := strings.Split(data, "###") // handle legacy client IDs
  240. if len(oldID) == 2 {
  241. if node, err = logic.GetNodeByIDorMacAddress(reqNode.ID, oldID[0], oldID[1]); err != nil {
  242. return models.Node{}, err
  243. }
  244. } else {
  245. return models.Node{}, err
  246. }
  247. } else {
  248. node, err = logic.GetNodeByIDorMacAddress(reqNode.ID, reqNode.MacAddress, reqNode.Network)
  249. if err != nil {
  250. return models.Node{}, err
  251. }
  252. }
  253. return node, nil
  254. }
  255. func isServer(node *models.Node) bool {
  256. return node.IsServer == "yes"
  257. }