nodeGrpcController.go 12 KB

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