nodeGrpcController.go 13 KB

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