dns_test.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. package controller
  2. import (
  3. "net"
  4. "os"
  5. "testing"
  6. "github.com/google/uuid"
  7. "github.com/stretchr/testify/assert"
  8. "github.com/txn2/txeh"
  9. "golang.zx2c4.com/wireguard/wgctrl/wgtypes"
  10. "github.com/gravitl/netmaker/functions"
  11. "github.com/gravitl/netmaker/logic"
  12. "github.com/gravitl/netmaker/models"
  13. )
  14. var dnsHost models.Host
  15. func TestGetAllDNS(t *testing.T) {
  16. deleteAllDNS(t)
  17. deleteAllNetworks()
  18. createNet()
  19. createHost()
  20. t.Run("NoEntries", func(t *testing.T) {
  21. entries, err := logic.GetAllDNS()
  22. assert.Nil(t, err)
  23. assert.Equal(t, []models.DNSEntry(nil), entries)
  24. })
  25. t.Run("OneEntry", func(t *testing.T) {
  26. entry := models.DNSEntry{
  27. Address: "10.0.0.3", Name: "newhost", Network: "skynet",
  28. }
  29. _, err := logic.CreateDNS(entry)
  30. assert.Nil(t, err)
  31. entries, err := logic.GetAllDNS()
  32. assert.Nil(t, err)
  33. assert.Equal(t, 1, len(entries))
  34. })
  35. t.Run("MultipleEntry", func(t *testing.T) {
  36. entry := models.DNSEntry{Address: "10.0.0.7", Name: "anotherhost", Network: "skynet"}
  37. _, err := logic.CreateDNS(entry)
  38. assert.Nil(t, err)
  39. entries, err := logic.GetAllDNS()
  40. assert.Nil(t, err)
  41. assert.Equal(t, 2, len(entries))
  42. })
  43. }
  44. func TestGetNodeDNS(t *testing.T) {
  45. deleteAllDNS(t)
  46. deleteAllNetworks()
  47. createNet()
  48. createHost()
  49. err := functions.SetDNSDir()
  50. assert.Nil(t, err)
  51. t.Run("NoNodes", func(t *testing.T) {
  52. dns, _ := logic.GetNodeDNS("skynet")
  53. assert.Equal(t, []models.DNSEntry(nil), dns)
  54. })
  55. t.Run("NodeExists", func(t *testing.T) {
  56. createHost()
  57. _, ipnet, _ := net.ParseCIDR("10.0.0.1/32")
  58. tmpCNode := models.CommonNode{
  59. ID: uuid.New(),
  60. Network: "skynet",
  61. Address: *ipnet,
  62. }
  63. createnode := models.Node{
  64. CommonNode: tmpCNode,
  65. }
  66. err := logic.AssociateNodeToHost(&createnode, &dnsHost)
  67. assert.Nil(t, err)
  68. dns, err := logic.GetNodeDNS("skynet")
  69. assert.Nil(t, err)
  70. assert.Equal(t, "10.0.0.1", dns[0].Address)
  71. })
  72. t.Run("MultipleNodes", func(t *testing.T) {
  73. _, ipnet, _ := net.ParseCIDR("10.100.100.3/32")
  74. tmpCNode := models.CommonNode{
  75. ID: uuid.New(),
  76. Network: "skynet",
  77. Address: *ipnet,
  78. }
  79. createnode := models.Node{
  80. CommonNode: tmpCNode,
  81. }
  82. err := logic.AssociateNodeToHost(&createnode, &dnsHost)
  83. assert.Nil(t, err)
  84. dns, err := logic.GetNodeDNS("skynet")
  85. assert.Nil(t, err)
  86. assert.Equal(t, 2, len(dns))
  87. })
  88. }
  89. func TestGetCustomDNS(t *testing.T) {
  90. deleteAllDNS(t)
  91. deleteAllNetworks()
  92. t.Run("NoNetworks", func(t *testing.T) {
  93. dns, err := logic.GetCustomDNS("skynet")
  94. assert.EqualError(t, err, "could not find any records")
  95. assert.Equal(t, []models.DNSEntry(nil), dns)
  96. })
  97. t.Run("NoNodes", func(t *testing.T) {
  98. createNet()
  99. dns, err := logic.GetCustomDNS("skynet")
  100. assert.EqualError(t, err, "could not find any records")
  101. assert.Equal(t, []models.DNSEntry(nil), dns)
  102. })
  103. t.Run("NodeExists", func(t *testing.T) {
  104. createTestNode()
  105. dns, err := logic.GetCustomDNS("skynet")
  106. assert.EqualError(t, err, "could not find any records")
  107. assert.Equal(t, 0, len(dns))
  108. })
  109. t.Run("EntryExist", func(t *testing.T) {
  110. entry := models.DNSEntry{Address: "10.0.0.3", Name: "custom1", Network: "skynet"}
  111. _, err := logic.CreateDNS(entry)
  112. assert.Nil(t, err)
  113. dns, err := logic.GetCustomDNS("skynet")
  114. assert.Nil(t, err)
  115. assert.Equal(t, 1, len(dns))
  116. })
  117. t.Run("MultipleEntries", func(t *testing.T) {
  118. entry := models.DNSEntry{Address: "10.0.0.4", Name: "host4", Network: "skynet"}
  119. _, err := logic.CreateDNS(entry)
  120. assert.Nil(t, err)
  121. dns, err := logic.GetCustomDNS("skynet")
  122. assert.Nil(t, err)
  123. assert.Equal(t, 2, len(dns))
  124. })
  125. }
  126. func TestGetDNSEntryNum(t *testing.T) {
  127. deleteAllDNS(t)
  128. deleteAllNetworks()
  129. createNet()
  130. t.Run("NoNodes", func(t *testing.T) {
  131. num, err := logic.GetDNSEntryNum("myhost", "skynet")
  132. assert.Nil(t, err)
  133. assert.Equal(t, 0, num)
  134. })
  135. t.Run("NodeExists", func(t *testing.T) {
  136. entry := models.DNSEntry{Address: "10.0.0.2", Name: "newhost", Network: "skynet"}
  137. _, err := logic.CreateDNS(entry)
  138. assert.Nil(t, err)
  139. num, err := logic.GetDNSEntryNum("newhost", "skynet")
  140. assert.Nil(t, err)
  141. assert.Equal(t, 1, num)
  142. })
  143. }
  144. func TestGetDNS(t *testing.T) {
  145. deleteAllDNS(t)
  146. deleteAllNetworks()
  147. createNet()
  148. t.Run("NoEntries", func(t *testing.T) {
  149. dns, err := logic.GetDNS("skynet")
  150. assert.Nil(t, err)
  151. assert.Nil(t, dns)
  152. })
  153. t.Run("CustomDNSExists", func(t *testing.T) {
  154. entry := models.DNSEntry{Address: "10.0.0.2", Name: "newhost", Network: "skynet"}
  155. _, err := logic.CreateDNS(entry)
  156. assert.Nil(t, err)
  157. dns, err := logic.GetDNS("skynet")
  158. t.Log(dns)
  159. assert.Nil(t, err)
  160. assert.NotNil(t, dns)
  161. assert.Equal(t, "skynet", dns[0].Network)
  162. assert.Equal(t, 1, len(dns))
  163. })
  164. t.Run("NodeExists", func(t *testing.T) {
  165. deleteAllDNS(t)
  166. createTestNode()
  167. dns, err := logic.GetDNS("skynet")
  168. assert.Nil(t, err)
  169. assert.NotNil(t, dns)
  170. assert.Equal(t, "skynet", dns[0].Network)
  171. assert.Equal(t, 1, len(dns))
  172. })
  173. t.Run("NodeAndCustomDNS", func(t *testing.T) {
  174. entry := models.DNSEntry{Address: "10.0.0.2", Name: "newhost", Network: "skynet"}
  175. _, err := logic.CreateDNS(entry)
  176. assert.Nil(t, err)
  177. dns, err := logic.GetDNS("skynet")
  178. t.Log(dns)
  179. assert.Nil(t, err)
  180. assert.NotNil(t, dns)
  181. assert.Equal(t, "skynet", dns[0].Network)
  182. assert.Equal(t, "skynet", dns[1].Network)
  183. assert.Equal(t, 2, len(dns))
  184. })
  185. }
  186. func TestCreateDNS(t *testing.T) {
  187. deleteAllDNS(t)
  188. deleteAllNetworks()
  189. createNet()
  190. entry := models.DNSEntry{Address: "10.0.0.2", Name: "newhost", Network: "skynet"}
  191. dns, err := logic.CreateDNS(entry)
  192. assert.Nil(t, err)
  193. assert.Equal(t, "newhost", dns.Name)
  194. }
  195. func TestSetDNS(t *testing.T) {
  196. deleteAllDNS(t)
  197. deleteAllNetworks()
  198. etc, err := txeh.NewHosts(&txeh.HostsConfig{})
  199. assert.Nil(t, err)
  200. err = functions.SetDNSDir()
  201. assert.Nil(t, err)
  202. t.Run("NoNetworks", func(t *testing.T) {
  203. err := logic.SetDNS()
  204. assert.Nil(t, err)
  205. info, err := txeh.NewHosts(&txeh.HostsConfig{
  206. ReadFilePath: "./config/dnsconfig/netmaker.hosts",
  207. })
  208. assert.Nil(t, err)
  209. assert.Equal(t, etc.RenderHostsFile(), info.RenderHostsFile())
  210. })
  211. t.Run("NoEntries", func(t *testing.T) {
  212. createNet()
  213. err := logic.SetDNS()
  214. assert.Nil(t, err)
  215. info, err := txeh.NewHosts(&txeh.HostsConfig{
  216. ReadFilePath: "./config/dnsconfig/netmaker.hosts",
  217. })
  218. assert.Nil(t, err)
  219. assert.Equal(t, etc.RenderHostsFile(), info.RenderHostsFile())
  220. })
  221. t.Run("NodeExists", func(t *testing.T) {
  222. createTestNode()
  223. err := logic.SetDNS()
  224. assert.Nil(t, err)
  225. info, err := os.Stat("./config/dnsconfig/netmaker.hosts")
  226. assert.Nil(t, err)
  227. assert.False(t, info.IsDir())
  228. content, err := os.ReadFile("./config/dnsconfig/netmaker.hosts")
  229. assert.Nil(t, err)
  230. assert.Contains(t, string(content), "linuxhost")
  231. })
  232. t.Run("EntryExists", func(t *testing.T) {
  233. entry := models.DNSEntry{Address: "10.0.0.3", Name: "newhost", Network: "skynet"}
  234. _, err := logic.CreateDNS(entry)
  235. assert.Nil(t, err)
  236. err = logic.SetDNS()
  237. assert.Nil(t, err)
  238. info, err := os.Stat("./config/dnsconfig/netmaker.hosts")
  239. assert.Nil(t, err)
  240. assert.False(t, info.IsDir())
  241. content, err := os.ReadFile("./config/dnsconfig/netmaker.hosts")
  242. assert.Nil(t, err)
  243. assert.Contains(t, string(content), "newhost")
  244. })
  245. }
  246. func TestGetDNSEntry(t *testing.T) {
  247. deleteAllDNS(t)
  248. deleteAllNetworks()
  249. createNet()
  250. createTestNode()
  251. entry := models.DNSEntry{Address: "10.0.0.2", Name: "newhost", Network: "skynet"}
  252. _, _ = logic.CreateDNS(entry)
  253. t.Run("wrong net", func(t *testing.T) {
  254. entry, err := GetDNSEntry("newhost", "w286 Toronto Street South, Uxbridge, ONirecat")
  255. assert.EqualError(t, err, "no result found")
  256. assert.Equal(t, models.DNSEntry{}, entry)
  257. })
  258. t.Run("wrong host", func(t *testing.T) {
  259. entry, err := GetDNSEntry("badhost", "skynet")
  260. assert.EqualError(t, err, "no result found")
  261. assert.Equal(t, models.DNSEntry{}, entry)
  262. })
  263. t.Run("good host", func(t *testing.T) {
  264. entry, err := GetDNSEntry("newhost", "skynet")
  265. assert.Nil(t, err)
  266. assert.Equal(t, "newhost", entry.Name)
  267. })
  268. t.Run("node", func(t *testing.T) {
  269. entry, err := GetDNSEntry("testnode", "skynet")
  270. assert.EqualError(t, err, "no result found")
  271. assert.Equal(t, models.DNSEntry{}, entry)
  272. })
  273. }
  274. func TestDeleteDNS(t *testing.T) {
  275. deleteAllDNS(t)
  276. deleteAllNetworks()
  277. createNet()
  278. entry := models.DNSEntry{Address: "10.0.0.2", Name: "newhost", Network: "skynet"}
  279. _, _ = logic.CreateDNS(entry)
  280. t.Run("EntryExists", func(t *testing.T) {
  281. err := logic.DeleteDNS("newhost", "skynet")
  282. assert.Nil(t, err)
  283. })
  284. t.Run("NodeExists", func(t *testing.T) {
  285. err := logic.DeleteDNS("myhost", "skynet")
  286. assert.Nil(t, err)
  287. })
  288. t.Run("NoEntries", func(t *testing.T) {
  289. err := logic.DeleteDNS("myhost", "skynet")
  290. assert.Nil(t, err)
  291. })
  292. }
  293. func TestValidateDNSUpdate(t *testing.T) {
  294. deleteAllDNS(t)
  295. deleteAllNetworks()
  296. createNet()
  297. entry := models.DNSEntry{Address: "10.0.0.2", Name: "myhost", Network: "skynet"}
  298. t.Run("BadNetwork", func(t *testing.T) {
  299. change := models.DNSEntry{Address: "10.0.0.2", Name: "myhost", Network: "badnet"}
  300. err := logic.ValidateDNSUpdate(change, entry)
  301. assert.NotNil(t, err)
  302. assert.Contains(t, err.Error(), "Field validation for 'Network' failed on the 'network_exists' tag")
  303. })
  304. t.Run("EmptyNetwork", func(t *testing.T) {
  305. // this can't actually happen as change.Network is populated if is blank
  306. change := models.DNSEntry{Address: "10.0.0.2", Name: "myhost"}
  307. err := logic.ValidateDNSUpdate(change, entry)
  308. assert.NotNil(t, err)
  309. assert.Contains(t, err.Error(), "Field validation for 'Network' failed on the 'network_exists' tag")
  310. })
  311. // t.Run("EmptyAddress", func(t *testing.T) {
  312. // //this can't actually happen as change.Address is populated if is blank
  313. // change := models.DNSEntry{"", "", "myhost", "skynet"}
  314. // err := logic.ValidateDNSUpdate(change, entry)
  315. // assert.NotNil(t, err)
  316. // assert.Contains(t, err.Error(), "Field validation for 'Address' failed on the 'required' tag")
  317. // })
  318. t.Run("BadAddress", func(t *testing.T) {
  319. change := models.DNSEntry{Address: "10.0.256.1", Name: "myhost", Network: "skynet"}
  320. err := logic.ValidateDNSUpdate(change, entry)
  321. assert.NotNil(t, err)
  322. assert.Contains(t, err.Error(), "Field validation for 'Address' failed on the 'ip' tag")
  323. })
  324. t.Run("EmptyName", func(t *testing.T) {
  325. // this can't actually happen as change.Name is populated if is blank
  326. change := models.DNSEntry{Address: "10.0.0.2", Network: "skynet"}
  327. err := logic.ValidateDNSUpdate(change, entry)
  328. assert.NotNil(t, err)
  329. assert.Contains(t, err.Error(), "Field validation for 'Name' failed on the 'required' tag")
  330. })
  331. t.Run("NameTooLong", func(t *testing.T) {
  332. name := ""
  333. for i := 1; i < 194; i++ {
  334. name = name + "a"
  335. }
  336. change := models.DNSEntry{Address: "10.0.0.2", Name: name, Network: "skynet"}
  337. err := logic.ValidateDNSUpdate(change, entry)
  338. assert.NotNil(t, err)
  339. assert.Contains(t, err.Error(), "Field validation for 'Name' failed on the 'max' tag")
  340. })
  341. t.Run("NameUnique", func(t *testing.T) {
  342. change := models.DNSEntry{Address: "10.0.0.2", Name: "myhost", Network: "wirecat"}
  343. _, _ = logic.CreateDNS(entry)
  344. _, _ = logic.CreateDNS(change)
  345. err := logic.ValidateDNSUpdate(change, entry)
  346. assert.NotNil(t, err)
  347. assert.Contains(t, err.Error(), "Field validation for 'Name' failed on the 'name_unique' tag")
  348. // cleanup
  349. err = logic.DeleteDNS("myhost", "wirecat")
  350. assert.Nil(t, err)
  351. })
  352. }
  353. func TestValidateDNSCreate(t *testing.T) {
  354. _ = logic.DeleteDNS("mynode", "skynet")
  355. t.Run("NoNetwork", func(t *testing.T) {
  356. entry := models.DNSEntry{Address: "10.0.0.2", Name: "myhost", Network: "badnet"}
  357. err := logic.ValidateDNSCreate(entry)
  358. assert.NotNil(t, err)
  359. assert.Contains(t, err.Error(), "Field validation for 'Network' failed on the 'network_exists' tag")
  360. })
  361. // t.Run("EmptyAddress", func(t *testing.T) {
  362. // entry := models.DNSEntry{"", "", "myhost", "skynet"}
  363. // err := logic.ValidateDNSCreate(entry)
  364. // assert.NotNil(t, err)
  365. // assert.Contains(t, err.Error(), "Field validation for 'Address' failed on the 'required' tag")
  366. // })
  367. t.Run("BadAddress", func(t *testing.T) {
  368. entry := models.DNSEntry{Address: "10.0.256.1", Name: "myhost", Network: "skynet"}
  369. err := logic.ValidateDNSCreate(entry)
  370. assert.NotNil(t, err)
  371. assert.Contains(t, err.Error(), "Field validation for 'Address' failed on the 'ip' tag")
  372. })
  373. t.Run("EmptyName", func(t *testing.T) {
  374. entry := models.DNSEntry{Address: "10.0.0.2", Network: "skynet"}
  375. err := logic.ValidateDNSCreate(entry)
  376. assert.NotNil(t, err)
  377. assert.Contains(t, err.Error(), "invalid input")
  378. })
  379. t.Run("NameTooLong", func(t *testing.T) {
  380. name := ""
  381. for i := 1; i < 194; i++ {
  382. name = name + "a"
  383. }
  384. entry := models.DNSEntry{Address: "10.0.0.2", Name: name, Network: "skynet"}
  385. err := logic.ValidateDNSCreate(entry)
  386. assert.NotNil(t, err)
  387. assert.Contains(t, err.Error(), "Field validation for 'Name' failed on the 'max' tag")
  388. })
  389. t.Run("NameUnique", func(t *testing.T) {
  390. entry := models.DNSEntry{Address: "10.0.0.2", Name: "myhost", Network: "skynet"}
  391. _, _ = logic.CreateDNS(entry)
  392. err := logic.ValidateDNSCreate(entry)
  393. assert.NotNil(t, err)
  394. assert.Contains(t, err.Error(), "Field validation for 'Name' failed on the 'name_unique' tag")
  395. })
  396. t.Run("WhiteSpace", func(t *testing.T) {
  397. entry := models.DNSEntry{Address: "10.10.10.5", Name: "white space", Network: "skynet"}
  398. err := logic.ValidateDNSCreate(entry)
  399. assert.NotNil(t, err)
  400. assert.Contains(t, err.Error(), "invalid input")
  401. })
  402. t.Run("AllSpaces", func(t *testing.T) {
  403. entry := models.DNSEntry{Address: "10.10.10.5", Name: " ", Network: "skynet"}
  404. err := logic.ValidateDNSCreate(entry)
  405. assert.NotNil(t, err)
  406. assert.Contains(t, err.Error(), "invalid input")
  407. })
  408. }
  409. func createHost() {
  410. k, _ := wgtypes.ParseKey("DM5qhLAE20PG9BbfBCger+Ac9D2NDOwCtY1rbYDLf34=")
  411. dnsHost = models.Host{
  412. ID: uuid.New(),
  413. PublicKey: k.PublicKey(),
  414. HostPass: "password",
  415. OS: "linux",
  416. Name: "dnshost",
  417. }
  418. _ = logic.CreateHost(&dnsHost)
  419. }
  420. func deleteAllDNS(t *testing.T) {
  421. dns, err := logic.GetAllDNS()
  422. assert.Nil(t, err)
  423. for _, record := range dns {
  424. err := logic.DeleteDNS(record.Name, record.Network)
  425. assert.Nil(t, err)
  426. }
  427. }