2021-03-26 00:17:52 +08:00
|
|
|
package controller
|
|
|
|
|
|
|
|
import (
|
2021-05-06 23:57:32 +08:00
|
|
|
"context"
|
2021-08-03 06:06:26 +08:00
|
|
|
"encoding/json"
|
|
|
|
"errors"
|
2022-02-05 03:19:26 +08:00
|
|
|
"fmt"
|
2022-02-07 00:36:38 +08:00
|
|
|
"strings"
|
2022-02-01 00:25:05 +08:00
|
|
|
"time"
|
2021-09-18 22:33:14 +08:00
|
|
|
|
2021-03-26 00:17:52 +08:00
|
|
|
nodepb "github.com/gravitl/netmaker/grpc"
|
2021-12-07 04:31:08 +08:00
|
|
|
"github.com/gravitl/netmaker/logger"
|
2021-10-06 03:02:09 +08:00
|
|
|
"github.com/gravitl/netmaker/logic"
|
2021-03-26 00:17:52 +08:00
|
|
|
"github.com/gravitl/netmaker/models"
|
2022-02-02 23:37:05 +08:00
|
|
|
"github.com/gravitl/netmaker/mq"
|
2022-02-17 09:42:57 +08:00
|
|
|
"github.com/gravitl/netmaker/servercfg"
|
2022-02-01 11:56:07 +08:00
|
|
|
"github.com/gravitl/netmaker/serverctl"
|
2021-03-26 00:17:52 +08:00
|
|
|
)
|
|
|
|
|
2021-10-09 03:07:12 +08:00
|
|
|
// NodeServiceServer - represents the service server for gRPC
|
2021-03-26 00:17:52 +08:00
|
|
|
type NodeServiceServer struct {
|
|
|
|
nodepb.UnimplementedNodeServiceServer
|
|
|
|
}
|
2021-05-06 23:57:32 +08:00
|
|
|
|
2021-10-09 03:07:12 +08:00
|
|
|
// NodeServiceServer.ReadNode - reads node and responds with gRPC
|
2021-08-03 06:06:26 +08:00
|
|
|
func (s *NodeServiceServer) ReadNode(ctx context.Context, req *nodepb.Object) (*nodepb.Object, error) {
|
2022-02-02 11:36:02 +08:00
|
|
|
var node, err = getNodeFromRequestData(req.Data)
|
2021-03-26 00:17:52 +08:00
|
|
|
if err != nil {
|
2021-08-03 06:06:26 +08:00
|
|
|
return nil, err
|
2021-03-26 00:17:52 +08:00
|
|
|
}
|
2022-01-11 06:52:21 +08:00
|
|
|
|
2021-11-15 08:17:30 +08:00
|
|
|
node.NetworkSettings, err = logic.GetNetworkSettings(node.Network)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2022-02-01 10:28:34 +08:00
|
|
|
getServerAddrs(&node)
|
|
|
|
|
2021-08-06 02:19:19 +08:00
|
|
|
node.SetLastCheckIn()
|
2021-03-26 00:17:52 +08:00
|
|
|
// Cast to ReadNodeRes type
|
2021-11-15 08:17:30 +08:00
|
|
|
nodeData, errN := json.Marshal(&node)
|
|
|
|
if errN != nil {
|
2021-08-03 06:06:26 +08:00
|
|
|
return nil, err
|
|
|
|
}
|
2021-10-27 00:27:29 +08:00
|
|
|
logic.UpdateNode(&node, &node)
|
2021-08-03 06:06:26 +08:00
|
|
|
response := &nodepb.Object{
|
|
|
|
Data: string(nodeData),
|
|
|
|
Type: nodepb.NODE_TYPE,
|
2021-03-26 00:17:52 +08:00
|
|
|
}
|
|
|
|
return response, nil
|
|
|
|
}
|
2021-07-22 06:55:19 +08:00
|
|
|
|
2021-10-09 03:07:12 +08:00
|
|
|
// NodeServiceServer.CreateNode - creates a node and responds over gRPC
|
2021-08-03 06:06:26 +08:00
|
|
|
func (s *NodeServiceServer) CreateNode(ctx context.Context, req *nodepb.Object) (*nodepb.Object, error) {
|
2021-12-11 10:09:42 +08:00
|
|
|
var node = models.Node{}
|
|
|
|
var err error
|
2021-08-03 06:06:26 +08:00
|
|
|
data := req.GetData()
|
2021-12-11 10:09:42 +08:00
|
|
|
if err := json.Unmarshal([]byte(data), &node); err != nil {
|
2021-08-03 06:06:26 +08:00
|
|
|
return nil, err
|
2021-03-26 00:17:52 +08:00
|
|
|
}
|
|
|
|
|
2021-10-27 00:27:29 +08:00
|
|
|
validKey := logic.IsKeyValid(node.Network, node.AccessKey)
|
2021-12-11 10:09:42 +08:00
|
|
|
node.NetworkSettings, err = logic.GetNetworkSettings(node.Network)
|
2021-05-06 23:57:32 +08:00
|
|
|
if err != nil {
|
2021-08-03 06:06:26 +08:00
|
|
|
return nil, err
|
2021-04-19 22:02:30 +08:00
|
|
|
}
|
2021-05-06 23:57:32 +08:00
|
|
|
if !validKey {
|
2021-12-11 10:09:42 +08:00
|
|
|
if node.NetworkSettings.AllowManualSignUp == "yes" {
|
2021-07-27 00:24:36 +08:00
|
|
|
node.IsPending = "yes"
|
2021-05-06 23:57:32 +08:00
|
|
|
} else {
|
2021-08-03 06:06:26 +08:00
|
|
|
return nil, errors.New("invalid key, and network does not allow no-key signups")
|
2021-05-06 23:57:32 +08:00
|
|
|
}
|
|
|
|
}
|
2022-01-31 05:06:07 +08:00
|
|
|
getServerAddrs(&node)
|
2022-02-01 03:01:09 +08:00
|
|
|
|
2022-01-30 04:02:37 +08:00
|
|
|
key, keyErr := logic.RetrievePublicTrafficKey()
|
2022-01-29 04:33:30 +08:00
|
|
|
if keyErr != nil {
|
2022-01-29 06:58:57 +08:00
|
|
|
logger.Log(0, "error retrieving key: ", keyErr.Error())
|
2022-01-29 04:33:30 +08:00
|
|
|
return nil, keyErr
|
|
|
|
}
|
|
|
|
|
2022-02-05 03:19:26 +08:00
|
|
|
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")
|
|
|
|
}
|
|
|
|
|
2022-01-29 04:33:30 +08:00
|
|
|
node.TrafficKeys = models.TrafficKeys{
|
|
|
|
Mine: node.TrafficKeys.Mine,
|
2022-01-29 22:37:53 +08:00
|
|
|
Server: key,
|
2022-01-29 04:33:30 +08:00
|
|
|
}
|
2022-01-26 11:14:31 +08:00
|
|
|
|
2022-02-19 05:12:40 +08:00
|
|
|
commID, err := logic.FetchCommsNetID()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
node.CommID = commID
|
|
|
|
|
2021-12-11 10:09:42 +08:00
|
|
|
err = logic.CreateNode(&node)
|
2021-11-15 08:17:30 +08:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2021-12-11 10:09:42 +08:00
|
|
|
|
2021-11-15 08:17:30 +08:00
|
|
|
nodeData, errN := json.Marshal(&node)
|
|
|
|
if errN != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2021-12-11 10:09:42 +08:00
|
|
|
|
2021-08-03 06:06:26 +08:00
|
|
|
response := &nodepb.Object{
|
|
|
|
Data: string(nodeData),
|
|
|
|
Type: nodepb.NODE_TYPE,
|
2021-03-26 00:17:52 +08:00
|
|
|
}
|
2021-12-11 10:09:42 +08:00
|
|
|
|
2022-02-17 22:33:30 +08:00
|
|
|
runForceServerUpdate(&node)
|
2022-02-17 10:33:10 +08:00
|
|
|
|
2022-02-02 23:37:05 +08:00
|
|
|
go func(node *models.Node) {
|
|
|
|
if node.UDPHolePunch == "yes" {
|
2022-02-03 00:56:39 +08:00
|
|
|
var currentServerNode, getErr = logic.GetNetworkServerLeader(node.Network)
|
2022-02-02 23:37:05 +08:00
|
|
|
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)
|
|
|
|
|
2021-05-06 23:57:32 +08:00
|
|
|
return response, nil
|
2021-03-26 00:17:52 +08:00
|
|
|
}
|
|
|
|
|
2021-10-09 03:07:12 +08:00
|
|
|
// NodeServiceServer.UpdateNode updates a node and responds over gRPC
|
2022-02-17 09:42:57 +08:00
|
|
|
// DELETE ONE DAY - DEPRECATED
|
|
|
|
func (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
|
|
|
|
}
|
2021-03-26 00:17:52 +08:00
|
|
|
|
2022-01-31 05:06:07 +08:00
|
|
|
func getServerAddrs(node *models.Node) {
|
2022-02-19 00:11:21 +08:00
|
|
|
serverNodes := logic.GetServerNodes(serverctl.COMMS_NETID)
|
2022-02-01 06:30:56 +08:00
|
|
|
//pubIP, _ := servercfg.GetPublicIP()
|
2022-02-01 11:56:07 +08:00
|
|
|
if len(serverNodes) == 0 {
|
2022-02-19 00:11:21 +08:00
|
|
|
if err := serverctl.SyncServerNetwork(serverctl.COMMS_NETID); err != nil {
|
2022-02-01 11:56:07 +08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-06 03:26:19 +08:00
|
|
|
var serverAddrs = make([]models.ServerAddr, 0)
|
2022-02-01 11:56:07 +08:00
|
|
|
|
|
|
|
for _, node := range serverNodes {
|
2022-02-06 03:26:19 +08:00
|
|
|
if node.Address != "" {
|
|
|
|
serverAddrs = append(serverAddrs, models.ServerAddr{
|
|
|
|
IsLeader: logic.IsLeader(&node),
|
|
|
|
Address: node.Address,
|
|
|
|
})
|
|
|
|
}
|
2022-02-01 03:46:49 +08:00
|
|
|
}
|
2022-02-01 11:56:07 +08:00
|
|
|
|
2022-02-01 05:25:29 +08:00
|
|
|
networkSettings, _ := logic.GetParentNetwork(node.Network)
|
2022-01-31 05:06:07 +08:00
|
|
|
// TODO consolidate functionality around files
|
2022-02-01 03:46:49 +08:00
|
|
|
networkSettings.NodesLastModified = time.Now().Unix()
|
|
|
|
networkSettings.DefaultServerAddrs = serverAddrs
|
|
|
|
if err := logic.SaveNetwork(&networkSettings); err != nil {
|
2022-02-01 03:01:09 +08:00
|
|
|
logger.Log(1, "unable to save network on serverAddr update", err.Error())
|
|
|
|
}
|
2022-02-01 05:31:28 +08:00
|
|
|
node.NetworkSettings.DefaultServerAddrs = networkSettings.DefaultServerAddrs
|
2022-01-31 05:06:07 +08:00
|
|
|
}
|
|
|
|
|
2021-10-09 03:07:12 +08:00
|
|
|
// NodeServiceServer.DeleteNode - deletes a node and responds over gRPC
|
2021-08-03 06:06:26 +08:00
|
|
|
func (s *NodeServiceServer) DeleteNode(ctx context.Context, req *nodepb.Object) (*nodepb.Object, error) {
|
2022-01-11 08:36:13 +08:00
|
|
|
|
2022-02-02 11:36:02 +08:00
|
|
|
var node, err = getNodeFromRequestData(req.Data)
|
2022-01-11 08:36:13 +08:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2021-12-08 04:51:57 +08:00
|
|
|
}
|
2022-01-11 07:32:49 +08:00
|
|
|
|
|
|
|
err = logic.DeleteNodeByID(&node, true)
|
2021-07-22 06:55:19 +08:00
|
|
|
if err != nil {
|
2021-08-03 06:06:26 +08:00
|
|
|
return nil, err
|
2021-03-26 00:17:52 +08:00
|
|
|
}
|
2022-02-09 00:01:44 +08:00
|
|
|
|
2022-02-17 22:33:30 +08:00
|
|
|
runForceServerUpdate(&node)
|
2022-01-18 22:06:43 +08:00
|
|
|
|
2021-08-03 06:06:26 +08:00
|
|
|
return &nodepb.Object{
|
|
|
|
Data: "success",
|
|
|
|
Type: nodepb.STRING_TYPE,
|
2021-03-26 00:17:52 +08:00
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
2021-10-09 03:07:12 +08:00
|
|
|
// NodeServiceServer.GetPeers - fetches peers over gRPC
|
2021-08-03 06:06:26 +08:00
|
|
|
func (s *NodeServiceServer) GetPeers(ctx context.Context, req *nodepb.Object) (*nodepb.Object, error) {
|
2022-01-11 08:36:13 +08:00
|
|
|
|
2022-02-02 11:36:02 +08:00
|
|
|
var node, err = getNodeFromRequestData(req.Data)
|
2022-01-11 07:32:49 +08:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2022-01-12 08:01:20 +08:00
|
|
|
|
2022-02-19 00:43:49 +08:00
|
|
|
peers, err := logic.GetPeersList(&node)
|
2022-01-11 07:32:49 +08:00
|
|
|
if err != nil {
|
2022-02-07 00:36:38 +08:00
|
|
|
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
|
|
|
|
}
|
2022-01-11 07:32:49 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
peersData, err := json.Marshal(&peers)
|
|
|
|
logger.Log(3, node.Address, "checked in successfully")
|
2021-08-03 06:06:26 +08:00
|
|
|
return &nodepb.Object{
|
2022-01-11 07:32:49 +08:00
|
|
|
Data: string(peersData),
|
2021-08-03 06:06:26 +08:00
|
|
|
Type: nodepb.NODE_TYPE,
|
2022-01-11 07:32:49 +08:00
|
|
|
}, err
|
2021-03-26 00:17:52 +08:00
|
|
|
}
|
2021-05-20 01:59:10 +08:00
|
|
|
|
2021-10-09 03:07:12 +08:00
|
|
|
// NodeServiceServer.GetExtPeers - returns ext peers for a gateway node
|
2021-08-03 06:06:26 +08:00
|
|
|
func (s *NodeServiceServer) GetExtPeers(ctx context.Context, req *nodepb.Object) (*nodepb.Object, error) {
|
2022-01-11 07:32:49 +08:00
|
|
|
|
2022-02-02 11:36:02 +08:00
|
|
|
var node, err = getNodeFromRequestData(req.Data)
|
2022-01-11 07:32:49 +08:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
peers, err := logic.GetExtPeersList(&node)
|
2021-07-22 06:55:19 +08:00
|
|
|
if err != nil {
|
2021-08-03 06:06:26 +08:00
|
|
|
return nil, err
|
2021-07-22 06:55:19 +08:00
|
|
|
}
|
2021-08-03 06:06:26 +08:00
|
|
|
var extPeers []models.Node
|
2021-07-22 06:55:19 +08:00
|
|
|
for i := 0; i < len(peers); i++ {
|
2021-08-03 06:06:26 +08:00
|
|
|
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,
|
2021-07-22 06:55:19 +08:00
|
|
|
})
|
|
|
|
}
|
2021-05-20 01:59:10 +08:00
|
|
|
|
2021-08-03 06:06:26 +08:00
|
|
|
extData, err := json.Marshal(&extPeers)
|
2021-07-22 06:55:19 +08:00
|
|
|
if err != nil {
|
2021-08-03 06:06:26 +08:00
|
|
|
return nil, err
|
2021-07-22 06:55:19 +08:00
|
|
|
}
|
|
|
|
|
2021-08-03 06:06:26 +08:00
|
|
|
return &nodepb.Object{
|
|
|
|
Data: string(extData),
|
|
|
|
Type: nodepb.EXT_PEER,
|
|
|
|
}, nil
|
2021-05-20 01:59:10 +08:00
|
|
|
}
|
2022-01-12 08:01:20 +08:00
|
|
|
|
|
|
|
// == private methods ==
|
|
|
|
|
2022-02-02 11:36:02 +08:00
|
|
|
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)
|
|
|
|
}
|
2022-01-31 09:50:37 +08:00
|
|
|
|
|
|
|
func isServer(node *models.Node) bool {
|
|
|
|
return node.IsServer == "yes"
|
|
|
|
}
|
2022-02-17 22:33:30 +08:00
|
|
|
|
|
|
|
func runForceServerUpdate(node *models.Node) {
|
2022-02-17 23:56:48 +08:00
|
|
|
go func() {
|
|
|
|
if err := mq.PublishPeerUpdate(node); err != nil {
|
|
|
|
logger.Log(1, "failed a peer update after creation of node", node.Name)
|
2022-02-17 22:33:30 +08:00
|
|
|
}
|
2022-02-17 23:56:48 +08:00
|
|
|
|
|
|
|
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")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}()
|
2022-02-17 22:33:30 +08:00
|
|
|
}
|