nodeGrpcController.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. package controller
  2. import (
  3. "context"
  4. "fmt"
  5. nodepb "github.com/gravitl/netmaker/grpc"
  6. "github.com/gravitl/netmaker/models"
  7. "github.com/gravitl/netmaker/functions"
  8. "go.mongodb.org/mongo-driver/mongo"
  9. "google.golang.org/grpc/codes"
  10. "google.golang.org/grpc/status"
  11. )
  12. type NodeServiceServer struct {
  13. NodeDB *mongo.Collection
  14. nodepb.UnimplementedNodeServiceServer
  15. }
  16. func (s *NodeServiceServer) ReadNode(ctx context.Context, req *nodepb.ReadNodeReq) (*nodepb.ReadNodeRes, error) {
  17. // convert string id (from proto) to mongoDB ObjectId
  18. macaddress := req.GetMacaddress()
  19. networkName := req.GetNetwork()
  20. network, _ := functions.GetParentNetwork(networkName)
  21. node, err := GetNode(macaddress, networkName)
  22. if err != nil {
  23. return nil, status.Errorf(codes.InvalidArgument, fmt.Sprintf("Something went wrong: %v", err))
  24. }
  25. /*
  26. if node == nil {
  27. return nil, status.Errorf(codes.NotFound, fmt.Sprintf("Could not find node with Mac Address %s: %v", req.GetMacaddress(), err))
  28. }
  29. */
  30. // Cast to ReadNodeRes type
  31. response := &nodepb.ReadNodeRes{
  32. Node: &nodepb.Node{
  33. Macaddress: node.MacAddress,
  34. Name: node.Name,
  35. Address: node.Address,
  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. Ispending: node.IsPending,
  45. Publickey: node.PublicKey,
  46. Listenport: node.ListenPort,
  47. Keepalive: node.PersistentKeepalive,
  48. Islocal: *network.IsLocal,
  49. Localrange: network.LocalRange,
  50. },
  51. }
  52. return response, nil
  53. }
  54. func (s *NodeServiceServer) CreateNode(ctx context.Context, req *nodepb.CreateNodeReq) (*nodepb.CreateNodeRes, error) {
  55. // Get the protobuf node type from the protobuf request type
  56. // Essentially doing req.Node to access the struct with a nil check
  57. data := req.GetNode()
  58. // Now we have to convert this into a NodeItem type to convert into BSON
  59. node := models.Node{
  60. // ID: primitive.NilObjectID,
  61. MacAddress: data.GetMacaddress(),
  62. LocalAddress: data.GetLocaladdress(),
  63. Name: data.GetName(),
  64. Address: data.GetAddress(),
  65. AccessKey: data.GetAccesskey(),
  66. Endpoint: data.GetEndpoint(),
  67. PersistentKeepalive: data.GetKeepalive(),
  68. Password: data.GetPassword(),
  69. Interface: data.GetInterface(),
  70. Network: data.GetNodenetwork(),
  71. IsPending: data.GetIspending(),
  72. PublicKey: data.GetPublickey(),
  73. ListenPort: data.GetListenport(),
  74. }
  75. err := ValidateNode("create", node.Network, node)
  76. if err != nil {
  77. // return internal gRPC error to be handled later
  78. return nil, err
  79. }
  80. //Check to see if key is valid
  81. //TODO: Triple inefficient!!! This is the third call to the DB we make for networks
  82. validKey := functions.IsKeyValid(node.Network, node.AccessKey)
  83. network, _ := functions.GetParentNetwork(node.Network)
  84. if !validKey {
  85. //Check to see if network will allow manual sign up
  86. //may want to switch this up with the valid key check and avoid a DB call that way.
  87. if *network.AllowManualSignUp {
  88. node.IsPending = true
  89. } else {
  90. return nil, status.Errorf(
  91. codes.Internal,
  92. fmt.Sprintf("Invalid key, and network does not allow no-key signups"),
  93. )
  94. }
  95. }
  96. node, err = CreateNode(node, node.Network)
  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.CreateNodeRes{
  106. Node: &nodepb.Node{
  107. Macaddress: node.MacAddress,
  108. Localaddress: node.LocalAddress,
  109. Name: node.Name,
  110. Address: node.Address,
  111. Endpoint: node.Endpoint,
  112. Password: node.Password,
  113. Interface: node.Interface,
  114. Nodenetwork: node.Network,
  115. Ispending: node.IsPending,
  116. Publickey: node.PublicKey,
  117. Listenport: node.ListenPort,
  118. Keepalive: node.PersistentKeepalive,
  119. Islocal: *network.IsLocal,
  120. Localrange: network.LocalRange,
  121. },
  122. }
  123. err = SetNetworkNodesLastModified(node.Network)
  124. if err != nil {
  125. return nil, status.Errorf(codes.NotFound, fmt.Sprintf("Could not update network last modified date: %v", err))
  126. }
  127. return response, nil
  128. }
  129. func (s *NodeServiceServer) CheckIn(ctx context.Context, req *nodepb.CheckInReq) (*nodepb.CheckInRes, error) {
  130. // Get the protobuf node type from the protobuf request type
  131. // Essentially doing req.Node to access the struct with a nil check
  132. data := req.GetNode()
  133. //postchanges := req.GetPostchanges()
  134. // Now we have to convert this into a NodeItem type to convert into BSON
  135. node := models.Node{
  136. // ID: primitive.NilObjectID,
  137. MacAddress: data.GetMacaddress(),
  138. Address: data.GetAddress(),
  139. Endpoint: data.GetEndpoint(),
  140. Network: data.GetNodenetwork(),
  141. Password: data.GetPassword(),
  142. LocalAddress: data.GetLocaladdress(),
  143. ListenPort: data.GetListenport(),
  144. PersistentKeepalive: data.GetKeepalive(),
  145. PublicKey: data.GetPublickey(),
  146. }
  147. checkinresponse, err := NodeCheckIn(node, node.Network)
  148. if err != nil {
  149. // return internal gRPC error to be handled later
  150. if checkinresponse == (models.CheckInResponse{}) || !checkinresponse.IsPending {
  151. return nil, status.Errorf(
  152. codes.Internal,
  153. fmt.Sprintf("Internal error: %v", err),
  154. )
  155. }
  156. }
  157. // return the node in a CreateNodeRes type
  158. response := &nodepb.CheckInRes{
  159. Checkinresponse: &nodepb.CheckInResponse{
  160. Success: checkinresponse.Success,
  161. Needpeerupdate: checkinresponse.NeedPeerUpdate,
  162. Needdelete: checkinresponse.NeedDelete,
  163. Needconfigupdate: checkinresponse.NeedConfigUpdate,
  164. Needkeyupdate: checkinresponse.NeedKeyUpdate,
  165. Nodemessage: checkinresponse.NodeMessage,
  166. Ispending: checkinresponse.IsPending,
  167. },
  168. }
  169. return response, nil
  170. }
  171. func (s *NodeServiceServer) UpdateNode(ctx context.Context, req *nodepb.UpdateNodeReq) (*nodepb.UpdateNodeRes, error) {
  172. // Get the node data from the request
  173. data := req.GetNode()
  174. // Now we have to convert this into a NodeItem type to convert into BSON
  175. nodechange := models.Node{
  176. // ID: primitive.NilObjectID,
  177. MacAddress: data.GetMacaddress(),
  178. Name: data.GetName(),
  179. Address: data.GetAddress(),
  180. LocalAddress: data.GetLocaladdress(),
  181. Endpoint: data.GetEndpoint(),
  182. Password: data.GetPassword(),
  183. PersistentKeepalive: data.GetKeepalive(),
  184. Network: data.GetNodenetwork(),
  185. Interface: data.GetInterface(),
  186. PostDown: data.GetPostdown(),
  187. PostUp: data.GetPostup(),
  188. IsPending: data.GetIspending(),
  189. PublicKey: data.GetPublickey(),
  190. ListenPort: data.GetListenport(),
  191. }
  192. // Convert the Id string to a MongoDB ObjectId
  193. macaddress := nodechange.MacAddress
  194. networkName := nodechange.Network
  195. network, _ := functions.GetParentNetwork(networkName)
  196. err := ValidateNode("update", networkName, nodechange)
  197. if err != nil {
  198. return nil, err
  199. }
  200. node, err := functions.GetNodeByMacAddress(networkName, macaddress)
  201. if err != nil {
  202. return nil, status.Errorf(
  203. codes.NotFound,
  204. fmt.Sprintf("Could not find node with supplied Mac Address: %v", err),
  205. )
  206. }
  207. newnode, err := UpdateNode(nodechange, node)
  208. if err != nil {
  209. return nil, status.Errorf(
  210. codes.NotFound,
  211. fmt.Sprintf("Could not find node with supplied Mac Address: %v", err),
  212. )
  213. }
  214. return &nodepb.UpdateNodeRes{
  215. Node: &nodepb.Node{
  216. Macaddress: newnode.MacAddress,
  217. Localaddress: newnode.LocalAddress,
  218. Name: newnode.Name,
  219. Address: newnode.Address,
  220. Endpoint: newnode.Endpoint,
  221. Password: newnode.Password,
  222. Interface: newnode.Interface,
  223. Postdown: newnode.PostDown,
  224. Postup: newnode.PostUp,
  225. Nodenetwork: newnode.Network,
  226. Ispending: newnode.IsPending,
  227. Publickey: newnode.PublicKey,
  228. Listenport: newnode.ListenPort,
  229. Keepalive: newnode.PersistentKeepalive,
  230. Islocal: *network.IsLocal,
  231. Localrange: network.LocalRange,
  232. },
  233. }, nil
  234. }
  235. func (s *NodeServiceServer) DeleteNode(ctx context.Context, req *nodepb.DeleteNodeReq) (*nodepb.DeleteNodeRes, error) {
  236. fmt.Println("beginning node delete")
  237. macaddress := req.GetMacaddress()
  238. network := req.GetNetworkName()
  239. success, err := DeleteNode(macaddress, network)
  240. if err != nil || !success {
  241. fmt.Println("Error deleting node.")
  242. fmt.Println(err)
  243. return nil, status.Errorf(codes.NotFound, fmt.Sprintf("Could not find/delete node with mac address %s", macaddress))
  244. }
  245. fmt.Println("updating network last modified of " + req.GetNetworkName())
  246. err = SetNetworkNodesLastModified(req.GetNetworkName())
  247. if err != nil {
  248. fmt.Println("Error updating Network")
  249. fmt.Println(err)
  250. return nil, status.Errorf(codes.NotFound, fmt.Sprintf("Could not update network last modified date: %v", err))
  251. }
  252. return &nodepb.DeleteNodeRes{
  253. Success: true,
  254. }, nil
  255. }
  256. func (s *NodeServiceServer) GetPeers(req *nodepb.GetPeersReq, stream nodepb.NodeService_GetPeersServer) error {
  257. // Initiate a NodeItem type to write decoded data to
  258. //data := &models.PeersResponse{}
  259. // collection.Find returns a cursor for our (empty) query
  260. //cursor, err := s.NodeDB.Find(context.Background(), bson.M{})
  261. peers, err := GetPeersList(req.GetNetwork())
  262. if err != nil {
  263. return status.Errorf(codes.Internal, fmt.Sprintf("Unknown internal error: %v", err))
  264. }
  265. // cursor.Next() returns a boolean, if false there are no more items and loop will break
  266. for i := 0; i < len(peers); i++ {
  267. // If no error is found send node over stream
  268. stream.Send(&nodepb.GetPeersRes{
  269. Peers: &nodepb.PeersResponse{
  270. Address: peers[i].Address,
  271. Endpoint: peers[i].Endpoint,
  272. Gatewayrange: peers[i].GatewayRange,
  273. Isgateway: peers[i].IsGateway,
  274. Publickey: peers[i].PublicKey,
  275. Keepalive: peers[i].KeepAlive,
  276. Listenport: peers[i].ListenPort,
  277. Localaddress: peers[i].LocalAddress,
  278. },
  279. })
  280. }
  281. node, err := functions.GetNodeByMacAddress(req.GetNetwork(), req.GetMacaddress())
  282. if err != nil {
  283. return status.Errorf(codes.Internal, fmt.Sprintf("Could not get node: %v", err))
  284. }
  285. err = TimestampNode(node, false, true, false)
  286. if err != nil {
  287. return status.Errorf(codes.Internal, fmt.Sprintf("Internal error occurred: %v", err))
  288. }
  289. return nil
  290. }