failover.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. package logic
  2. import (
  3. "github.com/google/uuid"
  4. "github.com/gravitl/netmaker/logger"
  5. "github.com/gravitl/netmaker/logic"
  6. "github.com/gravitl/netmaker/models"
  7. )
  8. // SetFailover - finds a suitable failover candidate and sets it
  9. func SetFailover(node *models.Node) error {
  10. failoverNode := determineFailoverCandidate(node)
  11. if failoverNode != nil {
  12. return setFailoverNode(failoverNode, node)
  13. }
  14. return nil
  15. }
  16. // ResetFailover - sets the failover node and wipes disconnected status
  17. func ResetFailover(network string) error {
  18. nodes, err := logic.GetNetworkNodes(network)
  19. if err != nil {
  20. return err
  21. }
  22. for _, node := range nodes {
  23. node := node
  24. err = SetFailover(&node)
  25. if err != nil {
  26. logger.Log(2, "error setting failover for node", node.ID.String(), ":", err.Error())
  27. }
  28. err = WipeFailover(node.ID.String())
  29. if err != nil {
  30. logger.Log(2, "error wiping failover for node", node.ID.String(), ":", err.Error())
  31. }
  32. }
  33. return nil
  34. }
  35. // determineFailoverCandidate - returns a list of nodes that
  36. // are suitable for relaying a given node
  37. func determineFailoverCandidate(nodeToBeRelayed *models.Node) *models.Node {
  38. currentNetworkNodes, err := logic.GetNetworkNodes(nodeToBeRelayed.Network)
  39. if err != nil {
  40. return nil
  41. }
  42. currentMetrics, err := logic.GetMetrics(nodeToBeRelayed.ID.String())
  43. if err != nil || currentMetrics == nil || currentMetrics.Connectivity == nil {
  44. return nil
  45. }
  46. minLatency := int64(9223372036854775807) // max signed int64 value
  47. var fastestCandidate *models.Node
  48. for i := range currentNetworkNodes {
  49. if currentNetworkNodes[i].ID == nodeToBeRelayed.ID {
  50. continue
  51. }
  52. if currentMetrics.Connectivity[currentNetworkNodes[i].ID.String()].Connected && (currentNetworkNodes[i].Failover) {
  53. if currentMetrics.Connectivity[currentNetworkNodes[i].ID.String()].Latency < int64(minLatency) {
  54. fastestCandidate = &currentNetworkNodes[i]
  55. minLatency = currentMetrics.Connectivity[currentNetworkNodes[i].ID.String()].Latency
  56. }
  57. }
  58. }
  59. return fastestCandidate
  60. }
  61. // setFailoverNode - changes node's failover node
  62. func setFailoverNode(failoverNode, node *models.Node) error {
  63. node.FailoverNode = failoverNode.ID
  64. nodeToUpdate, err := logic.GetNodeByID(node.ID.String())
  65. if err != nil {
  66. return err
  67. }
  68. if nodeToUpdate.FailoverNode == failoverNode.ID {
  69. return nil
  70. }
  71. return logic.UpdateNode(&nodeToUpdate, node)
  72. }
  73. // WipeFailover - removes the failover peers of given node (ID)
  74. func WipeFailover(nodeid string) error {
  75. metrics, err := logic.GetMetrics(nodeid)
  76. if err != nil {
  77. return err
  78. }
  79. if metrics != nil {
  80. metrics.FailoverPeers = make(map[string]string)
  81. return logic.UpdateMetrics(nodeid, metrics)
  82. }
  83. return nil
  84. }
  85. // WipeAffectedFailoversOnly - wipes failovers for nodes that have given node (ID)
  86. // in their respective failover lists
  87. func WipeAffectedFailoversOnly(nodeid uuid.UUID, network string) error {
  88. currentNetworkNodes, err := logic.GetNetworkNodes(network)
  89. if err != nil {
  90. return nil
  91. }
  92. WipeFailover(nodeid.String())
  93. for i := range currentNetworkNodes {
  94. currNodeID := currentNetworkNodes[i].ID
  95. if currNodeID == nodeid {
  96. continue
  97. }
  98. currMetrics, err := logic.GetMetrics(currNodeID.String())
  99. if err != nil || currMetrics == nil {
  100. continue
  101. }
  102. if currMetrics.FailoverPeers != nil {
  103. if len(currMetrics.FailoverPeers[nodeid.String()]) > 0 {
  104. WipeFailover(currNodeID.String())
  105. }
  106. }
  107. }
  108. return nil
  109. }