| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368 | package controllerimport (	"context"	"fmt"	"github.com/gravitl/netmaker/functions"	nodepb "github.com/gravitl/netmaker/grpc"	"github.com/gravitl/netmaker/models"	"github.com/gravitl/netmaker/servercfg"	"google.golang.org/grpc/codes"	"google.golang.org/grpc/status")type NodeServiceServer struct {	nodepb.UnimplementedNodeServiceServer}func (s *NodeServiceServer) ReadNode(ctx context.Context, req *nodepb.ReadNodeReq) (*nodepb.ReadNodeRes, error) {	// convert string id (from proto) to mongoDB ObjectId	macaddress := req.GetMacaddress()	networkName := req.GetNetwork()	network, _ := functions.GetParentNetwork(networkName)	node, err := GetNode(macaddress, networkName)	if err != nil {		return nil, status.Errorf(codes.InvalidArgument, fmt.Sprintf("Something went wrong: %v", err))	}	// Cast to ReadNodeRes type	response := &nodepb.ReadNodeRes{		Node: &nodepb.Node{			Macaddress:          node.MacAddress,			Name:                node.Name,			Address:             node.Address,			Address6:            node.Address6,			Endpoint:            node.Endpoint,			Password:            node.Password,			Nodenetwork:         node.Network,			Interface:           node.Interface,			Localaddress:        node.LocalAddress,			Postdown:            node.PostDown,			Postup:              node.PostUp,			Checkininterval:     node.CheckInInterval,			Dnsoff:              !servercfg.IsDNSMode(),			Ispending:           node.IsPending == "yes",			Isingressgateway:    node.IsIngressGateway == "yes",			Ingressgatewayrange: node.IngressGatewayRange,			Publickey:           node.PublicKey,			Listenport:          node.ListenPort,			Keepalive:           node.PersistentKeepalive,			Islocal:             network.IsLocal == "yes",			Isdualstack:         network.IsDualStack == "yes",			Localrange:          network.LocalRange,			Udpholepunch:        node.UDPHolePunch,		},	}	return response, nil}func (s *NodeServiceServer) CreateNode(ctx context.Context, req *nodepb.CreateNodeReq) (*nodepb.CreateNodeRes, error) {	// Get the protobuf node type from the protobuf request type	// Essentially doing req.Node to access the struct with a nil check	data := req.GetNode()	// Now we have to convert this into a NodeItem type to convert into BSON	node := models.Node{		// ID:       primitive.NilObjectID,		MacAddress:          data.GetMacaddress(),		LocalAddress:        data.GetLocaladdress(),		Name:                data.GetName(),		Address:             data.GetAddress(),		Address6:            data.GetAddress6(),		AccessKey:           data.GetAccesskey(),		Endpoint:            data.GetEndpoint(),		PersistentKeepalive: data.GetKeepalive(),		Password:            data.GetPassword(),		Interface:           data.GetInterface(),		Network:             data.GetNodenetwork(),		PublicKey:           data.GetPublickey(),		ListenPort:          data.GetListenport(),		UDPHolePunch:        data.GetUdpholepunch(),	}	//Check to see if key is valid	//TODO: Triple inefficient!!! This is the third call to the DB we make for networks	validKey := functions.IsKeyValid(node.Network, node.AccessKey)	network, err := functions.GetParentNetwork(node.Network)	if err != nil {		return nil, status.Errorf(codes.NotFound, fmt.Sprintf("Could not find network: %v", err))	}	if !validKey {		//Check to see if network will allow manual sign up		//may want to switch this up with the valid key check and avoid a DB call that way.		if network.AllowManualSignUp == "yes" {			node.IsPending = "yes"		} else {			return nil, status.Errorf(				codes.Internal,				fmt.Sprintf("Invalid key, and network does not allow no-key signups"),			)		}	}	node, err = CreateNode(node, node.Network)	if err != nil {		// return internal gRPC error to be handled later		return nil, status.Errorf(			codes.Internal,			fmt.Sprintf("Internal error: %v", err),		)	}	// return the node in a CreateNodeRes type	response := &nodepb.CreateNodeRes{		Node: &nodepb.Node{			Macaddress:   node.MacAddress,			Localaddress: node.LocalAddress,			Name:         node.Name,			Address:      node.Address,			Address6:     node.Address6,			Endpoint:     node.Endpoint,			Password:     node.Password,			Interface:    node.Interface,			Nodenetwork:  node.Network,			Dnsoff:       !servercfg.IsDNSMode(),			Ispending:    node.IsPending == "yes",			Publickey:    node.PublicKey,			Listenport:   node.ListenPort,			Keepalive:    node.PersistentKeepalive,			Islocal:      network.IsLocal == "yes",			Isdualstack:  network.IsDualStack == "yes",			Localrange:   network.LocalRange,			Udpholepunch: node.UDPHolePunch,		},	}	err = SetNetworkNodesLastModified(node.Network)	if err != nil {		return nil, status.Errorf(codes.NotFound, fmt.Sprintf("Could not update network last modified date: %v", err))	}	return response, nil}func (s *NodeServiceServer) CheckIn(ctx context.Context, req *nodepb.CheckInReq) (*nodepb.CheckInRes, error) {	// Get the protobuf node type from the protobuf request type	// Essentially doing req.Node to access the struct with a nil check	data := req.GetNode()	//postchanges := req.GetPostchanges()	// Now we have to convert this into a NodeItem type to convert into BSON	node := models.Node{		// ID:       primitive.NilObjectID,		MacAddress:          data.GetMacaddress(),		Address:             data.GetAddress(),		Address6:            data.GetAddress6(),		Endpoint:            data.GetEndpoint(),		Network:             data.GetNodenetwork(),		Password:            data.GetPassword(),		LocalAddress:        data.GetLocaladdress(),		ListenPort:          data.GetListenport(),		PersistentKeepalive: data.GetKeepalive(),		PublicKey:           data.GetPublickey(),		UDPHolePunch:        data.GetUdpholepunch(),		SaveConfig:          data.GetSaveconfig(),	}	checkinresponse, err := NodeCheckIn(node, node.Network)	if err != nil {		// return internal gRPC error to be handled later		if checkinresponse == (models.CheckInResponse{}) || !checkinresponse.IsPending {			return nil, status.Errorf(				codes.Internal,				fmt.Sprintf("Internal error: %v", err),			)		}	}	// return the node in a CreateNodeRes type	response := &nodepb.CheckInRes{		Checkinresponse: &nodepb.CheckInResponse{			Success:          checkinresponse.Success,			Needpeerupdate:   checkinresponse.NeedPeerUpdate,			Needdelete:       checkinresponse.NeedDelete,			Needconfigupdate: checkinresponse.NeedConfigUpdate,			Needkeyupdate:    checkinresponse.NeedKeyUpdate,			Nodemessage:      checkinresponse.NodeMessage,			Ispending:        checkinresponse.IsPending,		},	}	return response, nil}func (s *NodeServiceServer) UpdateNode(ctx context.Context, req *nodepb.UpdateNodeReq) (*nodepb.UpdateNodeRes, error) {	// Get the node data from the request	data := req.GetNode()	// Now we have to convert this into a NodeItem type to convert into BSON	newnode := models.Node{		// ID:       primitive.NilObjectID,		MacAddress:          data.GetMacaddress(),		Name:                data.GetName(),		Address:             data.GetAddress(),		Address6:            data.GetAddress6(),		LocalAddress:        data.GetLocaladdress(),		Endpoint:            data.GetEndpoint(),		Password:            data.GetPassword(),		PersistentKeepalive: data.GetKeepalive(),		Network:             data.GetNodenetwork(),		Interface:           data.GetInterface(),		PostDown:            data.GetPostdown(),		PostUp:              data.GetPostup(),		PublicKey:           data.GetPublickey(),		ListenPort:          data.GetListenport(),		UDPHolePunch:        data.GetUdpholepunch(),		SaveConfig:          data.GetSaveconfig(),	}	// Convert the Id string to a MongoDB ObjectId	macaddress := newnode.MacAddress	networkName := newnode.Network	network, _ := functions.GetParentNetwork(networkName)	node, err := functions.GetNodeByMacAddress(networkName, macaddress)	if err != nil {		return nil, status.Errorf(			codes.NotFound,			fmt.Sprintf("Could not find node with supplied Mac Address: %v", err),		)	}	err = node.Update(&newnode)	if err != nil {		return nil, status.Errorf(			codes.NotFound,			fmt.Sprintf("Could not update node: %v", err),		)	}	return &nodepb.UpdateNodeRes{		Node: &nodepb.Node{			Macaddress:   newnode.MacAddress,			Localaddress: newnode.LocalAddress,			Name:         newnode.Name,			Address:      newnode.Address,			Address6:     newnode.Address6,			Endpoint:     newnode.Endpoint,			Password:     newnode.Password,			Interface:    newnode.Interface,			Postdown:     newnode.PostDown,			Postup:       newnode.PostUp,			Nodenetwork:  newnode.Network,			Ispending:    newnode.IsPending == "yes",			Publickey:    newnode.PublicKey,			Dnsoff:       !servercfg.IsDNSMode(),			Listenport:   newnode.ListenPort,			Keepalive:    newnode.PersistentKeepalive,			Islocal:      network.IsLocal == "yes",			Isdualstack:  network.IsDualStack == "yes",			Localrange:   network.LocalRange,			Udpholepunch: newnode.UDPHolePunch,		},	}, nil}func (s *NodeServiceServer) DeleteNode(ctx context.Context, req *nodepb.DeleteNodeReq) (*nodepb.DeleteNodeRes, error) {	macaddress := req.GetMacaddress()	network := req.GetNetworkName()	err := DeleteNode(macaddress, network)	if err != nil {		fmt.Println("Error deleting node.")		fmt.Println(err)		return nil, status.Errorf(codes.NotFound, fmt.Sprintf("Could not find/delete node with mac address %s", macaddress))	}	fmt.Println("updating network last modified of " + req.GetNetworkName())	err = SetNetworkNodesLastModified(req.GetNetworkName())	if err != nil {		fmt.Println("Error updating Network")		fmt.Println(err)		return nil, status.Errorf(codes.NotFound, fmt.Sprintf("Could not update network last modified date: %v", err))	}	return &nodepb.DeleteNodeRes{		Success: true,	}, nil}func (s *NodeServiceServer) GetPeers(req *nodepb.GetPeersReq, stream nodepb.NodeService_GetPeersServer) error {	// Initiate a NodeItem type to write decoded data to	//data := &models.PeersResponse{}	// collection.Find returns a cursor for our (empty) query	peers, err := GetPeersList(req.GetNetwork())	if err != nil {		return status.Errorf(codes.Internal, fmt.Sprintf("Unknown internal error: %v", err))	}	// cursor.Next() returns a boolean, if false there are no more items and loop will break	for i := 0; i < len(peers); i++ {		// If no error is found send node over stream		stream.Send(&nodepb.GetPeersRes{			Peers: &nodepb.PeersResponse{				Address:            peers[i].Address,				Address6:           peers[i].Address6,				Endpoint:           peers[i].Endpoint,				Egressgatewayranges: peers[i].EgressGatewayRanges,				Isegressgateway:    peers[i].IsEgressGateway == "yes",				Publickey:          peers[i].PublicKey,				Keepalive:          peers[i].KeepAlive,				Listenport:         peers[i].ListenPort,				Localaddress:       peers[i].LocalAddress,			},		})	}	node, err := functions.GetNodeByMacAddress(req.GetNetwork(), req.GetMacaddress())	if err != nil {		return status.Errorf(codes.Internal, fmt.Sprintf("Could not get node: %v", err))	}	err = TimestampNode(node, false, true, false)	if err != nil {		return status.Errorf(codes.Internal, fmt.Sprintf("Internal error occurred: %v", err))	}	return nil}func (s *NodeServiceServer) GetExtPeers(req *nodepb.GetExtPeersReq, stream nodepb.NodeService_GetExtPeersServer) error {	// Initiate a NodeItem type to write decoded data to	//data := &models.PeersResponse{}	// collection.Find returns a cursor for our (empty) query	peers, err := GetExtPeersList(req.GetNetwork(), req.GetMacaddress())	if err != nil {		return status.Errorf(codes.Internal, fmt.Sprintf("Unknown internal error: %v", err))	}	// cursor.Next() returns a boolean, if false there are no more items and loop will break	for i := 0; i < len(peers); i++ {		// If no error is found send node over stream		stream.Send(&nodepb.GetExtPeersRes{			Extpeers: &nodepb.ExtPeersResponse{				Address:      peers[i].Address,				Address6:     peers[i].Address6,				Endpoint:     peers[i].Endpoint,				Publickey:    peers[i].PublicKey,				Keepalive:    peers[i].KeepAlive,				Listenport:   peers[i].ListenPort,				Localaddress: peers[i].LocalAddress,			},		})	}	node, err := functions.GetNodeByMacAddress(req.GetNetwork(), req.GetMacaddress())	if err != nil {		return status.Errorf(codes.Internal, fmt.Sprintf("Could not get node: %v", err))	}	err = TimestampNode(node, false, true, false)	if err != nil {		return status.Errorf(codes.Internal, fmt.Sprintf("Internal error occurred: %v", err))	}	return nil}
 |