nodeGrpcController.go 15 KB

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