From 0de1d8d4ca8f7bb51c3e39259d0e0f48039ba5d0 Mon Sep 17 00:00:00 2001
From: Kyle Mestery <mestery@mestery.com>
Date: Wed, 17 Jun 2015 14:46:47 +0000
Subject: [PATCH] dhcp: Default to using local DNS resolution

It's pointless to not include default DNS resolution for Neutron.
This adds a new config option (dnsmasq_local_resolv) which defaults
to 'True' and will allow for DNS name resolution to work out of
the box. The caveat is that if the 'dnsmasq_dns_servers' is set it
will override the 'dnsmasq_local_resolv' setting, thus allowing
operators to explicitly set their own DNS servers.

DocImpact: Default to using local DNS resolution with the DHCP agent.

Change-Id: I17a884f467d307432a06f67a9dd93ed2fa6081a3
Closes-Bug: #1466117
Signed-off-by: Kyle Mestery <mestery@mestery.com>
---
 neutron/agent/dhcp/config.py                       |  7 +++++++
 neutron/agent/linux/dhcp.py                        |  6 +++++-
 neutron/tests/unit/agent/linux/test_dhcp.py        |  7 ++++++-
 .../notes/default-local-dns-a1c3fa1451f228fa.yaml  | 14 ++++++++++++++
 4 files changed, 32 insertions(+), 2 deletions(-)
 create mode 100644 releasenotes/notes/default-local-dns-a1c3fa1451f228fa.yaml

diff --git a/neutron/agent/dhcp/config.py b/neutron/agent/dhcp/config.py
index 926e8ec8f60..ab0d9b7263a 100644
--- a/neutron/agent/dhcp/config.py
+++ b/neutron/agent/dhcp/config.py
@@ -85,6 +85,13 @@ DNSMASQ_OPTS = [
                       "The log contains DHCP and DNS log information and "
                       "is useful for debugging issues with either DHCP or "
                       "DNS. If this section is null, disable dnsmasq log.")),
+    cfg.BoolOpt('dnsmasq_local_resolv', default=True,
+                help=_("Enables the dnsmasq service to provide name "
+                       "resolution for instances via DNS resolvers on the "
+                       "host running the DHCP agent. Effectively removes the "
+                       "'--no-resolv' option from the dnsmasq process "
+                       "arguments. Adding custom DNS resolvers to the "
+                       "'dnsmasq_dns_servers' option disables this feature.")),
     cfg.IntOpt(
         'dnsmasq_lease_max',
         default=(2 ** 24),
diff --git a/neutron/agent/linux/dhcp.py b/neutron/agent/linux/dhcp.py
index ff44a8e2310..4ccb7f6593b 100644
--- a/neutron/agent/linux/dhcp.py
+++ b/neutron/agent/linux/dhcp.py
@@ -307,7 +307,6 @@ class Dnsmasq(DhcpLocalProcess):
         cmd = [
             'dnsmasq',
             '--no-hosts',
-            '--no-resolv',
             '--strict-order',
             '--except-interface=lo',
             '--pid-file=%s' % pid_file,
@@ -384,6 +383,11 @@ class Dnsmasq(DhcpLocalProcess):
             cmd.extend(
                 '--server=%s' % server
                 for server in self.conf.dnsmasq_dns_servers)
+        else:
+            # We only look at 'dnsmasq_local_resolv' if 'dnsmasq_dns_servers'
+            # is not set, which explicitly overrides 'dnsmasq_local_resolv'.
+            if not self.conf.dnsmasq_local_resolv:
+                cmd.append('--no-resolv')
 
         if self.conf.dhcp_domain:
             cmd.append('--domain=%s' % self.conf.dhcp_domain)
diff --git a/neutron/tests/unit/agent/linux/test_dhcp.py b/neutron/tests/unit/agent/linux/test_dhcp.py
index 2fce527f59d..fe4016dc203 100644
--- a/neutron/tests/unit/agent/linux/test_dhcp.py
+++ b/neutron/tests/unit/agent/linux/test_dhcp.py
@@ -1000,7 +1000,6 @@ class TestDnsmasq(TestBase):
         expected = [
             'dnsmasq',
             '--no-hosts',
-            '--no-resolv',
             '--strict-order',
             '--except-interface=lo',
             '--pid-file=%s' % expected_pid_file,
@@ -1129,6 +1128,12 @@ class TestDnsmasq(TestBase):
                           ('--log-facility=%s' % dhcp_dns_log)],
                          network)
 
+    def test_spawn_cfg_no_local_resolv(self):
+        self.conf.set_override('dnsmasq_local_resolv', False)
+
+        self._test_spawn(['--conf-file=', '--no-resolv',
+                          '--domain=openstacklocal'])
+
     def test_spawn_max_leases_is_smaller_than_cap(self):
         self._test_spawn(
             ['--conf-file=', '--domain=openstacklocal'],
diff --git a/releasenotes/notes/default-local-dns-a1c3fa1451f228fa.yaml b/releasenotes/notes/default-local-dns-a1c3fa1451f228fa.yaml
new file mode 100644
index 00000000000..0c77e96a074
--- /dev/null
+++ b/releasenotes/notes/default-local-dns-a1c3fa1451f228fa.yaml
@@ -0,0 +1,14 @@
+---
+fixes:
+  - Prior to Mitaka, neither specifying DNS resolvers via the
+    'dnsmasq_dns_servers' option in the DHCP agent configuration file nor via
+    neutron subnet options causes the dnsmasq service to offer the IP address
+    on which it resides to instances for name resolution. However, the static
+    dnsmasq '--no-resolv' process argument prevents name resolution via dnsmasq
+    leaving instances without name resolution. In Mitaka+, the
+    'dnsmasq_local_resolv' option in the DHCP agent configuration file enables
+    (by default) the dnsmasq service to provide name resolution for instances
+    via DNS resolvers on the host running the DHCP agent by effectively
+    removing the '--no-resolv' option from the dnsmasq process arguments.
+    Adding custom DNS resolvers to the 'dnsmasq_dns_servers' option in the DHCP
+    agent configuration file disables this feature.