Merge lp:~mpontillo/maas/dns-template-changes-1.7 into lp:maas/1.7

Proposed by Mike Pontillo on 2015-07-09
Status: Merged
Approved by: Mike Pontillo on 2015-07-10
Approved revision: 3376
Merged at revision: 3376
Proposed branch: lp:~mpontillo/maas/dns-template-changes-1.7
Merge into: lp:maas/1.7
Diff against target: 352 lines (+176/-7)
8 files modified
etc/maas/templates/dns/named.conf.options.inside.maas.template (+7/-1)
src/maasserver/management/commands/edit_named_options.py (+1/-1)
src/maasserver/tests/test_commands_edit_named_options.py (+2/-2)
src/provisioningserver/dns/config.py (+38/-0)
src/provisioningserver/dns/testing.py (+2/-0)
src/provisioningserver/dns/tests/test_config.py (+117/-0)
src/provisioningserver/utils/isc.py (+3/-1)
src/provisioningserver/utils/tests/test_isc.py (+6/-2)
To merge this branch: bzr merge lp:~mpontillo/maas/dns-template-changes-1.7
Reviewer Review Type Date Requested Status
Mike Pontillo (community) Approve on 2015-07-09
Review via email: mp+264219@code.launchpad.net

Commit message

Allow users to define allow-* parameters in named.conf.options; prevent writing them to named.conf.options.inside.maas in that case. (Merge from trunk revision 4082)

To post a comment you must log in.
Mike Pontillo (mpontillo) wrote :

