nodeGrpcController.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. package controller
  2. import (
  3. "context"
  4. "fmt"
  5. "log"
  6. "github.com/gravitl/netmaker/functions"
  7. nodepb "github.com/gravitl/netmaker/grpc"
  8. "github.com/gravitl/netmaker/models"
  9. "github.com/gravitl/netmaker/servercfg"
  10. "google.golang.org/grpc/codes"
  11. "google.golang.org/grpc/status"
  12. )
  13. type NodeServiceServer struct {
  14. nodepb.UnimplementedNodeServiceServer
  15. }
  16. func (s *NodeServiceServer) ReadNode(ctx context.Context, req *nodepb.ReadNodeReq) (*nodepb.ReadNodeRes, error) {
  17. // convert string id (from proto) to mongoDB ObjectId
  18. macaddress := req.GetMacaddress()
  19. networkName := req.GetNetwork()
  20. network, _ := functions.GetParentNetwork(networkName)
  21. node, err := GetNode(macaddress, networkName)
  22. if err != nil {
  23. return nil, status.Errorf(codes.InvalidArgument, fmt.Sprintf("Something went wrong: %v", err))
  24. }
  25. /*
  26. if node == nil {
  27. return nil, status.Errorf(codes.NotFound, fmt.Sprintf("Could not find node with Mac Address %s: %v", req.GetMacaddress(), err))
  28. }
  29. */
  30. // Cast to ReadNodeRes type
  31. response := &nodepb.ReadNodeRes{
  32. Node: &nodepb.Node{
  33. Macaddress: node.MacAddress,
  34. Name: node.Name,
  35. Address: node.Address,
  36. Address6: node.Address6,
  37. Endpoint: node.Endpoint,
  38. Password: node.Password,
  39. Nodenetwork: node.Network,
  40. Interface: node.Interface,
  41. Localaddress: node.LocalAddress,
  42. Postdown: node.PostDown,
  43. Postup: node.PostUp,
  44. Checkininterval: node.CheckInInterval,
  45. Dnsoff: !servercfg.IsDNSMode(),
  46. Ispending: node.IsPending,
  47. Isingressgateway: node.IsIngressGateway,
  48. Ingressgatewayrange: node.IngressGatewayRange,
  49. Publickey: node.PublicKey,
  50. Listenport: node.ListenPort,
  51. Keepalive: node.PersistentKeepalive,
  52. Islocal: network.IsLocal == "yes",
  53. Isdualstack: network.IsDualStack == "yes",
  54. Localrange: network.LocalRange,
  55. Udpholepunch: node.UDPHolePunch,
  56. },
  57. }
  58. return response, nil
  59. }
  60. func (s *NodeServiceServer) CreateNode(ctx context.Context, req *nodepb.CreateNodeReq) (*nodepb.CreateNodeRes, error) {
  61. // Get the protobuf node type from the protobuf request type
  62. // Essentially doing req.Node to access the struct with a nil check
  63. data := req.GetNode()
  64. // Now we have to convert this into a NodeItem type to convert into BSON
  65. node := models.Node{
  66. // ID: primitive.NilObjectID,
  67. MacAddress: data.GetMacaddress(),
  68. LocalAddress: data.GetLocaladdress(),
  69. Name: data.GetName(),
  70. Address: data.GetAddress(),
  71. Address6: data.GetAddress6(),
  72. AccessKey: data.GetAccesskey(),
  73. Endpoint: data.GetEndpoint(),
  74. PersistentKeepalive: data.GetKeepalive(),
  75. Password: data.GetPassword(),
  76. Interface: data.GetInterface(),
  77. Network: data.GetNodenetwork(),
  78. IsPending: data.GetIspending(),
  79. PublicKey: data.GetPublickey(),
  80. ListenPort: data.GetListenport(),
  81. UDPHolePunch: data.GetUdpholepunch(),
  82. }
  83. //Check to see if key is valid
  84. //TODO: Triple inefficient!!! This is the third call to the DB we make for networks
  85. validKey := functions.IsKeyValid(node.Network, node.AccessKey)
  86. network, err := functions.GetParentNetwork(node.Network)
  87. if err != nil {
  88. return nil, status.Errorf(codes.NotFound, fmt.Sprintf("Could not find network: %v", err))
  89. }
  90. if !validKey {
  91. //Check to see if network will allow manual sign up
  92. //may want to switch this up with the valid key check and avoid a DB call that way.
  93. if network.AllowManualSignUp == "yes" {
  94. node.IsPending = true
  95. } else {
  96. return nil, status.Errorf(
  97. codes.Internal,
  98. fmt.Sprintf("Invalid key, and network does not allow no-key signups"),
  99. )
  100. }
  101. }
  102. node, err = CreateNode(node, node.Network)
  103. if err != nil {
  104. // return internal gRPC error to be handled later
  105. return nil, status.Errorf(
  106. codes.Internal,
  107. fmt.Sprintf("Internal error: %v", err),
  108. )
  109. }
  110. // return the node in a CreateNodeRes type
  111. response := &nodepb.CreateNodeRes{
  112. Node: &nodepb.Node{
  113. Macaddress: node.MacAddress,
  114. Localaddress: node.LocalAddress,
  115. Name: node.Name,
  116. Address: node.Address,
  117. Address6: node.Address6,
  118. Endpoint: node.Endpoint,
  119. Password: node.Password,
  120. Interface: node.Interface,
  121. Nodenetwork: node.Network,
  122. Dnsoff: !servercfg.IsDNSMode(),
  123. Ispending: node.IsPending,
  124. Publickey: node.PublicKey,
  125. Listenport: node.ListenPort,
  126. Keepalive: node.PersistentKeepalive,
  127. Islocal: network.IsLocal == "yes",
  128. Isdualstack: network.IsDualStack == "yes",
  129. Localrange: network.LocalRange,
  130. Udpholepunch: node.UDPHolePunch,
  131. },
  132. }
  133. err = SetNetworkNodesLastModified(node.Network)
  134. if err != nil {
  135. return nil, status.Errorf(codes.NotFound, fmt.Sprintf("Could not update network last modified date: %v", err))
  136. }
  137. return response, nil
  138. }
  139. func (s *NodeServiceServer) CheckIn(ctx context.Context, req *nodepb.CheckInReq) (*nodepb.CheckInRes, error) {
  140. // Get the protobuf node type from the protobuf request type
  141. // Essentially doing req.Node to access the struct with a nil check
  142. data := req.GetNode()
  143. //postchanges := req.GetPostchanges()
  144. // Now we have to convert this into a NodeItem type to convert into BSON
  145. log.Println("checkin data:",data)
  146. node := models.Node{
  147. // ID: primitive.NilObjectID,
  148. MacAddress: data.GetMacaddress(),
  149. Address: data.GetAddress(),
  150. Address6: data.GetAddress6(),
  151. Endpoint: data.GetEndpoint(),
  152. Network: data.GetNodenetwork(),
  153. Password: data.GetPassword(),
  154. LocalAddress: data.GetLocaladdress(),
  155. ListenPort: data.GetListenport(),
  156. PersistentKeepalive: data.GetKeepalive(),
  157. PublicKey: data.GetPublickey(),
  158. UDPHolePunch: data.GetUdpholepunch(),
  159. SaveConfig: data.GetSaveconfig(),
  160. }
  161. checkinresponse, err := NodeCheckIn(node, node.Network)
  162. if err != nil {
  163. // return internal gRPC error to be handled later
  164. if checkinresponse == (models.CheckInResponse{}) || !checkinresponse.IsPending {
  165. return nil, status.Errorf(
  166. codes.Internal,
  167. fmt.Sprintf("Internal error: %v", err),
  168. )
  169. }
  170. }
  171. // return the node in a CreateNodeRes type
  172. response := &nodepb.CheckInRes{
  173. Checkinresponse: &nodepb.CheckInResponse{
  174. Success: checkinresponse.Success,
  175. Needpeerupdate: checkinresponse.NeedPeerUpdate,
  176. Needdelete: checkinresponse.NeedDelete,
  177. Needconfigupdate: checkinresponse.NeedConfigUpdate,
  178. Needkeyupdate: checkinresponse.NeedKeyUpdate,
  179. Nodemessage: checkinresponse.NodeMessage,
  180. Ispending: checkinresponse.IsPending,
  181. },
  182. }
  183. return response, nil
  184. }
  185. func (s *NodeServiceServer) UpdateNode(ctx context.Context, req *nodepb.UpdateNodeReq) (*nodepb.UpdateNodeRes, error) {
  186. // Get the node data from the request
  187. data := req.GetNode()
  188. log.Println("DATA:",data)
  189. // Now we have to convert this into a NodeItem type to convert into BSON
  190. newnode := models.Node{
  191. // ID: primitive.NilObjectID,
  192. MacAddress: data.GetMacaddress(),
  193. Name: data.GetName(),
  194. Address: data.GetAddress(),
  195. Address6: data.GetAddress6(),
  196. LocalAddress: data.GetLocaladdress(),
  197. Endpoint: data.GetEndpoint(),
  198. Password: data.GetPassword(),
  199. PersistentKeepalive: data.GetKeepalive(),
  200. Network: data.GetNodenetwork(),
  201. Interface: data.GetInterface(),
  202. PostDown: data.GetPostdown(),
  203. PostUp: data.GetPostup(),
  204. IsPending: data.GetIspending(),
  205. PublicKey: data.GetPublickey(),
  206. ListenPort: data.GetListenport(),
  207. UDPHolePunch: data.GetUdpholepunch(),
  208. SaveConfig: data.GetSaveconfig(),
  209. }
  210. // Convert the Id string to a MongoDB ObjectId
  211. macaddress := newnode.MacAddress
  212. networkName := newnode.Network
  213. network, _ := functions.GetParentNetwork(networkName)
  214. log.Println("NODE SAVECONFIG:",newnode.SaveConfig)
  215. node, err := functions.GetNodeByMacAddress(networkName, macaddress)
  216. if err != nil {
  217. return nil, status.Errorf(
  218. codes.NotFound,
  219. fmt.Sprintf("Could not find node with supplied Mac Address: %v", err),
  220. )
  221. }
  222. err = node.Update(&newnode)
  223. if err != nil {
  224. return nil, status.Errorf(
  225. codes.NotFound,
  226. fmt.Sprintf("Could not update node: %v", err),
  227. )
  228. }
  229. return &nodepb.UpdateNodeRes{
  230. Node: &nodepb.Node{
  231. Macaddress: newnode.MacAddress,
  232. Localaddress: newnode.LocalAddress,
  233. Name: newnode.Name,
  234. Address: newnode.Address,
  235. Address6: newnode.Address6,
  236. Endpoint: newnode.Endpoint,
  237. Password: newnode.Password,
  238. Interface: newnode.Interface,
  239. Postdown: newnode.PostDown,
  240. Postup: newnode.PostUp,
  241. Nodenetwork: newnode.Network,
  242. Ispending: newnode.IsPending,
  243. Publickey: newnode.PublicKey,
  244. Dnsoff: !servercfg.IsDNSMode(),
  245. Listenport: newnode.ListenPort,
  246. Keepalive: newnode.PersistentKeepalive,
  247. Islocal: network.IsLocal == "yes",
  248. Isdualstack: network.IsDualStack == "yes",
  249. Localrange: network.LocalRange,
  250. Udpholepunch: newnode.UDPHolePunch,
  251. },
  252. }, nil
  253. }
  254. func (s *NodeServiceServer) DeleteNode(ctx context.Context, req *nodepb.DeleteNodeReq) (*nodepb.DeleteNodeRes, error) {
  255. macaddress := req.GetMacaddress()
  256. network := req.GetNetworkName()
  257. err := DeleteNode(macaddress, network)
  258. if err != nil {
  259. fmt.Println("Error deleting node.")
  260. fmt.Println(err)
  261. return nil, status.Errorf(codes.NotFound, fmt.Sprintf("Could not find/delete node with mac address %s", macaddress))
  262. }
  263. fmt.Println("updating network last modified of " + req.GetNetworkName())
  264. err = SetNetworkNodesLastModified(req.GetNetworkName())
  265. if err != nil {
  266. fmt.Println("Error updating Network")
  267. fmt.Println(err)
  268. return nil, status.Errorf(codes.NotFound, fmt.Sprintf("Could not update network last modified date: %v", err))
  269. }
  270. return &nodepb.DeleteNodeRes{
  271. Success: true,
  272. }, nil
  273. }
  274. func (s *NodeServiceServer) GetPeers(req *nodepb.GetPeersReq, stream nodepb.NodeService_GetPeersServer) error {
  275. // Initiate a NodeItem type to write decoded data to
  276. //data := &models.PeersResponse{}
  277. // collection.Find returns a cursor for our (empty) query
  278. peers, err := GetPeersList(req.GetNetwork())
  279. if err != nil {
  280. return status.Errorf(codes.Internal, fmt.Sprintf("Unknown internal error: %v", err))
  281. }
  282. // cursor.Next() returns a boolean, if false there are no more items and loop will break
  283. for i := 0; i < len(peers); i++ {
  284. // If no error is found send node over stream
  285. stream.Send(&nodepb.GetPeersRes{
  286. Peers: &nodepb.PeersResponse{
  287. Address: peers[i].Address,
  288. Address6: peers[i].Address6,
  289. Endpoint: peers[i].Endpoint,
  290. Egressgatewayrange: peers[i].EgressGatewayRange,
  291. Isegressgateway: peers[i].IsEgressGateway,
  292. Publickey: peers[i].PublicKey,
  293. Keepalive: peers[i].KeepAlive,
  294. Listenport: peers[i].ListenPort,
  295. Localaddress: peers[i].LocalAddress,
  296. },
  297. })
  298. }
  299. node, err := functions.GetNodeByMacAddress(req.GetNetwork(), req.GetMacaddress())
  300. if err != nil {
  301. return status.Errorf(codes.Internal, fmt.Sprintf("Could not get node: %v", err))
  302. }
  303. err = TimestampNode(node, false, true, false)
  304. if err != nil {
  305. return status.Errorf(codes.Internal, fmt.Sprintf("Internal error occurred: %v", err))
  306. }
  307. return nil
  308. }
  309. func (s *NodeServiceServer) GetExtPeers(req *nodepb.GetExtPeersReq, stream nodepb.NodeService_GetExtPeersServer) error {
  310. // Initiate a NodeItem type to write decoded data to
  311. //data := &models.PeersResponse{}
  312. // collection.Find returns a cursor for our (empty) query
  313. peers, err := GetExtPeersList(req.GetNetwork(), req.GetMacaddress())
  314. if err != nil {
  315. return status.Errorf(codes.Internal, fmt.Sprintf("Unknown internal error: %v", err))
  316. }
  317. // cursor.Next() returns a boolean, if false there are no more items and loop will break
  318. for i := 0; i < len(peers); i++ {
  319. // If no error is found send node over stream
  320. stream.Send(&nodepb.GetExtPeersRes{
  321. Extpeers: &nodepb.ExtPeersResponse{
  322. Address: peers[i].Address,
  323. Address6: peers[i].Address6,
  324. Endpoint: peers[i].Endpoint,
  325. Publickey: peers[i].PublicKey,
  326. Keepalive: peers[i].KeepAlive,
  327. Listenport: peers[i].ListenPort,
  328. Localaddress: peers[i].LocalAddress,
  329. },
  330. })
  331. }
  332. node, err := functions.GetNodeByMacAddress(req.GetNetwork(), req.GetMacaddress())
  333. if err != nil {
  334. return status.Errorf(codes.Internal, fmt.Sprintf("Could not get node: %v", err))
  335. }
  336. err = TimestampNode(node, false, true, false)
  337. if err != nil {
  338. return status.Errorf(codes.Internal, fmt.Sprintf("Internal error occurred: %v", err))
  339. }
  340. return nil
  341. }