nodeGrpcController.go 16 KB

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