api_node.go 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. package models
  2. import (
  3. "net"
  4. "time"
  5. "github.com/google/uuid"
  6. "golang.org/x/exp/slog"
  7. )
  8. // ApiNode is a stripped down Node DTO that exposes only required fields to external systems
  9. type ApiNode struct {
  10. ID string `json:"id,omitempty" validate:"required,min=5,id_unique"`
  11. HostID string `json:"hostid,omitempty" validate:"required,min=5,id_unique"`
  12. Address string `json:"address" validate:"omitempty,cidrv4"`
  13. Address6 string `json:"address6" validate:"omitempty,cidrv6"`
  14. LocalAddress string `json:"localaddress" validate:"omitempty,cidr"`
  15. AllowedIPs []string `json:"allowedips"`
  16. LastModified int64 `json:"lastmodified"`
  17. ExpirationDateTime int64 `json:"expdatetime"`
  18. LastCheckIn int64 `json:"lastcheckin"`
  19. LastPeerUpdate int64 `json:"lastpeerupdate"`
  20. Network string `json:"network"`
  21. NetworkRange string `json:"networkrange"`
  22. NetworkRange6 string `json:"networkrange6"`
  23. IsRelayed bool `json:"isrelayed"`
  24. IsRelay bool `json:"isrelay"`
  25. RelayedBy string `json:"relayedby" bson:"relayedby" yaml:"relayedby"`
  26. RelayedNodes []string `json:"relaynodes" yaml:"relayedNodes"`
  27. IsEgressGateway bool `json:"isegressgateway"`
  28. IsIngressGateway bool `json:"isingressgateway"`
  29. EgressGatewayRanges []string `json:"egressgatewayranges"`
  30. EgressGatewayNatEnabled bool `json:"egressgatewaynatenabled"`
  31. DNSOn bool `json:"dnson"`
  32. IngressDns string `json:"ingressdns"`
  33. Server string `json:"server"`
  34. Connected bool `json:"connected"`
  35. PendingDelete bool `json:"pendingdelete"`
  36. Metadata string `json:"metadata"`
  37. // == PRO ==
  38. DefaultACL string `json:"defaultacl,omitempty" validate:"checkyesornoorunset"`
  39. IsFailOver bool `json:"is_fail_over"`
  40. FailOverPeers map[string]struct{} `json:"fail_over_peers" yaml:"fail_over_peers"`
  41. FailedOverBy uuid.UUID `json:"failed_over_by" yaml:"failed_over_by"`
  42. IsInternetGateway bool `json:"isinternetgateway" yaml:"isinternetgateway"`
  43. InetNodeReq InetNodeReq `json:"inet_node_req" yaml:"inet_node_req"`
  44. InternetGwID string `json:"internetgw_node_id" yaml:"internetgw_node_id"`
  45. AdditionalRagIps []string `json:"additional_rag_ips" yaml:"additional_rag_ips"`
  46. }
  47. // ApiNode.ConvertToServerNode - converts an api node to a server node
  48. func (a *ApiNode) ConvertToServerNode(currentNode *Node) *Node {
  49. convertedNode := Node{}
  50. convertedNode.Network = a.Network
  51. convertedNode.Server = a.Server
  52. convertedNode.Action = currentNode.Action
  53. convertedNode.Connected = a.Connected
  54. convertedNode.ID, _ = uuid.Parse(a.ID)
  55. convertedNode.HostID, _ = uuid.Parse(a.HostID)
  56. convertedNode.IsRelay = a.IsRelay
  57. convertedNode.IsRelayed = a.IsRelayed
  58. convertedNode.RelayedBy = a.RelayedBy
  59. convertedNode.RelayedNodes = a.RelayedNodes
  60. convertedNode.PendingDelete = a.PendingDelete
  61. convertedNode.FailedOverBy = currentNode.FailedOverBy
  62. convertedNode.FailOverPeers = currentNode.FailOverPeers
  63. convertedNode.IsEgressGateway = a.IsEgressGateway
  64. convertedNode.IsIngressGateway = a.IsIngressGateway
  65. // prevents user from changing ranges, must delete and recreate
  66. convertedNode.EgressGatewayRanges = currentNode.EgressGatewayRanges
  67. convertedNode.IngressGatewayRange = currentNode.IngressGatewayRange
  68. convertedNode.IngressGatewayRange6 = currentNode.IngressGatewayRange6
  69. convertedNode.DNSOn = a.DNSOn
  70. convertedNode.IngressDNS = a.IngressDns
  71. convertedNode.IsInternetGateway = a.IsInternetGateway
  72. convertedNode.EgressGatewayRequest = currentNode.EgressGatewayRequest
  73. convertedNode.EgressGatewayNatEnabled = currentNode.EgressGatewayNatEnabled
  74. convertedNode.InternetGwID = currentNode.InternetGwID
  75. convertedNode.InetNodeReq = currentNode.InetNodeReq
  76. convertedNode.RelayedNodes = a.RelayedNodes
  77. convertedNode.DefaultACL = a.DefaultACL
  78. convertedNode.OwnerID = currentNode.OwnerID
  79. _, networkRange, err := net.ParseCIDR(a.NetworkRange)
  80. if err == nil {
  81. convertedNode.NetworkRange = *networkRange
  82. }
  83. _, networkRange6, err := net.ParseCIDR(a.NetworkRange6)
  84. if err == nil {
  85. convertedNode.NetworkRange6 = *networkRange6
  86. }
  87. if len(a.LocalAddress) > 0 {
  88. _, localAddr, err := net.ParseCIDR(a.LocalAddress)
  89. if err == nil {
  90. convertedNode.LocalAddress = *localAddr
  91. }
  92. } else if !isEmptyAddr(currentNode.LocalAddress.String()) {
  93. convertedNode.LocalAddress = currentNode.LocalAddress
  94. }
  95. ip, addr, err := net.ParseCIDR(a.Address)
  96. if err == nil {
  97. convertedNode.Address = *addr
  98. convertedNode.Address.IP = ip
  99. }
  100. ip6, addr6, err := net.ParseCIDR(a.Address6)
  101. if err == nil {
  102. convertedNode.Address6 = *addr6
  103. convertedNode.Address6.IP = ip6
  104. }
  105. convertedNode.LastModified = time.Unix(a.LastModified, 0)
  106. convertedNode.LastCheckIn = time.Unix(a.LastCheckIn, 0)
  107. convertedNode.LastPeerUpdate = time.Unix(a.LastPeerUpdate, 0)
  108. convertedNode.ExpirationDateTime = time.Unix(a.ExpirationDateTime, 0)
  109. convertedNode.Metadata = a.Metadata
  110. for _, ip := range a.AdditionalRagIps {
  111. ragIp := net.ParseIP(ip)
  112. if ragIp == nil {
  113. slog.Error("error parsing additional rag ip", "error", err, "ip", ip)
  114. return nil
  115. }
  116. convertedNode.AdditionalRagIps = append(convertedNode.AdditionalRagIps, ragIp)
  117. }
  118. return &convertedNode
  119. }
  120. // Node.ConvertToAPINode - converts a node to an API node
  121. func (nm *Node) ConvertToAPINode() *ApiNode {
  122. apiNode := ApiNode{}
  123. apiNode.ID = nm.ID.String()
  124. apiNode.HostID = nm.HostID.String()
  125. apiNode.Address = nm.Address.String()
  126. if isEmptyAddr(apiNode.Address) {
  127. apiNode.Address = ""
  128. }
  129. apiNode.Address6 = nm.Address6.String()
  130. if isEmptyAddr(apiNode.Address6) {
  131. apiNode.Address6 = ""
  132. }
  133. apiNode.LocalAddress = nm.LocalAddress.String()
  134. if isEmptyAddr(apiNode.LocalAddress) {
  135. apiNode.LocalAddress = ""
  136. }
  137. apiNode.LastModified = nm.LastModified.Unix()
  138. apiNode.LastCheckIn = nm.LastCheckIn.Unix()
  139. apiNode.LastPeerUpdate = nm.LastPeerUpdate.Unix()
  140. apiNode.ExpirationDateTime = nm.ExpirationDateTime.Unix()
  141. apiNode.Network = nm.Network
  142. apiNode.NetworkRange = nm.NetworkRange.String()
  143. if isEmptyAddr(apiNode.NetworkRange) {
  144. apiNode.NetworkRange = ""
  145. }
  146. apiNode.NetworkRange6 = nm.NetworkRange6.String()
  147. if isEmptyAddr(apiNode.NetworkRange6) {
  148. apiNode.NetworkRange6 = ""
  149. }
  150. apiNode.IsRelayed = nm.IsRelayed
  151. apiNode.IsRelay = nm.IsRelay
  152. apiNode.RelayedBy = nm.RelayedBy
  153. apiNode.RelayedNodes = nm.RelayedNodes
  154. apiNode.IsEgressGateway = nm.IsEgressGateway
  155. apiNode.IsIngressGateway = nm.IsIngressGateway
  156. apiNode.EgressGatewayRanges = nm.EgressGatewayRanges
  157. apiNode.EgressGatewayNatEnabled = nm.EgressGatewayNatEnabled
  158. apiNode.DNSOn = nm.DNSOn
  159. apiNode.IngressDns = nm.IngressDNS
  160. apiNode.Server = nm.Server
  161. apiNode.Connected = nm.Connected
  162. apiNode.PendingDelete = nm.PendingDelete
  163. apiNode.DefaultACL = nm.DefaultACL
  164. apiNode.IsInternetGateway = nm.IsInternetGateway
  165. apiNode.InternetGwID = nm.InternetGwID
  166. apiNode.InetNodeReq = nm.InetNodeReq
  167. apiNode.IsFailOver = nm.IsFailOver
  168. apiNode.FailOverPeers = nm.FailOverPeers
  169. apiNode.FailedOverBy = nm.FailedOverBy
  170. apiNode.Metadata = nm.Metadata
  171. apiNode.AdditionalRagIps = []string{}
  172. for _, ip := range nm.AdditionalRagIps {
  173. apiNode.AdditionalRagIps = append(apiNode.AdditionalRagIps, ip.String())
  174. }
  175. return &apiNode
  176. }
  177. func isEmptyAddr(addr string) bool {
  178. return addr == "<nil>" || addr == ":0"
  179. }