nodeGrpcController.go 13 KB

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