mirror of
https://github.com/gravitl/netmaker.git
synced 2024-11-14 21:57:49 +08:00
121 lines
3.2 KiB
Go
121 lines
3.2 KiB
Go
package logic
|
|
|
|
import (
|
|
"github.com/gravitl/netmaker/logger"
|
|
"github.com/gravitl/netmaker/logic"
|
|
"github.com/gravitl/netmaker/models"
|
|
)
|
|
|
|
// SetFailover - finds a suitable failover candidate and sets it
|
|
func SetFailover(node *models.Node) error {
|
|
failoverNode := determineFailoverCandidate(node)
|
|
if failoverNode != nil {
|
|
return setFailoverNode(failoverNode, node)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// ResetFailover - sets the failover node and wipes disconnected status
|
|
func ResetFailover(network string) error {
|
|
nodes, err := logic.GetNetworkNodes(network)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, node := range nodes {
|
|
err = SetFailover(&node)
|
|
if err != nil {
|
|
logger.Log(2, "error setting failover for node", node.Name, ":", err.Error())
|
|
}
|
|
err = WipeFailover(node.ID)
|
|
if err != nil {
|
|
logger.Log(2, "error wiping failover for node", node.Name, ":", err.Error())
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// determineFailoverCandidate - returns a list of nodes that
|
|
// are suitable for relaying a given node
|
|
func determineFailoverCandidate(nodeToBeRelayed *models.Node) *models.Node {
|
|
|
|
currentNetworkNodes, err := logic.GetNetworkNodes(nodeToBeRelayed.Network)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
|
|
currentMetrics, err := logic.GetMetrics(nodeToBeRelayed.ID)
|
|
if err != nil || currentMetrics == nil || currentMetrics.Connectivity == nil {
|
|
return nil
|
|
}
|
|
|
|
minLatency := int64(9223372036854775807) // max signed int64 value
|
|
var fastestCandidate *models.Node
|
|
for i := range currentNetworkNodes {
|
|
if currentNetworkNodes[i].ID == nodeToBeRelayed.ID {
|
|
continue
|
|
}
|
|
|
|
if currentMetrics.Connectivity[currentNetworkNodes[i].ID].Connected && (currentNetworkNodes[i].Failover == "yes") {
|
|
if currentMetrics.Connectivity[currentNetworkNodes[i].ID].Latency < int64(minLatency) {
|
|
fastestCandidate = ¤tNetworkNodes[i]
|
|
minLatency = currentMetrics.Connectivity[currentNetworkNodes[i].ID].Latency
|
|
}
|
|
}
|
|
}
|
|
|
|
return fastestCandidate
|
|
}
|
|
|
|
// setFailoverNode - changes node's failover node
|
|
func setFailoverNode(failoverNode, node *models.Node) error {
|
|
|
|
node.FailoverNode = failoverNode.ID
|
|
nodeToUpdate, err := logic.GetNodeByID(node.ID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if nodeToUpdate.FailoverNode == failoverNode.ID {
|
|
return nil
|
|
}
|
|
return logic.UpdateNode(&nodeToUpdate, node)
|
|
}
|
|
|
|
// WipeFailover - removes the failover peers of given node (ID)
|
|
func WipeFailover(nodeid string) error {
|
|
metrics, err := logic.GetMetrics(nodeid)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if metrics != nil {
|
|
metrics.FailoverPeers = make(map[string]string)
|
|
return logic.UpdateMetrics(nodeid, metrics)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// WipeAffectedFailoversOnly - wipes failovers for nodes that have given node (ID)
|
|
// in their respective failover lists
|
|
func WipeAffectedFailoversOnly(nodeid, network string) error {
|
|
currentNetworkNodes, err := logic.GetNetworkNodes(network)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
WipeFailover(nodeid)
|
|
|
|
for i := range currentNetworkNodes {
|
|
currNodeID := currentNetworkNodes[i].ID
|
|
if currNodeID == nodeid {
|
|
continue
|
|
}
|
|
currMetrics, err := logic.GetMetrics(currNodeID)
|
|
if err != nil || currMetrics == nil {
|
|
continue
|
|
}
|
|
if currMetrics.FailoverPeers != nil {
|
|
if len(currMetrics.FailoverPeers[nodeid]) > 0 {
|
|
WipeFailover(currNodeID)
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|