Merge lp:~rvb/maas/bug-1066938-rndc2 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: 1278
Proposed branch: lp:~rvb/maas/bug-1066938-rndc2
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 100 lines (+34/-2)
4 files modified
etc/celeryconfig_common.py (+3/-0)
etc/democeleryconfig_common.py (+5/-0)
src/provisioningserver/dns/config.py (+15/-2)
src/provisioningserver/dns/tests/test_config.py (+11/-0)
To merge this branch: bzr merge lp:~rvb/maas/bug-1066938-rndc2
Reviewer Review Type Date Requested Status
Gavin Panella (community) Approve
Review via email: mp+129841@code.launchpad.net

Commit message

This branch adds the inclusion of the default 'controls' statement so that the init scripts can control the bind server using the default RNDC key from localhost.

= Notes =

It turns out that if not controls statement is provided, "inet 127.0.0.1 port 953 allow { localhost; };" is included silently and this is used by the init scripts to control the bind server. Since MAAS adds a 'controls' statement to control the bind server, we also need to explicitly include the default 'controls' statement.

I've created a package locally and tested this fix:

Without the default 'controls' statement:

$ sudo /etc/init.d/bind9 restart
 * Stopping domain name service... bind9 rndc: connect failed: 127.0.0.1#953: connection refused
waiting for pid 14057 to die [ OK ]
 * Starting domain name service... bind9 [ OK ]

With the default 'controls' statement:

sudo /etc/init.d/bind9 restart
 * Stopping domain name service... bind9 waiting for pid 13819 to die [ OK ]
 * Starting domain name service... bind9 [ OK ]

Description of the change

Include the default 'controls' statement so that the init scripts can control the bind server using the default RNDC key from localhost.

To post a comment you must log in.
Revision history for this message
Gavin Panella (allenap) wrote :

Looks good.

[1]

>  * Stopping domain name service... bind9 rndc: connect failed:
>    127.0.0.1#953: connection refused waiting for pid 14057 to die
>    [ OK ]

Do you know why it prints OK when it has failed?

[2]

+# Include the default RNDC controls (default RNDC key on port 953).
+DNS_DEFAULT_CONTROLS = True

Why is this in a Celery config file?

[3]

+DEFAULT_CONTROLS = """
+controls {
+    inet 127.0.0.1 port 953 allow { localhost; };
+};
+"""

Include a comment here, about what placed it, and why? Also, remove
leading new-line?

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

Thanks for the review!

> [1]
>
> >  * Stopping domain name service... bind9 rndc: connect failed:
> >    127.0.0.1#953: connection refused waiting for pid 14057 to die
> >    [ OK ]
>
> Do you know why it prints OK when it has failed?

Yeah, if stopping bind using a clean rndc command fails, the init script goes for the jugular: http://paste.ubuntu.com/1282827/

> [2]
>
> +# Include the default RNDC controls (default RNDC key on port 953).
> +DNS_DEFAULT_CONTROLS = True
>
> Why is this in a Celery config file?

Because all of this code is in the provisioningserver code. Basically all the DNS-related is in provisioningserver. Strickly speaking, this set-up stuff is not executed by a task though.

> [3]
>
> +DEFAULT_CONTROLS = """
> +controls {
> +    inet 127.0.0.1 port 953 allow { localhost; };
> +};
> +"""
>
> Include a comment here, about what placed it, and why? Also, remove
> leading new-line?

Added a comment, but I'd like to keep the leading new-line because this snippet is used with "content += snippet" and so the leading new-line is a safety net to avoid any change of fucking up the config file.

Revision history for this message
Gavin Panella (allenap) wrote :

> > [2]
> >
> > +# Include the default RNDC controls (default RNDC key on port 953).
> > +DNS_DEFAULT_CONTROLS = True
> >
> > Why is this in a Celery config file?
>
> Because all of this code is in the provisioningserver code.

