diff --git a/config.yaml b/config.yaml index d49981de..0fa5de43 100644 --- a/config.yaml +++ b/config.yaml @@ -142,6 +142,13 @@ options: which do not include a neutron-gateway (do not require l3, lbaas or vpnaas services) and should only be used in-conjunction with flat or VLAN provider networks configurations. + dnsmasq-flags: + type: string + default: + description: | + Comma-separated list of key=value config flags with the additional + dhcp options for neutron dnsmasq. Note, this option is only valid when + enable-local-dhcp-and-metadata option is set to True. prevent-arp-spoofing: type: boolean default: true diff --git a/hooks/neutron_ovs_context.py b/hooks/neutron_ovs_context.py index 240d6886..d92e6bbf 100644 --- a/hooks/neutron_ovs_context.py +++ b/hooks/neutron_ovs_context.py @@ -30,6 +30,7 @@ from charmhelpers.core.host import ( ) from charmhelpers.contrib.openstack import context from charmhelpers.contrib.openstack.utils import get_host_ip +from charmhelpers.contrib.openstack.utils import config_flags_parser from charmhelpers.contrib.network.ip import get_address_in_network from charmhelpers.contrib.openstack.context import ( OSContextGenerator, @@ -164,6 +165,7 @@ class DHCPAgentContext(OSContextGenerator): # its principal charm. Thus we can take the 1st (only) element in each # list. rids = relation_ids('neutron-plugin') + ctxt = {} if rids: rid = rids[0] units = related_units(rid) @@ -173,8 +175,13 @@ class DHCPAgentContext(OSContextGenerator): rid=rid, unit=units[0]) if availability_zone: - return {'availability_zone': availability_zone} - return {} + ctxt['availability_zone'] = availability_zone + + dnsmasq_flags = config('dnsmasq-flags') + if dnsmasq_flags: + ctxt['dnsmasq_flags'] = config_flags_parser(dnsmasq_flags) + + return ctxt class L3AgentContext(OSContextGenerator): diff --git a/hooks/neutron_ovs_utils.py b/hooks/neutron_ovs_utils.py index 7227c93f..541e6230 100644 --- a/hooks/neutron_ovs_utils.py +++ b/hooks/neutron_ovs_utils.py @@ -127,6 +127,7 @@ GIT_PACKAGE_BLACKLIST = [ VERSION_PACKAGE = 'neutron-common' NOVA_CONF_DIR = "/etc/nova" NEUTRON_DHCP_AGENT_CONF = "/etc/neutron/dhcp_agent.ini" +NEUTRON_DNSMASQ_CONF = "/etc/neutron/dnsmasq.conf" NEUTRON_CONF_DIR = "/etc/neutron" NEUTRON_CONF = '%s/neutron.conf' % NEUTRON_CONF_DIR NEUTRON_DEFAULT = '/etc/default/neutron-server' @@ -191,6 +192,10 @@ DHCP_RESOURCE_MAP = OrderedDict([ 'services': ['neutron-dhcp-agent'], 'contexts': [neutron_ovs_context.DHCPAgentContext()], }), + (NEUTRON_DNSMASQ_CONF, { + 'services': ['neutron-dhcp-agent'], + 'contexts': [neutron_ovs_context.DHCPAgentContext()], + }), ]) DVR_RESOURCE_MAP = OrderedDict([ (NEUTRON_L3_AGENT_CONF, { diff --git a/templates/dnsmasq.conf b/templates/dnsmasq.conf new file mode 100644 index 00000000..9f798b5f --- /dev/null +++ b/templates/dnsmasq.conf @@ -0,0 +1,5 @@ +{% if dnsmasq_flags -%} +{% for key, value in dnsmasq_flags.iteritems() -%} +{{ key }} = {{ value }} +{% endfor -%} +{% endif -%} diff --git a/templates/icehouse/dhcp_agent.ini b/templates/icehouse/dhcp_agent.ini index fe6c7b41..a49feef7 100644 --- a/templates/icehouse/dhcp_agent.ini +++ b/templates/icehouse/dhcp_agent.ini @@ -10,6 +10,10 @@ interface_driver = neutron.agent.linux.interface.OVSInterfaceDriver dhcp_driver = neutron.agent.linux.dhcp.Dnsmasq root_helper = sudo /usr/bin/neutron-rootwrap /etc/neutron/rootwrap.conf +{% if dnsmasq_flags -%} +dnsmasq_config_file = /etc/neutron/dnsmasq.conf +{% endif -%} + enable_metadata_network = True enable_isolated_metadata = True diff --git a/templates/mitaka/dhcp_agent.ini b/templates/mitaka/dhcp_agent.ini index 24a1ab41..03eb0598 100644 --- a/templates/mitaka/dhcp_agent.ini +++ b/templates/mitaka/dhcp_agent.ini @@ -11,6 +11,10 @@ interface_driver = neutron.agent.linux.interface.OVSInterfaceDriver dhcp_driver = neutron.agent.linux.dhcp.Dnsmasq root_helper = sudo /usr/bin/neutron-rootwrap /etc/neutron/rootwrap.conf +{% if dnsmasq_flags -%} +dnsmasq_config_file = /etc/neutron/dnsmasq.conf +{% endif -%} + enable_metadata_network = True enable_isolated_metadata = True diff --git a/unit_tests/test_neutron_ovs_context.py b/unit_tests/test_neutron_ovs_context.py index f0866385..d2f6632a 100644 --- a/unit_tests/test_neutron_ovs_context.py +++ b/unit_tests/test_neutron_ovs_context.py @@ -283,6 +283,24 @@ class DHCPAgentContextTest(CharmTestCase): rid='rid1', unit='nova-compute/0') + def test_dnsmasq_flags(self): + self.relation_ids.return_value = ['rid1'] + self.related_units.return_value = ['nova-compute/0'] + self.relation_get.return_value = None + self.test_config.set('dnsmasq-flags', 'dhcp-userclass=set:ipxe,iPXE,' + 'dhcp-match=set:ipxe,175,' + 'server=1.2.3.4') + self.assertEqual( + context.DHCPAgentContext()(), + { + 'dnsmasq_flags': { + 'dhcp-userclass': 'set:ipxe,iPXE', + 'dhcp-match': 'set:ipxe,175', + 'server': '1.2.3.4', + } + } + ) + class L3AgentContextTest(CharmTestCase):