Merge lp:~rvb/maas/rev-zone-generation-ipv6 into lp:~maas-committers/maas/trunk

Proposed by Raphaël Badin
Status: Merged
Approved by: Raphaël Badin
Approved revision: no longer in the source branch.
Merged at revision: 2469
Proposed branch: lp:~rvb/maas/rev-zone-generation-ipv6
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 104 lines (+50/-21)
2 files modified
src/provisioningserver/dns/config.py (+21/-3)
src/provisioningserver/dns/tests/test_config.py (+29/-18)
To merge this branch: bzr merge lp:~rvb/maas/rev-zone-generation-ipv6
Reviewer Review Type Date Requested Status
Raphaël Badin (community) Approve
Blake Rouse (community) Approve
Review via email: mp+224316@code.launchpad.net

Commit message

Make DNSReverseZoneConfig.compose_zone_name capable of generating reverse zone file names for IPv6 networks.

To post a comment you must log in.
Revision history for this message
Blake Rouse (blake-rouse) wrote :

Approved.

The naming of variable "rest" is a little weird. I assume you are meaning the rest of the reverse_dns? Having an issue with coming up with a better name. Maybe "rest_limit", don't know if that is any better. :)

review: Approve
Revision history for this message
Raphaël Badin (rvb) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/provisioningserver/dns/config.py'
2--- src/provisioningserver/dns/config.py 2014-06-10 14:45:14 +0000
3+++ src/provisioningserver/dns/config.py 2014-06-25 09:35:41 +0000
4@@ -31,10 +31,12 @@
5 imap,
6 islice,
7 )
8+import math
9 import os.path
10 import re
11
12 from celery.app import app_or_default
13+from netaddr import IPAddress
14 from provisioningserver.dns.utils import generated_hostname
15 from provisioningserver.utils import (
16 atomic_write,
17@@ -411,9 +413,25 @@
18 @classmethod
19 def compose_zone_name(cls, network):
20 """Return the name of the reverse zone."""
21- broadcast, netmask = network.broadcast, network.netmask
22- octets = broadcast.words[:netmask.words.count(255)]
23- return '%s.in-addr.arpa' % '.'.join(imap(unicode, reversed(octets)))
24+ # Generate the name of the reverse zone file:
25+ # Use netaddr's reverse_dns() to get the reverse IP name
26+ # of the first IP address in the network and then drop the first
27+ # octets of that name (i.e. drop the octets that will be specified in
28+ # the zone file).
29+ first = IPAddress(network.first)
30+ if first.version == 6:
31+ # IPv6.
32+ # Use float division and ceil to cope with network sizes that
33+ # are not divisible by 4.
34+ rest_limit = int(math.ceil((128 - network.prefixlen) / 4.))
35+ else:
36+ # IPv4.
37+ # Use float division and ceil to cope with splits not done on
38+ # octets boundaries.
39+ rest_limit = int(math.ceil((32 - network.prefixlen) / 8.))
40+ reverse_name = first.reverse_dns.split('.', rest_limit)[-1]
41+ # Strip off trailing '.'.
42+ return reverse_name[:-1]
43
44 @classmethod
45 def shortened_reversed_ip(cls, ip, num_bytes):
46
47=== modified file 'src/provisioningserver/dns/tests/test_config.py'
48--- src/provisioningserver/dns/tests/test_config.py 2014-01-22 05:45:16 +0000
49+++ src/provisioningserver/dns/tests/test_config.py 2014-06-25 09:35:41 +0000
50@@ -547,25 +547,36 @@
51 os.path.join(conf.DNS_CONFIG_DIR, reverse_file_name),
52 dns_zone_config.target_path)
53
54- def test_reverse_data_slash_24(self):
55- # DNSReverseZoneConfig calculates the reverse data correctly for
56- # a /24 network.
57- domain = factory.make_name('zone')
58- network = IPNetwork('192.168.0.1/24')
59- dns_zone_config = DNSReverseZoneConfig(domain, network=network)
60- self.assertEqual(
61- '0.168.192.in-addr.arpa',
62- dns_zone_config.zone_name)
63+ def test_reverse_zone_file(self):
64+ # DNSReverseZoneConfig calculates the reverse zone file name
65+ # correctly for IPv4 and IPv6 networks.
66+ expected = [
67+ # IPv4 networks.
68+ (IPNetwork('192.168.0.1/22'), '168.192.in-addr.arpa'),
69+ (IPNetwork('192.168.0.1/24'), '0.168.192.in-addr.arpa'),
70+ # IPv6 networks.
71+ (IPNetwork('3ffe:801::/32'), '1.0.8.0.e.f.f.3.ip6.arpa'),
72+ (IPNetwork('2001:db8:0::/48'), '0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa'),
73+ (
74+ IPNetwork('2001:ba8:1f1:400::/56'),
75+ '4.0.1.f.1.0.8.a.b.0.1.0.0.2.ip6.arpa'
76+ ),
77+ (
78+ IPNetwork('2610:8:6800:1::/64'),
79+ '1.0.0.0.0.0.8.6.8.0.0.0.0.1.6.2.ip6.arpa',
80+ ),
81+ (
82+ IPNetwork('2001:ba8:1f1:400::/103'),
83+ '0.0.0.0.0.0.0.0.0.0.0.4.0.1.f.1.0.8.a.b.0.1.0.0.2.ip6.arpa',
84+ ),
85
86- def test_reverse_data_slash_22(self):
87- # DNSReverseZoneConfig calculates the reverse data correctly for
88- # a /22 network.
89- domain = factory.getRandomString()
90- network = IPNetwork('192.168.0.1/22')
91- dns_zone_config = DNSReverseZoneConfig(domain, network=network)
92- self.assertEqual(
93- '168.192.in-addr.arpa',
94- dns_zone_config.zone_name)
95+ ]
96+ results = []
97+ for network, _ in expected:
98+ domain = factory.make_name('zone')
99+ dns_zone_config = DNSReverseZoneConfig(domain, network=network)
100+ results.append((network, dns_zone_config.zone_name))
101+ self.assertEqual(expected, results)
102
103 def test_get_static_mapping_returns_iterator(self):
104 self.assertThat(