Self-approving backport.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'etc/maas/templates/dns/named.conf.options.inside.maas.template'
2--- etc/maas/templates/dns/named.conf.options.inside.maas.template 2015-07-03 08:57:15 +0000
3+++ etc/maas/templates/dns/named.conf.options.inside.maas.template 2015-07-09 23:21:59 +0000
4@@ -6,7 +6,13 @@
5 };
6 {{endif}}
7
8+
9+{{if not upstream_allow_query}}
10 allow-query { any; };
11+{{endif}}
12+{{if not upstream_allow_recursion}}
13 allow-recursion { trusted; };
14+{{endif}}
15+{{if not upstream_allow_query_cache}}
16 allow-query-cache { trusted; };
17-
18+{{endif}}
19
20=== modified file 'src/maasserver/management/commands/edit_named_options.py'
21--- src/maasserver/management/commands/edit_named_options.py 2015-07-08 00:26:38 +0000
22+++ src/maasserver/management/commands/edit_named_options.py 2015-07-09 23:21:59 +0000
23@@ -33,7 +33,7 @@
24 CommandError,
25 )
26 from maasserver.models import Config
27-from maasserver.utils.isc import (
28+from provisioningserver.utils.isc import (
29 ISCParseException,
30 make_isc_string,
31 parse_isc_string,
32
33=== modified file 'src/maasserver/tests/test_commands_edit_named_options.py'
34--- src/maasserver/tests/test_commands_edit_named_options.py 2015-07-08 00:26:38 +0000
35+++ src/maasserver/tests/test_commands_edit_named_options.py 2015-07-09 23:21:59 +0000
36@@ -30,12 +30,12 @@
37 from maasserver.testing.factory import factory
38 from maasserver.testing.testcase import MAASServerTestCase
39 from maasserver.utils import get_one
40-from maasserver.utils.isc import (
41+from provisioningserver.dns.config import MAAS_NAMED_CONF_OPTIONS_INSIDE_NAME
42+from provisioningserver.utils.isc import (
43 make_isc_string,
44 parse_isc_string,
45 read_isc_file,
46 )
47-from provisioningserver.dns.config import MAAS_NAMED_CONF_OPTIONS_INSIDE_NAME
48 from testtools.matchers import (
49 Contains,
50 Equals,
51
52=== modified file 'src/provisioningserver/dns/config.py'
53--- src/provisioningserver/dns/config.py 2014-11-17 11:02:09 +0000
54+++ src/provisioningserver/dns/config.py 2015-07-09 23:21:59 +0000
55@@ -31,10 +31,12 @@
56
57 from provisioningserver.utils import locate_config
58 from provisioningserver.utils.fs import atomic_write
59+from provisioningserver.utils.isc import read_isc_file
60 from provisioningserver.utils.shell import call_and_check
61 import tempita
62
63
64+NAMED_CONF_OPTIONS = 'named.conf.options'
65 MAAS_NAMED_CONF_NAME = 'named.conf.maas'
66 MAAS_NAMED_CONF_OPTIONS_INSIDE_NAME = 'named.conf.options.inside.maas'
67 MAAS_NAMED_RNDC_CONF_NAME = 'named.conf.rndc.maas'
68@@ -53,6 +55,18 @@
69 return setting
70
71
72+def get_bind_config_dir():
73+ """Location of bind configuration files."""
74+ setting = os.getenv(
75+ "MAAS_BIND_CONFIG_DIR",
76+ locate_config(os.path.pardir, "bind"))
77+ if isinstance(setting, bytes):
78+ fsenc = sys.getfilesystemencoding()
79+ return setting.decode(fsenc)
80+ else:
81+ return setting
82+
83+
84 def get_dns_rndc_port():
85 """RNDC port to be configured by MAAS to communicate with BIND."""
86 setting = os.getenv("MAAS_DNS_RNDC_PORT", "954")
87@@ -192,6 +206,25 @@
88 # specify it. If it's not set, the substitution will fail with the default
89 # template that uses this value.
90 kwargs.setdefault("upstream_dns")
91+
92+ # Parse the options file and make sure MAAS doesn't define any options
93+ # that the user has already customized.
94+ allow_user_override_options = [
95+ "allow-query",
96+ "allow-recursion",
97+ "allow-query-cache",
98+ ]
99+
100+ try:
101+ parsed_options = read_isc_file(
102+ compose_bind_config_path(NAMED_CONF_OPTIONS))
103+ except IOError:
104+ parsed_options = {}
105+
106+ options = parsed_options.get('options', {})
107+ for option in allow_user_override_options:
108+ kwargs['upstream_' + option.replace('-', '_')] = option in options
109+
110 try:
111 rendered = template.substitute(kwargs)
112 except NameError as error:
113@@ -206,6 +239,11 @@
114 return os.path.join(get_dns_config_dir(), filename)
115
116
117+def compose_bind_config_path(filename):
118+ """Return the full path for a DNS config or zone file."""
119+ return os.path.join(get_bind_config_dir(), filename)
120+
121+
122 def render_dns_template(template_name, *parameters):
123 """Generate contents for a DNS configuration or zone file.
124
125
126=== modified file 'src/provisioningserver/dns/testing.py'
127--- src/provisioningserver/dns/testing.py 2014-09-24 09:32:18 +0000
128+++ src/provisioningserver/dns/testing.py 2015-07-09 23:21:59 +0000
129@@ -32,6 +32,8 @@
130 config_dir = config_dir.encode(fsenc)
131 testcase.useFixture(
132 EnvironmentVariable(b"MAAS_DNS_CONFIG_DIR", config_dir))
133+ testcase.useFixture(
134+ EnvironmentVariable(b"MAAS_BIND_CONFIG_DIR", config_dir))
135 return config_dir.decode(fsenc)
136
137
138
139=== modified file 'src/provisioningserver/dns/tests/test_config.py'
140--- src/provisioningserver/dns/tests/test_config.py 2015-07-03 09:30:27 +0000
141+++ src/provisioningserver/dns/tests/test_config.py 2015-07-09 23:21:59 +0000
142@@ -39,6 +39,7 @@
143 MAAS_NAMED_CONF_OPTIONS_INSIDE_NAME,
144 MAAS_NAMED_RNDC_CONF_NAME,
145 MAAS_RNDC_CONF_NAME,
146+ NAMED_CONF_OPTIONS,
147 render_dns_template,
148 report_missing_config_dir,
149 set_up_options_conf,
150@@ -54,12 +55,16 @@
151 DNSReverseZoneConfig,
152 )
153 from provisioningserver.utils import locate_config
154+from provisioningserver.utils.isc import read_isc_file
155 from testtools.matchers import (
156+ AllMatch,
157 Contains,
158 ContainsAll,
159 EndsWith,
160+ Equals,
161 FileContains,
162 FileExists,
163+ Is,
164 IsInstance,
165 MatchesAll,
166 Not,
167@@ -70,6 +75,47 @@
168 from twisted.python.filepath import FilePath
169
170
171+NAMED_CONF_OPTIONS_CONTENTS = dedent("""\
172+ options {
173+ forwarders {
174+ 8.8.8.8;
175+ 8.8.4.4;
176+ };
177+ dnssec-validation auto;
178+ allow-query { any; };
179+ allow-recursion { trusted; };
180+ allow-query-cache { trusted; };
181+ auth-nxdomain no;
182+ listen-on-v6 { any; };
183+ };
184+ """)
185+
186+NAMED_CONF_OPTIONS_WITH_ALLOW_QUERY_CONTENTS = dedent("""\
187+ options {
188+ forwarders {
189+ 8.8.8.8;
190+ 8.8.4.4;
191+ };
192+ dnssec-validation auto;
193+ allow-query { any; };
194+ auth-nxdomain no;
195+ listen-on-v6 { any; };
196+ };
197+ """)
198+
199+NAMED_CONF_OPTIONS_NO_ALLOW_CONTENTS = dedent("""\
200+ options {
201+ forwarders {
202+ 8.8.8.8;
203+ 8.8.4.4;
204+ };
205+ dnssec-validation auto;
206+ auth-nxdomain no;
207+ listen-on-v6 { any; };
208+ };
209+ """)
210+
211+
212 class TestHelpers(MAASTestCase):
213
214 def test_get_dns_config_dir_defaults_to_etc_bind_maas(self):
215@@ -90,6 +136,24 @@
216 IsInstance(unicode),
217 ))
218
219+ def test_get_bind_config_dir_defaults_to_etc_bind_maas(self):
220+ self.useFixture(EnvironmentVariable("MAAS_BIND_CONFIG_DIR"))
221+ self.assertThat(
222+ config.get_bind_config_dir(), MatchesAll(
223+ SamePath(locate_config("../bind")),
224+ IsInstance(unicode),
225+ ))
226+
227+ def test_get_bind_config_dir_checks_environ_first(self):
228+ directory = self.make_dir()
229+ self.useFixture(EnvironmentVariable(
230+ "MAAS_BIND_CONFIG_DIR", directory.encode("ascii")))
231+ self.assertThat(
232+ config.get_bind_config_dir(), MatchesAll(
233+ SamePath(directory),
234+ IsInstance(unicode),
235+ ))
236+
237 def test_get_dns_root_port_defaults_to_954(self):
238 self.useFixture(EnvironmentVariable("MAAS_DNS_RNDC_PORT"))
239 self.assertEqual(954, config.get_dns_rndc_port())
240@@ -145,6 +209,59 @@
241 ])
242 )
243
244+ def test_set_up_options_conf_write_config_assumes_no_overrides(self):
245+ dns_conf_dir = patch_dns_config_path(self)
246+ set_up_options_conf()
247+ target_file = os.path.join(
248+ dns_conf_dir, MAAS_NAMED_CONF_OPTIONS_INSIDE_NAME)
249+ target = read_isc_file(target_file)
250+ self.assertThat([
251+ target['allow-query']['any'],
252+ target['allow-recursion']['trusted'],
253+ target['allow-query-cache']['trusted'],
254+ ], AllMatch(Equals(True)))
255+
256+ def test_set_up_options_conf_write_config_allows_overrides(self):
257+ dns_conf_dir = patch_dns_config_path(self)
258+ factory.make_file(
259+ location=dns_conf_dir, name=NAMED_CONF_OPTIONS,
260+ contents=NAMED_CONF_OPTIONS_CONTENTS)
261+ set_up_options_conf()
262+ target_file = os.path.join(
263+ dns_conf_dir, MAAS_NAMED_CONF_OPTIONS_INSIDE_NAME)
264+ target = read_isc_file(target_file)
265+ self.assertThat([
266+ target.get('allow-query'),
267+ target.get('allow-recursion'),
268+ target.get('allow-query-cache'),
269+ ], AllMatch(Is(None)))
270+
271+ def test_set_up_options_conf_write_config_allows_zero_overrides(self):
272+ dns_conf_dir = patch_dns_config_path(self)
273+ factory.make_file(
274+ location=dns_conf_dir, name=NAMED_CONF_OPTIONS,
275+ contents=NAMED_CONF_OPTIONS_NO_ALLOW_CONTENTS)
276+ set_up_options_conf()
277+ target_file = os.path.join(
278+ dns_conf_dir, MAAS_NAMED_CONF_OPTIONS_INSIDE_NAME)
279+ target = read_isc_file(target_file)
280+ self.assertThat([
281+ target['allow-query']['any'],
282+ target['allow-recursion']['trusted'],
283+ target['allow-query-cache']['trusted'],
284+ ], AllMatch(Equals(True)))
285+
286+ def test_set_up_options_conf_write_config_allows_single_override(self):
287+ dns_conf_dir = patch_dns_config_path(self)
288+ factory.make_file(
289+ location=dns_conf_dir, name=NAMED_CONF_OPTIONS,
290+ contents=NAMED_CONF_OPTIONS_WITH_ALLOW_QUERY_CONTENTS)
291+ set_up_options_conf()
292+ target_file = os.path.join(
293+ dns_conf_dir, MAAS_NAMED_CONF_OPTIONS_INSIDE_NAME)
294+ target = read_isc_file(target_file)
295+ self.assertIsNone(target.get('allow-query'))
296+
297 def test_set_up_options_conf_handles_no_upstream_dns(self):
298 dns_conf_dir = patch_dns_config_path(self)
299 set_up_options_conf()
300
301=== renamed file 'src/maasserver/utils/isc.py' => 'src/provisioningserver/utils/isc.py'
302--- src/maasserver/utils/isc.py 2015-07-08 00:26:38 +0000
303+++ src/provisioningserver/utils/isc.py 2015-07-09 23:21:59 +0000
304@@ -144,6 +144,8 @@
305 # If there are more than 1 'keywords' at new_char_list[index]
306 # ex - "recursion no;"
307 elif len(new_char_list[index].split()) >= 2:
308+ if type(dictionary_fragment) == list:
309+ raise ISCParseException("Syntax error")
310 dictionary_fragment[
311 new_char_list[index].split()[0]] = (
312 ' '.join(new_char_list[index].split()[1:]))
313@@ -155,7 +157,7 @@
314 elif new_char_list[index] not in ['{', ';', '}']:
315 key = new_char_list[index]
316 if type(dictionary_fragment) == list:
317- raise ISCParseException("Dictionary expected; got a list")
318+ raise ISCParseException("Syntax error")
319 dictionary_fragment[key] = ''
320 index += 1
321 index += 1
322
323=== renamed file 'src/maasserver/utils/tests/test_isc.py' => 'src/provisioningserver/utils/tests/test_isc.py'
324--- src/maasserver/utils/tests/test_isc.py 2015-07-08 00:26:38 +0000
325+++ src/provisioningserver/utils/tests/test_isc.py 2015-07-09 23:21:59 +0000
326@@ -18,13 +18,13 @@
327 from collections import OrderedDict
328 from textwrap import dedent
329
330-from maasserver.utils.isc import (
331+from maastesting.testcase import MAASTestCase
332+from provisioningserver.utils.isc import (
333 ISCParseException,
334 make_isc_string,
335 parse_isc_string,
336 read_isc_file,
337 )
338-from maastesting.testcase import MAASTestCase
339 from testtools import ExpectedException
340
341
342@@ -220,6 +220,10 @@
343 with ExpectedException(ISCParseException):
344 parse_isc_string("forwarders {{}a;;b}")
345
346+ def test_parse_forgotten_semicolons_throw_iscparseexception(self):
347+ with ExpectedException(ISCParseException):
348+ parse_isc_string("a { b; } { c; } d e;")
349+
350 def test_read_isc_file(self):
351 testdata = dedent("""\
352 acl canonical-int-ns { 91.189.90.151; 91.189.89.192; };

Subscribers

People subscribed via source and target branches

to all changes: