nodeGrpcController.go 15 KB

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