| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 | package controllerimport (	"context"	"encoding/json"	"errors"	"strings"	"github.com/gravitl/netmaker/functions"	nodepb "github.com/gravitl/netmaker/grpc"	"github.com/gravitl/netmaker/models")type NodeServiceServer struct {	nodepb.UnimplementedNodeServiceServer}func (s *NodeServiceServer) ReadNode(ctx context.Context, req *nodepb.Object) (*nodepb.Object, error) {	// convert string id (from proto) to mongoDB ObjectId	macAndNetwork := strings.Split(req.Data, "###")	if len(macAndNetwork) != 2 {		return nil, errors.New("could not read node, invalid node id given")	}	node, err := GetNode(macAndNetwork[0], macAndNetwork[1])	if err != nil {		return nil, err	}	node.SetLastCheckIn()	// Cast to ReadNodeRes type	nodeData, err := json.Marshal(&node)	if err != nil {		return nil, err	}	node.Update(&node)	response := &nodepb.Object{		Data: string(nodeData),		Type: nodepb.NODE_TYPE,	}	return response, nil}func (s *NodeServiceServer) CreateNode(ctx context.Context, req *nodepb.Object) (*nodepb.Object, error) {	// Get the protobuf node type from the protobuf request type	// Essentially doing req.Node to access the struct with a nil check	var node models.Node	data := req.GetData()	if err := json.Unmarshal([]byte(data), &node); err != nil {		return nil, err	}	//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, 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, errors.New("invalid key, and network does not allow no-key signups")		}	}	node, err = CreateNode(node, node.Network)	if err != nil {		return nil, err	}	nodeData, err := json.Marshal(&node)	// return the node in a CreateNodeRes type	response := &nodepb.Object{		Data: string(nodeData),		Type: nodepb.NODE_TYPE,	}	err = SetNetworkNodesLastModified(node.Network)	if err != nil {		return nil, err	}	return response, nil}func (s *NodeServiceServer) UpdateNode(ctx context.Context, req *nodepb.Object) (*nodepb.Object, error) {	// Get the node data from the request	var newnode models.Node	if err := json.Unmarshal([]byte(req.GetData()), &newnode); err != nil {		return nil, err	}	macaddress := newnode.MacAddress	networkName := newnode.Network	node, err := functions.GetNodeByMacAddress(networkName, macaddress)	if err != nil {		return nil, err	}	err = node.Update(&newnode)	if err != nil {		return nil, err	}	nodeData, err := json.Marshal(&newnode)	if err != nil {		return nil, err	}	return &nodepb.Object{		Data: string(nodeData),		Type: nodepb.NODE_TYPE,	}, nil}func (s *NodeServiceServer) DeleteNode(ctx context.Context, req *nodepb.Object) (*nodepb.Object, error) {	nodeID := req.GetData()	err := DeleteNode(nodeID, true)	if err != nil {		return nil, err	}	return &nodepb.Object{		Data: "success",		Type: nodepb.STRING_TYPE,	}, nil}func (s *NodeServiceServer) GetPeers(ctx context.Context, req *nodepb.Object) (*nodepb.Object, error) {	macAndNetwork := strings.Split(req.Data, "###")	if len(macAndNetwork) == 2 {		// TODO: Make constant and new variable for isServer		node, err := GetNode(macAndNetwork[0], macAndNetwork[1])		if err != nil {			return nil, err		}		if node.IsServer == "yes" {			SetNetworkServerPeers(macAndNetwork[1])		}		peers, err := GetPeersList(macAndNetwork[1])		if err != nil {			return nil, err		}		peersData, err := json.Marshal(&peers)		return &nodepb.Object{			Data: string(peersData),			Type: nodepb.NODE_TYPE,		}, err	}	return &nodepb.Object{		Data: "",		Type: nodepb.NODE_TYPE,	}, errors.New("could not fetch peers, invalid node id")}/** * Return Ext Peers (clients).NodeCheckIn * When a gateway node checks in, it pulls these peers to add to peers list in addition to normal network peers. */func (s *NodeServiceServer) GetExtPeers(ctx context.Context, req *nodepb.Object) (*nodepb.Object, error) {	// Initiate a NodeItem type to write decoded data to	//data := &models.PeersResponse{}	// collection.Find returns a cursor for our (empty) query	macAndNetwork := strings.Split(req.Data, "###")	if len(macAndNetwork) != 2 {		return nil, errors.New("did not receive valid node id when fetching ext peers")	}	peers, err := GetExtPeersList(macAndNetwork[0], macAndNetwork[1])	if err != nil {		return nil, err	}	// cursor.Next() returns a boolean, if false there are no more items and loop will break	var extPeers []models.Node	for i := 0; i < len(peers); i++ {		extPeers = append(extPeers, models.Node{			Address:             peers[i].Address,			Address6:            peers[i].Address6,			Endpoint:            peers[i].Endpoint,			PublicKey:           peers[i].PublicKey,			PersistentKeepalive: peers[i].KeepAlive,			ListenPort:          peers[i].ListenPort,			LocalAddress:        peers[i].LocalAddress,		})	}	extData, err := json.Marshal(&extPeers)	if err != nil {		return nil, err	}	return &nodepb.Object{		Data: string(extData),		Type: nodepb.EXT_PEER,	}, nil}
 |