api_node.go 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. package models
  2. import (
  3. "net"
  4. "time"
  5. "github.com/google/uuid"
  6. "golang.org/x/exp/slog"
  7. )
  8. type ApiNodeStatus struct {
  9. ID string `json:"id"`
  10. IsStatic bool `json:"is_static"`
  11. IsUserNode bool `json:"is_user_node"`
  12. Status NodeStatus `json:"status"`
  13. }
  14. // ApiNode is a stripped down Node DTO that exposes only required fields to external systems
  15. type ApiNode struct {
  16. ID string `json:"id,omitempty" validate:"required,min=5,id_unique"`
  17. HostID string `json:"hostid,omitempty" validate:"required,min=5,id_unique"`
  18. Address string `json:"address" validate:"omitempty,cidrv4"`
  19. Address6 string `json:"address6" validate:"omitempty,cidrv6"`
  20. LocalAddress string `json:"localaddress" validate:"omitempty,cidr"`
  21. AllowedIPs []string `json:"allowedips"`
  22. LastModified int64 `json:"lastmodified" swaggertype:"primitive,integer" format:"int64"`
  23. ExpirationDateTime int64 `json:"expdatetime" swaggertype:"primitive,integer" format:"int64"`
  24. LastCheckIn int64 `json:"lastcheckin" swaggertype:"primitive,integer" format:"int64"`
  25. LastPeerUpdate int64 `json:"lastpeerupdate" swaggertype:"primitive,integer" format:"int64"`
  26. Network string `json:"network"`
  27. NetworkRange string `json:"networkrange"`
  28. NetworkRange6 string `json:"networkrange6"`
  29. IsRelayed bool `json:"isrelayed"`
  30. IsRelay bool `json:"isrelay"`
  31. IsGw bool `json:"is_gw"`
  32. IsAutoRelay bool `json:"is_auto_relay"`
  33. AutoRelayedPeers map[string]string `json:"auto_relayed_peers"`
  34. AutoAssignGateway bool `json:"auto_assign_gw"`
  35. //AutoRelayedBy uuid.UUID `json:"auto_relayed_by"`
  36. RelayedBy string `json:"relayedby" bson:"relayedby" yaml:"relayedby"`
  37. RelayedNodes []string `json:"relaynodes" yaml:"relayedNodes"`
  38. IsEgressGateway bool `json:"isegressgateway"`
  39. IsIngressGateway bool `json:"isingressgateway"`
  40. EgressGatewayRanges []string `json:"egressgatewayranges"`
  41. EgressGatewayNatEnabled bool `json:"egressgatewaynatenabled"`
  42. EgressGatewayRangesWithMetric []EgressRangeMetric `json:"egressgatewayranges_with_metric"`
  43. DNSOn bool `json:"dnson"`
  44. IngressDns string `json:"ingressdns"`
  45. IngressPersistentKeepalive int32 `json:"ingresspersistentkeepalive"`
  46. IngressMTU int32 `json:"ingressmtu"`
  47. Server string `json:"server"`
  48. Connected bool `json:"connected"`
  49. PendingDelete bool `json:"pendingdelete"`
  50. Metadata string `json:"metadata"`
  51. // == PRO ==
  52. DefaultACL string `json:"defaultacl,omitempty" validate:"checkyesornoorunset"`
  53. IsFailOver bool `json:"is_fail_over"`
  54. FailOverPeers map[string]struct{} `json:"fail_over_peers" yaml:"fail_over_peers"`
  55. FailedOverBy uuid.UUID `json:"failed_over_by" yaml:"failed_over_by"`
  56. IsInternetGateway bool `json:"isinternetgateway" yaml:"isinternetgateway"`
  57. InetNodeReq InetNodeReq `json:"inet_node_req" yaml:"inet_node_req"`
  58. InternetGwID string `json:"internetgw_node_id" yaml:"internetgw_node_id"`
  59. AdditionalRagIps []string `json:"additional_rag_ips" yaml:"additional_rag_ips"`
  60. Tags map[TagID]struct{} `json:"tags" yaml:"tags"`
  61. IsStatic bool `json:"is_static"`
  62. IsUserNode bool `json:"is_user_node"`
  63. StaticNode ExtClient `json:"static_node"`
  64. Status NodeStatus `json:"status"`
  65. Location string `json:"location"`
  66. }
  67. // ApiNode.ConvertToServerNode - converts an api node to a server node
  68. func (a *ApiNode) ConvertToServerNode(currentNode *Node) *Node {
  69. convertedNode := Node{}
  70. convertedNode.Network = a.Network
  71. convertedNode.Server = a.Server
  72. convertedNode.Action = currentNode.Action
  73. convertedNode.Connected = a.Connected
  74. convertedNode.ID, _ = uuid.Parse(a.ID)
  75. convertedNode.HostID, _ = uuid.Parse(a.HostID)
  76. //convertedNode.IsRelay = a.IsRelay
  77. if a.RelayedBy != "" && !a.IsRelayed {
  78. a.IsRelayed = true
  79. }
  80. convertedNode.IsRelayed = a.IsRelayed
  81. convertedNode.RelayedBy = a.RelayedBy
  82. convertedNode.RelayedNodes = a.RelayedNodes
  83. convertedNode.PendingDelete = a.PendingDelete
  84. convertedNode.FailedOverBy = uuid.Nil
  85. convertedNode.FailOverPeers = make(map[string]struct{})
  86. convertedNode.IsFailOver = false
  87. //convertedNode.IsIngressGateway = a.IsIngressGateway
  88. convertedNode.IngressGatewayRange = currentNode.IngressGatewayRange
  89. convertedNode.IngressGatewayRange6 = currentNode.IngressGatewayRange6
  90. convertedNode.IngressDNS = a.IngressDns
  91. convertedNode.IngressPersistentKeepalive = a.IngressPersistentKeepalive
  92. convertedNode.IngressMTU = a.IngressMTU
  93. convertedNode.IsInternetGateway = a.IsInternetGateway
  94. convertedNode.InternetGwID = currentNode.InternetGwID
  95. convertedNode.InetNodeReq = currentNode.InetNodeReq
  96. convertedNode.RelayedNodes = a.RelayedNodes
  97. convertedNode.DefaultACL = a.DefaultACL
  98. convertedNode.OwnerID = currentNode.OwnerID
  99. _, networkRange, err := net.ParseCIDR(a.NetworkRange)
  100. if err == nil {
  101. convertedNode.NetworkRange = *networkRange
  102. }
  103. _, networkRange6, err := net.ParseCIDR(a.NetworkRange6)
  104. if err == nil {
  105. convertedNode.NetworkRange6 = *networkRange6
  106. }
  107. if len(a.LocalAddress) > 0 {
  108. _, localAddr, err := net.ParseCIDR(a.LocalAddress)
  109. if err == nil {
  110. convertedNode.LocalAddress = *localAddr
  111. }
  112. } else if !isEmptyAddr(currentNode.LocalAddress.String()) {
  113. convertedNode.LocalAddress = currentNode.LocalAddress
  114. }
  115. ip, addr, err := net.ParseCIDR(a.Address)
  116. if err == nil {
  117. convertedNode.Address = *addr
  118. convertedNode.Address.IP = ip
  119. }
  120. ip6, addr6, err := net.ParseCIDR(a.Address6)
  121. if err == nil {
  122. convertedNode.Address6 = *addr6
  123. convertedNode.Address6.IP = ip6
  124. }
  125. convertedNode.LastModified = time.Unix(a.LastModified, 0)
  126. convertedNode.LastCheckIn = time.Unix(a.LastCheckIn, 0)
  127. convertedNode.LastPeerUpdate = time.Unix(a.LastPeerUpdate, 0)
  128. convertedNode.ExpirationDateTime = time.Unix(a.ExpirationDateTime, 0)
  129. convertedNode.Metadata = a.Metadata
  130. for _, ip := range a.AdditionalRagIps {
  131. ragIp := net.ParseIP(ip)
  132. if ragIp == nil {
  133. slog.Error("error parsing additional rag ip", "error", err, "ip", ip)
  134. return nil
  135. }
  136. convertedNode.AdditionalRagIps = append(convertedNode.AdditionalRagIps, ragIp)
  137. }
  138. convertedNode.Tags = a.Tags
  139. convertedNode.IsGw = a.IsGw
  140. convertedNode.IsAutoRelay = a.IsAutoRelay
  141. if convertedNode.IsGw {
  142. convertedNode.IsRelay = true
  143. convertedNode.IsIngressGateway = true
  144. }
  145. convertedNode.AutoAssignGateway = a.AutoAssignGateway
  146. return &convertedNode
  147. }
  148. func (nm *Node) ConvertToStatusNode() *ApiNodeStatus {
  149. apiNode := ApiNodeStatus{}
  150. if nm.IsStatic {
  151. apiNode.ID = nm.StaticNode.ClientID
  152. } else {
  153. apiNode.ID = nm.ID.String()
  154. }
  155. apiNode.IsStatic = nm.IsStatic
  156. apiNode.IsUserNode = nm.IsUserNode
  157. apiNode.Status = nm.Status
  158. return &apiNode
  159. }
  160. // Node.ConvertToAPINode - converts a node to an API node
  161. func (nm *Node) ConvertToAPINode() *ApiNode {
  162. apiNode := ApiNode{}
  163. apiNode.ID = nm.ID.String()
  164. apiNode.HostID = nm.HostID.String()
  165. apiNode.Address = nm.Address.String()
  166. if isEmptyAddr(apiNode.Address) {
  167. apiNode.Address = ""
  168. }
  169. apiNode.Address6 = nm.Address6.String()
  170. if isEmptyAddr(apiNode.Address6) {
  171. apiNode.Address6 = ""
  172. }
  173. apiNode.LocalAddress = nm.LocalAddress.String()
  174. if isEmptyAddr(apiNode.LocalAddress) {
  175. apiNode.LocalAddress = ""
  176. }
  177. apiNode.LastModified = nm.LastModified.Unix()
  178. apiNode.LastCheckIn = nm.LastCheckIn.Unix()
  179. apiNode.LastPeerUpdate = nm.LastPeerUpdate.Unix()
  180. apiNode.ExpirationDateTime = nm.ExpirationDateTime.Unix()
  181. apiNode.Network = nm.Network
  182. apiNode.NetworkRange = nm.NetworkRange.String()
  183. if isEmptyAddr(apiNode.NetworkRange) {
  184. apiNode.NetworkRange = ""
  185. }
  186. apiNode.NetworkRange6 = nm.NetworkRange6.String()
  187. if isEmptyAddr(apiNode.NetworkRange6) {
  188. apiNode.NetworkRange6 = ""
  189. }
  190. apiNode.IsRelayed = nm.IsRelayed
  191. apiNode.IsRelay = nm.IsRelay
  192. apiNode.IsGw = nm.IsGw
  193. apiNode.RelayedBy = nm.RelayedBy
  194. apiNode.RelayedNodes = nm.RelayedNodes
  195. apiNode.IsAutoRelay = nm.IsAutoRelay
  196. //apiNode.AutoRelayedBy = nm.AutoRelayedBy
  197. apiNode.AutoRelayedPeers = nm.AutoRelayedPeers
  198. apiNode.AutoAssignGateway = nm.AutoAssignGateway
  199. apiNode.IsIngressGateway = nm.IsIngressGateway
  200. apiNode.IngressDns = nm.IngressDNS
  201. apiNode.IngressPersistentKeepalive = nm.IngressPersistentKeepalive
  202. apiNode.IngressMTU = nm.IngressMTU
  203. apiNode.Server = nm.Server
  204. apiNode.Connected = nm.Connected
  205. apiNode.PendingDelete = nm.PendingDelete
  206. apiNode.DefaultACL = nm.DefaultACL
  207. apiNode.IsInternetGateway = nm.IsInternetGateway
  208. apiNode.InternetGwID = nm.InternetGwID
  209. apiNode.InetNodeReq = nm.InetNodeReq
  210. apiNode.IsFailOver = false
  211. apiNode.FailOverPeers = nm.FailOverPeers
  212. apiNode.FailedOverBy = nm.FailedOverBy
  213. apiNode.Metadata = nm.Metadata
  214. apiNode.AdditionalRagIps = []string{}
  215. apiNode.Tags = nm.Tags
  216. for _, ip := range nm.AdditionalRagIps {
  217. apiNode.AdditionalRagIps = append(apiNode.AdditionalRagIps, ip.String())
  218. }
  219. apiNode.IsStatic = nm.IsStatic
  220. apiNode.IsUserNode = nm.IsUserNode
  221. apiNode.StaticNode = nm.StaticNode
  222. apiNode.Status = nm.Status
  223. return &apiNode
  224. }
  225. func isEmptyAddr(addr string) bool {
  226. return addr == "<nil>" || addr == ":0"
  227. }