Merge lp:~lamont/maas/bug-1564925 into lp:~maas-committers/maas/trunk

Proposed by LaMont Jones
Status: Merged
Approved by: LaMont Jones
Approved revision: no longer in the source branch.
Merged at revision: 4866
Proposed branch: lp:~lamont/maas/bug-1564925
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 275 lines (+63/-38)
3 files modified
src/provisioningserver/dhcp/testing/config.py (+13/-6)
src/provisioningserver/dhcp/tests/test_config.py (+49/-31)
src/provisioningserver/templates/dhcp/dhcpd6.conf.template (+1/-1)
To merge this branch: bzr merge lp:~lamont/maas/bug-1564925
Reviewer Review Type Date Requested Status
Blake Rouse (community) Approve
Review via email: mp+290765@code.launchpad.net

Commit message

Generate correct dhcpd6.conf configuration.

Description of the change

Generate correct dhcpd6.conf configuration.

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

Looks good. Thanks for the quick fix. Testing was more work than fixing the bug. ;-)

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/provisioningserver/dhcp/testing/config.py'
--- src/provisioningserver/dhcp/testing/config.py 2016-03-26 00:36:43 +0000
+++ src/provisioningserver/dhcp/testing/config.py 2016-04-01 17:46:03 +0000
@@ -40,7 +40,7 @@
4040
41def make_host(41def make_host(
42 hostname=None, interface_name=None,42 hostname=None, interface_name=None,
43 mac_address=None, ip=None, dhcp_snippets=None):43 mac_address=None, ip=None, ipv6=False, dhcp_snippets=None):
44 """Return a host entry for a subnet from network."""44 """Return a host entry for a subnet from network."""
45 if hostname is None:45 if hostname is None:
46 hostname = factory.make_name("host")46 hostname = factory.make_name("host")
@@ -49,7 +49,10 @@
49 if mac_address is None:49 if mac_address is None:
50 mac_address = factory.make_mac_address()50 mac_address = factory.make_mac_address()
51 if ip is None:51 if ip is None:
52 ip = str(factory.make_ipv4_address())52 if ipv6 is True:
53 ip = str(factory.make_ipv6_address())
54 else:
55 ip = str(factory.make_ipv4_address())
53 if dhcp_snippets is None:56 if dhcp_snippets is None:
54 dhcp_snippets = make_dhcp_snippets()57 dhcp_snippets = make_dhcp_snippets()
55 return {58 return {
@@ -60,10 +63,14 @@
60 }63 }
6164
6265
63def make_subnet_config(network=None, pools=None, dhcp_snippets=None):66def make_subnet_config(network=None, pools=None, ipv6=False,
67 dhcp_snippets=None):
64 """Return complete DHCP configuration dict for a subnet."""68 """Return complete DHCP configuration dict for a subnet."""
65 if network is None:69 if network is None:
66 network = factory.make_ipv4_network()70 if ipv6 is True:
71 network = factory.make_ipv6_network()
72 else:
73 network = factory.make_ipv4_network()
67 if pools is None:74 if pools is None:
68 pools = [make_subnet_pool(network)]75 pools = [make_subnet_pool(network)]
69 if dhcp_snippets is None:76 if dhcp_snippets is None:
@@ -82,13 +89,13 @@
82 }89 }
8390
8491
85def make_shared_network(name=None, subnets=None):92def make_shared_network(name=None, subnets=None, ipv6=False):
86 """Return complete DHCP configuration dict for a shared network."""93 """Return complete DHCP configuration dict for a shared network."""
87 if name is None:94 if name is None:
88 name = factory.make_name("vlan")95 name = factory.make_name("vlan")
89 if subnets is None:96 if subnets is None:
90 subnets = [97 subnets = [
91 make_subnet_config()98 make_subnet_config(ipv6=ipv6)
92 for _ in range(3)99 for _ in range(3)
93 ]100 ]
94 return {101 return {
95102
=== modified file 'src/provisioningserver/dhcp/tests/test_config.py'
--- src/provisioningserver/dhcp/tests/test_config.py 2016-03-26 00:36:43 +0000
+++ src/provisioningserver/dhcp/tests/test_config.py 2016-04-01 17:46:03 +0000
@@ -62,19 +62,19 @@
62""")62""")
6363
6464
65def make_sample_params(hosts=None):65def make_sample_params(hosts=None, ipv6=False):
66 """Return a dict of arbitrary DHCP configuration parameters."""66 """Return a dict of arbitrary DHCP configuration parameters."""
67 failover_peers = [67 failover_peers = [
68 make_failover_peer_config()68 make_failover_peer_config()
69 for _ in range(3)69 for _ in range(3)
70 ]70 ]
71 shared_networks = [71 shared_networks = [
72 make_shared_network()72 make_shared_network(ipv6=ipv6)
73 for _ in range(3)73 for _ in range(3)
74 ]74 ]
75 if hosts is None:75 if hosts is None:
76 hosts = [76 hosts = [
77 make_host()77 make_host(ipv6=ipv6)
78 for _ in range(3)78 for _ in range(3)
79 ]79 ]
80 return {80 return {
@@ -89,6 +89,11 @@
89class TestGetConfig(PservTestCase):89class TestGetConfig(PservTestCase):
90 """Tests for `get_config`."""90 """Tests for `get_config`."""
9191
92 scenarios = [
93 ("v4", dict(template='dhcpd.conf.template', ipv6=False)),
94 ("v6", dict(template='dhcpd6.conf.template', ipv6=True)),
95 ]
96
92 def patch_template(self, name=None, template_content=sample_template):97 def patch_template(self, name=None, template_content=sample_template):
93 """Patch the DHCP config template with the given contents.98 """Patch the DHCP config template with the given contents.
9499
@@ -97,7 +102,7 @@
97 code being tested.102 code being tested.
98 """103 """
99 if name is None:104 if name is None:
100 name = 'dhcpd.conf.template'105 name = self.template
101 fake_root = self.make_dir()106 fake_root = self.make_dir()
102 template_dir = path.join(fake_root, 'templates', 'dhcp')107 template_dir = path.join(fake_root, 'templates', 'dhcp')
103 makedirs(template_dir)108 makedirs(template_dir)
@@ -106,30 +111,29 @@
106 self.patch(config, 'locate_template').return_value = template111 self.patch(config, 'locate_template').return_value = template
107 return tempita.Template(template_content, name=template)112 return tempita.Template(template_content, name=template)
108113
109 def test__uses_branch_template_by_default(self):
110 # Since the branch comes with dhcp templates in etc/maas, we can
111 # instantiate those templates without any hackery.
112 self.assertIsNotNone(
113 config.get_config('dhcpd.conf.template', **make_sample_params()))
114 self.assertIsNotNone(
115 config.get_config('dhcpd6.conf.template', **make_sample_params()))
116
117 def test__substitutes_parameters(self):114 def test__substitutes_parameters(self):
118 template_name = factory.make_name('template')115 template_name = factory.make_name('template')
119 template = self.patch_template(name=template_name)116 template = self.patch_template(name=template_name)
120 params = make_sample_params()117 params = make_sample_params(ipv6=self.ipv6)
121 self.assertEqual(118 self.assertEqual(
122 template.substitute(params),119 template.substitute(params),
123 config.get_config(template_name, **params))120 config.get_config(template_name, **params))
124121
122 def test__uses_branch_template_by_default(self):
123 # Since the branch comes with dhcp templates in etc/maas, we can
124 # instantiate those templates without any hackery.
125 self.assertIsNotNone(
126 config.get_config(
127 self.template, **make_sample_params(ipv6=self.ipv6)))
128
125 def test__complains_if_too_few_parameters(self):129 def test__complains_if_too_few_parameters(self):
126 template = self.patch_template()130 template = self.patch_template()
127 params = make_sample_params()131 params = make_sample_params(ipv6=self.ipv6)
128 del params['shared_networks'][0]['subnets'][0]['subnet']132 del params['shared_networks'][0]['subnets'][0]['subnet']
129133
130 e = self.assertRaises(134 e = self.assertRaises(
131 config.DHCPConfigError,135 config.DHCPConfigError,
132 config.get_config, 'dhcpd.conf.template', **params)136 config.get_config, self.template, **params)
133137
134 tbe = traceback.TracebackException.from_exception(e)138 tbe = traceback.TracebackException.from_exception(e)
135 self.assertDocTestMatches(139 self.assertDocTestMatches(
@@ -152,14 +156,14 @@
152 )156 )
153157
154 def test__includes_compose_conditional_bootloader(self):158 def test__includes_compose_conditional_bootloader(self):
155 params = make_sample_params()159 params = make_sample_params(ipv6=self.ipv6)
156 bootloader = config.compose_conditional_bootloader()160 bootloader = config.compose_conditional_bootloader()
157 self.assertThat(161 self.assertThat(
158 config.get_config('dhcpd.conf.template', **params),162 config.get_config(self.template, **params),
159 Contains(bootloader))163 Contains(bootloader))
160164
161 def test__renders_without_ntp_servers_set(self):165 def test__renders_without_ntp_servers_set(self):
162 params = make_sample_params()166 params = make_sample_params(ipv6=self.ipv6)
163 for network in params['shared_networks']:167 for network in params['shared_networks']:
164 for subnet in network['subnets']:168 for subnet in network['subnets']:
165 del subnet['ntp_server']169 del subnet['ntp_server']
@@ -167,19 +171,19 @@
167 rendered = template.substitute(params)171 rendered = template.substitute(params)
168 self.assertEqual(172 self.assertEqual(
169 rendered,173 rendered,
170 config.get_config('dhcpd.conf.template', **params))174 config.get_config(self.template, **params))
171 self.assertNotIn("ntp-servers", rendered)175 self.assertNotIn("ntp-servers", rendered)
172176
173 def test__renders_router_ip_if_present(self):177 def test__renders_router_ip_if_present(self):
174 params = make_sample_params()178 params = make_sample_params(ipv6=self.ipv6)
175 router_ip = factory.make_ipv4_address()179 router_ip = factory.make_ipv4_address()
176 params['shared_networks'][0]['subnets'][0]['router_ip'] = router_ip180 params['shared_networks'][0]['subnets'][0]['router_ip'] = router_ip
177 self.assertThat(181 self.assertThat(
178 config.get_config('dhcpd.conf.template', **params),182 config.get_config(self.template, **params),
179 Contains(router_ip))183 Contains(router_ip))
180184
181 def test__renders_with_empty_string_router_ip(self):185 def test__renders_with_empty_string_router_ip(self):
182 params = make_sample_params()186 params = make_sample_params(ipv6=self.ipv6)
183 for network in params['shared_networks']:187 for network in params['shared_networks']:
184 for subnet in network['subnets']:188 for subnet in network['subnets']:
185 subnet['router_ip'] = ''189 subnet['router_ip'] = ''
@@ -187,7 +191,7 @@
187 rendered = template.substitute(params)191 rendered = template.substitute(params)
188 self.assertEqual(192 self.assertEqual(
189 rendered,193 rendered,
190 config.get_config('dhcpd.conf.template', **params))194 config.get_config(self.template, **params))
191 self.assertNotIn("routers", rendered)195 self.assertNotIn("routers", rendered)
192196
193 def test__renders_with_hosts(self):197 def test__renders_with_hosts(self):
@@ -196,8 +200,8 @@
196 make_host(network)200 make_host(network)
197 for _ in range(3)201 for _ in range(3)
198 ]202 ]
199 params = make_sample_params(hosts)203 params = make_sample_params(hosts, ipv6=self.ipv6)
200 config_output = config.get_config('dhcpd.conf.template', **params)204 config_output = config.get_config(self.template, **params)
201 self.assertThat(205 self.assertThat(
202 config_output,206 config_output,
203 ContainsAll([207 ContainsAll([
@@ -218,8 +222,8 @@
218 ]))222 ]))
219223
220 def test__renders_global_dhcp_snippets(self):224 def test__renders_global_dhcp_snippets(self):
221 params = make_sample_params()225 params = make_sample_params(ipv6=self.ipv6)
222 config_output = config.get_config('dhcpd.conf.template', **params)226 config_output = config.get_config(self.template, **params)
223 self.assertThat(227 self.assertThat(
224 config_output,228 config_output,
225 ContainsAll([229 ContainsAll([
@@ -228,8 +232,8 @@
228 ]))232 ]))
229233
230 def test__renders_subnet_dhcp_snippets(self):234 def test__renders_subnet_dhcp_snippets(self):
231 params = make_sample_params()235 params = make_sample_params(ipv6=self.ipv6)
232 config_output = config.get_config('dhcpd.conf.template', **params)236 config_output = config.get_config(self.template, **params)
233 for shared_network in params['shared_networks']:237 for shared_network in params['shared_networks']:
234 for subnet in shared_network['subnets']:238 for subnet in shared_network['subnets']:
235 self.assertThat(239 self.assertThat(
@@ -240,8 +244,8 @@
240 ]))244 ]))
241245
242 def test__renders_node_dhcp_snippets(self):246 def test__renders_node_dhcp_snippets(self):
243 params = make_sample_params()247 params = make_sample_params(ipv6=self.ipv6)
244 config_output = config.get_config('dhcpd.conf.template', **params)248 config_output = config.get_config(self.template, **params)
245 for host in params['hosts']:249 for host in params['hosts']:
246 self.assertThat(250 self.assertThat(
247 config_output,251 config_output,
@@ -250,6 +254,20 @@
250 for dhcp_snippet in host['dhcp_snippets']254 for dhcp_snippet in host['dhcp_snippets']
251 ]))255 ]))
252256
257 def test__renders_subnet_cidr(self):
258 params = make_sample_params(ipv6=self.ipv6)
259 config_output = config.get_config(self.template, **params)
260 for shared_network in params['shared_networks']:
261 for subnet in shared_network['subnets']:
262 if self.ipv6 is True:
263 expected = "subnet6 %s" % subnet['subnet_cidr']
264 else:
265 expected = "subnet %s netmask %s" % (
266 subnet['subnet'], subnet['subnet_mask'])
267 self.assertThat(
268 config_output,
269 Contains(expected))
270
253271
254class TestComposeConditionalBootloader(PservTestCase):272class TestComposeConditionalBootloader(PservTestCase):
255 """Tests for `compose_conditional_bootloader`."""273 """Tests for `compose_conditional_bootloader`."""
256274
=== modified file 'src/provisioningserver/templates/dhcp/dhcpd6.conf.template'
--- src/provisioningserver/templates/dhcp/dhcpd6.conf.template 2016-03-26 00:36:43 +0000
+++ src/provisioningserver/templates/dhcp/dhcpd6.conf.template 2016-04-01 17:46:03 +0000
@@ -45,7 +45,7 @@
45{{for shared_network in shared_networks}}45{{for shared_network in shared_networks}}
46shared-network {{shared_network["name"]}} {46shared-network {{shared_network["name"]}} {
47 {{for dhcp_subnet in shared_network["subnets"]}}47 {{for dhcp_subnet in shared_network["subnets"]}}
48 subnet6 {{dhcp_subnet['subnet']}} netmask {{dhcp_subnet['subnet_mask']}} {48 subnet6 {{dhcp_subnet['subnet_cidr']}} {
49 ignore-client-uids true;49 ignore-client-uids true;
50 {{if dhcp_subnet.get('dns_servers')}}50 {{if dhcp_subnet.get('dns_servers')}}
51 option dhcp6.name-servers {{dhcp_subnet['dns_servers']}};51 option dhcp6.name-servers {{dhcp_subnet['dns_servers']}};