|
@@ -5,26 +5,32 @@ import (
|
|
|
"errors"
|
|
|
"fmt"
|
|
|
"sort"
|
|
|
- "strings"
|
|
|
"time"
|
|
|
|
|
|
"github.com/go-playground/validator/v10"
|
|
|
- "github.com/google/uuid"
|
|
|
"github.com/gravitl/netmaker/database"
|
|
|
"github.com/gravitl/netmaker/logger"
|
|
|
"github.com/gravitl/netmaker/models"
|
|
|
- "github.com/gravitl/netmaker/servercfg"
|
|
|
"github.com/gravitl/netmaker/validation"
|
|
|
- "golang.org/x/crypto/bcrypt"
|
|
|
)
|
|
|
|
|
|
// GetNetworkNodes - gets the nodes of a network
|
|
|
func GetNetworkNodes(network string) ([]models.Node, error) {
|
|
|
- var nodes, err = GetAllNodes()
|
|
|
+ var nodes []models.Node
|
|
|
+ collection, err := database.FetchRecords(database.NODES_TABLE_NAME)
|
|
|
if err != nil {
|
|
|
- return []models.Node{}, err
|
|
|
+ if database.IsEmptyRecord(err) {
|
|
|
+ return []models.Node{}, nil
|
|
|
+ }
|
|
|
+ return nodes, err
|
|
|
}
|
|
|
- for _, node := range nodes {
|
|
|
+ for _, value := range collection {
|
|
|
+
|
|
|
+ var node models.Node
|
|
|
+ err := json.Unmarshal([]byte(value), &node)
|
|
|
+ if err != nil {
|
|
|
+ continue
|
|
|
+ }
|
|
|
if node.Network == network {
|
|
|
nodes = append(nodes, node)
|
|
|
}
|
|
@@ -58,8 +64,8 @@ func GetSortedNetworkServerNodes(network string) ([]models.Node, error) {
|
|
|
}
|
|
|
|
|
|
// UncordonNode - approves a node to join a network
|
|
|
-func UncordonNode(nodeid string) (models.Node, error) {
|
|
|
- node, err := GetNodeByID(nodeid)
|
|
|
+func UncordonNode(network, macaddress string) (models.Node, error) {
|
|
|
+ node, err := GetNodeByMacAddress(network, macaddress)
|
|
|
if err != nil {
|
|
|
return models.Node{}, err
|
|
|
}
|
|
@@ -70,15 +76,19 @@ func UncordonNode(nodeid string) (models.Node, error) {
|
|
|
if err != nil {
|
|
|
return node, err
|
|
|
}
|
|
|
+ key, err := GetRecordKey(node.MacAddress, node.Network)
|
|
|
+ if err != nil {
|
|
|
+ return node, err
|
|
|
+ }
|
|
|
|
|
|
- err = database.Insert(node.ID, string(data), database.NODES_TABLE_NAME)
|
|
|
+ err = database.Insert(key, string(data), database.NODES_TABLE_NAME)
|
|
|
return node, err
|
|
|
}
|
|
|
|
|
|
// GetPeers - gets the peers of a given node
|
|
|
func GetPeers(node *models.Node) ([]models.Node, error) {
|
|
|
if IsLeader(node) {
|
|
|
- setNetworkServerPeers(node)
|
|
|
+ SetNetworkServerPeers(node)
|
|
|
}
|
|
|
excludeIsRelayed := node.IsRelay != "yes"
|
|
|
var relayedNode string
|
|
@@ -111,13 +121,6 @@ func IsLeader(node *models.Node) bool {
|
|
|
|
|
|
// UpdateNode - takes a node and updates another node with it's values
|
|
|
func UpdateNode(currentNode *models.Node, newNode *models.Node) error {
|
|
|
- if newNode.Address != currentNode.Address {
|
|
|
- if network, err := GetParentNetwork(newNode.Network); err == nil {
|
|
|
- if !IsAddressInCIDR(newNode.Address, network.AddressRange) {
|
|
|
- return fmt.Errorf("invalid address provided; out of network range for node %s", newNode.ID)
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
newNode.Fill(currentNode)
|
|
|
if err := ValidateNode(newNode, true); err != nil {
|
|
|
return err
|
|
@@ -165,128 +168,6 @@ func ValidateNode(node *models.Node, isUpdate bool) error {
|
|
|
return err
|
|
|
}
|
|
|
|
|
|
-// CreateNode - creates a node in database
|
|
|
-func CreateNode(node *models.Node) error {
|
|
|
-
|
|
|
- //encrypt that password so we never see it
|
|
|
- hash, err := bcrypt.GenerateFromPassword([]byte(node.Password), 5)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- //set password to encrypted password
|
|
|
- node.Password = string(hash)
|
|
|
- if node.Name == models.NODE_SERVER_NAME {
|
|
|
- node.IsServer = "yes"
|
|
|
- }
|
|
|
- if node.DNSOn == "" {
|
|
|
- if servercfg.IsDNSMode() {
|
|
|
- node.DNSOn = "yes"
|
|
|
- } else {
|
|
|
- node.DNSOn = "no"
|
|
|
- }
|
|
|
- }
|
|
|
- SetNodeDefaults(node)
|
|
|
- node.Address, err = UniqueAddress(node.Network)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- node.Address6, err = UniqueAddress6(node.Network)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
-
|
|
|
- // TODO: This covers legacy nodes, eventually want to remove legacy check
|
|
|
- if node.IsServer == "yes" {
|
|
|
- node.ID = uuid.NewString()
|
|
|
- } else if node.IsServer != "yes" || (node.ID == "" || strings.Contains(node.ID, "###")) {
|
|
|
- node.ID = uuid.NewString()
|
|
|
- }
|
|
|
-
|
|
|
- //Create a JWT for the node
|
|
|
- tokenString, _ := CreateJWT(node.ID, node.MacAddress, node.Network)
|
|
|
- if tokenString == "" {
|
|
|
- //returnErrorResponse(w, r, errorResponse)
|
|
|
- return err
|
|
|
- }
|
|
|
- err = ValidateNode(node, false)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
-
|
|
|
- nodebytes, err := json.Marshal(&node)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- err = database.Insert(node.ID, string(nodebytes), database.NODES_TABLE_NAME)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- if node.IsPending != "yes" {
|
|
|
- DecrimentKey(node.Network, node.AccessKey)
|
|
|
- }
|
|
|
- SetNetworkNodesLastModified(node.Network)
|
|
|
- if servercfg.IsDNSMode() {
|
|
|
- err = SetDNS()
|
|
|
- }
|
|
|
- return err
|
|
|
-}
|
|
|
-
|
|
|
-// ShouldPeersUpdate - takes old node and sees if certain fields changing would trigger a peer update
|
|
|
-func ShouldPeersUpdate(currentNode *models.Node, newNode *models.Node) bool {
|
|
|
- SetNodeDefaults(newNode)
|
|
|
- // single comparison statements
|
|
|
- if newNode.Endpoint != currentNode.Endpoint ||
|
|
|
- newNode.LocalAddress != currentNode.LocalAddress ||
|
|
|
- newNode.PublicKey != currentNode.PublicKey ||
|
|
|
- newNode.Address != currentNode.Address ||
|
|
|
- newNode.IsEgressGateway != currentNode.IsEgressGateway ||
|
|
|
- newNode.IsIngressGateway != currentNode.IsIngressGateway ||
|
|
|
- newNode.IsRelay != currentNode.IsRelay ||
|
|
|
- newNode.UDPHolePunch != currentNode.UDPHolePunch ||
|
|
|
- newNode.IsPending != currentNode.IsPending ||
|
|
|
- len(newNode.ExcludedAddrs) != len(currentNode.ExcludedAddrs) ||
|
|
|
- len(newNode.AllowedIPs) != len(currentNode.AllowedIPs) {
|
|
|
- return true
|
|
|
- }
|
|
|
-
|
|
|
- // multi-comparison statements
|
|
|
- if newNode.IsDualStack == "yes" {
|
|
|
- if newNode.Address6 != currentNode.Address6 {
|
|
|
- return true
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if newNode.IsEgressGateway == "yes" {
|
|
|
- if len(currentNode.EgressGatewayRanges) != len(newNode.EgressGatewayRanges) {
|
|
|
- return true
|
|
|
- }
|
|
|
- for _, address := range newNode.EgressGatewayRanges {
|
|
|
- if !StringSliceContains(currentNode.EgressGatewayRanges, address) {
|
|
|
- return true
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if newNode.IsRelay == "yes" {
|
|
|
- if len(currentNode.RelayAddrs) != len(newNode.RelayAddrs) {
|
|
|
- return true
|
|
|
- }
|
|
|
- for _, address := range newNode.RelayAddrs {
|
|
|
- if !StringSliceContains(currentNode.RelayAddrs, address) {
|
|
|
- return true
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- for _, address := range newNode.AllowedIPs {
|
|
|
- if !StringSliceContains(currentNode.AllowedIPs, address) {
|
|
|
- return true
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return false
|
|
|
-}
|
|
|
-
|
|
|
// GetAllNodes - returns all nodes in the DB
|
|
|
func GetAllNodes() ([]models.Node, error) {
|
|
|
var nodes []models.Node
|
|
@@ -415,7 +296,6 @@ func SetNodeDefaults(node *models.Node) {
|
|
|
}
|
|
|
|
|
|
// GetRecordKey - get record key
|
|
|
-// depricated
|
|
|
func GetRecordKey(id string, network string) (string, error) {
|
|
|
if id == "" || network == "" {
|
|
|
return "", errors.New("unable to get record key")
|
|
@@ -499,30 +379,6 @@ func GetNodeRelay(network string, relayedNodeAddr string) (models.Node, error) {
|
|
|
return relay, errors.New("could not find relay for node " + relayedNodeAddr)
|
|
|
}
|
|
|
|
|
|
-// GetNodeByIDorMacAddress - gets the node, if a mac address exists, but not id, then it should delete it and recreate in DB with new ID
|
|
|
-func GetNodeByIDorMacAddress(uuid string, macaddress string, network string) (models.Node, error) {
|
|
|
- var node models.Node
|
|
|
- var err error
|
|
|
- node, err = GetNodeByID(uuid)
|
|
|
- if err != nil && macaddress != "" && network != "" {
|
|
|
- node, err = GetNodeByMacAddress(network, macaddress)
|
|
|
- if err != nil {
|
|
|
- return models.Node{}, err
|
|
|
- }
|
|
|
- err = DeleteNodeByMacAddress(&node, true) // remove node
|
|
|
- if err != nil {
|
|
|
- return models.Node{}, err
|
|
|
- }
|
|
|
- err = CreateNode(&node)
|
|
|
- if err != nil {
|
|
|
- return models.Node{}, err
|
|
|
- }
|
|
|
- logger.Log(2, "rewriting legacy node data; node now has id,", node.ID)
|
|
|
- node.PullChanges = "yes"
|
|
|
- }
|
|
|
- return node, err
|
|
|
-}
|
|
|
-
|
|
|
// GetNodeByID - get node by uuid, should have been set by create
|
|
|
func GetNodeByID(uuid string) (models.Node, error) {
|
|
|
var record, err = database.FetchRecord(database.NODES_TABLE_NAME, uuid)
|
|
@@ -535,47 +391,3 @@ func GetNodeByID(uuid string) (models.Node, error) {
|
|
|
}
|
|
|
return node, nil
|
|
|
}
|
|
|
-
|
|
|
-// GetDeletedNodeByID - get a deleted node
|
|
|
-func GetDeletedNodeByID(uuid string) (models.Node, error) {
|
|
|
-
|
|
|
- var node models.Node
|
|
|
-
|
|
|
- record, err := database.FetchRecord(database.DELETED_NODES_TABLE_NAME, uuid)
|
|
|
- if err != nil {
|
|
|
- return models.Node{}, err
|
|
|
- }
|
|
|
-
|
|
|
- if err = json.Unmarshal([]byte(record), &node); err != nil {
|
|
|
- return models.Node{}, err
|
|
|
- }
|
|
|
-
|
|
|
- SetNodeDefaults(&node)
|
|
|
-
|
|
|
- return node, nil
|
|
|
-}
|
|
|
-
|
|
|
-// GetNetworkServerNodeID - get network server node ID if exists
|
|
|
-func GetNetworkServerNodeID(network string) (string, error) {
|
|
|
- var nodes, err = GetNetworkNodes(network)
|
|
|
- if err != nil {
|
|
|
- return "", err
|
|
|
- }
|
|
|
- for _, node := range nodes {
|
|
|
- if node.IsServer == "yes" {
|
|
|
- if servercfg.GetNodeID() != "" {
|
|
|
- if servercfg.GetNodeID() == node.MacAddress {
|
|
|
- if strings.Contains(node.ID, "###") {
|
|
|
- DeleteNodeByMacAddress(&node, true)
|
|
|
- logger.Log(1, "deleted legacy server node on network "+node.Network)
|
|
|
- return "", errors.New("deleted legacy server node on network " + node.Network)
|
|
|
- }
|
|
|
- return node.ID, nil
|
|
|
- }
|
|
|
- continue
|
|
|
- }
|
|
|
- return node.ID, nil
|
|
|
- }
|
|
|
- }
|
|
|
- return "", errors.New("could not find server node")
|
|
|
-}
|