| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 | package logicimport (	"time"	"github.com/gravitl/netmaker/logic"	"github.com/gravitl/netmaker/models")func getNodeStatusOld(node *models.Node) {	// On CE check only last check-in time	if node.IsStatic {		if !node.StaticNode.Enabled {			node.Status = models.OfflineSt			return		}		node.Status = models.OnlineSt		return	}	if time.Since(node.LastCheckIn) > time.Minute*10 {		node.Status = models.OfflineSt		return	}	node.Status = models.OnlineSt}func GetNodeStatus(node *models.Node, defaultEnabledPolicy bool) {	if node.IsStatic {		if !node.StaticNode.Enabled {			node.Status = models.OfflineSt			return		}		// check extclient connection from metrics		ingressMetrics, err := GetMetrics(node.StaticNode.IngressGatewayID)		if err != nil || ingressMetrics == nil || ingressMetrics.Connectivity == nil {			node.Status = models.UnKnown			return		}		if metric, ok := ingressMetrics.Connectivity[node.StaticNode.ClientID]; ok {			if metric.Connected {				node.Status = models.OnlineSt				return			} else {				node.Status = models.OfflineSt				return			}		}		node.Status = models.UnKnown		return	}	if time.Since(node.LastCheckIn) > models.LastCheckInThreshold {		node.Status = models.OfflineSt		return	}	host, err := logic.GetHost(node.HostID.String())	if err != nil {		node.Status = models.UnKnown		return	}	vlt, err := logic.VersionLessThan(host.Version, "v0.30.0")	if err != nil {		node.Status = models.UnKnown		return	}	if vlt {		getNodeStatusOld(node)		return	}	metrics, err := logic.GetMetrics(node.ID.String())	if err != nil {		return	}	if metrics == nil || metrics.Connectivity == nil || len(metrics.Connectivity) == 0 {		if time.Since(node.LastCheckIn) < models.LastCheckInThreshold {			node.Status = models.OnlineSt			return		}		if node.LastCheckIn.IsZero() {			node.Status = models.OfflineSt			return		}	}	// if node.IsFailOver {	// 	if time.Since(node.LastCheckIn) < models.LastCheckInThreshold {	// 		node.Status = models.OnlineSt	// 		return	// 	}	// }	// If all Peers are able to reach me and and the peer is not able to reached by any peer then return online	/* 1. FailOver Exists		a. check connectivity to failover Node - if no connection return warning		b. if getting failedover and still no connection to any of the peers - then show error		c. if getting failedOver and has connections to some peers - show warning	2. FailOver Doesn't Exist		a. check connectivity to pu	*/	// failoverNode, exists := FailOverExists(node.Network)	// if exists && failoverNode.FailedOverBy != uuid.Nil {	// 	// check connectivity to failover Node	// 	if metric, ok := metrics.Connectivity[failoverNode.ID.String()]; ok {	// 		if time.Since(failoverNode.LastCheckIn) < models.LastCheckInThreshold {	// 			if metric.Connected {	// 				node.Status = models.OnlineSt	// 				return	// 			} else {	// 				checkPeerConnectivity(node, metrics)	// 				return	// 			}	// 		}	// 	} else {	// 		node.Status = models.OnlineSt	// 		return	// 	}	// }	checkPeerConnectivity(node, metrics, defaultEnabledPolicy)}func checkPeerStatus(node *models.Node, defaultAclPolicy bool) {	peerNotConnectedCnt := 0	metrics, err := logic.GetMetrics(node.ID.String())	if err != nil {		return	}	if metrics == nil || metrics.Connectivity == nil {		if time.Since(node.LastCheckIn) < models.LastCheckInThreshold {			node.Status = models.OnlineSt			return		}	}	for peerID, metric := range metrics.Connectivity {		peer, err := logic.GetNodeByID(peerID)		if err != nil {			continue		}		if !defaultAclPolicy {			allowed, _ := logic.IsNodeAllowedToCommunicate(*node, peer, false)			if !allowed {				continue			}		}		if time.Since(peer.LastCheckIn) > models.LastCheckInThreshold {			continue		}		if metric.Connected {			continue		}		if peer.Status == models.ErrorSt {			continue		}		peerNotConnectedCnt++	}	if peerNotConnectedCnt == 0 {		node.Status = models.OnlineSt		return	}	if len(metrics.Connectivity) > 0 && peerNotConnectedCnt == len(metrics.Connectivity) {		node.Status = models.ErrorSt		return	}	node.Status = models.WarningSt}func checkPeerConnectivity(node *models.Node, metrics *models.Metrics, defaultAclPolicy bool) {	peerNotConnectedCnt := 0	for peerID, metric := range metrics.Connectivity {		peer, err := logic.GetNodeByID(peerID)		if err != nil {			continue		}		if !defaultAclPolicy {			allowed, _ := logic.IsNodeAllowedToCommunicate(*node, peer, false)			if !allowed {				continue			}		}		if time.Since(peer.LastCheckIn) > models.LastCheckInThreshold {			continue		}		if metric.Connected {			continue		}		// check if peer is in error state		checkPeerStatus(&peer, defaultAclPolicy)		if peer.Status == models.ErrorSt || peer.Status == models.WarningSt {			continue		}		peerNotConnectedCnt++	}	if peerNotConnectedCnt > len(metrics.Connectivity)/2 {		node.Status = models.WarningSt		return	}	if len(metrics.Connectivity) > 0 && peerNotConnectedCnt == len(metrics.Connectivity) {		node.Status = models.ErrorSt		return	}	node.Status = models.OnlineSt}
 |