2022-09-22 03:13:17 +08:00
|
|
|
package logic
|
|
|
|
|
|
|
|
import (
|
2022-09-28 02:42:14 +08:00
|
|
|
"github.com/gravitl/netmaker/logger"
|
2022-09-22 03:13:17 +08:00
|
|
|
"github.com/gravitl/netmaker/logic"
|
|
|
|
"github.com/gravitl/netmaker/models"
|
|
|
|
)
|
|
|
|
|
2022-09-28 01:59:49 +08:00
|
|
|
// 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)
|
2022-09-22 03:13:17 +08:00
|
|
|
}
|
2022-09-28 01:59:49 +08:00
|
|
|
return nil
|
2022-09-22 03:13:17 +08:00
|
|
|
}
|
|
|
|
|
2022-09-28 02:42:14 +08:00
|
|
|
// 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
|
|
|
|
}
|
|
|
|
|
2022-09-22 03:13:17 +08:00
|
|
|
// 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
|
|
|
|
}
|
|
|
|
|
2022-09-28 02:07:02 +08:00
|
|
|
if currentMetrics.Connectivity[currentNetworkNodes[i].ID].Connected && (currentNetworkNodes[i].Failover == "yes") {
|
2022-09-22 03:13:17 +08:00
|
|
|
if currentMetrics.Connectivity[currentNetworkNodes[i].ID].Latency < int64(minLatency) {
|
|
|
|
fastestCandidate = ¤tNetworkNodes[i]
|
|
|
|
minLatency = currentMetrics.Connectivity[currentNetworkNodes[i].ID].Latency
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return fastestCandidate
|
|
|
|
}
|
|
|
|
|
2022-09-28 01:59:49 +08:00
|
|
|
// setFailoverNode - changes node's failover node
|
|
|
|
func setFailoverNode(failoverNode, node *models.Node) error {
|
2022-09-29 02:59:21 +08:00
|
|
|
|
2022-09-28 01:59:49 +08:00
|
|
|
node.FailoverNode = failoverNode.ID
|
|
|
|
nodeToUpdate, err := logic.GetNodeByID(node.ID)
|
2022-09-22 03:13:17 +08:00
|
|
|
if err != nil {
|
2022-09-28 01:59:49 +08:00
|
|
|
return err
|
2022-09-22 03:13:17 +08:00
|
|
|
}
|
2022-09-29 01:05:41 +08:00
|
|
|
if nodeToUpdate.FailoverNode == failoverNode.ID {
|
|
|
|
return nil
|
|
|
|
}
|
2022-09-28 01:59:49 +08:00
|
|
|
return logic.UpdateNode(&nodeToUpdate, node)
|
2022-09-22 03:13:17 +08:00
|
|
|
}
|
2022-09-28 02:42:14 +08:00
|
|
|
|
2022-09-29 03:49:02 +08:00
|
|
|
// WipeFailover - removes the failover peers of given node (ID)
|
2022-09-28 02:42:14 +08:00
|
|
|
func WipeFailover(nodeid string) error {
|
|
|
|
metrics, err := logic.GetMetrics(nodeid)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2022-09-29 03:49:02 +08:00
|
|
|
if metrics != nil {
|
|
|
|
metrics.FailoverPeers = make(map[string]string)
|
|
|
|
return logic.UpdateMetrics(nodeid, metrics)
|
|
|
|
}
|
|
|
|
return nil
|
2022-09-28 02:42:14 +08:00
|
|
|
}
|