|
@@ -0,0 +1,77 @@
|
|
|
+package logic
|
|
|
+
|
|
|
+import (
|
|
|
+ "github.com/gravitl/netmaker/logger"
|
|
|
+ "github.com/gravitl/netmaker/logic"
|
|
|
+ "github.com/gravitl/netmaker/models"
|
|
|
+)
|
|
|
+
|
|
|
+// AutoRelay - finds a suitable relay candidate and creates a relay
|
|
|
+func AutoRelay(nodeToBeRelayed *models.Node) (updateNodes []models.Node, err error) {
|
|
|
+ newRelayer := determineFailoverCandidate(nodeToBeRelayed)
|
|
|
+ if newRelayer != nil {
|
|
|
+ return changeRelayStatus(newRelayer, nodeToBeRelayed)
|
|
|
+ }
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// 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)
|
|
|
+ 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].Connected && (currentNetworkNodes[i].Failover == "yes" || currentNetworkNodes[i].IsServer == "yes") {
|
|
|
+ if currentMetrics.Connectivity[currentNetworkNodes[i].ID].Latency < int64(minLatency) {
|
|
|
+ fastestCandidate = ¤tNetworkNodes[i]
|
|
|
+ minLatency = currentMetrics.Connectivity[currentNetworkNodes[i].ID].Latency
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if fastestCandidate == nil {
|
|
|
+ leader, err := logic.GetNetworkServerLeader(nodeToBeRelayed.Network)
|
|
|
+ if err != nil {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+ return &leader
|
|
|
+ }
|
|
|
+
|
|
|
+ return fastestCandidate
|
|
|
+}
|
|
|
+
|
|
|
+// changeRelayStatus - changes nodes to relay
|
|
|
+func changeRelayStatus(relayer, nodeToBeRelayed *models.Node) ([]models.Node, error) {
|
|
|
+ var newRelayRequest models.RelayRequest
|
|
|
+
|
|
|
+ if relayer.IsRelay == "yes" {
|
|
|
+ newRelayRequest.RelayAddrs = relayer.RelayAddrs
|
|
|
+ }
|
|
|
+ newRelayRequest.NodeID = relayer.ID
|
|
|
+ newRelayRequest.NetID = relayer.Network
|
|
|
+ newRelayRequest.RelayAddrs = append(newRelayRequest.RelayAddrs, nodeToBeRelayed.PrimaryAddress())
|
|
|
+
|
|
|
+ updatenodes, _, err := logic.CreateRelay(newRelayRequest)
|
|
|
+ if err != nil {
|
|
|
+ logger.Log(0, "failed to create relay automatically for node", nodeToBeRelayed.Name, "on network", nodeToBeRelayed.Network)
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ logger.Log(0, "created relay automatically for node", nodeToBeRelayed.Name, "on network", nodeToBeRelayed.Network)
|
|
|
+
|
|
|
+ return updatenodes, nil
|
|
|
+}
|