dns.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. package logic
  2. import (
  3. "context"
  4. "errors"
  5. "net"
  6. "github.com/gravitl/netmaker/db"
  7. "github.com/gravitl/netmaker/logic"
  8. "github.com/gravitl/netmaker/models"
  9. "github.com/gravitl/netmaker/schema"
  10. )
  11. func ValidateNameserverReq(ns schema.Nameserver) error {
  12. if ns.Name == "" {
  13. return errors.New("name is required")
  14. }
  15. if ns.NetworkID == "" {
  16. return errors.New("network is required")
  17. }
  18. if len(ns.Servers) == 0 {
  19. return errors.New("atleast one nameserver should be specified")
  20. }
  21. network, err := logic.GetNetwork(ns.NetworkID)
  22. if err != nil {
  23. return errors.New("invalid network id")
  24. }
  25. _, cidr, err4 := net.ParseCIDR(network.AddressRange)
  26. _, cidr6, err6 := net.ParseCIDR(network.AddressRange6)
  27. for _, nsIPStr := range ns.Servers {
  28. nsIP := net.ParseIP(nsIPStr)
  29. if nsIP == nil {
  30. return errors.New("invalid nameserver " + nsIPStr)
  31. }
  32. if err4 == nil && nsIP.To4() != nil {
  33. if cidr.Contains(nsIP) {
  34. return errors.New("cannot use netmaker IP as nameserver")
  35. }
  36. } else if err6 == nil && cidr6.Contains(nsIP) {
  37. return errors.New("cannot use netmaker IP as nameserver")
  38. }
  39. }
  40. if !ns.MatchAll && len(ns.Domains) == 0 {
  41. return errors.New("atleast one match domain is required")
  42. }
  43. if !ns.MatchAll {
  44. for _, domain := range ns.Domains {
  45. if !logic.IsValidMatchDomain(domain.Domain) {
  46. return errors.New("invalid match domain")
  47. }
  48. }
  49. }
  50. if len(ns.Tags) > 0 {
  51. for tagI := range ns.Tags {
  52. if tagI == "*" {
  53. continue
  54. }
  55. _, err := GetTag(models.TagID(tagI))
  56. if err != nil {
  57. return errors.New("invalid tag")
  58. }
  59. }
  60. }
  61. return nil
  62. }
  63. func GetNameserversForNode(node *models.Node) (returnNsLi []models.Nameserver) {
  64. filters := make(map[string]bool)
  65. if node.Address.IP != nil {
  66. filters[node.Address.IP.String()] = true
  67. }
  68. if node.Address6.IP != nil {
  69. filters[node.Address6.IP.String()] = true
  70. }
  71. ns := &schema.Nameserver{
  72. NetworkID: node.Network,
  73. }
  74. nsLi, _ := ns.ListByNetwork(db.WithContext(context.TODO()))
  75. for _, nsI := range nsLi {
  76. if !nsI.Status {
  77. continue
  78. }
  79. filteredIps := logic.FilterOutIPs(nsI.Servers, filters)
  80. if len(filteredIps) == 0 {
  81. continue
  82. }
  83. _, all := nsI.Tags["*"]
  84. if all {
  85. for _, domain := range nsI.Domains {
  86. returnNsLi = append(returnNsLi, models.Nameserver{
  87. IPs: filteredIps,
  88. MatchDomain: domain.Domain,
  89. IsSearchDomain: domain.IsSearchDomain,
  90. })
  91. }
  92. continue
  93. }
  94. foundTag := false
  95. for tagI := range node.Tags {
  96. if _, ok := nsI.Tags[tagI.String()]; ok {
  97. for _, domain := range nsI.Domains {
  98. returnNsLi = append(returnNsLi, models.Nameserver{
  99. IPs: filteredIps,
  100. MatchDomain: domain.Domain,
  101. IsSearchDomain: domain.IsSearchDomain,
  102. })
  103. }
  104. foundTag = true
  105. }
  106. if foundTag {
  107. break
  108. }
  109. }
  110. if foundTag {
  111. continue
  112. }
  113. if _, ok := nsI.Nodes[node.ID.String()]; ok {
  114. for _, domain := range nsI.Domains {
  115. returnNsLi = append(returnNsLi, models.Nameserver{
  116. IPs: nsI.Servers,
  117. MatchDomain: domain.Domain,
  118. IsSearchDomain: domain.IsSearchDomain,
  119. })
  120. }
  121. }
  122. }
  123. if node.IsInternetGateway {
  124. globalNs := models.Nameserver{
  125. MatchDomain: ".",
  126. }
  127. for _, nsI := range logic.GlobalNsList {
  128. globalNs.IPs = append(globalNs.IPs, nsI.IPs...)
  129. }
  130. returnNsLi = append(returnNsLi, globalNs)
  131. }
  132. return
  133. }
  134. func GetNameserversForHost(h *models.Host) (returnNsLi []models.Nameserver) {
  135. if h.DNS != "yes" {
  136. return
  137. }
  138. for _, nodeID := range h.Nodes {
  139. node, err := logic.GetNodeByID(nodeID)
  140. if err != nil {
  141. continue
  142. }
  143. filters := make(map[string]bool)
  144. if node.Address.IP != nil {
  145. filters[node.Address.IP.String()] = true
  146. }
  147. if node.Address6.IP != nil {
  148. filters[node.Address6.IP.String()] = true
  149. }
  150. ns := &schema.Nameserver{
  151. NetworkID: node.Network,
  152. }
  153. nsLi, _ := ns.ListByNetwork(db.WithContext(context.TODO()))
  154. for _, nsI := range nsLi {
  155. if !nsI.Status {
  156. continue
  157. }
  158. filteredIps := logic.FilterOutIPs(nsI.Servers, filters)
  159. if len(filteredIps) == 0 {
  160. continue
  161. }
  162. _, all := nsI.Tags["*"]
  163. if all {
  164. for _, domain := range nsI.Domains {
  165. returnNsLi = append(returnNsLi, models.Nameserver{
  166. IPs: filteredIps,
  167. MatchDomain: domain.Domain,
  168. IsSearchDomain: domain.IsSearchDomain,
  169. })
  170. }
  171. continue
  172. }
  173. foundTag := false
  174. for tagI := range node.Tags {
  175. if _, ok := nsI.Tags[tagI.String()]; ok {
  176. for _, domain := range nsI.Domains {
  177. returnNsLi = append(returnNsLi, models.Nameserver{
  178. IPs: filteredIps,
  179. MatchDomain: domain.Domain,
  180. IsSearchDomain: domain.IsSearchDomain,
  181. })
  182. }
  183. foundTag = true
  184. }
  185. if foundTag {
  186. break
  187. }
  188. }
  189. if foundTag {
  190. continue
  191. }
  192. if _, ok := nsI.Nodes[node.ID.String()]; ok {
  193. for _, domain := range nsI.Domains {
  194. returnNsLi = append(returnNsLi, models.Nameserver{
  195. IPs: nsI.Servers,
  196. MatchDomain: domain.Domain,
  197. IsSearchDomain: domain.IsSearchDomain,
  198. })
  199. }
  200. }
  201. }
  202. if node.IsInternetGateway {
  203. globalNs := models.Nameserver{
  204. MatchDomain: ".",
  205. }
  206. for _, nsI := range logic.GlobalNsList {
  207. globalNs.IPs = append(globalNs.IPs, nsI.IPs...)
  208. }
  209. returnNsLi = append(returnNsLi, globalNs)
  210. }
  211. }
  212. return
  213. }