failover.go 3.2 KB

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