failover.go 3.3 KB

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