| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326 | package controllerimport (	"context"	"encoding/json"	"errors"	"fmt"	"strings"	"time"	nodepb "github.com/gravitl/netmaker/grpc"	"github.com/gravitl/netmaker/logger"	"github.com/gravitl/netmaker/logic"	"github.com/gravitl/netmaker/models"	"github.com/gravitl/netmaker/mq"	"github.com/gravitl/netmaker/servercfg"	"github.com/gravitl/netmaker/serverctl")// NodeServiceServer - represents the service server for gRPCtype NodeServiceServer struct {	nodepb.UnimplementedNodeServiceServer}// NodeServiceServer.ReadNode - reads node and responds with gRPCfunc (s *NodeServiceServer) ReadNode(ctx context.Context, req *nodepb.Object) (*nodepb.Object, error) {	var node, err = getNodeFromRequestData(req.Data)	if err != nil {		return nil, err	}	node.NetworkSettings, err = logic.GetNetworkSettings(node.Network)	if err != nil {		return nil, err	}	getServerAddrs(&node)	node.SetLastCheckIn()	// Cast to ReadNodeRes type	nodeData, errN := json.Marshal(&node)	if errN != nil {		return nil, err	}	logic.UpdateNode(&node, &node)	response := &nodepb.Object{		Data: string(nodeData),		Type: nodepb.NODE_TYPE,	}	return response, nil}// NodeServiceServer.CreateNode - creates a node and responds over gRPCfunc (s *NodeServiceServer) CreateNode(ctx context.Context, req *nodepb.Object) (*nodepb.Object, error) {	var node = models.Node{}	var err error	data := req.GetData()	if err := json.Unmarshal([]byte(data), &node); err != nil {		return nil, err	}	validKey := logic.IsKeyValid(node.Network, node.AccessKey)	node.NetworkSettings, err = logic.GetNetworkSettings(node.Network)	if err != nil {		return nil, err	}	if !validKey {		if node.NetworkSettings.AllowManualSignUp == "yes" {			node.IsPending = "yes"		} else {			return nil, errors.New("invalid key, and network does not allow no-key signups")		}	}	getServerAddrs(&node)	key, keyErr := logic.RetrievePublicTrafficKey()	if keyErr != nil {		logger.Log(0, "error retrieving key: ", keyErr.Error())		return nil, keyErr	}	if key == nil {		logger.Log(0, "error: server traffic key is nil")		return nil, fmt.Errorf("error: server traffic key is nil")	}	if node.TrafficKeys.Mine == nil {		logger.Log(0, "error: node traffic key is nil")		return nil, fmt.Errorf("error: node traffic key is nil")	}	node.TrafficKeys = models.TrafficKeys{		Mine:   node.TrafficKeys.Mine,		Server: key,	}	commID, err := logic.FetchCommsNetID()	if err != nil {		return nil, err	}	node.CommID = commID	err = logic.CreateNode(&node)	if err != nil {		return nil, err	}	nodeData, errN := json.Marshal(&node)	if errN != nil {		return nil, err	}	response := &nodepb.Object{		Data: string(nodeData),		Type: nodepb.NODE_TYPE,	}	runForceServerUpdate(&node)	go func(node *models.Node) {		if node.UDPHolePunch == "yes" {			var currentServerNode, getErr = logic.GetNetworkServerLeader(node.Network)			if getErr != nil {				return			}			for i := 0; i < 5; i++ {				if logic.HasPeerConnected(node) {					if logic.ShouldPublishPeerPorts(¤tServerNode) {						err = mq.PublishPeerUpdate(¤tServerNode)						if err != nil {							logger.Log(1, "error publishing port updates when node", node.Name, "joined")						}						break					}				}				time.Sleep(time.Second << 1) // allow time for client to startup			}		}	}(&node)	return response, nil}// NodeServiceServer.UpdateNode updates a node and responds over gRPC// DELETE ONE DAY - DEPRECATEDfunc (s *NodeServiceServer) UpdateNode(ctx context.Context, req *nodepb.Object) (*nodepb.Object, error) {	var newnode models.Node	if err := json.Unmarshal([]byte(req.GetData()), &newnode); err != nil {		return nil, err	}	node, err := logic.GetNodeByID(newnode.ID)	if err != nil {		return nil, err	}	if !servercfg.GetRce() {		newnode.PostDown = node.PostDown		newnode.PostUp = node.PostUp	}	err = logic.UpdateNode(&node, &newnode)	if err != nil {		return nil, err	}	newnode.NetworkSettings, err = logic.GetNetworkSettings(node.Network)	if err != nil {		return nil, err	}	getServerAddrs(&newnode)	nodeData, errN := json.Marshal(&newnode)	if errN != nil {		return nil, err	}	return &nodepb.Object{		Data: string(nodeData),		Type: nodepb.NODE_TYPE,	}, nil}func getServerAddrs(node *models.Node) {	serverNodes := logic.GetServerNodes(serverctl.COMMS_NETID)	//pubIP, _ := servercfg.GetPublicIP()	if len(serverNodes) == 0 {		if err := serverctl.SyncServerNetwork(serverctl.COMMS_NETID); err != nil {			return		}	}	var serverAddrs = make([]models.ServerAddr, 0)	for _, node := range serverNodes {		if node.Address != "" {			serverAddrs = append(serverAddrs, models.ServerAddr{				IsLeader: logic.IsLeader(&node),				Address:  node.Address,			})		}	}	networkSettings, _ := logic.GetParentNetwork(node.Network)	// TODO consolidate functionality around files	networkSettings.NodesLastModified = time.Now().Unix()	networkSettings.DefaultServerAddrs = serverAddrs	if err := logic.SaveNetwork(&networkSettings); err != nil {		logger.Log(1, "unable to save network on serverAddr update", err.Error())	}	node.NetworkSettings.DefaultServerAddrs = networkSettings.DefaultServerAddrs}// NodeServiceServer.DeleteNode - deletes a node and responds over gRPCfunc (s *NodeServiceServer) DeleteNode(ctx context.Context, req *nodepb.Object) (*nodepb.Object, error) {	var node, err = getNodeFromRequestData(req.Data)	if err != nil {		return nil, err	}	err = logic.DeleteNodeByID(&node, true)	if err != nil {		return nil, err	}	runForceServerUpdate(&node)	return &nodepb.Object{		Data: "success",		Type: nodepb.STRING_TYPE,	}, nil}// NodeServiceServer.GetPeers - fetches peers over gRPCfunc (s *NodeServiceServer) GetPeers(ctx context.Context, req *nodepb.Object) (*nodepb.Object, error) {	var node, err = getNodeFromRequestData(req.Data)	if err != nil {		return nil, err	}	peers, err := logic.GetPeersList(&node)	if err != nil {		if strings.Contains(err.Error(), logic.RELAY_NODE_ERR) {			peers, err = logic.PeerListUnRelay(node.ID, node.Network)			if err != nil {				return nil, err			}		} else {			return nil, err		}	}	peersData, err := json.Marshal(&peers)	logger.Log(3, node.Address, "checked in successfully")	return &nodepb.Object{		Data: string(peersData),		Type: nodepb.NODE_TYPE,	}, err}// NodeServiceServer.GetExtPeers - returns ext peers for a gateway nodefunc (s *NodeServiceServer) GetExtPeers(ctx context.Context, req *nodepb.Object) (*nodepb.Object, error) {	var node, err = getNodeFromRequestData(req.Data)	if err != nil {		return nil, err	}	peers, err := logic.GetExtPeersList(&node)	if err != nil {		return nil, err	}	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}// == private methods ==func getNodeFromRequestData(data string) (models.Node, error) {	var reqNode models.Node	var err error	if err = json.Unmarshal([]byte(data), &reqNode); err != nil {		return models.Node{}, err	}	return logic.GetNodeByID(reqNode.ID)}func isServer(node *models.Node) bool {	return node.IsServer == "yes"}func runForceServerUpdate(node *models.Node) {	go func() {		if err := mq.PublishPeerUpdate(node); err != nil {			logger.Log(1, "failed a peer update after creation of node", node.Name)		}		var currentServerNode, getErr = logic.GetNetworkServerLeader(node.Network)		if getErr == nil {			if err := logic.ServerUpdate(¤tServerNode, false); err != nil {				logger.Log(1, "server node:", currentServerNode.ID, "failed update")			}		}	}()}
 |