rebase fixes

This commit is contained in:
Matthew R Kasun 2022-01-20 16:39:54 -05:00
parent b15a5112fc
commit d4399d1321
4 changed files with 225 additions and 144 deletions

View file

@ -161,9 +161,9 @@ func (s *NodeServiceServer) GetPeers(ctx context.Context, req *nodepb.Object) (*
return nil, err
}
if node.IsServer == "yes" && logic.IsLeader(&node) {
logic.SetNetworkServerPeers(&node)
}
//if node.IsServer == "yes" && logic.IsLeader(&node) {
// logic.setNetworkServerPeers(&node)
//}
excludeIsRelayed := node.IsRelay != "yes"
var relayedNode string
if node.IsRelayed == "yes" {

View file

@ -4,38 +4,27 @@ import (
"encoding/json"
"errors"
"fmt"
"net"
"sort"
"strconv"
"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.zx2c4.com/wireguard/wgctrl/wgtypes"
"golang.org/x/crypto/bcrypt"
)
// GetNetworkNodes - gets the nodes of a network
func GetNetworkNodes(network string) ([]models.Node, error) {
var nodes = []models.Node{}
collection, err := database.FetchRecords(database.NODES_TABLE_NAME)
var nodes, err = GetAllNodes()
if err != nil {
if database.IsEmptyRecord(err) {
return []models.Node{}, nil
}
return nodes, err
return []models.Node{}, err
}
for _, value := range collection {
var node models.Node
err := json.Unmarshal([]byte(value), &node)
if err != nil {
continue
}
for _, node := range nodes {
if node.Network == network {
nodes = append(nodes, node)
}
@ -77,7 +66,7 @@ func UncordonNode(nodeid string) (models.Node, error) {
node.SetLastModified()
node.IsPending = "no"
node.PullChanges = "yes"
data, err := json.Marshal(&node)
data, err := json.Marshal(&node)
if err != nil {
return node, err
}
@ -86,52 +75,11 @@ func UncordonNode(nodeid string) (models.Node, error) {
return node, err
}
// GetWGNodePeers - gets the wg peers of a given node
func GetWGNodePeers(node *models.Node) ([]wgtypes.PeerConfig, error){
var peers []wgtypes.PeerConfig
var peerData wgtypes.PeerConfig
nodes, err := GetPeers(node)
if err != nil {
return peers, err
}
logger.Log(0, "the peers of " + node.Name + " are:")
for _, peer := range nodes {
logger.Log(0, "peer: " + peer.Name)
}
for _, peer := range nodes {
//this should not happen but it does
if peer.Name == node.Name {
logger.Log(0, "GetPeers returned me " + node.Name)
continue
}
pubkey, err :=wgtypes.ParseKey(peer.PublicKey)
if err != nil {
logger.Log(0, "ParseKey failed " +err.Error())
continue
}
endpoint := peer.Endpoint + ":" + strconv.Itoa(int(peer.ListenPort))
address, err := net.ResolveUDPAddr("udp", endpoint)
if err != nil {
logger.Log(0, "could not resolve endpoint " + err.Error())
continue
}
///Persitent Keepalive
//Allowed IPs
peerData = wgtypes.PeerConfig{
PublicKey: pubkey,
Endpoint: address,
}
peers = append (peers, peerData)
}
return peers, nil
}
// GetPeers - gets a list of nodes that are peers of a given node
// GetPeers - gets the peers of a given node
func GetPeers(node *models.Node) ([]models.Node, error) {
//if IsLeader(node) {
// logger.Log(0, node.Name + " is a leader")
// SetNetworkServerPeers(node)
//}
if IsLeader(node) {
setNetworkServerPeers(node)
}
excludeIsRelayed := node.IsRelay != "yes"
var relayedNode string
if node.IsRelayed == "yes" {
@ -163,6 +111,13 @@ 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
@ -210,6 +165,128 @@ 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

View file

@ -4,18 +4,19 @@ package logic
import (
"encoding/base64"
"encoding/json"
"fmt"
"math/rand"
"net"
"os"
"strconv"
"strings"
"time"
"github.com/google/uuid"
"github.com/gravitl/netmaker/database"
"github.com/gravitl/netmaker/logger"
"github.com/gravitl/netmaker/models"
"github.com/gravitl/netmaker/netclient/ncutils"
"github.com/gravitl/netmaker/servercfg"
"golang.org/x/crypto/bcrypt"
)
// IsBase64 - checks if a string is in base64 format
@ -31,15 +32,36 @@ func CheckEndpoint(endpoint string) bool {
return len(endpointarr) == 2
}
// SetNetworkServerPeers - sets the network server peers of a given node
func SetNetworkServerPeers(node *models.Node) {
if currentPeersList, err := getSystemPeers(node); err == nil {
if database.SetPeers(currentPeersList, node.Network) {
logger.Log(1, "set new peers on network", node.Network)
}
} else {
logger.Log(1, "could not set peers on network", node.Network, ":", err.Error())
// FileExists - checks if local file exists
func FileExists(f string) bool {
info, err := os.Stat(f)
if os.IsNotExist(err) {
return false
}
return !info.IsDir()
}
// IsAddressInCIDR - util to see if an address is in a cidr or not
func IsAddressInCIDR(address, cidr string) bool {
var _, currentCIDR, cidrErr = net.ParseCIDR(cidr)
if cidrErr != nil {
return false
}
var addrParts = strings.Split(address, ".")
var addrPartLength = len(addrParts)
if addrPartLength != 4 {
return false
} else {
if addrParts[addrPartLength-1] == "0" ||
addrParts[addrPartLength-1] == "255" {
return false
}
}
ip, _, err := net.ParseCIDR(fmt.Sprintf("%s/32", address))
if err != nil {
return false
}
return currentCIDR.Contains(ip)
}
// DeleteNodeByMacAddress - deletes a node from database or moves into delete nodes table
@ -75,72 +97,6 @@ func DeleteNodeByMacAddress(node *models.Node, exterminate bool) error {
return removeLocalServer(node)
}
// 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
}
// SetNetworkNodesLastModified - sets the network nodes last modified
func SetNetworkNodesLastModified(networkName string) error {
@ -402,3 +358,16 @@ func StringSliceContains(slice []string, item string) bool {
}
return false
}
// == private ==
// sets the network server peers of a given node
func setNetworkServerPeers(serverNode *models.Node) {
if currentPeersList, err := getSystemPeers(serverNode); err == nil {
if database.SetPeers(currentPeersList, serverNode.Network) {
logger.Log(1, "set new peers on network", serverNode.Network)
}
} else {
logger.Log(1, "could not set peers on network", serverNode.Network, ":", err.Error())
}
}

View file

@ -73,6 +73,7 @@ type Node struct {
OS string `json:"os" bson:"os" yaml:"os"`
MTU int32 `json:"mtu" bson:"mtu" yaml:"mtu"`
Version string `json:"version" bson:"version" yaml:"version"`
ExcludedAddrs []string `json:"excludedaddrs" bson:"excludedaddrs" yaml:"excludedaddrs"`
}
// NodesArray - used for node sorting
@ -107,78 +108,91 @@ func (node *Node) SetDefaulIsPending() {
}
}
// Node.SetDefaultIsRelayed - set default is relayed
func (node *Node) SetDefaultIsRelayed() {
if node.IsRelayed == "" {
node.IsRelayed = "no"
}
}
// Node.SetDefaultIsRelay - set default isrelay
func (node *Node) SetDefaultIsRelay() {
if node.IsRelay == "" {
node.IsRelay = "no"
}
}
// Node.SetDefaultEgressGateway - sets default egress gateway status
func (node *Node) SetDefaultEgressGateway() {
if node.IsEgressGateway == "" {
node.IsEgressGateway = "no"
}
}
// Node.SetDefaultIngressGateway - sets default ingress gateway status
func (node *Node) SetDefaultIngressGateway() {
if node.IsIngressGateway == "" {
node.IsIngressGateway = "no"
}
}
// Node.SetDefaultAction - sets default action status
func (node *Node) SetDefaultAction() {
if node.Action == "" {
node.Action = NODE_NOOP
}
}
// Node.SetRoamingDefault - sets default roaming status
func (node *Node) SetRoamingDefault() {
if node.Roaming == "" {
node.Roaming = "yes"
}
}
// Node.SetPullChangesDefault - sets default pull changes status
func (node *Node) SetPullChangesDefault() {
if node.PullChanges == "" {
node.PullChanges = "no"
}
}
// Node.SetIPForwardingDefault - set ip forwarding default
func (node *Node) SetIPForwardingDefault() {
if node.IPForwarding == "" {
node.IPForwarding = "yes"
}
}
// Node.SetIsLocalDefault - set is local default
func (node *Node) SetIsLocalDefault() {
if node.IsLocal == "" {
node.IsLocal = "no"
}
}
// Node.SetDNSOnDefault - sets dns on default
func (node *Node) SetDNSOnDefault() {
if node.DNSOn == "" {
node.DNSOn = "yes"
}
}
// Node.SetIsDualStackDefault - set is dual stack default status
func (node *Node) SetIsDualStackDefault() {
if node.IsDualStack == "" {
node.IsDualStack = "no"
}
}
// Node.SetIsServerDefault - sets node isserver default
func (node *Node) SetIsServerDefault() {
if node.IsServer != "yes" {
node.IsServer = "no"
}
}
// Node.SetIsStaticDefault - set is static default
func (node *Node) SetIsStaticDefault() {
if node.IsServer == "yes" {
node.IsStatic = "yes"
@ -187,28 +201,41 @@ func (node *Node) SetIsStaticDefault() {
}
}
// Node.SetLastModified - set last modified initial time
func (node *Node) SetLastModified() {
node.LastModified = time.Now().Unix()
}
// Node.SetLastCheckIn - time.Now().Unix()
func (node *Node) SetLastCheckIn() {
node.LastCheckIn = time.Now().Unix()
}
// Node.SetLastPeerUpdate - sets last peer update time
func (node *Node) SetLastPeerUpdate() {
node.LastPeerUpdate = time.Now().Unix()
}
// Node.SetExpirationDateTime - sets node expiry time
func (node *Node) SetExpirationDateTime() {
node.ExpirationDateTime = time.Now().Unix() + TEN_YEARS_IN_SECONDS
}
// Node.SetDefaultName - sets a random name to node
func (node *Node) SetDefaultName() {
if node.Name == "" {
node.Name = GenerateNodeName()
}
}
// Node.SetDefaultExcludedAddrs - sets ExcludedAddrs to empty array if nil
func (node *Node) SetDefaultExcludedAddrs() {
if node.ExcludedAddrs == nil {
node.ExcludedAddrs = make([]string, 0)
}
}
// Node.Fill - fills other node data into calling node data if not set on calling node
func (newNode *Node) Fill(currentNode *Node) {
newNode.ID = currentNode.ID
@ -354,8 +381,15 @@ func (newNode *Node) Fill(currentNode *Node) {
if newNode.IsRelayed == "" {
newNode.IsRelayed = currentNode.IsRelayed
}
if newNode.Version == "" {
newNode.Version = currentNode.Version
}
if newNode.ExcludedAddrs == nil || len(newNode.ExcludedAddrs) != len(currentNode.ExcludedAddrs) {
newNode.ExcludedAddrs = currentNode.ExcludedAddrs
}
}
// StringWithCharset - returns random string inside defined charset
func StringWithCharset(length int, charset string) string {
b := make([]byte, length)
for i := range b {
@ -364,13 +398,14 @@ func StringWithCharset(length int, charset string) string {
return string(b)
}
//Check for valid IPv4 address
//Note: We dont handle IPv6 AT ALL!!!!! This definitely is needed at some point
//But for iteration 1, lets just stick to IPv4. Keep it simple stupid.
// IsIpv4Net - check for valid IPv4 address
// Note: We dont handle IPv6 AT ALL!!!!! This definitely is needed at some point
// But for iteration 1, lets just stick to IPv4. Keep it simple stupid.
func IsIpv4Net(host string) bool {
return net.ParseIP(host) != nil
}
// Node.NameInNodeCharset - returns if name is in charset below or not
func (node *Node) NameInNodeCharSet() bool {
charset := "abcdefghijklmnopqrstuvwxyz1234567890-"