nodeGrpcController.go 12 KB

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