123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- package logic
- import (
- "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 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 {
- 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 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.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 node
- func 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 := 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 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 := logic.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
- }
|