nodeGrpcController.go 13 KB

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