nodeGrpcController.go 16 KB

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