Precisely. The provisioningserver code has a config file, pserv.yaml.
More configuration options drifting around in semi-related files makes
the software, as a whole, harder to control, to understand, to debug,
to document.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'etc/celeryconfig_common.py'
2--- etc/celeryconfig_common.py 2012-10-05 16:33:37 +0000
3+++ etc/celeryconfig_common.py 2012-10-16 10:48:29 +0000
4@@ -27,6 +27,9 @@
5 # server.
6 DNS_RNDC_PORT = 954
7
8+# Include the default RNDC controls (default RNDC key on port 953).
9+DNS_DEFAULT_CONTROLS = True
10+
11 # DHCP leases file, as maintained by ISC dhcpd.
12 DHCP_LEASES_FILE = '/var/lib/maas/dhcp/dhcpd.leases'
13
14
15=== modified file 'etc/democeleryconfig_common.py'
16--- etc/democeleryconfig_common.py 2012-09-28 13:37:39 +0000
17+++ etc/democeleryconfig_common.py 2012-10-16 10:48:29 +0000
18@@ -25,6 +25,11 @@
19 DNS_RNDC_PORT = 9154
20
21
22+# Do not include the default RNDC controls statement to avoid
23+# a conflict while trying to listen on port 943.
24+DNS_DEFAULT_CONTROLS = False
25+
26+
27 DHCP_CONFIG_FILE = os.path.join(
28 DEV_ROOT_DIRECTORY, 'run/dhcpd.conf')
29
30
31=== modified file 'src/provisioningserver/dns/config.py'
32--- src/provisioningserver/dns/config.py 2012-10-16 09:31:20 +0000
33+++ src/provisioningserver/dns/config.py 2012-10-16 10:48:29 +0000
34@@ -57,7 +57,17 @@
35 """Raised if there's a problem with a DNS config."""
36
37
38-def generate_rndc(port=953, key_name='rndc-maas-key'):
39+# Default 'controls' statement included in the configuration so that the
40+# default RNDC can be used (by init scripts).
41+DEFAULT_CONTROLS = """
42+controls {
43+ inet 127.0.0.1 port 953 allow { localhost; };
44+};
45+"""
46+
47+
48+def generate_rndc(port=953, key_name='rndc-maas-key',
49+ include_default_controls=True):
50 """Use `rndc-confgen` (from bind9utils) to generate a rndc+named
51 configuration.
52
53@@ -79,6 +89,8 @@
54 named_start = rndc_content.index(start_marker) + len(start_marker)
55 named_end = rndc_content.index(end_marker)
56 named_conf = rndc_content[named_start:named_end].replace('\n# ', '\n')
57+ if include_default_controls:
58+ named_conf += DEFAULT_CONTROLS
59 # Return a tuple of the two configurations.
60 return rndc_content, named_conf
61
62@@ -98,7 +110,8 @@
63 conf.DNS_CONFIG_DIR.
64 """
65 rndc_content, named_content = generate_rndc(
66- conf.DNS_RNDC_PORT)
67+ port=conf.DNS_RNDC_PORT,
68+ include_default_controls=conf.DNS_DEFAULT_CONTROLS)
69
70 target_file = get_rndc_conf_path()
71 with open(target_file, "wb") as f:
72
73=== modified file 'src/provisioningserver/dns/tests/test_config.py'
74--- src/provisioningserver/dns/tests/test_config.py 2012-10-16 04:05:58 +0000
75+++ src/provisioningserver/dns/tests/test_config.py 2012-10-16 10:48:29 +0000
76@@ -35,6 +35,7 @@
77 )
78 from provisioningserver.dns import config
79 from provisioningserver.dns.config import (
80+ DEFAULT_CONTROLS,
81 DNSConfig,
82 DNSConfigDirectoryMissing,
83 DNSConfigFail,
84@@ -86,6 +87,16 @@
85 conf_content = stream.read()
86 self.assertIn(content, conf_content)
87
88+ def test_rndc_config_includes_default_controls(self):
89+ dns_conf_dir = self.make_dir()
90+ self.patch(conf, 'DNS_CONFIG_DIR', dns_conf_dir)
91+ self.patch(conf, 'DNS_DEFAULT_CONTROLS', True)
92+ setup_rndc()
93+ rndc_file = os.path.join(dns_conf_dir, MAAS_NAMED_RNDC_CONF_NAME)
94+ with open(rndc_file, "rb") as stream:
95+ conf_content = stream.read()
96+ self.assertIn(DEFAULT_CONTROLS, conf_content)
97+
98 def test_execute_rndc_command_executes_command(self):
99 recorder = FakeMethod()
100 fake_dir = factory.getRandomString()