dns.go 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. package controller
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "net/http"
  6. "github.com/gorilla/mux"
  7. "github.com/gravitl/netmaker/database"
  8. "github.com/gravitl/netmaker/logger"
  9. "github.com/gravitl/netmaker/logic"
  10. "github.com/gravitl/netmaker/models"
  11. "github.com/gravitl/netmaker/mq"
  12. "github.com/gravitl/netmaker/servercfg"
  13. )
  14. func dnsHandlers(r *mux.Router) {
  15. r.HandleFunc("/api/dns", logic.SecurityCheck(true, http.HandlerFunc(getAllDNS))).Methods(http.MethodGet)
  16. r.HandleFunc("/api/dns/adm/{network}/nodes", logic.SecurityCheck(true, http.HandlerFunc(getNodeDNS))).Methods(http.MethodGet)
  17. r.HandleFunc("/api/dns/adm/{network}/custom", logic.SecurityCheck(true, http.HandlerFunc(getCustomDNS))).Methods(http.MethodGet)
  18. r.HandleFunc("/api/dns/adm/{network}", logic.SecurityCheck(true, http.HandlerFunc(getDNS))).Methods(http.MethodGet)
  19. r.HandleFunc("/api/dns/{network}", logic.SecurityCheck(true, http.HandlerFunc(createDNS))).Methods(http.MethodPost)
  20. r.HandleFunc("/api/dns/adm/pushdns", logic.SecurityCheck(true, http.HandlerFunc(pushDNS))).Methods(http.MethodPost)
  21. r.HandleFunc("/api/dns/{network}/{domain}", logic.SecurityCheck(true, http.HandlerFunc(deleteDNS))).Methods(http.MethodDelete)
  22. }
  23. // swagger:route GET /api/dns/adm/{network}/nodes dns getNodeDNS
  24. //
  25. // Gets node DNS entries associated with a network.
  26. //
  27. // Schemes: https
  28. //
  29. // Security:
  30. // oauth
  31. // Responses:
  32. // 200: dnsResponse
  33. func getNodeDNS(w http.ResponseWriter, r *http.Request) {
  34. w.Header().Set("Content-Type", "application/json")
  35. var dns []models.DNSEntry
  36. var params = mux.Vars(r)
  37. network := params["network"]
  38. dns, err := logic.GetNodeDNS(network)
  39. if err != nil {
  40. logger.Log(0, r.Header.Get("user"),
  41. fmt.Sprintf("failed to get node DNS entries for network [%s]: %v", network, err))
  42. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  43. return
  44. }
  45. w.WriteHeader(http.StatusOK)
  46. json.NewEncoder(w).Encode(dns)
  47. }
  48. // swagger:route GET /api/dns dns getAllDNS
  49. //
  50. // Gets all DNS entries.
  51. //
  52. // Schemes: https
  53. //
  54. // Security:
  55. // oauth
  56. //
  57. // Responses:
  58. // 200: dnsResponse
  59. func getAllDNS(w http.ResponseWriter, r *http.Request) {
  60. w.Header().Set("Content-Type", "application/json")
  61. dns, err := logic.GetAllDNS()
  62. if err != nil {
  63. logger.Log(0, r.Header.Get("user"), "failed to get all DNS entries: ", err.Error())
  64. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  65. return
  66. }
  67. logic.SortDNSEntrys(dns[:])
  68. w.WriteHeader(http.StatusOK)
  69. json.NewEncoder(w).Encode(dns)
  70. }
  71. // swagger:route GET /api/dns/adm/{network}/custom dns getCustomDNS
  72. //
  73. // Gets custom DNS entries associated with a network.
  74. //
  75. // Schemes: https
  76. //
  77. // Security:
  78. // oauth
  79. //
  80. // Responses:
  81. // 200: dnsResponse
  82. func getCustomDNS(w http.ResponseWriter, r *http.Request) {
  83. w.Header().Set("Content-Type", "application/json")
  84. var dns []models.DNSEntry
  85. var params = mux.Vars(r)
  86. network := params["network"]
  87. dns, err := logic.GetCustomDNS(network)
  88. if err != nil {
  89. logger.Log(0, r.Header.Get("user"),
  90. fmt.Sprintf("failed to get custom DNS entries for network [%s]: %v", network, err.Error()))
  91. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  92. return
  93. }
  94. w.WriteHeader(http.StatusOK)
  95. json.NewEncoder(w).Encode(dns)
  96. }
  97. // swagger:route GET /api/dns/adm/{network} dns getDNS
  98. //
  99. // Gets all DNS entries associated with the network.
  100. //
  101. // Schemes: https
  102. //
  103. // Security:
  104. // oauth
  105. //
  106. // Responses:
  107. // 200: dnsResponse
  108. func getDNS(w http.ResponseWriter, r *http.Request) {
  109. w.Header().Set("Content-Type", "application/json")
  110. var dns []models.DNSEntry
  111. var params = mux.Vars(r)
  112. network := params["network"]
  113. dns, err := logic.GetDNS(network)
  114. if err != nil {
  115. logger.Log(0, r.Header.Get("user"),
  116. fmt.Sprintf("failed to get all DNS entries for network [%s]: %v", network, err.Error()))
  117. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  118. return
  119. }
  120. w.WriteHeader(http.StatusOK)
  121. json.NewEncoder(w).Encode(dns)
  122. }
  123. // swagger:route POST /api/dns/{network} dns createDNS
  124. //
  125. // Create a DNS entry.
  126. //
  127. // Schemes: https
  128. //
  129. // Security:
  130. // oauth
  131. //
  132. // Responses:
  133. // 200: dnsResponse
  134. func createDNS(w http.ResponseWriter, r *http.Request) {
  135. w.Header().Set("Content-Type", "application/json")
  136. var entry models.DNSEntry
  137. var params = mux.Vars(r)
  138. _ = json.NewDecoder(r.Body).Decode(&entry)
  139. entry.Network = params["network"]
  140. err := logic.ValidateDNSCreate(entry)
  141. if err != nil {
  142. logger.Log(0, r.Header.Get("user"),
  143. fmt.Sprintf("invalid DNS entry %+v: %v", entry, err))
  144. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  145. return
  146. }
  147. entry, err = logic.CreateDNS(entry)
  148. if err != nil {
  149. logger.Log(0, r.Header.Get("user"),
  150. fmt.Sprintf("Failed to create DNS entry %+v: %v", entry, err))
  151. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  152. return
  153. }
  154. err = logic.SetDNS()
  155. if err != nil {
  156. logger.Log(0, r.Header.Get("user"),
  157. fmt.Sprintf("Failed to set DNS entries on file: %v", err))
  158. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  159. return
  160. }
  161. logger.Log(1, "new DNS record added:", entry.Name)
  162. if servercfg.IsMessageQueueBackend() {
  163. go func() {
  164. if err = mq.PublishPeerUpdate(); err != nil {
  165. logger.Log(0, "failed to publish peer update after ACL update on", entry.Network)
  166. }
  167. if err := mq.PublishCustomDNS(&entry); err != nil {
  168. logger.Log(0, "error publishing custom dns", err.Error())
  169. }
  170. }()
  171. }
  172. logger.Log(2, r.Header.Get("user"),
  173. fmt.Sprintf("DNS entry is set: %+v", entry))
  174. w.WriteHeader(http.StatusOK)
  175. json.NewEncoder(w).Encode(entry)
  176. }
  177. // swagger:route DELETE /api/dns/{network}/{domain} dns deleteDNS
  178. //
  179. // Delete a DNS entry.
  180. //
  181. // Schemes: https
  182. //
  183. // Security:
  184. // oauth
  185. //
  186. // Responses:
  187. // 200: stringJSONResponse
  188. // *: stringJSONResponse
  189. func deleteDNS(w http.ResponseWriter, r *http.Request) {
  190. // Set header
  191. w.Header().Set("Content-Type", "application/json")
  192. // get params
  193. var params = mux.Vars(r)
  194. entrytext := params["domain"] + "." + params["network"]
  195. err := logic.DeleteDNS(params["domain"], params["network"])
  196. if err != nil {
  197. logger.Log(0, "failed to delete dns entry: ", entrytext)
  198. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  199. return
  200. }
  201. logger.Log(1, "deleted dns entry: ", entrytext)
  202. err = logic.SetDNS()
  203. if err != nil {
  204. logger.Log(0, r.Header.Get("user"),
  205. fmt.Sprintf("Failed to set DNS entries on file: %v", err))
  206. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  207. return
  208. }
  209. json.NewEncoder(w).Encode(entrytext + " deleted.")
  210. go func() {
  211. dns := models.DNSUpdate{
  212. Action: models.DNSDeleteByName,
  213. Name: entrytext,
  214. }
  215. if err := mq.PublishDNSUpdate(params["network"], dns); err != nil {
  216. logger.Log(0, "failed to publish dns update", err.Error())
  217. }
  218. }()
  219. }
  220. // GetDNSEntry - gets a DNS entry
  221. func GetDNSEntry(domain string, network string) (models.DNSEntry, error) {
  222. var entry models.DNSEntry
  223. key, err := logic.GetRecordKey(domain, network)
  224. if err != nil {
  225. return entry, err
  226. }
  227. record, err := database.FetchRecord(database.DNS_TABLE_NAME, key)
  228. if err != nil {
  229. return entry, err
  230. }
  231. err = json.Unmarshal([]byte(record), &entry)
  232. return entry, err
  233. }
  234. // swagger:route POST /api/dns/adm/pushdns dns pushDNS
  235. //
  236. // Push DNS entries to nameserver.
  237. //
  238. // Schemes: https
  239. //
  240. // Security:
  241. // oauth
  242. //
  243. // Responses:
  244. // 200: dnsResponse
  245. // *: dnsResponse
  246. func pushDNS(w http.ResponseWriter, r *http.Request) {
  247. // Set header
  248. w.Header().Set("Content-Type", "application/json")
  249. err := logic.SetDNS()
  250. if err != nil {
  251. logger.Log(0, r.Header.Get("user"),
  252. fmt.Sprintf("Failed to set DNS entries on file: %v", err))
  253. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  254. return
  255. }
  256. logger.Log(1, r.Header.Get("user"), "pushed DNS updates to nameserver")
  257. json.NewEncoder(w).Encode("DNS Pushed to CoreDNS")
  258. }