372
372
# /2 with hex digits ==> 4 /4 reverse zones
374
374
IPNetwork('8000::/2'),
376
IPNetwork('%x000::/4' % i + 8),
377
'%x.ip6.arpa' % i + 8) for i in range(4)],
376
DNSZoneInfo(IPNetwork('8000::/4'), '8.ip6.arpa'),
377
DNSZoneInfo(IPNetwork('9000::/4'), '9.ip6.arpa'),
378
DNSZoneInfo(IPNetwork('a000::/4'), 'a.ip6.arpa'),
379
DNSZoneInfo(IPNetwork('b000::/4'), 'b.ip6.arpa'),
379
382
# /103 ==> 2 /104 reverse zones
388
391
IPNetwork('2001:ba8:1f1:400::/125'),
390
IPNetwork('2001:ba8:1f1:400:0:0:0:0/125'),
393
IPNetwork('2001:ba8:1f1:400::/125'),
395
IPAddress('2001:ba8:1f1:400::').reverse_dns[2:-1]))],
476
481
for sub in range(4):
477
482
reverse_file_name = 'zone.%d.168.192.in-addr.arpa' % sub
478
483
expected_GEN_direct = dns_zone_config.get_GENERATE_directives(
479
dynamic_network, domain, IPNetwork('192.168.%d.0/24' % sub))
484
dynamic_network, domain,
486
IPNetwork('192.168.%d.0/24' % sub),
487
"%d.168.192.in-addr.arpa" % sub))
480
488
expected = ContainsAll(
482
490
'IN NS %s' % domain
502
510
IPRange(dynamic_network.first, dynamic_network.last)])
503
511
dns_zone_config.write_config()
512
reverse_zone_name = '0-26.0.168.192.in-addr.arpa'
504
513
reverse_file_name = 'zone.0-26.0.168.192.in-addr.arpa'
505
514
expected_GEN_direct = dns_zone_config.get_GENERATE_directives(
506
dynamic_network, domain, network)
515
dynamic_network, domain, DNSZoneInfo(network, reverse_zone_name))
507
516
expected = ContainsAll(
509
518
'IN NS %s' % domain
561
570
DNSReverseZoneConfig.get_GENERATE_directives(
564
network=IPNetwork('192.168.0.0/16')))
573
zone_info=DNSZoneInfo(
574
IPNetwork('192.168.0.0/16'),
575
"168.192.in-addr.arpa")))
566
577
def get_expected_generate_directives(self, network, domain):
567
578
ip_parts = network.network.format().split('.')
591
602
relevant_ip_parts.reverse()
592
603
expected_rdns_base = (
593
604
"%s.%s.in-addr.arpa." % tuple(relevant_ip_parts))
594
expected_rdns_template = "$.%s.%s" % (
595
num + second_octet_offset, expected_rdns_base)
605
if network.size >= 256:
606
expected_rdns_template = "$.%s.%s" % (
607
num + second_octet_offset, expected_rdns_base)
609
expected_rdns_template = "$"
596
610
expected_generate_directives.append(
598
612
"%s-%s" % (iterator_low, iterator_high),
605
619
def test_returns_single_entry_for_slash_24_network(self):
606
620
network = IPNetwork("%s/24" % factory.make_ipv4_address())
621
reverse = ".".join(IPAddress(network).reverse_dns.split('.')[1:-1])
607
622
domain = factory.make_string()
608
623
expected_generate_directives = self.get_expected_generate_directives(
610
625
directives = DNSReverseZoneConfig.get_GENERATE_directives(
611
network, domain, network)
626
network, domain, DNSZoneInfo(network, reverse))
612
627
self.expectThat(directives, HasLength(1))
613
628
self.assertItemsEqual(expected_generate_directives, directives)
615
630
def test_returns_single_entry_for_tiny_network(self):
616
631
network = IPNetwork("%s/28" % factory.make_ipv4_address())
632
reverse = IPAddress(network).reverse_dns.split('.')
633
reverse = ".".join(["%s-28" % reverse[0]] + reverse[1:-1])
617
634
domain = factory.make_string()
619
636
expected_generate_directives = self.get_expected_generate_directives(
621
638
directives = DNSReverseZoneConfig.get_GENERATE_directives(
622
network, domain, network)
639
network, domain, DNSZoneInfo(network, reverse))
623
640
self.expectThat(directives, HasLength(1))
624
641
self.assertItemsEqual(expected_generate_directives, directives)
627
644
ip_range = IPRange('10.0.0.1', '10.0.0.255')
628
645
domain = factory.make_string()
629
646
directives = DNSReverseZoneConfig.get_GENERATE_directives(
630
ip_range, domain, IPNetwork('10.0.0.0/24'))
648
DNSZoneInfo(IPNetwork('10.0.0.0/24'), '0.0.10.in-addr.arpa'))
631
649
self.expectThat(directives, HasLength(1))
633
651
# generate 2 zones, rather than 1 zone with 2 GENERATEs.
634
652
def test_returns_256_entries_for_slash_16_network(self):
635
653
network = IPNetwork(factory.make_ipv4_network(slash=16))
654
reverse = IPAddress(network.first).reverse_dns.split('.')[2:-1]
655
reverse = ".".join(reverse)
636
656
domain = factory.make_string()
638
658
expected_generate_directives = self.get_expected_generate_directives(
640
660
directives = DNSReverseZoneConfig.get_GENERATE_directives(
641
network, domain, network)
661
network, domain, DNSZoneInfo(network, reverse))
642
662
self.expectThat(directives, HasLength(256))
643
663
self.assertItemsEqual(expected_generate_directives, directives)
647
667
self.assertEqual(
649
669
DNSReverseZoneConfig.get_GENERATE_directives(
650
network, factory.make_string(), network))
670
network, factory.make_string(),
671
DNSZoneInfo(network, "do not care")))
652
673
def test_ignores_networks_that_span_slash_16s(self):
653
674
# If the upper and lower bounds of a range span two /16 networks
655
676
# get_GENERATE_directives() will return early
656
677
ip_range = IPRange('10.0.0.55', '10.1.0.54')
657
678
directives = DNSReverseZoneConfig.get_GENERATE_directives(
658
ip_range, factory.make_string(), IPNetwork('10.0.0.0/15'))
679
ip_range, factory.make_string(),
680
DNSZoneInfo(IPNetwork('10.0.0.0/15'), "do not care"))
659
681
self.assertEqual([], directives)
661
683
def test_sorts_output_by_hostname(self):
666
688
expected_rdns = "$.%s.0.10.in-addr.arpa."
668
690
directives = list(DNSReverseZoneConfig.get_GENERATE_directives(
669
network, domain, IPNetwork('10.0.0.0/24')))
692
DNSZoneInfo(IPNetwork('10.0.0.0/24'), '0.0.10.in-addr.arpa')))
671
694
directives[0], Equals(
672
695
("0-255", expected_rdns % "0", expected_hostname % "0")))
674
697
expected_hostname = "10-0-%s-$." + domain + "."
675
698
expected_rdns = "$.%s.0.10.in-addr.arpa."
676
699
directives = list(DNSReverseZoneConfig.get_GENERATE_directives(
677
network, domain, IPNetwork('10.0.1.0/24')))
701
DNSZoneInfo(IPNetwork('10.0.1.0/24'), '1.0.10.in-addr.arpa')))
679
703
directives[0], Equals(
680
704
("0-255", expected_rdns % "1", expected_hostname % "1")))