| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 | package logicimport (	"github.com/google/uuid"	"github.com/gravitl/netmaker/logger"	"github.com/gravitl/netmaker/logic"	"github.com/gravitl/netmaker/models")// SetFailover - finds a suitable failover candidate and sets itfunc 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 statusfunc ResetFailover(network string) error {	nodes, err := logic.GetNetworkNodes(network)	if err != nil {		return err	}	for _, node := range nodes {		node := node		err = SetFailover(&node)		if err != nil {			logger.Log(2, "error setting failover for node", node.ID.String(), ":", err.Error())		}		err = WipeFailover(node.ID.String())		if err != nil {			logger.Log(2, "error wiping failover for node", node.ID.String(), ":", err.Error())		}	}	return nil}// determineFailoverCandidate - returns a list of nodes that// are suitable for relaying a given nodefunc determineFailoverCandidate(nodeToBeRelayed *models.Node) *models.Node {	currentNetworkNodes, err := logic.GetNetworkNodes(nodeToBeRelayed.Network)	if err != nil {		return nil	}	currentMetrics, err := GetMetrics(nodeToBeRelayed.ID.String())	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.String()].Connected && (currentNetworkNodes[i].Failover) {			if currentMetrics.Connectivity[currentNetworkNodes[i].ID.String()].Latency < int64(minLatency) {				fastestCandidate = ¤tNetworkNodes[i]				minLatency = currentMetrics.Connectivity[currentNetworkNodes[i].ID.String()].Latency			}		}	}	return fastestCandidate}// setFailoverNode - changes node's failover nodefunc setFailoverNode(failoverNode, node *models.Node) error {	node.FailoverNode = failoverNode.ID	nodeToUpdate, err := logic.GetNodeByID(node.ID.String())	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 := 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 listsfunc WipeAffectedFailoversOnly(nodeid uuid.UUID, network string) error {	currentNetworkNodes, err := logic.GetNetworkNodes(network)	if err != nil {		return nil	}	WipeFailover(nodeid.String())	for i := range currentNetworkNodes {		currNodeID := currentNetworkNodes[i].ID		if currNodeID == nodeid {			continue		}		currMetrics, err := GetMetrics(currNodeID.String())		if err != nil || currMetrics == nil {			continue		}		if currMetrics.FailoverPeers != nil {			if len(currMetrics.FailoverPeers[nodeid.String()]) > 0 {				WipeFailover(currNodeID.String())			}		}	}	return nil}
 |