From de4e317aea174ccc3a58c11049be83dc4982ccb3 Mon Sep 17 00:00:00 2001 From: 0xdcarns Date: Mon, 10 Jan 2022 10:55:05 -0500 Subject: [PATCH] began transition --- go.mod | 9 +- logic/nodes.go | 230 +++++------------------------------------------- logic/server.go | 159 ++++++++++++++++++--------------- logic/util.go | 187 +++++++++++++++++++-------------------- models/node.go | 53 ++--------- 5 files changed, 210 insertions(+), 428 deletions(-) diff --git a/go.mod b/go.mod index 984754b1..70f37dc5 100644 --- a/go.mod +++ b/go.mod @@ -3,11 +3,9 @@ module github.com/gravitl/netmaker go 1.17 require ( - github.com/eclipse/paho.mqtt.golang v1.3.5 github.com/go-playground/validator/v10 v10.10.0 github.com/golang-jwt/jwt/v4 v4.2.0 github.com/golang/protobuf v1.5.2 // indirect - github.com/google/uuid v1.3.0 github.com/gorilla/handlers v1.5.1 github.com/gorilla/mux v1.8.0 github.com/lib/pq v1.10.4 @@ -27,7 +25,6 @@ require ( google.golang.org/genproto v0.0.0-20210201151548-94839c025ad4 // indirect google.golang.org/grpc v1.43.0 google.golang.org/protobuf v1.27.1 - gopkg.in/ini.v1 v1.66.2 gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b ) @@ -35,13 +32,11 @@ require ( cloud.google.com/go v0.34.0 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/eclipse/paho.mqtt.golang v1.3.5 // indirect github.com/felixge/httpsnoop v1.0.1 // indirect - github.com/go-ping/ping v0.0.0-20211130115550-779d1e919534 // indirect github.com/go-playground/locales v0.14.0 // indirect github.com/go-playground/universal-translator v0.18.0 // indirect github.com/google/go-cmp v0.5.5 // indirect - github.com/gorilla/websocket v1.4.2 // indirect + github.com/google/uuid v1.3.0 // indirect github.com/josharian/native v0.0.0-20200817173448-b6b71def0850 // indirect github.com/leodido/go-urn v1.2.1 // indirect github.com/mdlayher/genetlink v1.0.0 // indirect @@ -49,7 +44,5 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/russross/blackfriday/v2 v2.0.1 // indirect github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect - golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect google.golang.org/appengine v1.4.0 // indirect - gopkg.in/ini.v1 v1.66.2 // indirect ) diff --git a/logic/nodes.go b/logic/nodes.go index 073eeb20..61dea4cd 100644 --- a/logic/nodes.go +++ b/logic/nodes.go @@ -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") -} diff --git a/logic/server.go b/logic/server.go index 3eb8478f..4319c5b1 100644 --- a/logic/server.go +++ b/logic/server.go @@ -17,7 +17,6 @@ import ( "golang.zx2c4.com/wireguard/wgctrl/wgtypes" ) -// == Public == // == Join, Checkin, and Leave for Server == // KUBERNETES_LISTEN_PORT - starting port for Kubernetes in order to use NodePort range @@ -27,26 +26,23 @@ const KUBERNETES_LISTEN_PORT = 31821 const KUBERNETES_SERVER_MTU = 1024 // ServerJoin - responsible for joining a server to a network -func ServerJoin(networkSettings *models.Network) error { +func ServerJoin(networkSettings *models.Network, serverID string) error { if networkSettings == nil || networkSettings.NetID == "" { return errors.New("no network provided") } var err error - var node = &models.Node{ IsServer: "yes", DNSOn: "no", IsStatic: "yes", Name: models.NODE_SERVER_NAME, - MacAddress: servercfg.GetNodeID(), - ID: "", // will be set to new uuid + MacAddress: serverID, UDPHolePunch: "no", IsLocal: networkSettings.IsLocal, LocalRange: networkSettings.LocalRange, } - SetNodeDefaults(node) if servercfg.GetPlatform() == "Kubernetes" { @@ -120,7 +116,7 @@ func ServerJoin(networkSettings *models.Network) error { if err = StorePrivKey(node.ID, privateKey); err != nil { return err } - if err = serverPush(node); err != nil { + if err = ServerPush(node); err != nil { return err } @@ -138,12 +134,18 @@ func ServerJoin(networkSettings *models.Network) error { return nil } -// ServerUpdate - updates the server -// replaces legacy Checkin code -func ServerUpdate(serverNode *models.Node, shouldPeerUpdate bool) error { - var err = serverPull(serverNode, shouldPeerUpdate) +// ServerCheckin - runs pulls and pushes for server +func ServerCheckin(mac string, network string) error { + var serverNode = &models.Node{} + var currentNode, err = GetNode(mac, network) + if err != nil { + return err + } + serverNode = ¤tNode + + err = ServerPull(serverNode, false) if isDeleteError(err) { - return DeleteNodeByID(serverNode, true) + return ServerLeave(mac, network) } else if err != nil { return err } @@ -153,7 +155,66 @@ func ServerUpdate(serverNode *models.Node, shouldPeerUpdate bool) error { return errors.New("node has been removed") } - return serverPush(serverNode) + return ServerPush(serverNode) +} + +// ServerPull - pulls current config/peers for server +func ServerPull(serverNode *models.Node, onErr bool) error { + + var err error + if serverNode.IPForwarding == "yes" { + if err = setIPForwardingLinux(); err != nil { + return err + } + } + serverNode.OS = runtime.GOOS + + if serverNode.PullChanges == "yes" || onErr { + // check for interface change + // checks if address is in use by another interface + var oldIfaceName, isIfacePresent = isInterfacePresent(serverNode.Interface, serverNode.Address) + if !isIfacePresent { + if err = deleteInterface(oldIfaceName, serverNode.PostDown); err != nil { + logger.Log(1, "could not delete old interface", oldIfaceName) + } + logger.Log(1, "removed old interface", oldIfaceName) + } + serverNode.PullChanges = "no" + if err = setWGConfig(serverNode, false); err != nil { + return err + } + // handle server side update + if err = UpdateNode(serverNode, serverNode); err != nil { + return err + } + } else { + if err = setWGConfig(serverNode, true); err != nil { + if errors.Is(err, os.ErrNotExist) { + return ServerPull(serverNode, true) + } else { + return err + } + } + } + + return nil +} + +// ServerPush - pushes config changes for server checkins/join +func ServerPush(serverNode *models.Node) error { + serverNode.OS = runtime.GOOS + serverNode.SetLastCheckIn() + return UpdateNode(serverNode, serverNode) +} + +// ServerLeave - removes a server node +func ServerLeave(mac string, network string) error { + + var serverNode, err = GetNode(mac, network) + if err != nil { + return err + } + return DeleteNode(&serverNode, true) } /** @@ -167,14 +228,17 @@ func GetServerPeers(serverNode *models.Node) ([]wgtypes.PeerConfig, bool, []stri var gateways []string var peers []wgtypes.PeerConfig var nodes []models.Node // fill above fields from server or client - var err error - nodes, err = GetPeers(serverNode) + var nodecfg, err = GetNode(serverNode.MacAddress, serverNode.Network) + if err != nil { + return nil, hasGateway, gateways, err + } + nodes, err = GetPeers(&nodecfg) if err != nil { return nil, hasGateway, gateways, err } - keepalive := serverNode.PersistentKeepalive + keepalive := nodecfg.PersistentKeepalive keepalivedur, err := time.ParseDuration(strconv.FormatInt(int64(keepalive), 10) + "s") if err != nil { logger.Log(1, "Issue with format of keepalive duration value, Please view server config:", err.Error()) @@ -188,11 +252,11 @@ func GetServerPeers(serverNode *models.Node) ([]wgtypes.PeerConfig, bool, []stri return peers, hasGateway, gateways, err } - if serverNode.PublicKey == node.PublicKey { + if nodecfg.PublicKey == node.PublicKey { continue } - if serverNode.Endpoint == node.Endpoint { - if serverNode.LocalAddress != node.LocalAddress && node.LocalAddress != "" { + if nodecfg.Endpoint == node.Endpoint { + if nodecfg.LocalAddress != node.LocalAddress && node.LocalAddress != "" { node.Endpoint = node.LocalAddress } else { continue @@ -237,8 +301,8 @@ func GetServerPeers(serverNode *models.Node) ([]wgtypes.PeerConfig, bool, []stri logger.Log(2, "egress IP range of", iprange, "overlaps with", node.Endpoint, ", omitting") continue // skip adding egress range if overlaps with node's ip } - if ipnet.Contains(net.ParseIP(serverNode.LocalAddress)) { // ensuring egress gateway range does not contain public ip of node - logger.Log(2, "egress IP range of", iprange, "overlaps with", serverNode.LocalAddress, ", omitting") + if ipnet.Contains(net.ParseIP(nodecfg.LocalAddress)) { // ensuring egress gateway range does not contain public ip of node + logger.Log(2, "egress IP range of", iprange, "overlaps with", nodecfg.LocalAddress, ", omitting") continue // skip adding egress range if overlaps with node's local ip } gateways = append(gateways, iprange) @@ -284,7 +348,7 @@ func GetServerExtPeers(serverNode *models.Node) ([]wgtypes.PeerConfig, error) { var err error var tempPeers []models.ExtPeersResponse - tempPeers, err = GetExtPeersList(serverNode) + tempPeers, err = GetExtPeersList(serverNode.MacAddress, serverNode.Network) if err != nil { return nil, err } @@ -355,7 +419,7 @@ func checkNodeActions(node *models.Node) string { } } if node.Action == models.NODE_DELETE { - err := DeleteNodeByID(node, true) + err := ServerLeave(node.MacAddress, node.Network) if err != nil { logger.Log(1, "error deleting locally:", err.Error()) } @@ -364,49 +428,6 @@ func checkNodeActions(node *models.Node) string { return "" } -// == Private == - -func serverPull(serverNode *models.Node, onErr bool) error { - - var err error - if serverNode.IPForwarding == "yes" { - if err = setIPForwardingLinux(); err != nil { - return err - } - } - serverNode.OS = runtime.GOOS - - if serverNode.PullChanges == "yes" || onErr { - // check for interface change - // checks if address is in use by another interface - var oldIfaceName, isIfacePresent = isInterfacePresent(serverNode.Interface, serverNode.Address) - if !isIfacePresent { - if err = deleteInterface(oldIfaceName, serverNode.PostDown); err != nil { - logger.Log(1, "could not delete old interface", oldIfaceName) - } - logger.Log(1, "removed old interface", oldIfaceName) - } - serverNode.PullChanges = "no" - if err = setWGConfig(serverNode, false); err != nil { - return err - } - // handle server side update - if err = UpdateNode(serverNode, serverNode); err != nil { - return err - } - } else { - if err = setWGConfig(serverNode, true); err != nil { - if errors.Is(err, os.ErrNotExist) { - return serverPull(serverNode, true) - } else { - return err - } - } - } - - return nil -} - func getServerLocalIP(networkSettings *models.Network) (string, error) { var networkCIDR = networkSettings.LocalRange @@ -428,9 +449,3 @@ func getServerLocalIP(networkSettings *models.Network) (string, error) { } return "", errors.New("could not find a local ip for server") } - -func serverPush(serverNode *models.Node) error { - serverNode.OS = runtime.GOOS - serverNode.SetLastCheckIn() - return UpdateNode(serverNode, serverNode) -} diff --git a/logic/util.go b/logic/util.go index 3af94960..7b63fdfe 100644 --- a/logic/util.go +++ b/logic/util.go @@ -4,19 +4,18 @@ 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 @@ -32,45 +31,24 @@ func CheckEndpoint(endpoint string) bool { return len(endpointarr) == 2 } -// 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 +// 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()) } - 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 -func DeleteNodeByMacAddress(node *models.Node, exterminate bool) error { +// DeleteNode - deletes a node from database or moves into delete nodes table +func DeleteNode(node *models.Node, exterminate bool) error { var err error var key = node.ID if !exterminate { args := strings.Split(key, "###") - node, err := GetNodeByMacAddress(args[0], args[1]) + node, err := GetNode(args[0], args[1]) if err != nil { return err } @@ -97,6 +75,66 @@ 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 + } + //Create a JWT for the node + tokenString, _ := CreateJWT(node.MacAddress, node.Network) + if tokenString == "" { + //returnErrorResponse(w, r, errorResponse) + return err + } + err = ValidateNode(node, false) + if err != nil { + return err + } + + node.ID = uuid.NewString() + + 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 { @@ -118,56 +156,28 @@ func SetNetworkNodesLastModified(networkName string) error { return nil } -// // GetNode - fetches a node from database -// func GetNode(macaddress string, network string) (models.Node, error) { -// var node models.Node +// GetNode - fetches a node from database +func GetNode(macaddress string, network string) (models.Node, error) { + var node models.Node -// key, err := GetRecordKey(macaddress, network) -// if err != nil { -// return node, err -// } -// data, err := database.FetchRecord(database.NODES_TABLE_NAME, key) -// if err != nil { -// if data == "" { -// data, _ = database.FetchRecord(database.DELETED_NODES_TABLE_NAME, key) -// err = json.Unmarshal([]byte(data), &node) -// } -// return node, err -// } -// if err = json.Unmarshal([]byte(data), &node); err != nil { -// return node, err -// } -// SetNodeDefaults(&node) + key, err := GetRecordKey(macaddress, network) + if err != nil { + return node, err + } + data, err := database.FetchRecord(database.NODES_TABLE_NAME, key) + if err != nil { + if data == "" { + data, _ = database.FetchRecord(database.DELETED_NODES_TABLE_NAME, key) + err = json.Unmarshal([]byte(data), &node) + } + return node, err + } + if err = json.Unmarshal([]byte(data), &node); err != nil { + return node, err + } + SetNodeDefaults(&node) -// return node, err -// } - -// DeleteNodeByID - deletes a node from database or moves into delete nodes table -func DeleteNodeByID(node *models.Node, exterminate bool) error { - var err error - var key = node.ID - if !exterminate { - node.Action = models.NODE_DELETE - nodedata, err := json.Marshal(&node) - if err != nil { - return err - } - err = database.Insert(key, string(nodedata), database.DELETED_NODES_TABLE_NAME) - if err != nil { - return err - } - } else { - if err := database.DeleteRecord(database.DELETED_NODES_TABLE_NAME, key); err != nil { - logger.Log(2, err.Error()) - } - } - if err = database.DeleteRecord(database.NODES_TABLE_NAME, key); err != nil { - return err - } - if servercfg.IsDNSMode() { - SetDNS() - } - return removeLocalServer(node) + return node, err } // GetNodePeers - fetches peers for a given node @@ -358,16 +368,3 @@ 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()) - } -} diff --git a/models/node.go b/models/node.go index 16f65afd..4ed0ee63 100644 --- a/models/node.go +++ b/models/node.go @@ -23,9 +23,9 @@ const NODE_NOOP = "noop" var seededRand *rand.Rand = rand.New( rand.NewSource(time.Now().UnixNano())) -// Node - struct for node model +// node struct type Node struct { - ID string `json:"id,omitempty" bson:"id,omitempty" yaml:"id,omitempty" validate:"required,min=5"` + ID string `json:"id,omitempty" bson:"id,omitempty"` Address string `json:"address" bson:"address" yaml:"address" validate:"omitempty,ipv4"` Address6 string `json:"address6" bson:"address6" yaml:"address6" validate:"omitempty,ipv6"` LocalAddress string `json:"localaddress" bson:"localaddress" yaml:"localaddress" validate:"omitempty,ip"` @@ -46,7 +46,7 @@ type Node struct { ExpirationDateTime int64 `json:"expdatetime" bson:"expdatetime" yaml:"expdatetime"` LastPeerUpdate int64 `json:"lastpeerupdate" bson:"lastpeerupdate" yaml:"lastpeerupdate"` LastCheckIn int64 `json:"lastcheckin" bson:"lastcheckin" yaml:"lastcheckin"` - MacAddress string `json:"macaddress" bson:"macaddress" yaml:"macaddress"` + MacAddress string `json:"macaddress" bson:"macaddress" yaml:"macaddress" validate:"required,min=5,macaddress_unique"` // checkin interval is depreciated at the network level. Set on server with CHECKIN_INTERVAL CheckInInterval int32 `json:"checkininterval" bson:"checkininterval" yaml:"checkininterval"` Password string `json:"password" bson:"password" yaml:"password" validate:"required,min=6"` @@ -72,8 +72,6 @@ type Node struct { IPForwarding string `json:"ipforwarding" bson:"ipforwarding" yaml:"ipforwarding" validate:"checkyesorno"` 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 @@ -108,91 +106,78 @@ 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" @@ -201,44 +186,32 @@ 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 - + if newNode.ID == "" { + newNode.ID = currentNode.ID + } if newNode.Address == "" && newNode.IsStatic != "yes" { newNode.Address = currentNode.Address } @@ -381,15 +354,8 @@ 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 { @@ -398,14 +364,13 @@ func StringWithCharset(length int, charset string) string { return string(b) } -// 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. +//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-"