dns.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  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.MatchDomains) == 0 {
  41. return errors.New("atleast one match domain is required")
  42. }
  43. if !ns.MatchAll {
  44. for _, matchDomain := range ns.MatchDomains {
  45. if !logic.IsValidMatchDomain(matchDomain) {
  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 _, matchDomain := range nsI.MatchDomains {
  86. returnNsLi = append(returnNsLi, models.Nameserver{
  87. IPs: filteredIps,
  88. MatchDomain: matchDomain,
  89. })
  90. }
  91. continue
  92. }
  93. foundTag := false
  94. for tagI := range node.Tags {
  95. if _, ok := nsI.Tags[tagI.String()]; ok {
  96. for _, matchDomain := range nsI.MatchDomains {
  97. returnNsLi = append(returnNsLi, models.Nameserver{
  98. IPs: filteredIps,
  99. MatchDomain: matchDomain,
  100. })
  101. }
  102. foundTag = true
  103. }
  104. if foundTag {
  105. break
  106. }
  107. }
  108. if foundTag {
  109. continue
  110. }
  111. if _, ok := nsI.Nodes[node.ID.String()]; ok {
  112. for _, matchDomain := range nsI.MatchDomains {
  113. returnNsLi = append(returnNsLi, models.Nameserver{
  114. IPs: nsI.Servers,
  115. MatchDomain: matchDomain,
  116. })
  117. }
  118. }
  119. }
  120. if node.IsInternetGateway {
  121. globalNs := models.Nameserver{
  122. MatchDomain: ".",
  123. }
  124. for _, nsI := range logic.GlobalNsList {
  125. globalNs.IPs = append(globalNs.IPs, nsI.IPs...)
  126. }
  127. returnNsLi = append(returnNsLi, globalNs)
  128. }
  129. return
  130. }
  131. func GetNameserversForHost(h *models.Host) (returnNsLi []models.Nameserver) {
  132. if h.DNS != "yes" {
  133. return
  134. }
  135. for _, nodeID := range h.Nodes {
  136. node, err := logic.GetNodeByID(nodeID)
  137. if err != nil {
  138. continue
  139. }
  140. filters := make(map[string]bool)
  141. if node.Address.IP != nil {
  142. filters[node.Address.IP.String()] = true
  143. }
  144. if node.Address6.IP != nil {
  145. filters[node.Address6.IP.String()] = true
  146. }
  147. ns := &schema.Nameserver{
  148. NetworkID: node.Network,
  149. }
  150. nsLi, _ := ns.ListByNetwork(db.WithContext(context.TODO()))
  151. for _, nsI := range nsLi {
  152. if !nsI.Status {
  153. continue
  154. }
  155. filteredIps := logic.FilterOutIPs(nsI.Servers, filters)
  156. if len(filteredIps) == 0 {
  157. continue
  158. }
  159. _, all := nsI.Tags["*"]
  160. if all {
  161. for _, matchDomain := range nsI.MatchDomains {
  162. returnNsLi = append(returnNsLi, models.Nameserver{
  163. IPs: filteredIps,
  164. MatchDomain: matchDomain,
  165. })
  166. }
  167. continue
  168. }
  169. foundTag := false
  170. for tagI := range node.Tags {
  171. if _, ok := nsI.Tags[tagI.String()]; ok {
  172. for _, matchDomain := range nsI.MatchDomains {
  173. returnNsLi = append(returnNsLi, models.Nameserver{
  174. IPs: filteredIps,
  175. MatchDomain: matchDomain,
  176. })
  177. }
  178. foundTag = true
  179. }
  180. if foundTag {
  181. break
  182. }
  183. }
  184. if foundTag {
  185. continue
  186. }
  187. if _, ok := nsI.Nodes[node.ID.String()]; ok {
  188. for _, matchDomain := range nsI.MatchDomains {
  189. returnNsLi = append(returnNsLi, models.Nameserver{
  190. IPs: nsI.Servers,
  191. MatchDomain: matchDomain,
  192. })
  193. }
  194. }
  195. }
  196. if node.IsInternetGateway {
  197. globalNs := models.Nameserver{
  198. MatchDomain: ".",
  199. }
  200. for _, nsI := range logic.GlobalNsList {
  201. globalNs.IPs = append(globalNs.IPs, nsI.IPs...)
  202. }
  203. returnNsLi = append(returnNsLi, globalNs)
  204. }
  205. }
  206. return
  207. }