status.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. package logic
  2. import (
  3. "time"
  4. "github.com/gravitl/netmaker/logic"
  5. "github.com/gravitl/netmaker/models"
  6. )
  7. func getNodeStatusOld(node *models.Node) {
  8. // On CE check only last check-in time
  9. if node.IsStatic {
  10. if !node.StaticNode.Enabled {
  11. node.Status = models.OfflineSt
  12. return
  13. }
  14. node.Status = models.OnlineSt
  15. return
  16. }
  17. if !node.Connected {
  18. node.Status = models.Disconnected
  19. return
  20. }
  21. if time.Since(node.LastCheckIn) > time.Minute*10 {
  22. node.Status = models.OfflineSt
  23. return
  24. }
  25. node.Status = models.OnlineSt
  26. }
  27. func GetNodeStatus(node *models.Node, defaultEnabledPolicy bool) {
  28. if node.IsStatic {
  29. if !node.StaticNode.Enabled {
  30. node.Status = models.OfflineSt
  31. return
  32. }
  33. ingNode, err := logic.GetNodeByID(node.StaticNode.IngressGatewayID)
  34. if err != nil {
  35. node.Status = models.OfflineSt
  36. return
  37. }
  38. if !defaultEnabledPolicy {
  39. allowed, _ := logic.IsNodeAllowedToCommunicate(*node, ingNode, false)
  40. if !allowed {
  41. node.Status = models.OnlineSt
  42. return
  43. }
  44. }
  45. // check extclient connection from metrics
  46. ingressMetrics, err := GetMetrics(node.StaticNode.IngressGatewayID)
  47. if err != nil || ingressMetrics == nil || ingressMetrics.Connectivity == nil {
  48. node.Status = models.UnKnown
  49. return
  50. }
  51. if metric, ok := ingressMetrics.Connectivity[node.StaticNode.ClientID]; ok {
  52. if metric.Connected {
  53. node.Status = models.OnlineSt
  54. return
  55. } else {
  56. node.Status = models.OfflineSt
  57. return
  58. }
  59. }
  60. node.Status = models.UnKnown
  61. return
  62. }
  63. if !node.Connected {
  64. node.Status = models.Disconnected
  65. return
  66. }
  67. if time.Since(node.LastCheckIn) > models.LastCheckInThreshold {
  68. node.Status = models.OfflineSt
  69. return
  70. }
  71. host, err := logic.GetHost(node.HostID.String())
  72. if err != nil {
  73. node.Status = models.UnKnown
  74. return
  75. }
  76. vlt, err := logic.VersionLessThan(host.Version, "v0.30.0")
  77. if err != nil {
  78. node.Status = models.UnKnown
  79. return
  80. }
  81. if vlt {
  82. getNodeStatusOld(node)
  83. return
  84. }
  85. metrics, err := logic.GetMetrics(node.ID.String())
  86. if err != nil {
  87. return
  88. }
  89. if metrics == nil || metrics.Connectivity == nil || len(metrics.Connectivity) == 0 {
  90. if time.Since(node.LastCheckIn) < models.LastCheckInThreshold {
  91. node.Status = models.OnlineSt
  92. return
  93. }
  94. if node.LastCheckIn.IsZero() {
  95. node.Status = models.OfflineSt
  96. return
  97. }
  98. }
  99. // if node.IsFailOver {
  100. // if time.Since(node.LastCheckIn) < models.LastCheckInThreshold {
  101. // node.Status = models.OnlineSt
  102. // return
  103. // }
  104. // }
  105. // If all Peers are able to reach me and and the peer is not able to reached by any peer then return online
  106. /* 1. FailOver Exists
  107. a. check connectivity to failover Node - if no connection return warning
  108. b. if getting failedover and still no connection to any of the peers - then show error
  109. c. if getting failedOver and has connections to some peers - show warning
  110. 2. FailOver Doesn't Exist
  111. a. check connectivity to pu
  112. */
  113. // failoverNode, exists := FailOverExists(node.Network)
  114. // if exists && failoverNode.FailedOverBy != uuid.Nil {
  115. // // check connectivity to failover Node
  116. // if metric, ok := metrics.Connectivity[failoverNode.ID.String()]; ok {
  117. // if time.Since(failoverNode.LastCheckIn) < models.LastCheckInThreshold {
  118. // if metric.Connected {
  119. // node.Status = models.OnlineSt
  120. // return
  121. // } else {
  122. // checkPeerConnectivity(node, metrics)
  123. // return
  124. // }
  125. // }
  126. // } else {
  127. // node.Status = models.OnlineSt
  128. // return
  129. // }
  130. // }
  131. checkPeerConnectivity(node, metrics, defaultEnabledPolicy)
  132. }
  133. func checkPeerStatus(node *models.Node, defaultAclPolicy bool) {
  134. peerNotConnectedCnt := 0
  135. metrics, err := logic.GetMetrics(node.ID.String())
  136. if err != nil {
  137. return
  138. }
  139. if metrics == nil || metrics.Connectivity == nil {
  140. if time.Since(node.LastCheckIn) < models.LastCheckInThreshold {
  141. node.Status = models.OnlineSt
  142. return
  143. }
  144. }
  145. for peerID, metric := range metrics.Connectivity {
  146. peer, err := logic.GetNodeByID(peerID)
  147. if err != nil {
  148. continue
  149. }
  150. if !defaultAclPolicy {
  151. allowed, _ := logic.IsNodeAllowedToCommunicate(*node, peer, false)
  152. if !allowed {
  153. continue
  154. }
  155. }
  156. if time.Since(peer.LastCheckIn) > models.LastCheckInThreshold {
  157. continue
  158. }
  159. if metric.Connected {
  160. continue
  161. }
  162. if peer.Status == models.ErrorSt {
  163. continue
  164. }
  165. peerNotConnectedCnt++
  166. }
  167. if peerNotConnectedCnt == 0 {
  168. node.Status = models.OnlineSt
  169. return
  170. }
  171. if len(metrics.Connectivity) > 0 && peerNotConnectedCnt == len(metrics.Connectivity) {
  172. node.Status = models.ErrorSt
  173. return
  174. }
  175. node.Status = models.WarningSt
  176. }
  177. func checkPeerConnectivity(node *models.Node, metrics *models.Metrics, defaultAclPolicy bool) {
  178. peerNotConnectedCnt := 0
  179. for peerID, metric := range metrics.Connectivity {
  180. peer, err := logic.GetNodeByID(peerID)
  181. if err != nil {
  182. continue
  183. }
  184. if !defaultAclPolicy {
  185. allowed, _ := logic.IsNodeAllowedToCommunicate(*node, peer, false)
  186. if !allowed {
  187. continue
  188. }
  189. }
  190. if time.Since(peer.LastCheckIn) > models.LastCheckInThreshold {
  191. continue
  192. }
  193. if metric.Connected {
  194. continue
  195. }
  196. // check if peer is in error state
  197. checkPeerStatus(&peer, defaultAclPolicy)
  198. if peer.Status == models.ErrorSt || peer.Status == models.WarningSt {
  199. continue
  200. }
  201. peerNotConnectedCnt++
  202. }
  203. if peerNotConnectedCnt > len(metrics.Connectivity)/2 {
  204. node.Status = models.WarningSt
  205. return
  206. }
  207. if len(metrics.Connectivity) > 0 && peerNotConnectedCnt == len(metrics.Connectivity) {
  208. node.Status = models.ErrorSt
  209. return
  210. }
  211. node.Status = models.OnlineSt
  212. }