nodeGrpcController.go 13 KB

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